File Coverage

lib/Crypt/Random.pm
Criterion Covered Total %
statement 62 62 100.0
branch 11 14 78.6
condition 5 6 83.3
subroutine 11 11 100.0
pod 3 3 100.0
total 92 96 95.8


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -s
2             ##
3             ## Crypt::Random -- Interface to /dev/random and /dev/urandom.
4             ##
5             ## Copyright (c) 1998, Vipul Ved Prakash. All rights reserved.
6             ## This code is free software; you can redistribute it and/or modify
7             ## it under the same terms as Perl itself.
8             ##
9             ## $Id: Random.pm,v 1.11 2001/07/12 15:59:47 vipul Exp $
10              
11             package Crypt::Random;
12             require Exporter;
13 5     5   72 use vars qw($VERSION @EXPORT_OK);
  5         139  
  5         95  
14              
15             BEGIN {
16 5     5   180     *import = \&Exporter::import;
17 5         64     @EXPORT_OK = qw( makerandom makerandom_itv makerandom_octet );
18             }
19              
20 5     5   166 use Math::Pari qw(PARI floor Mod pari2pv pari2num lift);
  5         50  
  5         75  
21 5     5   87 use Carp;
  5         44  
  5         88  
22 5     5   255 use Data::Dumper;
  5         51  
  5         117  
23 5     5   204 use Class::Loader;
  5         64  
  5         159  
24 5     5   213 use Crypt::Random::Generator;
  5         51  
  5         118  
