This brings up an obvious question.
Okay. We don't want pseudorandom numbers,
we want random numbers.
How do we produce them? Where do these things come from?
Well, let's look at some of the functions of the system.
The first one that everyone sees,
at least on Linux and Unix,
is a function called rand().
It's a library function.
It uses srand() to set a seed.
You can also use sranddev() on some systems to
get the generate a seed
automatically from things within the kernel.
The idea here is that what it uses in the kernel will be
sufficiently random so that the seed itself will be
random and then the sequence of
numbers you get is going to be random.
Typically, this is a 32 bit seed
and a four byte internal state and
the internal state is also
32-bits and the outputs a 32 bit number.
For whatever it's worth,
the early versions of this were not random at all.
In some versions, in fact,
the low bit alternated between zero and one.
So, if you are planning on using
a random number generator
and the system you're using has this one,
check it out and be sure it's not the original one.
Be sure it's a different one.
My own recommendation is not to
use this for anything serious.
Now, the systems also supply something called random().
It's another library function and it's very similar to
rand() except it's statistically random.
You can set up the initial state.
It's an array used to hold
the initial state and
you give it a seed and the number of
bytes in an array and that number of bytes in
the array can be anywhere from eight to 256 bytes.
It generates a 31 bit output.
If you use the full array, that is,
256 bytes, the period,
that is the time before
this pseudorandom number generator
begins to repeat itself,
is over two to the 69th which
is long enough for all practical purposes.
However, it will repeat,
which means it's a statistically
random pseudorandom number generator,
but it's not a cryptographic one.
There are other library functions as well,
lrand48() does signed random number generation
between minus two to the 31st and two to 31st minus one.
There are a variety of these.
Drand() does it for real numbers from zero to one.
Includes zero doesn't include one,
lrand() is positive numbers and mrand()
is both positive and negative numbers.
Again, you set the seed using srand().
This is a better. However, it still pseudorandom.
It's statistically random,
but it's not cryptographically random.
If you want cryptographic randomness,
go to there, many systems
there's something called arc4random().
Essentially, what you do is you look for a function that
uses cryptography to generate random numbers.
This one is based on a cipher
called ARC4 which is pretty strong.
Without going into the details of how ARC4 works,
essentially what it does is it keeps track of state.
It has over two to the 1,700 states.
Again, which is very, very, very long.
It returns an unsigned value between
zero and two to the 32nd not including two to the 32nd.
Also when you call it, automatically initializes itself.
Now, the state is encompassed by what are called S-boxes.
As you can see from this slide,
it uses 64 8-bit S-boxes.
We're not going to go into what an S-box is here other
than to say it's a substitution
of one set of bits for another.
If you don't like the one you started with or you
want to mix it up later on in
the cipher, use arc4random_stir().
That function will generate a new set
of 64 8-bit S-boxes.
It uses data from a file called or rather
from a device called /dev/urandom.
Urandom stands for unsigned random.
It's basically a file for a device that
generates random numbers from the kernel and
from other hardware things.
So, this one is very good for
cryptographic applications because you
get cryptographically secure, cryptographic randomness.