How to seed srand()?

Hello, I need to generate random number in my app. I cannot find any documentation in hardwario SDK, however I found that srand() and rand() are available. However, I lack the idea how to proper seed the generator as I cannot find out any good source of entropy. Maybe mix readings from accelerator + temperature + analog input read?

I don’t need cryptographically strong entropy, but calling rand() gives me deterministic results. I suppose it is seeded by MCU ID or something like this. Did anyone solved it yet? Any tested code here around? Thank you!

Hi,
we never really needed real random numbers. The reason is that we use rand() only in our radio stack to repeat the transmission.
There are more solutions where to get random data based on your requirements.

MCU random generator

The MCU has this peripheral, but we haven’t support for it in SDK. But you can still use STM32 HAL library which is not used now but it is still included in the SDK.

in file sdk/bcl/stm/inc/stm32l0xx_hal_conf.h uncomment HAL_RNG_MODULE_ENABLED

Create global structure in the top of application.c for RNG

RNG_HandleTypeDef rnd;

In application_init() enable clock and peripheral and read value.

__HAL_RCC_RNG_CLK_ENABLE();
rnd.Instance = RNG;
HAL_RNG_Init(&rnd);

And in application_task() loop I have this. Note that RNG needs to enable PLL at least during number generation.

uint32_t rng;

bc_system_pll_enable();
int ret = HAL_RNG_GenerateRandomNumber(&rnd, &rng);
bc_system_pll_disable();

bc_log_debug("APP: ret %d, %lu", ret, rng);

And here are random values

0.50 <D> APP: ret 0, 1868780179
1.00 <D> APP: ret 0, 1768378975
1.50 <D> APP: ret 0, 1807353431
2.00 <D> APP: ret 0, 67176906

The ATSHA204 cryptochip and RNG

This would be the best solution, but you need to write some nonce value and then lock the chip EEPROM forever if I understood it right. Since we are not using this chip yet we did not decided to lock it so the generator should return just some fixed data 0xFFFF0000 according to datasheet. http://ww1.microchip.com/downloads/en/devicedoc/Atmel-8740-CryptoAuth-ATSHA204-Datasheet.pdf
If you or someone needs real radnomness, this would be the best solution.

ADC, reference

I tried now the ADC and I’m not convinced that these data are “noisy” enough. But you can try it on your module and maybe there will be difference.

I put bc_adc_init(); to the application_init() and then this is my task:

void application_task(void)
{
    float voltage;
    uint16_t res;
    bc_adc_get_vdda_voltage(&voltage);
    bc_adc_get_value(7, &res);
    bc_log_debug("APP: %f, %d", voltage, res);
    bc_scheduler_plan_current_from_now(500);
}

This is result, not too much randomness in it

0.50 <D> APP: 1.227206, 8320
1.00 <D> APP: 1.227206, 3952
1.50 <D> APP: 1.227206, 3888
2.00 <D> APP: 1.227206, 3936
2.50 <D> APP: 1.227206, 3936
3.00 <D> APP: 1.227206, 3936
3.50 <D> APP: 1.227206, 3952
4.00 <D> APP: 1.227206, 3808
4.50 <D> APP: 1.227206, 3904
5.00 <D> APP: 1.227206, 3936
5.50 <D> APP: 1.227206, 3920
6.00 <D> APP: 1.227206, 3904
6.50 <D> APP: 1.227206, 3920

MCU has also internal temperature sensor but we haven’t support for it in SDK. It is connected to the ADC ADC_IN18 input.

Accelerometer

Combine somehow all three axes (XORing?) and then hash it and use the number. In the accelerometer there is also internal temperature sensor which could be used, but this has no support in SDK and you need to set or read some I2C registers inside.

TMP122 temperature sensor

This sensor is on every Core Module and could be used to seed randomness.

Thank you for your comprehensive answer! I think it can be eventually useful for other users, too.

For cryptographic operations I would definitely go with MCU HRNG or ATSHA HRNG. However, in my particular case I don’t like the need to modify SDK as I want to be on upstream as much as possible, plus what I really need is something like easy dice roll. So I’ll give it a try to XORing accelerometer values, ADC and temperature. Especially because I already read accelerometer and TMP112 in my app.

Hi, I’ve enabled that RNG module in SDK

Just call make update in your project and the MCU RNG should work. So you can use default SDK.

2 Likes