File Coverage

blib/lib/Crypt/PRNG.pm
Criterion Covered Total %
statement 43 44 97.7
branch 11 16 68.7
condition n/a
subroutine 14 15 93.3
pod 10 10 100.0
total 78 85 91.7


line stmt bran cond sub pod time code
1             package Crypt::PRNG;
2              
3 21     21   70707 use strict;
  21         49  
  21         584  
4 21     21   99 use warnings;
  21         46  
  21         2313  
5             our $VERSION = '0.079_007';
6              
7             require Exporter; our @ISA = qw(Exporter); ### use Exporter 5.57 'import';
8             our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] );
9             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
10             our @EXPORT = qw();
11              
12 21     21   146 use Carp;
  21         39  
  21         1485  
13             $Carp::Internal{(__PACKAGE__)}++;
14 21     21   2761 use CryptX;
  21         42  
  21         13472  
15              
16             sub string {
17 12     12 1 2098 my ($self, $len) = @_;
18 12         43 return $self->string_from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", $len);
19             }
20              
21             sub string_from {
22 24     24 1 69 my ($self, $chars, $len) = @_;
23              
24 24 50       71 $len = 20 unless defined $len;
25 24 50       65 return unless $len > 0;
26 24 50       68 return unless length($chars) > 0;
27              
28 24         246 my @ch = split(//, $chars);
29 24         61 my $max_index = $#ch;
30 24 50       78 return if $max_index > 65535;
31              
32 24         39 my $mask;
33 24         64 for my $n (1..31) {
34 108         155 $mask = (1<<$n) - 1;
35 108 100       218 last if $mask >= $max_index;
36             }
37              
38 24 50       76 my $upck = ($max_index > 255) ? "n*" : "C*";
39 24         53 my $l = $len * 2;
40              
41 24         35 my $rv = '';
42 24         38 my @r;
43 24         64 while (length $rv < $len) {
44 1259 100       2381 @r = unpack($upck, $self->bytes($l)) if scalar @r == 0;
45 1259         1738 my $i = (shift @r) & $mask;
46 1259 100       2106 next if $i > $max_index;
47 1080         1895 $rv .= $ch[$i];
48             }
49 24         388 return $rv;
50             }
51              
52 0     0   0 sub CLONE_SKIP { 1 } # prevent cloning
53              
54             ### FUNCTIONS
55              
56             {
57             ### stolen from Bytes::Random::Secure
58             #
59             # Instantiate our random number generator(s) inside of a lexical closure,
60             # limiting the scope of the RNG object so it can't be tampered with.
61             my $RNG_object = undef;
62             my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once.
63             $RNG_object = Crypt::PRNG->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR';
64             return $RNG_object;
65             };
66 2000     2000 1 7808 sub rand(;$) { return $fetch_RNG->()->double(@_) }
67 1000     1000 1 2221 sub irand() { return $fetch_RNG->()->int32() }
68 2     2 1 9 sub random_bytes($) { return $fetch_RNG->()->bytes(@_) }
69 1     1 1 15 sub random_bytes_hex($) { return $fetch_RNG->()->bytes_hex(@_) }
70 1     1 1 4 sub random_bytes_b64($) { return $fetch_RNG->()->bytes_b64(@_) }
71 1     1 1 4 sub random_bytes_b64u($) { return $fetch_RNG->()->bytes_b64u(@_) }
72 1     1 1 4 sub random_string_from($;$) { return $fetch_RNG->()->string_from(@_) }
73 1     1 1 5 sub random_string(;$) { return $fetch_RNG->()->string(@_) }
74             }
75              
76             1;
77              
78             =pod
79              
80             =head1 NAME
81              
82             Crypt::PRNG - Cryptographically secure random number generator
83              
84             =head1 SYNOPSIS
85              
86             ### Functional interface:
87             use Crypt::PRNG qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u
88             random_string random_string_from rand irand);
89              
90             $octets = random_bytes(45);
91             $hex_string = random_bytes_hex(45);
92             $base64_string = random_bytes_b64(45);
93             $base64url_string = random_bytes_b64u(45);
94             $alphanumeric_string = random_string(30);
95             $string = random_string_from('ACGT', 64);
96             $floating_point_number_0_to_1 = rand;
97             $floating_point_number_0_to_88 = rand(88);
98             $unsigned_32bit_int = irand;
99              
100             ### OO interface:
101             use Crypt::PRNG;
102              
103             $prng = Crypt::PRNG->new;
104             #or
105             $prng = Crypt::PRNG->new("RC4");
106             #or
107             $prng = Crypt::PRNG->new("RC4", "some data used for seeding PRNG");
108              
109             $octets = $prng->bytes(45);
110             $hex_string = $prng->bytes_hex(45);
111             $base64_string = $prng->bytes_b64(45);
112             $base64url_string = $prng->bytes_b64u(45);
113             $alphanumeric_string = $prng->string(30);
114             $string = $prng->string_from('ACGT', 64);
115             $floating_point_number_0_to_1 = $prng->double;
116             $floating_point_number_0_to_88 = $prng->double(88);
117             $unsigned_32bit_int = $prng->int32;
118              
119             =head1 DESCRIPTION
120              
121             Provides an interface to the ChaCha20 based pseudo random number generator (thread-safe and fork-safe).
122              
123             =head1 FUNCTIONS
124              
125             =head2 random_bytes
126              
127             $octets = random_bytes($length);
128              
129             Returns C<$length> random octects.
130              
131             =head2 random_bytes_hex
132              
133             $hex_string = random_bytes_hex($length);
134              
135             Returns C<$length> random octects encoded as hexadecimal string.
136              
137             =head2 random_bytes_b64
138              
139             $base64_string = random_bytes_b64($length);
140              
141             Returns C<$length> random octects Base64 encoded.
142              
143             =head2 random_bytes_b64u
144              
145             $base64url_string = random_bytes_b64u($length);
146              
147             Returns C<$length> random octects Base64 URL Safe (RFC 4648 section 5) encoded.
148              
149             =head2 random_string_from
150              
151             $string = random_string_from($range, $length);
152             #e.g.
153             $string = random_string_from("ABCD", 10);
154              
155             Returns a random string made of C<$length> chars randomly chosen from C<$range> string.
156              
157             =head2 random_string
158              
159             $alphanumeric_string = random_string($length);
160             #or
161             $alphanumeric_string = random_string; # default length = 20
162              
163             Similar to random_string_from, only C<$range> is fixed to C<'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'>.
164              
165             =head2 rand
166              
167             $n = rand;
168             #or
169             $n = rand($limit);
170              
171             Returns a random floating point number from range C<[0,1)> (if called without parameter) or C<[0,$limit)>.
172              
173             =head2 irand
174              
175             $i = irand;
176              
177             Returns a random unsigned 32bit integer - range C<0 .. 0xFFFFFFFF>.
178              
179             =head1 METHODS
180              
181             =head2 new
182              
183             $prng = Crypt::PRNG->new;
184             #or
185             $prng = Crypt::PRNG->new($alg);
186             #or
187             $prng = Crypt::PRNG->new($alg, $seed);
188              
189             # $alg ... algorithm name 'Frotuna' (DEFAULT), 'RC4', 'Sober128' or 'Yarrow'
190             # $seed ... will be used as an initial entropy for seeding PRNG
191              
192             If C<$seed> is not specified the PRNG is automatically seeded with 32bytes random data taken from C (UNIX) or C (Win32)
193              
194             =head2 add_entropy
195              
196             $prng->add_entropy($random_data);
197             #or
198             $prng->add_entropy();
199              
200             If called without parameter it uses 32bytes random data taken from C (UNIX) or C (Win32).
201              
202             B you probably do not need this function at all as the module does automatic seeding on initialization as well as reseeding after fork and thread creation.
203              
204             =head2 bytes
205              
206             $octets = $prng->bytes($length);
207              
208             See L
209              
210             =head2 bytes_hex
211              
212             $hex_string = $prng->bytes_hex($length);
213              
214             See L
215              
216             =head2 bytes_b64
217              
218             $base64_string = $prng->bytes_b64($length);
219              
220             See L
221              
222             =head2 bytes_b64u
223              
224             $base64url_string = $prng->bytes_b64u($length);
225              
226             See L
227              
228             =head2 string
229              
230             $alphanumeric_string = $prng->string($length);
231             #or
232             $alphanumeric_string = $prng->string;
233              
234             See L
235              
236             =head2 string_from
237              
238             $string = $prng->string_from($range, $length);
239              
240             See L
241              
242             =head2 double
243              
244             $n = $prng->double;
245             #or
246             $n = $prng->double($limit);
247              
248             See L
249              
250             =head2 int32
251              
252             $i = $prng->int32;
253              
254             See L
255              
256             =head1 SEE ALSO
257              
258             L, L, L, L
259              
260             =cut