25              
26             $VERSION     = 1.25;
27              
28              
29             sub _pickprovider {
30              
31 1221     1221   224994     my (%params) = @_;
32              
33 1221 100       18413     return $params{Provider} if $params{Provider};
34 1203   50     16277     $params{Strength} ||= 0;
35 1203         26618     my $gen = new Crypt::Random::Generator Strength => $params{Strength};
36 1203         35149     return $gen->{Provider};
37              
38             }
39              
40             sub makerandom {
41              
42 1217     1217 1 15844     my ( %params ) = @_;
43              
44 1217 100       20639     $params{Verbosity} = 0 unless $params{Verbosity};
45 1217   100     224021     my $uniform = $params{Uniform} || 0;
46 1217         26112     local $| = 1;
47              
48 1217         19518     my $provider = _pickprovider(%params);
49 1217         223843     my $loader = new Class::Loader;
50 2434         239638     my $po = $loader->_load ( Module => "Crypt::Random::Provider::$provider",
51 1217 50       244832                               Args => [ map { $_ => $params{$_} }
52                                             qw(Strength Provider) ] )
53              
54                     or die "Unable to load module Crypt::Random::Provider::$provider - $!";
55 1217         50686     my $r = $po->get_data( %params );
56              
57 1217         14092     my $size = $params{Size};
58 1217         20055     my $down = $size - 1;
59              
60 1217 100       12877     unless ($uniform) {
61              
62             # We always set the high bit of the random number if
63             # we want the result to occupy exactly $size bits.
64              
65 217 100       5038         $y = unpack "H*", pack "B*", '0' x ( $size%8 ? 8-$size % 8 : 0 ). '1'.
66                          unpack "b$down", $r;
67              
68                 } else {
69              
70             # If $uniform is set $size of 2 could return 00
71             # and 01 in addition to 10 and 11. 00 and 01 can
72             # be represented in less than 2 bits, but
73             # the result of this generation is uniformally
74             # distributed.
75              
76 1000 50       245384         $y = unpack "H*", pack "B*", '0' x ( $size%8 ? 8-$size % 8 : 0 ).
77                          unpack "b$size", $r;
78              
79                 }
80              
81 1217         237057     return Math::Pari::_hex_cvt ( "0x$y" );
82              
83             }
84              
85              
86             sub makerandom_itv {
87              
88 603     603 1 9050     my ( %params ) = @_;
89              
90 603   100     13377     my $a = $params{ Lower } || 0; $a = PARI ( $a );
  603         10662  
91 603         9970     my $b = $params{ Upper }; $b = PARI ( $b );
  603         245660  
92              
93 603         13202     my $itv = Mod ( 0, $b - $a );
94 603         14363     my $size = length ( $itv ) * 5;
95 603         8777     my $random = makerandom %params, Size => $size;
96              
97 603         404878     do { $random = makerandom %params, Size => $size }
  603         10645  
98                 while ( $random >= (PARI(2)**$size) - ((PARI(2)**$size) % lift($b-$a)));
99              
100 603         655526     $itv += $random;
101 603         16571     my $r = PARI ( lift ( $itv ) + $a );
102              
103 603         8447     undef $itv; undef $a; undef $b;
  603         211520  
  603         7295  
104 603         24866     return "$r";
105              
106             }
107              
108              
109             sub makerandom_octet {
110              
111 4     4 1 54     my ( %params ) = @_;
112              
113 4 50       79     $params{Verbosity} = 0 unless $params{Verbosity};
114              
115 4         52     my $provider = _pickprovider(%params);
116 4         64     my $loader = new Class::Loader;
117 4         119     my $po = $loader->_load ( Module => "Crypt::Random::Provider::$provider",
118                                           Args => [ %params ] );
119 4         130     return $po->get_data( %params );
120              
121              
122             }
123              
124              
125             'True Value';
126              
127             =head1 NAME
128            
129             Crypt::Random - Cryptographically Secure, True Random Number Generator.
130            
131             =head1 VERSION
132            
133             $Revision: 1.11 $
134             $Date: 2001/07/12 15:59:47 $
135            
136             =head1 SYNOPSIS
137            
138             use Crypt::Random qw( makerandom );
139             my $r = makerandom ( Size => 512, Strength => 1 );
140            
141             =head1 DESCRIPTION
142            
143             Crypt::Random is an interface module to the /dev/random device found on
144             most modern unix systems. It also interfaces with egd, a user space
145             entropy gathering daemon, available for systems where /dev/random (or
146             similar) devices are not available. When Math::Pari is installed,
147             Crypt::Random can generate random integers of arbritary size of a given
148             bitsize or in a specified interval.
149            
150             =head1 BLOCKING BEHAVIOUR
151            
152             The /dev/random driver maintains an estimate of true randomness in the
153             pool and decreases it every time random strings are requested for use.
154             When the estimate goes down to zero, the routine blocks and waits for the
155             occurrence of non-deterministic events to refresh the pool.
156            
157             When the routine is blocked, Crypt::Random's read() will be blocked till
158             desired amount of random bytes have been read off of the device. The
159             /dev/random kernel module also provides another interface, /dev/urandom,
160             that does not wait for the entropy-pool to recharge and returns as many
161             bytes as requested. For applications that must not block (for a
162             potentially long time) should use /dev/urandom. /dev/random should be
163             reserved for instances where very high quality randomness is desired.
164            
165             =head1 HARDWARE RNG
166            
167             If there's a hardware random number generator available, for instance the
168             Intel i8x0 random number generator, please use it instead of /dev/random!.
169             It'll be high quality, a lot faster and it won't block! Usually your OS
170             will provide access to the RNG as a device, eg (/dev/intel_rng).
171            
172             =head1 METHODS
173            
174             =over 4
175            
176             =item B<makerandom()>
177            
178             Generates a random number of requested bitsize in base 10. Following
179             arguments can be specified.
180            
181             =over 4
182            
183             =item B<Size>
184            
185             Bitsize of the random number.
186            
187             =item B<Strength> 0 || 1
188            
189             Value of 1 implies that /dev/random should be used
190             for requesting random bits while 0 implies /dev/urandom.
191            
192             =item B<Device>
193            
194             Alternate device to request random bits from.
195            
196             =item B<Uniform> 0 || 1
197            
198             Value of 0 (default) implies that the high bit of the generated random
199             number is always set, ensuring the bitsize of the generated random will be
200             exactly Size bits. For uniformally distributed random numbers, Uniform
201             should be set to 1.
202            
203             =back
204            
205             =item B<makerandom_itv()>
206            
207             Generates a random number in the specified interval. In addition
208             to the arguments to makerandom() following attributes can be
209             specified.
210            
211             =over 4
212            
213             =item B<Lower>
214            
215             Inclusive Lower limit.
216            
217             =item B<Upper>
218            
219             Exclusive Upper limit.
220            
221             =back
222            
223             =item B<makerandom_octet()>
224            
225             Generates a random octet string of specified length. In addition to
226             B<Strength>, B<Device> and B<Verbosity>, following arguments can be
227             specified.
228            
229             =over 4
230            
231             =item B<Length>
232            
233             Length of the desired octet string.
234            
235             =item B<Skip>
236            
237             An octet string consisting of characters to be skipped while reading from
238             the random device.
239            
240             =back
241            
242             =back
243            
244             =head1 DEPENDENCIES
245            
246             Crypt::Random needs Math::Pari 2.001802 or higher. As of this writing, the
247             latest version of Math::Pari isn't available from CPAN. Fetch it from
248             ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl/modules/
249            
250             =head1 BIBLIOGRAPHY
251            
252             =over 4
253            
254             =item 1 random.c by Theodore Ts'o. Found in drivers/char directory of
255             the Linux kernel sources.
256            
257             =item 2 Handbook of Applied Cryptography by Menezes, Paul C. van Oorschot
258             and Scott Vanstone.
259            
260             =back
261            
262             =head1 AUTHOR
263            
264             Vipul Ved Prakash, <mail@vipul.net>
265            
266             =cut
267              
268