File Coverage

blib/lib/Crypt/Random.pm
Criterion Covered Total %
statement 71 73 97.2
branch 16 20 80.0
condition 4 4 100.0
subroutine 13 13 100.0
pod 3 3 100.0
total 107 113 94.6


line stmt bran cond sub pod time code
1             ##
2             ## Crypt::Random -- Interface to /dev/random and /dev/urandom.
3             ##
4             ## Copyright (c) 1998-2018, Vipul Ved Prakash. All rights reserved.
5             ## This code is free software; you can redistribute it and/or modify
6             ## it under the same terms as Perl itself.
7              
8 7     7   244200 use strict;
  7         13  
  7         485  
9 7     7   60 use warnings;
  7         13  
  7         529  
10             package Crypt::Random;
11             require Exporter;
12 7     7   40 use vars qw($VERSION @EXPORT_OK);
  7         13  
  7         693  
13              
14             BEGIN {
15 7     7   31 *import = \&Exporter::import;
16 7         214 @EXPORT_OK = qw( makerandom makerandom_itv makerandom_octet );
17             }
18              
19 7     7   5846 use Math::Pari qw(PARI floor Mod pari2pv pari2num lift);
  7         119138  
  7         34  
20 7     7   5954 use Carp;
  7         25  
  7         556  
21 7     7   4973 use Data::Dumper;
  7         76417  
  7         640  
22 7     7   3184 use Class::Loader;
  7         6967  
  7         294  
23 7     7   4187 use Crypt::Random::Generator;
  7         23  
  7         5980  
