AnalogRead for a Random Seed.

When programming in Windows, I use a Randomizer feature or it's not "random" infact it's not really random because at the core of it, the seed to which generate a random value is indeed not random, taken from the internal clock etc.

So I was thinking of creating a little USB box and sticking an attiny85 in there and then using AnalogRead on a floating pin, maybe a small antenna, using any interference and any radio waves to generate a seed to base my Random on, so would this work? or is there some quirk with analogRead(); to produce a random seed?

...so would this work?

Not very well.

And your reasoning? (Picking up stray waves, has to be "Random")

https://www.google.com/search?q="coding+badly"+analogread+randomseed+site%3Aforum.arduino.cc

Ah but he's got no antenna.... I purposely want to detect something...

Ah but he's got no antenna.... I purposely want to detect something...

What are you going to connect the antenna to? For what purpose? The value read from an analog pin with nothing connected to it, or with a long wire connected to it but nothing else, is NOT random.

PaulS:

Ah but he's got no antenna.... I purposely want to detect something...

What are you going to connect the antenna to? For what purpose? The value read from an analog pin with nothing connected to it, or with a long wire connected to it but nothing else, is NOT random.

Why's picking up emi/emf (via an antenna) NOT going to give a random value?

Do you mind explaining yourself for a change?

Do you mind explaining yourself for a change?

Do you mind reading the link that Coding Badly posted? Do you mind reading all the other threads where people have whined about the non-randomness of analogRead()? You can't expect random values from analogRead(). Get over it.

Well obviously its picking up a signal from the environment, and most of that is
likely mains sine wave, which is periodic and easy to eavesdrop (from miles away!)

To be random it needs to have no correlation with anything a "attacker" can observe
or affect and be fundamentally unpredictable (this is why people use geiger counters
to generate cryptographical secure random bits).

Most uses of random numbers are for cryptography these days, and the obvious way
to break a system using analogRead() and an antenna is to place a large voltage
signal of known frequency near the antenna(*), saturating the ADC so it returns 0 or
1023 almost every sample. Not random then is it?

(*) mains is good for this!

Much more insight into the thorny problem of generating randomness is in the
book "Cryptography Engineering" Schneier on Security: : Cryptography Engineering, which
I'd recommend as a good starting place for learning about such issues and the
reality of security coding.

Modern processors have on-chip random noise generators for producing secure
random bits (I think all intel chips have this now, even the Arduino Due has one).
Are you sure Windows isn't already producing random bits in hardware?

PaulS:

Do you mind explaining yourself for a change?

Do you mind reading the link that Coding Badly posted? Do you mind reading all the other threads where people have whined about the non-randomness of analogRead()? You can't expect random values from analogRead(). Get over it.

Do you mind listening for a change instead of spouting.... because however amusing it is to see you wound up, it's not answerinv my question...

Mark has just pointed out something useful... yeah saturating the airwaves would break a crypto routine, but I'm interested in only pulling a random value from the air, let the attacks begin, I'd be using it as a seed for whatever os you use.

But... Mains yes I never considered that, 50/60 hertz I'd need to work out antenna length... thanks for input gives me something to think about...

I guess I could amplify a weak signal without the antenna but that would just be interference... no I like the idea of tuning the atenna for mains frequency. ..

Forget the RF. Amplify the signal from a reverse biased PN junction and use a schmitt trigger to square it up.

Or re-create the lavarand. 8^)

I think you are ignoring the fundamental problem with using analogRead() to get random values - how can you prove that it's random? How can you prove it's more random than the system within your PC?

There is a huge amount of non-random electromagnetic radiation - BBC radio, Wifi, phones etc etc. How can you know whether you are detecting some of that or something truly non-random. I reckon it would be safest to assume that "randomly chosen" electromagnetic radiation is anything but random.

What (or who) are you trying to protect against? Perhaps there are simpler security measures.

...R

cjdelphi:
I guess I could amplify a weak signal without the antenna but that would just be interference...

