Crypt::Random::Seed - Simple method to get strong randomness
Version 0.01
use Crypt::Random::Seed; my $source = new Crypt::Random::Seed; die "No strong sources exist" unless defined $source; my $seed_string = $source->random_bytes(4); my @seed_values = $source->random_values(4); # Allow weak sources, in case nothing strong is available my $maybe_weak_source = Crypt::Random::Seed( Weak=>1 ); # Only non-blocking sources my $nonblocking_source = Crypt::Random::Seed( NonBlocking=>1 ); # Blacklist sources (never choose the listed sources) my $nowin32_source = Crypt::Random::Seed( Never=>['Win32'] ); # Whitelist sources (only choose from these sources) my $devr_source = Crypt::Random::Seed( Only=>['TESHA2'] ); # Supply a custom source my $user_source = Crypt::Random::Seed( Source=>sub { egd(shift) } ); # Or supply a list of [name, sub, is_blocking, is_strong] $user_source = Crypt::Random::Seed( Source=>['egd',sub {egd(shift)},0,1] ); # Given a source there are a few things we can do: say "My randomness source is ", $source->name(); say "I am a blocking source" if $source->is_blocking(); say "I am a strong randomness source" if $source->is_strong() say "Four 8-bit numbers:", join(",", map { ord $source->random_bytes(1) } 1..4);' say "Four 32-bit numbers:", join(",", $source->random_values(4));
A simple mechanism to get strong randomness. The main purpose of this module is to provide a simple way to generate a seed for a PRNG such as Math::Random::ISAAC, or for use in cryptographic key generation. Flags for accepting weak sources or requiring nonblocking sources are given, as well as a very simple method for plugging in a source.
The randomness sources used are, in order:
CryptGenRandom
RtlGenRand
A source can also be supplied in the constructor. Each of these sources will have its debatable points about perceived strength. E.g. Why is /dev/urandom considered weak while Win32 is strong? Can any userspace method such as TrueRand or TESHA2 be considered strong?
The constructor with no arguments will find the first strong source in its fixed list and return an object that performs the defined methods. This will mean Win32, /dev/random, and TESHA2 (if it was considered strong on this platform). If no strong sources could be found (quite unusual) then the returned value will be undef.
Optional parameters are passed in as a hash and may be mixed.
Weak sources are also allowed. This means /dev/urandom will be checked right after /dev/random, and TESHA2 will be allowed even if it was considered weak on this system. If this option is specified, a source should always be available. Note that strong sources are still preferred.
Only non-blocking sources will be allowed. In practice this means /dev/random will not be chosen (except on FreeBSD where it is non-blocking).
Takes an array reference containing one or more string source names. No source whose name does not match one of these strings will be chosen. The string 'Win32' will match either of the Win32 sources.
Takes an array reference containing one or more string source names. No source whose name matches one of these strings will be chosen. The string 'Win32' will match either of the Win32 sources.
Uses the given anonymous subroutine as the generator. The subroutine will be given an integer (the argument to random_bytes) and should return random data in a string of the given length. For the purposes of the other object methods, the returned object will have the name 'User', and be considered non-blocking and non-strong.
random_bytes
Similar to the simpler source routine, but also allows the other source parameters to be defined. The name may not be one of the standard names listed in the "name" section.
Takes an integer and returns a string of that size filled with random data. Returns an empty string if the argument is not defined or is not more than zero.
Takes an integer and returns an array of that many random 32-bit values. Returns an empty array if the argument is not defined or is not more than zero.
Returns the text name of the random source. This will be one of: User for user defined, CryptGenRandom for Windows 2000 Crypto API, RtlGenRand for Windows XP and newer Crypto API, /dev/random for the UNIX-like strong randomness source, /dev/urandom for the UNIX-like non-blocking randomness source, TESHA2 for the userspace entropy method. Other methods may be supported in the future. User supplied sources may be named anything other than one of the defined names.
User
/dev/random
/dev/urandom
TESHA2
Returns 1 or 0 indicating whether the source is considered a strong source of randomness.
Returns 1 or 0 indicating whether the source can block on read. Be aware that even if a source doesn't block, it may be extremely slow.
Dana Jacobsen <dana@acm.org>
To the best of my knowledge, Max Kanat-Alexander was the original author of the Perl code that uses the Win32 API. I used his code as a reference.
David Oswald gave me a lot of help with API discussions and code reviews.
The first question one may ask is "Why yet another module of this type?" None of the modules on CPAN quite fit my needs, hence this. Some alternatives:
A comprehensive system using multiple plugins. It has a nice API, but uses Any::Moose which means you're loading up Moose or Mouse just to read a few bytes from /dev/random. It also has a very long dependency chain, with on the order of 40 modules being installed as prerequisites (depending of course on whether you use any of them on other projects). Lastly, it requires at least Perl 5.8, which may or may not matter to you. But it matters to some other module builders who end up with the restriction in their modules.
A great little module that is almost what I was looking for. Crypt::Random::Seed will act the same if given the constructor:
my $source = Crypt::Random::Seed->new( Weak => 1, NonBlocking => 1, Only => [qw(/dev/random /dev/urandom Win32)] ); croak "No randomness source available" unless defined $source;
Or you can leave out the Only and have TESHA2 as a backup.
Only
Requires Math::Pari which makes it unacceptable in some environments. Has more features (numbers in arbitrary bigint intervals or bit sizes). Crypt::Random::Seed is taking a simpler approach, just handling returning octets and letting upstream modules handle the rest.
Some modules that could use this module to help them: Bytes::Random::Secure, Math::Random::ISAAC, Math::Random::Secure, and Math::Random::MT to name a few.
Copyright 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.
To install Crypt::Random::Seed, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Crypt::Random::Seed
CPAN shell
perl -MCPAN -e shell install Crypt::Random::Seed
For more information on module installation, please visit the detailed CPAN module installation guide.