File Coverage

lib/Crypt/Random.pm
Criterion Covered Total %
statement 64 66 96.9
branch 14 18 77.7
condition 5 6 83.3
subroutine 11 11 100.0
pod 3 3 100.0
total 97 104 93.2


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-2018, 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             package Crypt::Random;
10             require Exporter;
11 6     6   5838 use vars qw($VERSION @EXPORT_OK);
  6         30  
  6         451  
12              
13             BEGIN {
14 6     6   30 *import = \&Exporter::import;
15 6         112 @EXPORT_OK = qw( makerandom makerandom_itv makerandom_octet );
16             }
17              
18 6     6   4203 use Math::Pari qw(PARI floor Mod pari2pv pari2num lift);
  6         61396  
  6         32  
19 6     6   1165 use Carp;
  6         11  
  6         420  
20 6     6   3106 use Data::Dumper;
  6         39704  
  6         336  
21 6     6   2174 use Class::Loader;
  6         3703  
  6         160  
22 6     6   1371 use Crypt::Random::Generator;
  6         13  
  6         3253  
23              
24             $VERSION = 1.54;
25              
26              
27             sub _pickprovider {
28              
29 1714     1714   3674 my (%params) = @_;
30              
31 1714 100       3760 return $params{Provider} if $params{Provider};
32 703   50     2483 $params{Strength} ||= 0;
33 703         2069 my $gen = new Crypt::Random::Generator Strength => $params{Strength};
34 703         2921 return $gen->{Provider};
35              
36             }
37              
38             sub makerandom {
39              
40 1711     1711 1 4121 my ( %params ) = @_;
41              
42 1711 100       3119 $params{Verbosity} = 0 unless $params{Verbosity};
43 1711   100     2515 my $uniform = $params{Uniform} || 0;
44 1711         24178 local $| = 1;
45              
46 1711         5170 my $provider = _pickprovider(%params);
47 1711         4139 my $loader = new Class::Loader;
48             my $po = $loader->_load ( Module => "Crypt::Random::Provider::$provider",
49 1711 50       6710 Args => [ map { $_ => $params{$_} }
  3422         7691  
50             qw(Strength Provider) ] )
51              
52             or die "Unable to load module Crypt::Random::Provider::$provider - $!";
53 1711         17160 my $r = $po->get_data( %params );
54              
55 1711         3137 my $size = $params{Size};
56 1711 50       2428 unless ($size) { die "makerandom() called without 'Size' parameter." }
  0         0  
57              
58 1711         1791 my $down = $size - 1;
59              
60 1711 100       2308 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 8 100       70 $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 uniformaly
74             # distributed.
75              
76 1703 100       9056 $y = unpack "H*", pack "B*", '0' x ( $size%8 ? 8-$size % 8 : 0 ).
77             unpack "b$size", $r;
78              
79             }
80              
81 1711         5355 return Math::Pari::_hex_cvt ( "0x$y" );
82              
83             }
84              
85              
86             sub makerandom_itv {
87              
88 702     702 1 7089 my ( %params ) = @_;
89              
90 702   100     2173 my $a = $params{ Lower } || 0; $a = PARI ( $a );
  702         1455  
91 702         892 my $b = $params{ Upper }; $b = PARI ( $b );
  702         1130  
92              
93 702 50       1827 unless ($b) {
94 0         0 die "makerandom_itv needs 'Upper' parameter."
95             }
96              
97 702         2336 my $itv = Mod ( 0, $b - $a );
98 702         3262 my $size = length ( $itv ) * 5;
99             #my $random = makerandom %params, Size => $size; # extra we can get rid of it
100              
101 702         950 my $random;
102 702         739 do { $random = makerandom %params, Size => $size, Uniform => 1 } # should always be uniform
  702         1674  
103             while ( $random >= (PARI(2)**$size) - ((PARI(2)**$size) % lift($b-$a)));
104              
105 702         52052 $itv += $random;
106 702         2281 my $r = PARI ( lift ( $itv ) + $a );
107              
108 702         1822 undef $itv; undef $a; undef $b;
  702         1084  
  702         947  
109 702         4368 return "$r";
110              
111             }
112              
113              
114             sub makerandom_octet {
115              
116 3     3 1 212 my ( %params ) = @_;
117              
118 3 50       9 $params{Verbosity} = 0 unless $params{Verbosity};
119              
120 3         12 my $provider = _pickprovider(%params);
121 3         17 my $loader = new Class::Loader;
122 3         25 my $po = $loader->_load ( Module => "Crypt::Random::Provider::$provider",
123             Args => [ %params ] );
124 3         38 return $po->get_data( %params );
125              
126              
127             }
128              
129              
130             'True Value';
131              
132             =head1 NAME
133              
134             Crypt::Random - Cryptographically Secure, True Random Number Generator.
135              
136             =head1 VERSION
137              
138             $Revision: 1.11 $
139             $Date: 2001/07/12 15:59:47 $
140              
141             =head1 SYNOPSIS
142              
143             use Crypt::Random qw( makerandom );
144             my $r = makerandom ( Size => 512, Strength => 1 );
145              
146             =head1 DESCRIPTION
147              
148             Crypt::Random is an interface module to the /dev/random device found on
149             most modern unix systems. It also interfaces with egd, a user space
150             entropy gathering daemon, available for systems where /dev/random (or
151             similar) devices are not available. When Math::Pari is installed,
152             Crypt::Random can generate random integers of arbitrary size of a given
153             bitsize or in a specified interval.
154              
155             =head1 BLOCKING BEHAVIOUR
156              
157             The /dev/random driver maintains an estimate of true randomness in the
158             pool and decreases it every time random strings are requested for use.
159             When the estimate goes down to zero, the routine blocks and waits for the
160             occurrence of non-deterministic events to refresh the pool.
161              
162             When the routine is blocked, Crypt::Random's read() will be blocked till
163             desired amount of random bytes have been read off of the device. The
164             /dev/random kernel module also provides another interface, /dev/urandom,
165             that does not wait for the entropy-pool to recharge and returns as many
166             bytes as requested. For applications that must not block (for a
167             potentially long time) should use /dev/urandom. /dev/random should be
168             reserved for instances where very high quality randomness is desired.
169              
170             =head1 HARDWARE RNG
171              
172             If there's a hardware random number generator available, for instance the
173             Intel i8x0 random number generator, please use it instead of /dev/random!.
174             It'll be high quality, a lot faster and it won't block! Usually your OS
175             will provide access to the RNG as a device, eg (/dev/intel_rng).
176              
177             =head1 METHODS
178              
179             =over 4
180              
181             =item B
182              
183             Generates a random number of requested bitsize in base 10. Following
184             arguments can be specified.
185              
186             =over 4
187              
188             =item B
189              
190             Bitsize of the random number.
191              
192             =item B 0 || 1
193              
194             Value of 1 implies that /dev/random should be used
195             for requesting random bits while 0 implies /dev/urandom.
196              
197             =item B
198              
199             Alternate device to request random bits from.
200              
201             =item B 0 || 1
202              
203             Value of 0 (default) implies that the high bit of the generated random
204             number is always set, ensuring the bitsize of the generated random will be
205             exactly Size bits. For uniformly distributed random numbers, Uniform
206             should be set to 1.
207              
208             =back
209              
210             =item B
211              
212             Generates a random number in the specified interval. In addition
213             to the arguments to makerandom() following attributes can be
214             specified.
215              
216             =over 4
217              
218             =item B
219              
220             Inclusive Lower limit.
221              
222             =item B
223              
224             Exclusive Upper limit.
225              
226             =back
227              
228             =item B
229              
230             Generates a random octet string of specified length. In addition to
231             B, B and B, following arguments can be
232             specified.
233              
234             =over 4
235              
236             =item B
237              
238             Length of the desired octet string.
239              
240             =item B
241              
242             An octet string consisting of characters to be skipped while reading from
243             the random device.
244              
245             =back
246              
247             =back
248              
249             =head1 DEPENDENCIES
250              
251             Crypt::Random needs Math::Pari 2.001802 or higher.
252              
253             =head1 BIBLIOGRAPHY
254              
255             =over 4
256              
257             =item 1 random.c by Theodore Ts'o. Found in drivers/char directory of
258             the Linux kernel sources.
259              
260             =item 2 Handbook of Applied Cryptography by Menezes, Paul C. van Oorschot
261             and Scott Vanstone.
262              
263             =back
264              
265             =head1 AUTHOR
266              
267             Vipul Ved Prakash,
268              
269             =cut
270