24              
25             our $VERSION = '1.57';
26              
27             sub _pickprovider {
28              
29 1714     1714   8084 my (%params) = @_;
30              
31 1714 100       5907 return $params{Provider} if $params{Provider};
32 703 100       2182 $params{Strength} = defined $params{Strength} ? $params{Strength} : 1;
33 703         3431 my $gen = Crypt::Random::Generator->new( ( Strength => $params{Strength} ));
34 703         5118 return $gen->{Provider};
35              
36             }
37              
38             sub makerandom {
39              
40 1711     1711 1 226043 my ( %params ) = @_;
41              
42 1711 100       4832 $params{Verbosity} = 0 unless $params{Verbosity};
43 1711   100     4414 my $uniform = $params{Uniform} || 0;
44 1711         34773 local $| = 1;
45              
46 1711         5989 my $provider = _pickprovider(%params);
47 1711         6541 my $loader = Class::Loader->new();
48             my $po = $loader->_load ( Module => "Crypt::Random::Provider::$provider",
49 1711 50       12161 Args => [ map { $_ => $params{$_} }
  3422         15731  
50             qw(Strength Provider) ] )
51              
52             or die "Unable to load module Crypt::Random::Provider::$provider - $!";
53 1711         27786 my $r = $po->get_data( %params );
54              
55 1711         7171 my $size = $params{Size};
56 1711 50       3551 unless ($size) { die "makerandom() called without 'Size' parameter." }
  0         0  
57              
58 1711         2706 my $down = $size - 1;
59              
60 1711         2516 my $y;
61 1711 100       3445 unless ($uniform) {
62              
63             # We always set the high bit of the random number if
64             # we want the result to occupy exactly $size bits.
65              
66 8 100       91 $y = unpack "H*", pack "B*", '0' x ( $size%8 ? 8-$size % 8 : 0 ). '1'.
67             unpack "b$down", $r;
68              
69             } else {
70              
71             # If $uniform is set, $size of 2 could return 00
72             # and 01 in addition to 10 and 11. 00 and 01 can
73             # be represented in less than 2 bits, but
74             # the result of this generation is uniformaly
75             # distributed.
76              
77 1703 100       28130 $y = unpack "H*", pack "B*", '0' x ( $size%8 ? 8-$size % 8 : 0 ).
78             unpack "b$size", $r;
79              
80             }
81              
82 1711         9191 return Math::Pari::_hex_cvt ( "0x$y" );
83              
84             }
85              
86              
87             sub makerandom_itv {
88              
89 702     702 1 468946 my ( %params ) = @_;
90              
91 702   100     3654 my $a = $params{ Lower } || 0; $a = PARI ( $a );
  702         1951  
92 702         1531 my $b = $params{ Upper }; $b = PARI ( $b );
  702         1902  
93              
94 702 50       2931 unless ($b) {
95 0         0 die "makerandom_itv needs 'Upper' parameter."
96             }
97              
98 702         3372 my $itv = Mod ( 0, $b - $a );
99 702         4530 my $size = length ( $itv ) * 5;
100             #my $random = makerandom %params, Size => $size; # extra we can get rid of it
101              
102 702         1309 my $random;
103 702         1040 do { $random = makerandom %params, Size => $size, Uniform => 1 } # should always be uniform
  702         2503  
104             while ( $random >= (PARI(2)**$size) - ((PARI(2)**$size) % lift($b-$a)));
105              
106 702         90224 $itv += $random;
107 702         5098 my $r = PARI ( lift ( $itv ) + $a );
108              
109 702         2771 undef $itv; undef $a; undef $b;
  702         2219  
  702         1550  
110 702         8179 return "$r";
111              
112             }
113              
114              
115             sub makerandom_octet {
116              
117 3     3 1 225011 my ( %params ) = @_;
118              
119 3 50       10 $params{Verbosity} = 0 unless $params{Verbosity};
120              
121 3         7 my $provider = _pickprovider(%params);
122 3         17 my $loader = Class::Loader->new();
123 3         25 my $po = $loader->_load ( Module => "Crypt::Random::Provider::$provider",
124             Args => [ %params ] );
125 3         45 return $po->get_data( %params );
126              
127              
128             }
129              
130              
131             'True Value';
132              
133             =head1 NAME
134              
135             Crypt::Random - Cryptographically Secure, True Random Number Generator.
136              
137             =head1 SYNOPSIS
138              
139             use Crypt::Random qw( makerandom );
140             my $r = makerandom ( Size => 512, Strength => 1 );
141              
142             =head1 DESCRIPTION
143              
144             Crypt::Random is an interface module to the /dev/random and /dev/urandom
145             device found on most modern unix systems. It also interfaces with egd,
146             a user space entropy gathering daemon, available for systems where
147             /dev/random (or similar) devices are not available. When Math::Pari is
148             installed, Crypt::Random can generate random integers of arbitrary size
149             of a given bitsize or in a specified interval.
150              
151             =head1 ALTERNATIVES
152              
153             Crypt::Random has numerous options for obtaining randomness. If you would
154             prefer a simpler module that provides cryptographic grade randomness
155             Crypt::URandom should be considered.
156              
157             The CPANSec group has developed the L that should be reviewed before dealing with randomness.
158              
159             =head1 BLOCKING BEHAVIOUR
160              
161             Since kernel version 5.6 in 2020, /dev/random is no longer blocking and
162             there is effectively no difference between /dev/random and /dev/urandom.
163             Indeed there has been no difference in the quality of randomness from
164             either in many years. /dev/random now only blocks on startup of the
165             system and only for a very short time.
166              
167             =head1 HARDWARE RNG
168              
169             If there's a hardware random number generator available, for instance
170             the Intel i8x0 random number generator, you can use it instead of
171             /dev/random or /dev/urandom. Usually your OS will provide access to the
172             RNG as a device, eg (/dev/intel_rng).
173              
174             =head1 METHODS
175              
176             =over 4
177              
178             =item B
179              
180             Generates a random number of requested bitsize in base 10. Following
181             arguments can be specified.
182              
183             =over 4
184              
185             =item B
186              
187             Bitsize of the random number.
188              
189             =item B
190              
191             Specifies the name of the Provider to be used. B.
192              
193             Options are:
194              
195             =over 4
196              
197             =item devrandom
198              
199             Uses /dev/random to generate randomness.
200              
201             =item devurandom
202              
203             Uses /dev/urandom to generate randomness.
204              
205             =item Win32API
206              
207             Uses the Windows API SystemFunction036 (RtlGenRandom) to generate
208             randomness on Windows Operating Systems.
209              
210             =item egd (INSECURE)
211              
212             An Entropy Gathering Daemon (egd) daemon is read to obtain randomness.
213             As egd has not been updated since 2002 it has been moved to the low
214             strength provider list.
215              
216             =item rand
217              
218             Generates randomness based on Perl's Crypt::URandom urandom function.
219              
220             =back
221              
222             =item B 0 || 1
223              
224             Value of 1 implies that /dev/random or /dev/urandom should be used
225             for requesting random bits while 0 implies insecure including rand.
226              
227             As of release 1.55 Strength defaults to 1 (/dev/random or
228             /dev/urandom or rand (using Crypt::URandom::urandom))
229              
230             =item B
231              
232             Alternate device to request random bits from.
233              
234             =item B 0 || 1
235              
236             Value of 0 (default) implies that the high bit of the generated random
237             number is always set, ensuring the bitsize of the generated random will be
238             exactly Size bits. For uniformly distributed random numbers, Uniform
239             should be set to 1.
240              
241             =back
242              
243             =item B
244              
245             Generates a random number in the specified interval. In addition
246             to the arguments to makerandom() following attributes can be
247             specified.
248              
249             =over 4
250              
251             =item B
252              
253             Inclusive Lower limit.
254              
255             =item B
256              
257             Exclusive Upper limit.
258              
259             =back
260              
261             =item B
262              
263             Generates a random octet string of specified length. In addition to
264             B, B and B, following arguments can be
265             specified.
266              
267             =over 4
268              
269             =item B
270              
271             Length of the desired octet string.
272              
273             =item B
274              
275             An octet string consisting of characters to be skipped while reading from
276             the random device.
277              
278             =back
279              
280             =back
281              
282             =head1 DEPENDENCIES
283              
284             Crypt::Random needs Math::Pari 2.001802 or higher.
285              
286             =head1 SEE ALSO
287              
288             Crypt::URandom should be considered as simpler module for obtaining
289             cryptographically secure source of Randomness.
290              
291             The CPANSec group has developed the L that should be reviewed before dealing with randomness.
292              
293             =head1 BIBLIOGRAPHY
294              
295             =over 4
296              
297             =item 1 random.c by Theodore Ts'o. Found in drivers/char directory of
298             the Linux kernel sources.
299              
300             =item 2 Handbook of Applied Cryptography by Menezes, Paul C. van Oorschot
301             and Scott Vanstone.
302              
303             =back
304              
305             =head1 LICENSE
306              
307             This is free software; you can redistribute it and/or modify it under
308             the same terms as the Perl 5 programming language system itself.
309              
310             =head1 AUTHOR
311              
312             Vipul Ved Prakash,
313              
314             =cut
315