Codebase list libcryptx-perl / 663f2fe
Crypt::PRNG::ChaCha20 Karel Miko 7 years ago
5 changed file(s) with 228 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
1717 - NEW: Crypt::Digest::SHA3_512
1818 - NEW: Crypt::AuthEnc::ChaCha20Poly1305
1919 - NEW: Crypt::Mac::Poly1305
20 - NEW: Crypt::PRNG::ChaCha20
2021 - NEW: Crypt::Stream::ChaCha
2122 - NEW: Crypt::Stream::RC4
2223 - NEW: Crypt::Stream::Sober128
0 package Crypt::PRNG::ChaCha20;
1
2 use strict;
3 use warnings;
4 our $VERSION = '0.047';
5
6 use base qw(Crypt::PRNG Exporter);
7 our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] );
8 our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
9 our @EXPORT = qw();
10
11 use CryptX;
12 use base 'Crypt::PRNG';
13
14 {
15 ### stolen from Bytes::Random::Secure
16 my $RNG_object = undef;
17 my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once.
18 $RNG_object = Crypt::PRNG::ChaCha20->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR';
19 return $RNG_object;
20 };
21 sub rand { return $fetch_RNG->()->double(@_) }
22 sub irand { return $fetch_RNG->()->int32(@_) }
23 sub random_bytes { return $fetch_RNG->()->bytes(@_) }
24 sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) }
25 sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) }
26 sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) }
27 sub random_string_from { return $fetch_RNG->()->string_from(@_) }
28 sub random_string { return $fetch_RNG->()->string(@_) }
29 }
30
31
32 1;
33
34 =pod
35
36 =head1 NAME
37
38 Crypt::PRNG::ChaCha20 - Cryptographically secure PRNG based on ChaCha20 (stream cipher) algorithm
39
40 =head1 SYNOPSIS
41
42 ### Functional interface:
43 use Crypt::PRNG::ChaCha20 qw(random_bytes random_bytes_hex random_bytes_b64 random_string random_string_from rand irand);
44
45 $octets = random_bytes(45);
46 $hex_string = random_bytes_hex(45);
47 $base64_string = random_bytes_b64(45);
48 $base64url_string = random_bytes_b64u(45);
49 $alphanumeric_string = random_string(30);
50 $string = random_string_from('ACGT', 64);
51 $floating_point_number_0_to_1 = rand;
52 $floating_point_number_0_to_88 = rand(88);
53 $unsigned_32bit_int = irand;
54
55 ### OO interface:
56 use Crypt::PRNG::ChaCha20;
57
58 $prng = Crypt::PRNG::ChaCha20->new;
59 #or
60 $prng = Crypt::PRNG::ChaCha20->new("some data used for seeding PRNG");
61
62 $octets = $prng->bytes(45);
63 $hex_string = $prng->bytes_hex(45);
64 $base64_string = $prng->bytes_b64(45);
65 $base64url_string = $prng->bytes_b64u(45);
66 $alphanumeric_string = $prng->string(30);
67 $string = $prng->string_from('ACGT', 64);
68 $floating_point_number_0_to_1 = rand;
69 $floating_point_number_0_to_88 = rand(88);
70 $unsigned_32bit_int = irand;
71
72 =head1 DESCRIPTION
73
74 Provides an interface to the ChaCha20 based pseudo random number generator
75
76 All methods and functions are the same as for L<Crypt::PRNG>.
77
78 =head1 FUNCTIONS
79
80 =head2 random_bytes
81
82 See L<Crypt::PRNG/random_bytes>.
83
84 =head2 random_bytes_hex
85
86 See L<Crypt::PRNG/random_bytes_hex>.
87
88 =head2 random_bytes_b64
89
90 See L<Crypt::PRNG/random_bytes_b64>.
91
92 =head2 random_bytes_b64u
93
94 See L<Crypt::PRNG/random_bytes_b64u>.
95
96 =head2 random_string
97
98 See L<Crypt::PRNG/random_string>.
99
100 =head2 random_string_from
101
102 See L<Crypt::PRNG/random_string_from>.
103
104 =head2 rand
105
106 See L<Crypt::PRNG/rand>.
107
108 =head2 irand
109
110 See L<Crypt::PRNG/irand>.
111
112 =head1 METHODS
113
114 =head2 new
115
116 See L<Crypt::PRNG/new>.
117
118 =head2 bytes
119
120 See L<Crypt::PRNG/bytes>.
121
122 =head2 bytes_hex
123
124 See L<Crypt::PRNG/bytes_hex>.
125
126 =head2 bytes_b64
127
128 See L<Crypt::PRNG/bytes_b64>.
129
130 =head2 bytes_b64u
131
132 See L<Crypt::PRNG/bytes_b64u>.
133
134 =head2 string
135
136 See L<Crypt::PRNG/string>.
137
138 =head2 string_from
139
140 See L<Crypt::PRNG/string_from>.
141
142 =head2 double
143
144 See L<Crypt::PRNG/double>.
145
146 =head2 int32
147
148 See L<Crypt::PRNG/int32>.
149
150 =head1 SEE ALSO
151
152 =over
153
154 =item * L<Crypt::PRNG>
155
156 =item * L<https://tools.ietf.org/html/rfc7539>
157
158 =back
1616
1717 const struct ltc_prng_descriptor chacha20_prng_desc =
1818 {
19 "chacha",
19 "chacha20",
2020 sizeof(chacha_state),
2121 &chacha20_prng_start,
2222 &chacha20_prng_add_entropy,
44
55 plan skip_all => "File::Find not installed" unless eval { require File::Find };
66 plan skip_all => "Test::Pod not installed" unless eval { require Test::Pod };
7 plan tests => 83;
7 plan tests => 84;
88
99 my @files;
1010 File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib');
0 use strict;
1 use warnings;
2 use Test::More tests => 19;
3
4 use Crypt::PRNG::ChaCha20 qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand);
5
6 my $r = Crypt::PRNG::ChaCha20->new();
7 ok($r, 'new');
8
9 {
10 my $sum = 0;
11 $sum += $r->double for (1..1000);
12 my $avg = $sum/1000;
13 ok($avg>0.4 && $avg<0.6, "rand $avg");
14 }
15
16 {
17 my $sum = 0;
18 $sum += $r->double(-180) for (1..1000);
19 my $avg = $sum/1000;
20 ok($avg>-100 && $avg<-80, "rand $avg");
21 }
22
23 {
24 my $sum = 0;
25 $sum += $r->int32 for (1..1000);
26 my $avg = $sum/1000;
27 ok($avg>2**30 && $avg<2**32, "rand $avg");
28 }
29
30 {
31 my $sum = 0;
32 $sum += rand(80) for (1..1000);
33 my $avg = $sum/1000;
34 ok($avg>30 && $avg<50, "rand $avg");
35 }
36
37 {
38 my $sum = 0;
39 $sum += rand(-180) for (1..1000);
40 my $avg = $sum/1000;
41 ok($avg>-100 && $avg<-80, "rand $avg");
42 }
43
44 {
45 my $sum = 0;
46 $sum += irand for (1..1000);
47 my $avg = $sum/1000;
48 ok($avg>2**30 && $avg<2**32, "rand $avg");
49 }
50
51 {
52 like($r->string(45), qr/^[A-Z-a-z0-9]+$/, 'string');
53 like($r->string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string');
54 is(length $r->bytes(55), 55, "bytes");
55 like($r->bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex");
56 like($r->bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64");
57 like($r->bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u");
58
59 like(random_string(45), qr/^[A-Z-a-z0-9]+$/, 'string');
60 like(random_string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string');
61 is(length random_bytes(55), 55, "bytes");
62 like(random_bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex");
63 like(random_bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64");
64 like(random_bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u");
65 }