Very likely "Interference" from the processor's clock (or surrounding circuit) which would be perfectly synchronized to the processor making it impossible to extract any entropy.

no I like the idea of tuning the atenna for mains frequency. ..

Which is a perfectly tuned 60 (or 50) Hz signal also making it a terrible source of entropy.

The links provided by CB provide plenty of evidence that AnalogRead is always a bad source for entropy.

Here is a single link to a post where I actually provided measurement evidence of the problem (something that should be done for any source of 'entropy' that is being considered for use.

http://forum.arduino.cc/index.php?topic=111868.msg840693#msg840693

OP, for your stated interest (a box of entropy to feed a windows machine) you can find code, circuits, and test data at Google Code Archive - Long-term storage for Google Code Project Hosting.

If you can get by with a relatively slow generation rate, about 8 bytes per second, the Entropy library at the above link can work with nothing more than a plain jane arduino.

For faster generation rates there are two other options that I have tested on that link. Radioactive decay, and avalance noise from a reverse biased transistor. The radioactive decay was a problem for long term use since two geiger counters from two different manufacturers failed in much the same manner in fairly short order. However, if you are willing to risk replacing the geiger counters fairly regularly, then it works. However, without a fairly high radiation source the generation rate will still be fairly low (couple of megabytes per day).

I have found avalanche noise to be the best source that will produce the best entropy rate, about 40Mb per day.

No matter what source you decide to use, it should be tested before it is relied on. Even those designs I present in the above link which worked for me. Individual environments and assembly can introduce significant biases, that require testing to ensure the source is valid. The above link also provides some explanation of basic testing as well as source of software for more thorough testing if your needs demand it.

Oh, and having a truly random seed is only part of the battle. The quality of the pseudo random number generator used is also vitally important. The ones built into ALL operating systems are quite poor from a crypto-graphic sense and even with a 'true and perfect' random seed will still be easily broken. The book mentioned above is a good start to learning how to implement/select a good pseudo random number generator.

Granted I’m just going on instinct here and haven’t tested it, but after reading up on this issues more I have an idea.

  1. randomSeed() take a number between 0 and 2147483647 (aka 31 bits)
  2. analogRead(0) returns values with very little variation

Well, that seems like a nonstarter doesn’t it? However, lets think about those 31 bits a little more. There is very little variation in the possible value of each of those bits. You might even call it boolean. So, that immediately suggests 2 approaches.

  1. Take 31 readings of analogRead(0) and set a bit to previousReading < currentReading
  2. Take 31 readings, calculate the mean (or maybe median), set each bit to mean < reading

I would expect that you’d get a lot more variation in your seed values.

  1. randomSeed() take a number between 0 and 2147483647 (aka 31 bits)

1 and 2147483647. Zero is poison.

I would expect that you'd get a lot more variation in your seed values.

You are in good company. You are not the first person to make the mistake of believing that helps.

http://forum.arduino.cc/index.php?topic=66206.msg630884#msg630884
http://forum.arduino.cc/index.php?topic=66206.msg631681#msg631681

Why do you exclude negative numbers? They are feeling left out.

The reference page for randomSeed() doesn't mention anything about positive or negative numbers. All it says is that the parameter is a long int, ie, signed 32 bits.

https://www.google.com/search?q=park+miller+valid+seeds

Negative seed values are degenerative (essentially worthless). Zero is poison. srandom / srand ensure the seed is never set to zero.

While @RichardBronosky is correct that randomSeed can "take 0", there is no point in including zero in any discussion.

So it turns out that the reference for randomSeed() is incorrect (or incomplete at best). It actually takes an unsigned long int parameter. This matches the underlying srandom() call. Previously (before May 20 of this year), it took an unsigned int. Fail. It never took a long int parameter.

(Also, the fact that Arduino/avr-libc uses a Park-Miller PRNG is an implementation detail. It should work correctly with all valid inputs as documented.)