Crypt::Random::TESHA2(3)

NAME
Crypt::Random::TESHA2 - Random numbers using timer/schedule entropy

VERSION
Version 0.01

WARNING
This module implements userspace voodoo entropy. You should use a proper O/S supplied entropy source such as /dev/random or the Win32 Crypt API.

SYNOPSIS
  # Nothing exported by default
  use Crypt::Random::TESHA2 qw(random_bytes random_values irand rand);

  # Get 64 random bytes
  my $seed_string = random_bytes(64);

  # Get 16 random 32-bit values
  my @seeds = random_values(16);

  # Get a 32-bit random integer (value between 0 and 4294967295 inclusive)
  my $i = irand();

  # rand, like system rand, with 32 bits of randomness.
  my $r1 = rand();      # floating point in range [0,1).
  my $r2 = rand(1000);  # floating point in range [0,1000).

  # croak if installation determined we couldn't generate enough entropy
  use Crypt::Random::TESHA2 ':strong';

  # No warnings even if we are a weak source
  use Crypt::Random::TESHA2 ':weak';

  # Ask for yourself
  die "No key for you!" unless Crypt::Random::TESHA2::is_strong();

DESCRIPTION
Generate random numbers using entropy gathered from timer / scheduler jitter.

This can be used to generate non-pseudorandom data to seed a PRNG (e.g. "srand"/"rand", Math::Random::MT, etc.) or CSPRNG (e.g. AES-CTR or Math::Random::ISAAC). You may use it directly or as part of a random source module that first checks for O/S randomness sources.

Only Perl CORE modules are used, making this very portable. However, systems must have a high resolution timer and support "usleep" from Time::HiRes.

At installation time, measurements are taken of the estimated entropy gathered by the timer differences. If the results indicated we could not get good results, then the module will consider itself "weak". On the first use of any of the functions that return randomness (e.g. random_bytes), the module will carp about not being a strong randomness source. However, two special options, ":strong" and ":weak" may be given to the importer to change this behavior. If ":strong" is used, then the module will croak. If ":weak" is used, then no carp will be generated. The function "is_strong" can be used at any time for finer control. Note that this should be an unusual case, and neither flag has any effect if the module considers itself strong.

FUNCTIONS

  random_bytes($n)
Takes an integer and returns a string of that size filled with random data.

  random_values($n)
Takes an integer and returns an array containing that many random 32-bit integers. The values will be in the range [0,4294967295] (all 32-bit values are possible).

  irand
Returns a single random 32-bit integer in the range [0,4294967295].

  rand
Returns a random float greater than or equal to 0 and less than the value of the argument. If no argument is given or the argument is zero, 1 is used. This has an identical API as system rand, though of course there is no associated srand function. The result has 32 bits of randomness.

  is_strong
Returns 0 if the installation procedure determined that not enough entropy could be gathered on this system. Returns 1 if it was able. If 0 is returned, then the bytes returned may be no better than a CSPRNG using a convoluted time-based reseed every bit.

METHOD
The underlying entropy gathering is done using timing differences between usleep calls. We wrap usleep calls of varying intervals along with some Perl hash processing inside microsecond timer calls. The two values are xored. This is the raw entropy source. Eight of these, along with the current time, are fed to a SHA-256 which can be added to an entropy pool.

Measurements of the raw timer entropy (just the timing differences -- no hashes, time, counters, xors, or entropy pool) on systems I have available indicate 1.5 to 4 bits of entropy per usleep. The installation procedure does a measurement of the 0-order entropy gathered from the raw timing process, halves it, limits to the range 1/8 - 7/8, and uses that as the estimated entropy gathered.

The actual output random bytes are generated by an entropy pool that uses SHA-512 or SHA-256. This adds data as needed from the above method, then extracts bits as needed to make the output bytes (again using a cryptographic hash and a counter, which means the entropy pool is not exposed).

The result will easily pass most stream randomness tests (e.g. FIPS-140, ENT, TestU01 Rabbit), but that is a given based on the last entropy pool stage, so this just shows we provide decorrelated output, not that we make a good seed.

LIMITATIONS
Note that pretty much every limitation of this module will apply to Math::TrulyRandom, which many non-cryptographers still think is cryptographically secure (it's recommended in both the perl core documentation as well as Math::Random::ISAAC). If you think that module is great for your application, then you should be happy with this one. Probably happier since this is more portable, doesn't hang infinitely, runs much faster, and generates better output on most systems.

As mentioned in the Warnings section, this generates userspace entropy -- what most people used until the waning years of the 20th century. We should not have to do this on modern systems that have well designed APIs to get randomness from multiple entropy pools, all managed by production code. In other words, "/dev/random".

Performance is slow (about 10,000 times slower than Math::Random::ISAAC::XS), making this something best to be used to seed a PRNG or CSPRNG, rather than using directly. On newer Linux systems and Win32 it runs about 10,000 bits per second. Cygwin runs about 1000 bits per second. Older systems will run slower of course, such as an old HPPA system I use that runs at 40 bits/s. Much of the time is spent sleeping.

Gathering entropy with this method depends on high resolution timers. If the timers have low resolution, especially if we had a system with very fast yield turnaround, then we would gather very little entropy. One of the tests tries to determine this, but it isn't perfect. As with all such userspace systems, you should check that it works before using it for anything critical. RFC4086 <http://www.ietf.org/rfc/rfc4086.txt> section 3.4 discusses a few of the pitfalls of using portable clock-based software, and section 3.6 discusses the desire for multiple entropy sources.

Because of the use of SHA-2 hashes along with an entropy pool using a counter, the output stream will pass randomness tests (e.g. FIPS-140, ENT, TestU01 Rabbit) even if there is no underlying entropy. The installation measurements should indicate whether this is happening, but it doesn't measure everything.

AUTHORS
Dana Jacobsen <dana@acm.org>

SEE ALSO

Encyclopedia of Cryptography and Security, volume 2, "Entropy Sources". The entropy pool implemented in this module follows this design.
HAVEGE (<http://www.issihosts.com/haveged/>) Uses multiple methods to gather entropy and feed it to the O/S, which can measure it and add it to a pool.  Highly recommended for embedded or network devices that don't have good external interactions, or when running programs that use a lot of entropy (e.g. anything that uses Crypt::Random).
timer_entropyd (<http://www.vanheusden.com/te/>) Uses a related method (jitter in timing data between usleeps) as this module, but inefficient and only suitable for bulk feeding of an entropy pool.  Even after von Neumann debiasing, the output has distinct patterns and at most 0.5 bits of entropy per output bit.  HAVEGE is a superior overall solution.  However, note a number of other links at the site for other sources as well as links to hardware RNGs.
Math::TrulyRandom An old module that uses an obsolete version of Matt Blaze's TrueRand. TrueRand version 2.1 fixes a number of issues with the output quality and specifically recommends against using the old method.  In addition, the Perl module will not properly run on most current platforms. A pure Perl version is included in the examples directory of this module, but it is still TrueRand version 1 and, like the old module, will not run on Win32.
Crypt::Urandom A simple module that gets a good source of O/S non-blocking randomness.
Crypt::Random::Source A complicated module that has multiple plugins for randomness sources.

COPYRIGHT
Copyright 2012-2013 by Dana Jacobsen <dana@acm.org>

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

The software is provided "AS IS", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.