File Coverage

blib/lib/Data/Entropy.pm
Criterion Covered Total %
statement 36 36 100.0
branch 7 8 87.5
condition n/a
subroutine 8 8 100.0
pod 2 2 100.0
total 53 54 98.1


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Data::Entropy - entropy (randomness) management
4              
5             =head1 SYNOPSIS
6              
7             use Data::Entropy qw(entropy_source);
8              
9             $i = entropy_source->get_int(12345);
10              
11             use Data::Entropy qw(with_entropy_source);
12              
13             with_entropy_source $source, sub {
14             @a = shuffle(@a);
15             };
16              
17             =head1 DESCRIPTION
18              
19             This module maintains a concept of a current selection of
20             entropy source. Algorithms that require entropy, such as those in
21             L, can use the source nominated by this
22             module, avoiding the need for entropy source objects to be explicitly
23             passed around. This is convenient because usually one entropy source
24             will be used for an entire program run and so an explicit entropy source
25             parameter would rarely vary. There is also a default entropy source,
26             avoiding the need to explicitly configure a source at all.
27              
28             If nothing is done to set a source then it defaults to the use of Rijndael
29             (AES) in counter mode (see L
30             and L), keyed using Perl's built-in C function.
31             This gives a data stream that looks like concentrated entropy, but really
32             only has at most the entropy of the C seed. Within a single run it
33             is cryptographically difficult to detect the correlation between parts
34             of the pseudo-entropy stream. If more true entropy is required then it
35             is necessary to configure a different entropy source.
36              
37             =cut
38              
39             package Data::Entropy;
40              
41 10     10   114455 { use 5.006; }
  10         39  
  10         475  
42 10     10   58 use warnings;
  10         18  
  10         284  
43 10     10   73 use strict;
  10         19  
  10         407  
44              
45 10     10   230 use Carp qw(croak);
  10         21  
  10         716  
46 10     10   11054 use Params::Classify 0.000 qw(is_ref);
  10         49901  
  10         1207  
47              
48             our $VERSION = "0.007";
49              
50 10     10   86 use parent "Exporter";
  10         21  
  10         57  
51             our @EXPORT_OK = qw(entropy_source with_entropy_source);
52              
53             our $entropy_source;
54              
55             =head1 FUNCTIONS
56              
57             =over
58              
59             =item entropy_source
60              
61             Returns the current entropy source, a C
62             object. This will be the source passed to the innermost call to
63             C, if any, or otherwise the default entropy source.
64              
65             =cut
66              
67             my $default_entropy_source;
68              
69             sub entropy_source() {
70 21472 100   21472 1 65329 if(is_ref($entropy_source, "CODE")) {
71 2         4 my $source = $entropy_source->();
72 2 50       10 croak "entropy source thunk returned another thunk"
73             if is_ref($source, "CODE");
74 2         4 $entropy_source = $source;
75             }
76 21472 100       46745 unless(defined $entropy_source) {
77 4 100       20 unless(defined $default_entropy_source) {
78 2         7 my $key = "";
79 2         10 for(my $i = 32; $i--; ) {
80 64         273 $key .= chr(int(CORE::rand(256)));
81             }
82 2         5338 require Crypt::Rijndael;
83 2         3802 require Data::Entropy::RawSource::CryptCounter;
84 2         1979 require Data::Entropy::Source;
85 2         63 $default_entropy_source =
86             Data::Entropy::Source->new(
87             Data::Entropy::RawSource::CryptCounter
88             ->new(Crypt::Rijndael
89             ->new($key)),
90             "getc");
91             }
92 4         10 $entropy_source = $default_entropy_source;
93             }
94 21472         77766 return $entropy_source;
95             }
96              
97             =item with_entropy_source SOURCE, CLOSURE
98              
99             The SOURCE is selected, so that it will be returned by C,
100             and CLOSURE is called (with no arguments). The SOURCE is selected only
101             during the dynamic scope of the call; after CLOSURE finishes, by whatever
102             means, the previously selected entropy source is restored.
103              
104             SOURCE is normally a C object. Alternatively,
105             it may be C to cause use of the default entropy source. It may
106             also be a reference to a function of no arguments, which will be called to
107             generate the actual source only if required. This avoids unnecessarily
108             initialising the source object if it is uncertain whether any entropy
109             will be required. The source-generating closure may return a normal
110             source or C, but not another function reference.
111              
112             =cut
113              
114             sub with_entropy_source($&) {
115 14     14 1 51 my($source, $closure) = @_;
116 14         33 local $entropy_source = $source;
117 14         47 $closure->();
118             }
119              
120             =back
121              
122             =head1 SEE ALSO
123              
124             L,
125             L
126              
127             =head1 AUTHOR
128              
129             Andrew Main (Zefram)
130              
131             =head1 COPYRIGHT
132              
133             Copyright (C) 2006, 2007, 2009, 2011
134             Andrew Main (Zefram)
135              
136             =head1 LICENSE
137              
138             This module is free software; you can redistribute it and/or modify it
139             under the same terms as Perl itself.
140              
141             =cut
142              
143             1;