RobTillaart / DEVRANDOM

Arduino library to wrap a random generator in a stream
MIT License
2 stars 1 forks source link

Seeding #12

Closed chlordk closed 6 months ago

chlordk commented 7 months ago

When using PRNG setting the seed to something random is very important, otherwise the result can be predicted.

Arduino does not have a disk or network to give entropy, so the possibilities is:

RobTillaart commented 7 months ago

Seeding is very hard

For real entropy you need dedicated hardware, thats why I have the two modi analogRead and digitalRead to read from an external (noisy) source.

1) micros always has the last 2 bits zero on 16Mhz boards. So you can harvest 1 bit per ~8 micros max. But often not too bad

2) AnalogRead does not always float random if not connected. Sometimes it just stays stable. One can harvest 1 bit per call at most, and it needs a Neumann filter to remove bias. When it floats it is often good enough for games etc.

3) uniqueID - do you have a link. ?

4) EEPROM, could help however there are boards that do not have EE. So less usefull.

5) Hashing the content of all RAM including non initialized and time and date might give a reasonable seed, although predictable. To be tested.

6) key input from a user can be used to constantly harvest entropy. Especially in combination with micros.

On Hackaday there was recently an article of someone who had a geiger counter connected to an ESP32 (not sure ?) And used it as a random number server.

On the Arduino forum there was a great discussion about entropy by ??? in 2010-2023 or so. What he did was using the watchdog timer to generate entropy. If I understood well there are small differences in crystals / resonators and reboot time.

chlordk commented 7 months ago
  1. If I store the first value I can get with micros() it is 4. Minus two bits is one. So not very useful.

  2. UniqueID is in the libraries https://github.com/ricaun/ArduinoUniqueID My ID is 55 33 33 34 38 39 12 1B 0C and I guess many of your bits are the same, so not so many bits to get there.

  3. I meant: If the end user has EE he can use choose to use it. I didn't think of having it your library.

RobTillaart commented 7 months ago

2) Now I recall seeing that ID Library, Need to find time to check it again.

RobTillaart commented 7 months ago

The uniqueID is a nice library however not usable as seed It would provide different seeds per processor but give the same seed if a processor reboots, So in some scenarios still predictable. Usable as part of the seed.

RobTillaart commented 7 months ago

How about this function? Definitely not random however useful for seeding.

An analogWrite() call (~12 us) is about 9x faster than analogRead() (112 us) on an UNO.

uint32_t randomizer()
{
  uint32_t value = 0;
  for (int i = 0; i < 32; i++)
  {
    uint32_t start = micros();
    analogWrite(9, micros());
    uint32_t stop = micros();
    value <<= 1;
    value |= (((stop - start) >> 2) & 1);    //  strip one bit per iteration
  }
  return value;
}
RobTillaart commented 6 months ago

Seeding is very important however deriving good seeds is outside the scope of this library. It might be an idea to collect entropy generating algorithms in a repo. (Probably done already).

So I close this issue but feel free to add comments or remarks.

RobTillaart commented 6 months ago

@chlordk

FYI - https://forum.arduino.cc/t/random-input-for-randomseed/1202412