.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Bytes::Random::Secure::Tiny 3" .TH Bytes::Random::Secure::Tiny 3 "2020-09-25" "perl v5.30.3" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Bytes::Random::Secure::Tiny \- A tiny Perl extension to generate cryptographically\-secure random bytes. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Bytes::Random::Secure::Tiny; \& \& my $rng = Bytes::Random::Secure::Tiny\->new; # Seed with 256 bits. \& \& my $bytes = $rng\->bytes(32); # A string of 32 random bytes. \& my $long = $rng\->irand; # 32\-bit random unsigned int. \& my $hex = $rng\->bytes_hex(10); # 10 random bytes as hex digits. \& my $string = $rng\->string_from(\*(Aqabc\*(Aq, 10); # Random string from a, b, & c. .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Bytes::Random::Secure::Tiny provides random bytes from a cryptographically secure random number generator (\s-1ISAAC\s0), seeded from strong entropy sources on a wide variety of platforms. It does so without external dependencies (except on Windows), and has a minimal but useful user interface patterned after the module Bytes::Random::Secure. .PP Bytes::Random::Secure has a handful of dependencies. And its \s-1UI\s0 may be bigger than a typical user needs. Bytes::Random::Secure::Tiny is designed to provide what 90% of Bytes::Random::Secure's users need, but with a simpler user interface, and in a single module with no dependencies beyond core Perl. .PP In most cases this module may be used as a light-weight drop-in replacement for Bytes::Random::Secure. .SH "RATIONALE" .IX Header "RATIONALE" This module aims to provide a generalized tool for generating cryptographically secure randomness in a way that can fit into many applications while providing a zero dependency toolchain, and a user interface that is both minimal and simple. Common use-cases may include: .IP "\(bu" 4 Creating temporary passphrases. .IP "\(bu" 4 Generating random salts. .IP "\(bu" 4 Generating a secret that can be hashed along with session cookies. .IP "\(bu" 4 Nonces. .IP "\(bu" 4 Feeding secure key-gen utilities. .PP Bytes::Random::Secure::Tiny employs several well-designed algorithms adapted from established \s-1CPAN\s0 tools to generate a strong random seed, and then to instantiate a high quality cryptographically secure pseudo-random number generator based on the seed. It has taken significant research to come up with a strong and sensible choice of established and published algorithms. The interface is designed with minimalism and simplicity in mind. .PP In particular, the \s-1CSPRNG\s0 is based on the same algorithm used by Math::Random::ISAAC, and the seeding is based on algorithms from Crypt::Random::Seed. .PP Furthermore, this module runs its randomness through both statistical tests and \s-1NIST\s0 \s-1FIPS\-140\s0 tests to verify integrity. .PP As a \f(CW\*(C`::Tiny\*(C'\fR module, the additional goals of low (or no) dependencies and a light-weight code base make this an ideal choice for environments where heavier dependency chains are problematic. .SH "EXPORTS" .IX Header "EXPORTS" Nothing is exported. .SH "METHODS" .IX Header "METHODS" .SS "new" .IX Subsection "new" .Vb 1 \& my $rng = Bytes::Random::Secure::Tiny\->new; .Ve .PP Instantiate the pseudo-random number generator object. The seeding of the \s-1ISAAC CSPRING\s0 defaults to 256 bits from a non-blocking entropy source. The \s-1CSPRNG\s0 object should be instantiated as infrequently as practical; there is no benefit to re-seeding, with the single cavaet that the \s-1CSPRNG\s0 object should not be shared by threads or forked processes. .PP \fIConstructor Parameters\fR .IX Subsection "Constructor Parameters" .PP Parameters described below are optional and case-insensitive. .IP "bits" 4 .IX Item "bits" .Vb 1 \& my $rng = Bytes::Random::Secure::Tiny\->new(bits => 512); .Ve .Sp Number of bits to use in seeding. Must be a value between 64 and 8192 inclusive, and must satisfy \f(CW\*(C`bits==2**n\*(C'\fR. The default value is 256. .IP "nonblocking" 4 .IX Item "nonblocking" .Vb 2 \& my $nb_rng = Bytes::Random::Secure::Tiny\->new(nonblocking=>1); \& my $bl_rng = Bytes::Random::Secure::Tiny\->new(nonblocking=>0); .Ve .Sp If set to a false value, a blocking entropy source may be used in seeding. This is generally not necessary, as the non-blocking sources used are considered by most to be strong enough for cryptographic purposes. .Sp Instantiating with a blocking source can exhaust system entropy (this has been seen in testing), and in such cases \f(CW\*(C`new\*(C'\fR will block until sufficient entropy is generated. .Sp The default is to use a non-blocking source, and you should probably accept that default. .SS "bytes" .IX Subsection "bytes" .Vb 1 \& my $random_bytes = $rng\->bytes($n); .Ve .PP Returns a string of \f(CW$n\fR random bytes. \f(CW$n\fR must be a positive integer. .SS "bytes_hex" .IX Subsection "bytes_hex" .Vb 1 \& my $random_hex = $rng\->bytes_hex(6); # E.g. f35dde7c02a4 .Ve .PP Returns a string of hex digits. Each byte is represented by two lower-cased hex digits. Therefore, \f(CW\*(C`$rng\->bytes_hex(1)\*(C'\fR will return a string of length 2, such as \f(CW\*(C`7F\*(C'\fR. There is no \f(CW\*(C`0x\*(C'\fR prepended to the hex digits. .SS "string_from" .IX Subsection "string_from" .Vb 1 \& my $random_string = $rng\->string_from(\*(Aqabcdefg\*(Aq, 10); .Ve .PP Returns a string of random octets selected from the \*(L"Bag\*(R" string (in this case ten octets from 'abcdefg'). Repeated bag characters are weighted according to their frequency. For example, given the bag 'aabc', the character 'a' will be selected approximately 50% of the time, though being \fIrandom\fR, there are no guarantees it will be selected at all. For the bag 'abc', each character has the same weight. The output may contain duplicate characters. For example: .PP .Vb 1 \& say $rng\->string_from(\*(Aqa\*(Aq, 10); # Must always be \*(Aqaaaaaaaaaa\*(Aq .Ve .SS "irand" .IX Subsection "irand" .Vb 1 \& my $unsigned_long = $random\->irand; .Ve .PP Returns a pseudo-random 32\-bit unsigned integer. The value will satisfy \&\f(CW\*(C`0 <= x <= 2**32\-1\*(C'\fR. .SS "shuffle" .IX Subsection "shuffle" .Vb 1 \& my $aref_shuffled = $random\->shuffle($aref); .Ve .PP Shuffles the contents of a reference to an array in situ, and returns the same reference. .PP List::Util, which ships with Perl, includes \f(CW\*(C`shuffle\*(C'\fR function. But that function is flawed in two ways. First, from a cryptographic standpoint, it uses Perl's \f(CW\*(C`rand\*(C'\fR, which is not a \s-1CSPRNG,\s0 and therefore is inadequate. .PP Second, because Perl's rand has an internal state of just 32 bits, it cannot possibly generate all permutations of arrays containing 13 or more elements. .PP This module's \f(CW\*(C`shuffle\*(C'\fR uses a \s-1CSPRNG,\s0 and also benefits from large seeds and a huge internal state. \s-1ISAAC\s0 can be seeded with up to 8192 bits, yielding 2^8192 possible initial states, and 2^8288 possible internal states. A seed of 8192 bits will assure that for arrays of up to 966 elements every permutation is accessible. .SH "CONFIGURATION" .IX Header "CONFIGURATION" Nothing to configure. .SH "DEPENDENCIES" .IX Header "DEPENDENCIES" This module requires Perl 5.8 or newer. Unicode support in \f(CW\*(C`string_from\*(C'\fR is best with Perl 5.8.9 or newer. See the \s-1INSTALLATION\s0 section in this document for details. .SH "OPTIONAL DEPENDENCIES" .IX Header "OPTIONAL DEPENDENCIES" Bytes::Random::Secure::Tiny uses an embedded version of the \s-1ISAAC\s0 algorithm adapted from Math::Random::ISAAC as its \s-1CSPRNG,\s0 but will silently upgrade to using Math::Random::ISAAC proper if it is available on the target system. .PP \&\f(CW\*(C`Bytes::Random::Secure::Tiny\*(C'\fR seeds using an embedded adaptation of Crypt::Random::Seed, but it will silently upgrade to using Crypt::Random::Seed proper if it is available on the target system. .PP If performance is a consideration and you are able to install Math::Random::ISAAC::XS, do so; Bytes::Random::Secure::Tiny will silently upgrade to using \f(CW\*(C`Math::Random::ISAAC::XS\*(C'\fR instead of the embedded \&\s-1ISAAC CSPRING.\s0 Math::Random::ISAAC::XS implements the same \s-1ISAAC CSPRNG\s0 algorithm in C and \s-1XS\s0 for speed. .SH "FORK AND THREAD SAFETY" .IX Header "FORK AND THREAD SAFETY" When programming for parallel computation, create a unique \&\f(CW\*(C`Bytes::Random::Secure::Tiny\*(C'\fR object within each process or thread. Bytes::Random::Secure::Tiny uses a \s-1CSPRNG,\s0 and sharing the same \s-1RNG\s0 between threads or processes will share the same seed and the same starting point. By instantiating the B::R::S::T object after forking or creating threads, a unique randomness stream will be created per thread or process. .PP Always share the same \s-1RNG\s0 object between all non-concurrent consumers within a process, but never share the same \s-1RNG\s0 between threads or forked processes. .SH "ADDITIONAL DISCUSSION" .IX Header "ADDITIONAL DISCUSSION" .SS "\s-1STRONG RANDOMNESS\s0" .IX Subsection "STRONG RANDOMNESS" It's easy to generate weak pseudo-random bytes. It's also easy to think you're generating strong pseudo-random bytes when really you're not. And it's hard to test for pseudo-random cryptographic acceptable quality. There are many high quality random number generators that are suitable for statistical purposes, but not necessarily up to the rigors of cryptographic use. .PP Assuring strong (ie, secure) random bytes in a way that works across a wide variety of platforms is also challenging. A primary goal for this module is to provide cryptographically secure pseudo-random bytes while still meeting the secondary goals of simplicity, minimalism, and no dependencies. If more fine-grained control over seeding methods is needed, use Bytes::Random::Secure instead. .SS "\s-1ISAAC\s0" .IX Subsection "ISAAC" The \s-1ISAAC\s0 algorithm is considered a cryptographically strong pseudo-random number generator. It has 1.0e2466 possible initial states. The best known attack for discovering initial state would theoretically take a complexity of approximately 4.67e1240, which is of no practical consequence to \s-1ISAAC\s0's security. Cycles are guaranteed to have a minimum length of 2**40, with an average cycle of 2**8295. Because there is no practical attack capable of discovering initial state, and because the average cycle is so long, it's generally unnecessary to re-seed a running application. The results are uniformly distributed, unbiased, and unpredictable unless the seed is known. .PP To confirm the quality of the \s-1CSPRNG,\s0 this module's test suite implements the \&\s-1FIPS\-140\-1\s0 tests for strong random number generators. See the comments in \f(CW\*(C`t/27\-fips140\-1.t\*(C'\fR for details. .SS "\s-1UNICODE SUPPORT\s0" .IX Subsection "UNICODE SUPPORT" The \f(CW\*(C`string_from\*(C'\fR method permits the user to pass a \*(L"bag\*(R" (or source) string containing Unicode characters. For any modern Perl version, this will work just as you would hope. But some versions of Perl older than 5.8.9 exhibited varying degrees of bugginess in their handling of Unicode. If you're depending on the Unicode features of this module while using Perl versions older than 5.8.9 be sure to test thoroughly, and don't be surprised when the outcome isn't as expected. ...this is to be expected. Upgrade. This module works at the octet level, not grapheme cluster. .SS "\s-1MODULO BIAS\s0" .IX Subsection "MODULO BIAS" Care is taken so that there is no modulo bias in the randomness returned. This is exactly \fIwhy\fR the \f(CW\*(C`string_from\*(C'\fR method is preferable to a home-grown random string solution. However, the algorithm to eliminate modulo bias can impact the performance of the \f(CW\*(C`string_from\*(C'\fR method. Any time the length of the bag string is significantly less than the nearest greater or equal factor of 2**32, performance will degrade. Unfortunately there is no known algorithm that improves upon this situation. Fortunately, for sanely sized strings, it's a minor issue. To put it in perspective, even in the case of passing a \*(L"bag\*(R" string of length 2**31 (which is huge), the expected time to return random bytes will only double. .SH "INSTALLATION" .IX Header "INSTALLATION" No special requirements. .SH "SEE ALSO" .IX Header "SEE ALSO" If support for hardware entropy generators is needed, use Bytes::Random::Secure. Other good \s-1CSPRNG\s0's include Crypt::Random and Math::Random::Secure. .SH "AUTHOR" .IX Header "AUTHOR" David Oswald \fI\fR .SH "BUGS" .IX Header "BUGS" Please report any bugs or feature requests to \&\f(CW\*(C`bug\-bytes\-random\-secure at rt.cpan.org\*(C'\fR, or through the web interface at . I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. .SH "SUPPORT" .IX Header "SUPPORT" You can find documentation for this module with the perldoc command. .PP .Vb 1 \& perldoc Bytes::Random::Secure .Ve .PP You can also look for information at: .IP "\(bu" 4 Github Repo: .IP "\(bu" 4 \&\s-1RT: CPAN\s0's request tracker (report bugs here) .Sp .IP "\(bu" 4 AnnoCPAN: Annotated \s-1CPAN\s0 documentation .Sp .IP "\(bu" 4 \&\s-1CPAN\s0 Ratings .Sp .IP "\(bu" 4 Search \s-1CPAN\s0 .Sp .SH "ACKNOWLEDGEMENTS" .IX Header "ACKNOWLEDGEMENTS" Dana Jacobsen ( \fI\fR ) for his work that led to Crypt::Random::Seed, and for ideas and code reviews. .SH "LICENSE AND COPYRIGHT" .IX Header "LICENSE AND COPYRIGHT" Copyright 2015 David Oswald. .PP This program is free software; you can redistribute it and/or modify it under the terms of either: the \s-1GNU\s0 General Public License as published by the Free Software Foundation; or the Artistic License. .PP See http://dev.perl.org/licenses/ for more information.