Data-Entropy-0.008/0000755000175000017500000000000014771321110011655 5ustar rrrrData-Entropy-0.008/META.json0000664000175000017500000000335514771321107013314 0ustar rrrr{ "abstract" : "entropy (randomness) management", "author" : [ "Robert Rothenberg " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.72, CPAN::Meta::Converter version 2.150010", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Data-Entropy", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Carp" : "0", "Crypt::Rijndael" : "0", "Crypt::URandom" : "0.36", "Data::Float" : "0.008", "Errno" : "1.00", "Exporter" : "0", "HTTP::Lite" : "2.2", "IO::File" : "1.03", "Module::Build" : "0", "Params::Classify" : "0", "Test::More" : "0", "constant" : "0", "integer" : "0", "parent" : "0", "strict" : "0", "warnings" : "0" } }, "test" : { "requires" : { "Test::More" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/robrwo/Data-Entropy/issues" }, "repository" : { "type" : "git", "url" : "git://github.com/robrwo/Data-Entropy.git" } }, "version" : "0.008", "x_deprecated" : 1, "x_serialization_backend" : "JSON::PP version 4.06" } Data-Entropy-0.008/SIGNATURE0000664000175000017500000001124114771321110013142 0ustar rrrrThis file contains message digests of all files listed in MANIFEST, signed via the Module::Signature module, version 0.89. To verify the content in this distribution, first make sure you have Module::Signature installed, then type: % cpansign -v It will check each file's integrity, as well as the signature's validity. If "==> Signature verified OK! <==" is not displayed, the distribution may already have been compromised, and you should not run its Makefile.PL or Build.PL. -----BEGIN PGP SIGNED MESSAGE----- Hash: RIPEMD160 SHA256 c63a703aa9d037adc694ffb8c6ef82a4b475fd3ae1bafb375227b3be274323ed Changes SHA256 f9500f0eaf425305056e05253099a04535f6fd52f3a0bf61d2ef1d4aaa420a51 MANIFEST SHA256 ca23f4168d8fdf482ba648eae621307727dec6eb233cd3d8638ca859a5015399 MANIFEST.SKIP SHA256 fe99f03e39a9f6d29fb3e13e7d53e78156dc7efb1ffe91f72982ec01303bec0a META.json SHA256 0787c7672b56399009525c7cce91ba5a16e3bd47857fb2a01a60c8763dbca8c1 META.yml SHA256 fb4ac39f362453ba321dbeaa67da7539995aa8614eb546fbc9e251fcfa026bc9 Makefile.PL SHA256 5476ed1b38bae6291a5bb17b4c7203405f211466585e5d77cc159442f929bdff README SHA256 959047d794dcaa369895ef8795533ae5583d8c334e2a3767543e4e9562b3a293 SECURITY.md SHA256 2899cf99b13d0a724479fc60191ec6a2d7503878a48777f942dd6583f1ae3945 lib/Data/Entropy.pm SHA256 d43be2f0e9cbc0a6b4d2af8ae51b4e9d73c1a6e368f20d268202afd11c9265f8 lib/Data/Entropy/Algorithms.pm SHA256 3657c6cecbd41d4ba116e781d8311812a9acc1f52c9d5424366f6568a15ddd81 lib/Data/Entropy/RawSource/CryptCounter.pm SHA256 d97f1f80fb64246a3e2c1a8d61452231536ee98f12c50e0545491f5083a1dc87 lib/Data/Entropy/RawSource/Local.pm SHA256 6f5294b6b42385f6187d7c25b762a14748772af34e4f11ab74c1a46a2d01d589 lib/Data/Entropy/RawSource/RandomOrg.pm SHA256 b83cb636be953996f4d18c394f191bb756a4dd7cc24af6b2962369d2192e49c7 lib/Data/Entropy/RawSource/RandomnumbersInfo.pm SHA256 bd08379e08da4ae19ef9917819c66c545e8d668e4b853ef2ffde3f38d2d74613 lib/Data/Entropy/Source.pm SHA256 279f7a9a8f1f909b63bd01db288269edf53e8adaf6e7a6893166e3584bcd39d3 t/choose.t SHA256 3d4b1adf1fcbb55850c7f863e18d6e0669b9bb23b7a63abd9672d7dd54b0740e t/get_bits.t SHA256 cfdfdb63129f6d904b00e7402ab083c277a4868c40625a4b1dbe7dc2c0ef9972 t/get_int_large.t SHA256 5b75d72bc535bd3d9c4a14a6f919bd10c2c8e7f9aea334348a9860a47222743d t/get_int_medium.t SHA256 90fa2d521f1e9b182f84042135b2311276e4bd4de5f7e5c2429dc6f80c572db2 t/get_int_small.t SHA256 3f7f7b52fe7201d177792b11ce885e51992ea2645b3c7207db92abe39e2e5bf9 t/get_octet.t SHA256 d39b332db4199251f979a5fa7f90678213da87a13a53cb5664607f701329d064 t/get_prob_2.t SHA256 99c05fff36fb3972070bb5d4403b6b44ac0bc87c034ca4ae92bb58127869b485 t/get_prob_333a.t SHA256 d7404646e85c0dc067d0e25249abc72534ede2c36df15fdfcd231796ca5771b3 t/get_prob_333b.t SHA256 eb00d8ab970050aea08adb3c1f065e9248fe4c19adf05fc89fc2d349c2985063 t/pick.t SHA256 3679257bdfb4a07658e98a41325f82c1744f7dae6d1d0151f1b216af0c1df5c9 t/pod_cvg.t SHA256 e16860066c4ca9b2ee9e7d4604297def8a58b53bf0ca03eed863b5d9c5a2ac91 t/pod_syn.t SHA256 2b7e229e0601dada21cf840a4488b7e0c20a1c5a4e72d4a694e3a483806812fb t/rand.t SHA256 e4967cfffda5ae586dcc4bcbe567c0c24bd24872e06d38516f2217061b27806d t/rand_bits.t SHA256 8f4c501730ddc1293c5adeb71e97bef561319c9e64ed8407fb074b0be8ae1c28 t/rand_fix.t SHA256 120390c31fbb4ce0925de1b0b6b90e9a6d40f9b928bbdb0b05b3141562171302 t/rand_flt.t SHA256 9a456536a57d998123b423bc15f9c91d55eac5585c5fc13617dc53e337377ce8 t/rand_int.t SHA256 28bd9af533d721698b1e99da379efab041a91a6e6d50b1ebb5d687400f4a2069 t/rand_prob.t SHA256 232905cf8e56da855659f84cf84cda27cbb926fca02d1f8c020d2bb1e79f80a1 t/rs_cryptcounter.t SHA256 59d8b6f0066109a630adcb92a4ae99a54bb67fc2a774f8af2df8473293f1804d t/rs_local.t SHA256 9377cb4763ae1816c44b7c6fd0d431e2f31e5b3167b3fe5c24cb35646d0b0cde t/rs_randomnumbersinfo.t SHA256 96ca3e3a153c358d2b831e3777eb47d42eceed6e858ad86b897434b604fc9597 t/rs_randomorg.t SHA256 8a412cac67c052768c289744340acef8bfcd5d6ac9a65f4a77e108a88e68f501 t/shuffle.t SHA256 d2a501f632652fef7d711cf5fe0f02ee8ca98236dfaf367d56ddcc4fec7ea46d t/test0.entropy SHA256 dbe475f88b4820962a3ef21f909d2fdc0db1e441f4a333635c8312168e299a7a t/with.t -----BEGIN PGP SIGNATURE----- iQGzBAEBAwAdFiEEeIwq7Pfyfxtssr5nHmWrcYGDC6wFAmflokgACgkQHmWrcYGD C6xMVwwAhDdbV0iPMUzMS+jUiJbntRMoYXGyJTJ1I4OyDQFiWkIeBdt3f/IVr95e h8A0qkXU+itYHuD2Xi6Y9ly/2zdAyZZYa1KlpYi4HNtdirfHmq6bXjD91VrVmTNw qPZyt/jj7mmrKxIDu04NAT28+M9zYktpfpQYOyiZiciI61QeLAFESi+W25oYWmD+ 6LA07rEbzjxyb9BKYtEOzjGvcda94s3C5xNw4Q4Gsp7kDuUgKssaJv23duKHsYIT 2dYLs8IZYDNmkiu7V9TMIcvIBOpCe0RKOHa6v65FoqJYNKUzKxo8yqZ6AX4JW5/I OiN09Sfpwtje4v+fPKDGws7qBwunutsiSw9wgKdnftcBmpXG4Pi2b5nBYPqvcuyg lErIJB8f45nAVJd07ozdfnVaGXGSswa7IBghsbbAbJPAHIS2wqQiU95nGInHEKgF EOL6D3pxaBAJtfPkkL5WN4JQf0fBjrjMousIU+Lb5ASvM+HUxsR5af7A1T0BjbU5 tKg6eaNm =9S4a -----END PGP SIGNATURE----- Data-Entropy-0.008/MANIFEST0000644000175000017500000000140614771321107013015 0ustar rrrrChanges lib/Data/Entropy.pm lib/Data/Entropy/Algorithms.pm lib/Data/Entropy/RawSource/CryptCounter.pm lib/Data/Entropy/RawSource/Local.pm lib/Data/Entropy/RawSource/RandomnumbersInfo.pm lib/Data/Entropy/RawSource/RandomOrg.pm lib/Data/Entropy/Source.pm Makefile.PL MANIFEST MANIFEST.SKIP META.json META.yml README SECURITY.md t/choose.t t/get_bits.t t/get_int_large.t t/get_int_medium.t t/get_int_small.t t/get_octet.t t/get_prob_2.t t/get_prob_333a.t t/get_prob_333b.t t/pick.t t/pod_cvg.t t/pod_syn.t t/rand.t t/rand_bits.t t/rand_fix.t t/rand_flt.t t/rand_int.t t/rand_prob.t t/rs_cryptcounter.t t/rs_local.t t/rs_randomnumbersinfo.t t/rs_randomorg.t t/shuffle.t t/test0.entropy t/with.t SIGNATURE Public-key signature (added by MakeMaker) Data-Entropy-0.008/t/0000755000175000017500000000000014771321107012126 5ustar rrrrData-Entropy-0.008/t/pod_syn.t0000644000175000017500000000023611556073065013774 0ustar rrrruse warnings; use strict; use Test::More; plan skip_all => "Test::Pod not available" unless eval "use Test::Pod 1.00; 1"; Test::Pod::all_pod_files_ok(); 1; Data-Entropy-0.008/t/rand.t0000644000175000017500000000531511556073065013250 0ustar rrrruse warnings; use strict; use Test::More tests => 261; use Data::Float 0.008 qw(significand_bits); use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; use_ok "Data::Entropy", qw(with_entropy_source); use_ok "Data::Entropy::Algorithms", qw(rand); } my $skip_all = significand_bits < 47; with_entropy_source +Data::Entropy::Source->new( IO::File->new("t/test0.entropy", "r") || die($!), "getc" ), sub { while() { chop; SKIP: { skip "non-standard fraction length", 1 if $skip_all; is sprintf("%.5f", rand(7)), $_; } } SKIP: { skip "non-standard fraction length", 2 if $skip_all; is sprintf("%.5f", rand), "0.40339"; is sprintf("%.5f", rand(0)), "0.57643"; } }; 1; __DATA__ 4.03949 6.26147 2.24646 3.31700 2.63184 1.41796 1.75632 6.38682 6.21075 1.63176 5.71063 2.43165 3.18495 2.78352 4.11310 5.58357 1.76606 3.94127 5.90934 2.27813 1.95405 4.46778 4.57601 4.51026 4.30349 2.60453 2.00978 4.45786 6.37942 2.27727 1.88362 4.15862 0.57427 0.96454 2.60107 1.90690 1.13613 6.70783 2.43433 2.24860 1.40735 2.10218 5.67393 3.51704 0.24440 4.29856 6.91233 0.94936 6.75088 0.74813 2.42188 6.62988 5.21451 6.90324 3.60941 6.35343 4.18760 0.89604 2.08841 0.09973 2.00711 5.69009 2.07490 3.89745 0.69842 2.87520 6.72101 6.07440 1.23840 2.18090 5.15799 2.54962 0.55972 0.43877 0.67409 2.20667 4.32117 3.43950 0.62849 1.86054 1.04994 5.74697 0.87189 4.37112 3.38660 6.99221 2.99821 2.81080 0.86609 1.49858 1.29385 1.76830 4.43088 6.44048 3.71470 5.08121 4.64473 5.31372 0.34369 1.06673 2.74852 4.54882 6.37792 1.08316 3.15476 3.63793 2.75349 5.54332 2.80939 1.78511 4.93116 2.43973 2.26185 5.38060 3.52985 3.94641 5.33728 4.26592 5.74231 3.46603 6.37356 3.00379 4.77121 3.88470 0.40732 2.54157 6.38269 1.85012 0.76890 2.97151 6.22267 2.06356 1.33057 5.44889 2.30828 0.26282 4.69865 3.74545 2.13907 3.46982 6.17097 5.63820 1.32550 1.61326 0.33302 5.13187 6.72437 3.29962 2.37014 3.47556 0.56813 5.25896 2.13548 6.66921 4.50784 5.42553 2.68242 5.70127 3.55900 0.05206 3.96886 2.68604 1.53927 4.48165 5.82785 1.11145 6.54273 2.13742 2.54401 6.59339 6.63027 5.43635 5.12821 6.87728 5.24629 1.29661 2.37573 6.98835 0.19256 2.07780 2.43141 0.94029 0.69126 3.09621 0.52342 3.11194 1.06508 6.85913 0.21614 6.99600 5.67229 0.78744 0.84214 6.67875 5.50226 0.59036 4.40295 6.45787 0.90274 3.74152 3.92806 5.63668 6.50168 2.97061 1.47128 3.39240 5.76571 4.51666 6.43616 0.93874 2.53152 1.55657 5.85942 2.73972 3.46216 2.21395 4.92681 2.64671 3.00646 4.74593 1.42706 6.38814 0.15958 3.31778 0.40831 1.32963 4.11706 0.15047 1.26295 0.11315 1.95935 3.44559 3.87174 0.48446 0.81557 4.61928 1.54109 0.05700 1.87977 0.32297 3.99102 6.07300 2.80843 6.40068 6.80164 0.07676 3.85847 1.10786 2.09193 1.57233 4.67734 4.16937 1.02375 5.07615 0.88993 1.92688 Data-Entropy-0.008/t/test0.entropy0000644000175000017500000000400011556073065014606 0ustar rrrr䯪qRo^y(`Np3@ @N;!r7"/;"RЭ Xؐet.ezi =z k{@2RX#A7SoGPykOvW dw$Y찄U4__b%I@eP#w.17SM;>DHrژ2#z_FGE6)k(К4YPsRJ3;^/Lx6/e<#o1/m^4b"5'k#-{X\8AUو vM;,pv%iN0U|}Z %L `?]Ia)g(<KGչ?iƗt&y{ KY-&:OJ;''6X]c><xMca TP؀ĞoZ}|Ʈɏ9D< & Fes,,Ȳ)ٲK{۱KF8 m h&0f$,?˄dd/66/K@Qe< U?M F`*DӴ;[|Tj T'Ĕdh`rl[N.'?sݜ_d L>)ʳ-f+jAWH=5YV뼡R9yĸ/QƾNqɁS_w1 gW~6(q@UmO_OV}r$χ\uyClQS lF'gKlW0wǩ4^-TFԆk j̶2Y!Nk~:٢yήk)T02e:y [ O-c/xtAiVX?0nNSMKڤ۹abkSR#;d(fGo9b%\8;ZK5}d (" s凉/aNFއ]+'S\ UȽ!1,QzXwЩ@ M/I~nJVk0o[ACj/7K ̋_X^"DעcFqG(;scq$_Ѵp&ۨ~3)gςqML;KX@f~9Éj"//h!,p,4֤ΧQ$@IlƎS5Jv|Ά="alsA8.;"a14(\T8dI~2 hP@Դi1`.3gؽm8)Qu4z0ZY7yUp0iqܖ`\}#=x.}0TBG#[eA~ y  U)4Ӟ8t|\%b`lD 6ϴ[m ]foU_W<s΢(OF{LIf9; [=~%z0 p YSFhgwu ԓDwA!؏'F "Test::Pod::Coverage not available" unless eval "use Test::Pod::Coverage; 1"; Test::Pod::Coverage::all_pod_coverage_ok(); 1; Data-Entropy-0.008/t/rand_flt.t0000644000175000017500000000117311556073065014113 0ustar rrrruse warnings; use strict; use Test::More tests => 11001; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Algorithms", qw(rand_flt); } sub test_rand_flt($$) { my($min, $max) = @_; for(my $i = 500; $i--; ) { my $v = rand_flt($min, $max); ok $v >= $min && $v <= $max; $v = rand_flt($max, $min); ok $v >= $min && $v <= $max; } } test_rand_flt(1.0, 2.0); test_rand_flt(1.0, 2.75); test_rand_flt(1.25, 2.0); test_rand_flt(1.25, 2.75); test_rand_flt(-2.75, -1.25); test_rand_flt(0.0, 1.0); test_rand_flt(-1.0, 1.0); test_rand_flt(-2.0, 1.0); test_rand_flt(-1.0, 2.0); test_rand_flt(2.5, 2.5); test_rand_flt(-0.0, +0.0); 1; Data-Entropy-0.008/t/get_int_medium.t0000644000175000017500000000635711556073065015324 0ustar rrrruse warnings; use strict; use Test::More tests => 1 + (500 + 1)*3; use IO::File 1.03; my $have_bigint = eval("use Math::BigInt 1.16; 1"); my $have_bigrat = eval("use Math::BigRat 0.04; 1"); BEGIN { use_ok "Data::Entropy::Source"; } sub match($$) { my($a, $b) = @_; ok ref($a) eq ref($b) && $a == $b; } my $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source0 = Data::Entropy::Source->new($rawsource, "getc"); ok $source0; $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source1 = Data::Entropy::Source->new($rawsource, "getc"); ok $source1; $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source2 = Data::Entropy::Source->new($rawsource, "getc"); ok $source2; my $bigint_thousand = $have_bigint && Math::BigInt->new(1000); my $bigrat_thousand = $have_bigrat && Math::BigRat->new(1000); while() { while(/([0-9]+)/g) { my $val = 0 + $1; my $tval = $source0->get_int(1000); match $tval, $val; SKIP: { skip "Math::BigInt unavailable", 1 unless $have_bigint; $tval = $source1->get_int($bigint_thousand); match $tval, Math::BigInt->new($val); } SKIP: { skip "Math::BigRat unavailable", 1 unless $have_bigrat; $tval = $source2->get_int($bigrat_thousand); match $tval, Math::BigRat->new($val); } } } 1; __DATA__ 698 484 175 923 914 765 687 623 350 789 040 519 150 248 926 334 624 403 402 563 266 681 128 025 731 932 137 135 489 059 033 231 400 227 933 882 740 303 059 823 008 594 023 720 006 523 232 543 874 656 854 101 867 819 372 949 718 634 105 267 884 406 204 032 894 276 460 107 507 778 167 576 985 661 527 270 887 338 435 088 949 547 926 714 055 595 284 238 111 250 583 592 969 079 257 163 118 457 497 011 167 968 932 201 782 492 688 132 259 669 868 212 564 790 351 385 949 293 235 064 968 080 035 675 128 046 758 305 951 992 455 754 398 913 333 687 891 062 324 626 888 451 474 858 898 783 639 021 872 950 228 001 000 960 920 731 961 582 071 896 468 789 031 763 925 742 926 700 107 296 144 245 805 666 951 968 080 160 925 627 955 262 496 205 864 307 315 510 350 877 836 814 690 310 020 900 559 279 613 990 888 316 035 264 415 390 394 305 904 752 365 894 350 508 098 952 950 934 715 999 039 877 758 696 797 932 989 283 483 161 005 174 344 092 065 888 824 658 782 217 012 446 804 209 059 169 508 691 270 044 368 132 549 105 863 304 256 341 167 124 153 602 424 419 816 032 037 947 753 868 588 799 385 167 525 259 063 413 093 504 927 805 609 898 720 359 040 060 027 851 919 071 441 655 654 737 912 063 460 537 520 952 239 234 954 710 899 628 245 294 633 541 838 478 716 011 244 089 557 038 133 278 536 793 977 235 953 706 054 600 727 605 674 414 691 132 020 574 655 401 229 528 894 355 097 437 011 743 693 825 592 782 260 472 452 414 179 623 734 346 947 519 636 710 174 457 399 569 493 856 508 277 572 269 948 522 582 959 722 101 473 044 891 543 953 434 983 297 779 729 906 075 924 731 433 400 979 779 987 587 907 056 521 932 009 038 560 890 166 556 975 063 287 356 830 303 054 817 841 310 144 303 279 817 542 587 081 101 230 572 674 171 341 663 886 747 927 900 070 352 647 137 936 186 964 185 271 324 527 535 723 180 571 091 194 477 084 877 362 012 596 662 499 015 295 145 660 443 640 515 530 360 096 422 644 626 917 989 745 091 302 464 530 858 493 186 873 115 412 668 847 165 389 442 500 675 237 267 574 297 Data-Entropy-0.008/t/rs_cryptcounter.t0000644000175000017500000000372611556073065015575 0ustar rrrruse warnings; use strict; use Test::More tests => 58; use Crypt::Rijndael; BEGIN { use_ok "Data::Entropy::RawSource::CryptCounter"; } use constant SEEK_SET => 0; use constant SEEK_CUR => 1; use constant SEEK_END => 2; my $ctr = Data::Entropy::RawSource::CryptCounter ->new(Crypt::Rijndael->new("\0" x 32)); ok $ctr; my $d; is $ctr->tell, 0; is $ctr->getc, "\xdc"; is $ctr->getc, "\x95"; $ctr->ungetc(3); is $ctr->getc, "\x95"; is $ctr->read($d, 14), 14; is $d, "\xc0\x78\xa2\x40\x89\x89\xad\x48\xa2\x14\x92\x84\x20\x87"; is $ctr->getc, "\x52"; is $ctr->tell, 17; is $ctr->seek(5, SEEK_CUR), 1; is $ctr->getc, "\xb8"; is $ctr->seek(17, SEEK_CUR), 1; is $ctr->read($d, 14), 14; is $d, "\x8d\x60\x9d\x55\x1a\x5c\xc9\x8e\x39\xd6\xe9\xae\x76\xa9"; is $ctr->seek(-16, SEEK_CUR), 1; is $ctr->read($d, 3), 3; is $d, "\xb6\x3d\x8d"; is $ctr->tell, 41; is $ctr->getc, "\x60"; my $pos = $ctr->getpos; is $ctr->seek(207, SEEK_SET), 1; is $ctr->getc, "\xd2"; is $ctr->getc, "\x0f"; is $ctr->setpos($pos), "0 but true"; is $ctr->tell, 42; is $ctr->getc, "\x9d"; is $ctr->seek(-3, SEEK_SET), 0; is $ctr->tell, 43; is $ctr->seek(-300, SEEK_CUR), 0; is $ctr->tell, 43; is $ctr->seek(-3, SEEK_END), 0; is $ctr->tell, 43; is $ctr->sysseek(-3, SEEK_CUR), 40; is $ctr->tell, 40; is $ctr->sysseek(3, SEEK_SET), 3; is $ctr->tell, 3; is $ctr->sysseek(-4, SEEK_CUR), undef; is $ctr->tell, 3; is $ctr->sysseek(-3, SEEK_CUR), "0 but true"; is $ctr->tell, 0; is $ctr->sysseek(0, SEEK_SET), "0 but true"; is $ctr->tell, 0; is $ctr->sysread($d, 16), 16; is $d, "\xdc\x95\xc0\x78\xa2\x40\x89\x89\xad\x48\xa2\x14\x92\x84\x20\x87"; is $ctr->read($d, 6, 2), 6; is $d, "\xdc\x95\x52\x75\xf3\xd8\x6b\x4f"; is $ctr->tell, 22; is $ctr->read($d, 3, -2), 3; is $d, "\xdc\x95\x52\x75\xf3\xd8\xb8\x68\x45"; is $ctr->read($d, 3, 11), 3; is $d, "\xdc\x95\x52\x75\xf3\xd8\xb8\x68\x45\x00\x00\x93\x13\x3e"; ok $ctr->close; is $ctr->getc, "\xbf"; ok !$ctr->error; is $ctr->clearerr, 0; ok $ctr->opened; ok !$ctr->eof; is $ctr->getc, "\xa5"; 1; Data-Entropy-0.008/t/rand_fix.t0000644000175000017500000000674211556073065014123 0ustar rrrruse warnings; use strict; use Test::More tests => 261; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; use_ok "Data::Entropy", qw(with_entropy_source); use_ok "Data::Entropy::Algorithms", qw(rand_fix); } with_entropy_source +Data::Entropy::Source->new( IO::File->new("t/test0.entropy", "r") || die($!), "getc" ), sub { while() { chop; is rand_fix(10), $_; } is rand_fix(1), 0.0; eval { rand_fix(-1); }; like $@, qr/\Aneed a non-negative number of bits to dispense/; }; 1; __DATA__ 0.681640625 0.47265625 0.1708984375 0.9013671875 0.892578125 0.7470703125 0.6708984375 0.6083984375 0.341796875 0.7705078125 0.0390625 0.5068359375 0.146484375 0.2421875 0.904296875 0.326171875 0.609375 0.3935546875 0.392578125 0.5498046875 0.259765625 0.6650390625 0.125 0.0244140625 0.7138671875 0.91015625 0.1337890625 0.1318359375 0.4775390625 0.0576171875 0.0322265625 0.2255859375 0.390625 0.2216796875 0.9111328125 0.861328125 0.72265625 0.2958984375 0.0576171875 0.8037109375 0.0078125 0.580078125 0.0224609375 0.703125 0.005859375 0.5107421875 0.2265625 0.5302734375 0.853515625 0.640625 0.833984375 0.0986328125 0.8466796875 0.9853515625 0.7998046875 0.36328125 0.9287109375 0.0986328125 0.619140625 0.794921875 0.8056640625 0.619140625 0.646484375 0.44921875 0.1591796875 0.2041015625 0.51953125 0.8095703125 0.2451171875 0.693359375 0.1201171875 0.1630859375 0.7978515625 0.7470703125 0.6455078125 0.8125 0.140625 0.78125 0.9404296875 0.6748046875 0.71484375 0.4609375 0.2841796875 0.5634765625 0.3037109375 0.4189453125 0.0810546875 0.52734375 0.3583984375 0.3984375 0.744140625 0.0693359375 0.7919921875 0.6044921875 0.89453125 0.0009765625 0.365234375 0.89453125 0.9765625 0.8349609375 0.7880859375 0.765625 0.646484375 0.9130859375 0.28515625 0.66015625 0.3369140625 0.23046875 0.37890625 0.87109375 0.6533203125 0.486328125 0.70703125 0.75 0.0927734375 0.8330078125 0.1259765625 0.8173828125 0.9609375 0.7294921875 0.0625 0.0986328125 0.578125 0.0341796875 0.1591796875 0.625 0.294921875 0.490234375 0.2978515625 0.2275390625 0.5068359375 0.4443359375 0.486328125 0.8701171875 0.5810546875 0.0751953125 0.1708984375 0.8671875 0.9345703125 0.8076171875 0.111328125 0.97265625 0.4404296875 0.212890625 0.4716796875 0.0029296875 0.625 0.1240234375 0.779296875 0.271484375 0.548828125 0.16796875 0.5009765625 0.5341796875 0.7548828125 0.369140625 0.890625 0.23828125 0.0927734375 0.068359375 0.8271484375 0.4873046875 0.70703125 0.8193359375 0.7451171875 0.302734375 0.8291015625 0.474609375 0.18359375 0.4892578125 0.9990234375 0.5390625 0.2392578125 0.63671875 0.703125 0.400390625 0.30078125 0.5869140625 0.578125 0.890625 0.798828125 0.646484375 0.080078125 0.005859375 0.7001953125 0.02734375 0.072265625 0.8623046875 0.9375 0.7998046875 0.591796875 0.998046875 0.6171875 0.0009765625 0.673828125 0.052734375 0.2021484375 0.7197265625 0.9560546875 0.001953125 0.0986328125 0.375 0.375 0.234375 0.173828125 0.5341796875 0.9423828125 0.80859375 0.1083984375 0.134765625 0.5478515625 0.1533203125 0.5458984375 0.3564453125 0.9697265625 0.591796875 0.9375 0.345703125 0.248046875 0.3876953125 0.984375 0.8203125 0.9453125 0.5380859375 0.79296875 0.833984375 0.6796875 0.7841796875 0.9609375 0.5009765625 0.845703125 0.4716796875 0.6201171875 0.0048828125 0.169921875 0.0859375 0.0546875 0.3134765625 0.6376953125 0.9072265625 0.392578125 0.3330078125 0.7880859375 0.986328125 0.849609375 0.115234375 0.7041015625 0.0751953125 0.1650390625 0.24609375 0.7958984375 0.681640625 0.04296875 0.9326171875 0.12890625 0.763671875 Data-Entropy-0.008/t/rs_local.t0000644000175000017500000000046011556073065014116 0ustar rrrruse warnings; use strict; use Test::More tests => 4; BEGIN { use_ok "Data::Entropy::RawSource::Local"; } my $rawsrc = Data::Entropy::RawSource::Local->new("t/test0.entropy"); ok $rawsrc; is $rawsrc->getc, "\x93"; eval { Data::Entropy::RawSource::Local->new("t/notexist.entropy"); }; isnt $@, ""; 1; Data-Entropy-0.008/t/with.t0000644000175000017500000000143111556073065013272 0ustar rrrruse warnings; use strict; use Test::More tests => 13; BEGIN { use_ok "Data::Entropy", qw(with_entropy_source entropy_source); } my $default_source; with_entropy_source 4, sub { is entropy_source, 4; with_entropy_source undef, sub { $default_source = entropy_source; ok $default_source; }; is entropy_source, 4; with_entropy_source 5, sub { is entropy_source, 5; }; is entropy_source, 4; }; is entropy_source, $default_source; my $s0_called; with_entropy_source sub { $s0_called = 1; "foo"; }, sub { ok 1; }; ok !$s0_called; my $s1_called; with_entropy_source sub { $s1_called = 1; undef; }, sub { is entropy_source, $default_source; }; ok $s1_called; my $s2_called; with_entropy_source sub { $s2_called = 1; "bar"; }, sub { is entropy_source, "bar"; }; ok $s2_called; 1; Data-Entropy-0.008/t/get_octet.t0000644000175000017500000000072111556073065014275 0ustar rrrruse warnings; use strict; use Test::More tests => 2051; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; } my $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source = Data::Entropy::Source->new($rawsource, "getc"); ok $source; $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; until($rawsource->eof) { is $source->get_octet, $rawsource->getc; } eval { $source->get_octet; }; like $@, qr/\Aentropy source failed:/; 1; Data-Entropy-0.008/t/pick.t0000644000175000017500000000165711556073065013257 0ustar rrrruse warnings; use strict; use Test::More tests => 158; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; use_ok "Data::Entropy", qw(with_entropy_source); use_ok "Data::Entropy::Algorithms", qw(pick pick_r); } with_entropy_source +Data::Entropy::Source->new( IO::File->new("t/test0.entropy", "r") || die($!), "getc" ), sub { my @items = qw(a b c d e f g h i j); $_ = ; while(/([a-z])/g) { is pick(@items), $1; } $_ = ; while(/([a-z])/g) { is pick_r(\@items), $1; } is pick("a"), "a"; is pick_r(["a"]), "a"; eval { pick(); }; like $@, qr/\Aneed a non-empty array to pick from/; eval { pick_r([]); }; like $@, qr/\Aneed a non-empty array to pick from/; eval { pick_r("a"); }; like $@, qr/\Aneed a non-empty array to pick from/; }; 1; __DATA__ fhgfjhhejgdhcjegdidehfjcfhacbcbdccbhhaecfcdfbjchfgejdchgbdegaegcjighddbeegf ggiifdjdddhhdcdccefjhdhdcicecbeagjhjeieggegjgfdagedbeacjegdgghghddaijhibdja Data-Entropy-0.008/t/get_prob_333a.t0000644000175000017500000000213011556073065014646 0ustar rrrruse warnings; use strict; use Test::More tests => 752; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; } my $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source = Data::Entropy::Source->new($rawsource, "getc"); ok $source; while() { while(/([0-9])/g) { is $source->get_prob(1000, 3), $1; } } 1; __DATA__ 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000001000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000010000000000000000000000000000 000000000000000000000000000000000010000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000100000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 Data-Entropy-0.008/t/shuffle.t0000644000175000017500000000163511556073065013761 0ustar rrrruse warnings; use strict; use Test::More tests => 22; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; use_ok "Data::Entropy", qw(with_entropy_source); use_ok "Data::Entropy::Algorithms", qw(shuffle shuffle_r); } with_entropy_source +Data::Entropy::Source->new( IO::File->new("t/test0.entropy", "r") || die($!), "getc" ), sub { my @items = qw(a b c d e f g h i j); $_ = ; while(/([a-z]+)/g) { is join("", shuffle(@items)), $1; } $_ = ; while(/([a-z]+)/g) { is join("", @{shuffle_r(\@items)}), $1; } is_deeply [ shuffle(qw(a)) ], [ qw(a) ]; is_deeply shuffle_r([qw(a)]), [ qw(a) ]; is_deeply [ shuffle() ], []; is_deeply shuffle_r([]), []; eval { shuffle_r("a"); }; like $@, qr/\Aneed an array to shuffle/; }; 1; __DATA__ djeciabhgf jchfbgidae hcfijbgdae dfghaicebj dcibgfajeh cajgedfbhi fbejdihacg jdefaghcbi bigdajhfec efhbgacjdi jgiafcdheb cjfeahbgid dbhajegcfi iaefhcdbgj Data-Entropy-0.008/t/rand_int.t0000644000175000017500000000260511556073065014121 0ustar rrrruse warnings; use strict; use IO::File 1.03; use Test::More; BEGIN { eval "use Math::BigInt 1.16; 1" or plan skip_all => "Math::BigInt unavailable"; plan tests => 35; use_ok "Data::Entropy::Source"; use_ok "Data::Entropy", qw(with_entropy_source); use_ok "Data::Entropy::Algorithms", qw(rand_int); } sub match($$) { my($a, $b) = @_; ok ref($a) eq ref($b) && $a == $b; } with_entropy_source +Data::Entropy::Source->new( IO::File->new("t/test0.entropy", "r") || die($!), "getc" ), sub { my $limit = Math::BigInt->new("100000000000000000000"); while() { while(/([0-9]+)/g) { match rand_int($limit), Math::BigInt->new($1); } } match rand_int(1), 0; eval { rand_int(0); }; like $@, qr/\Aneed a positive upper limit for random variable/; }; 1; __DATA__ 68807314153453845935 44895925609758693014 91684367776668160563 56108518278522687113 28217278430494290576 71738743512311479074 74386544180255394792 39152281477817113805 90921893246479465065 82620448454531421388 44674519163021046525 84527795945300210520 34360252122495692115 38978214527762911353 79479987427485544715 12061931143224927321 53948765087340844500 80659296157555878729 78427179399174651950 91564990700810876914 61342958431468667976 63611026805453161344 27646495397604287489 00034572888809883207 85168650371487971070 90371971159857598709 88818527526349480067 26775678824341118026 59032056402338073720 55462451824035966722 Data-Entropy-0.008/t/rs_randomorg.t0000644000175000017500000000026711556073065015021 0ustar rrrruse warnings; use strict; use Test::More tests => 2; BEGIN { use_ok "Data::Entropy::RawSource::RandomOrg"; } my $rawsrc = Data::Entropy::RawSource::RandomOrg->new; ok $rawsrc; 1; Data-Entropy-0.008/t/get_prob_2.t0000644000175000017500000000212511556073065014342 0ustar rrrruse warnings; use strict; use Test::More tests => 752; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; } my $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source = Data::Entropy::Source->new($rawsource, "getc"); ok $source; while() { while(/([0-9])/g) { is $source->get_prob(2, 1), $1; } } 1; __DATA__ 010010000000010000000001011000000000010000000001010000010100100110000010101 110010000111000001000000000101011010001011101110000000010011111010010111100 101010000000000001001000000011000000000101000010011110001100110000001101010 100110100010101000000001100100000111010011000000100100010100000110001000010 110000000001101100010000011111100000100110111010010011000100100101110000110 000111000011010010000011101001101000000000100100011000000000000100100100110 001010000001101010000100111000011100000011001010000010001001001101001100010 010110110010000100000000000010110101000100000100000001011111100001000000000 000000101000011000000100010100000000010000010101011110100010010101000001100 000010001000001100001000101000001100011011000010100100000000000000100001111 Data-Entropy-0.008/t/get_prob_333b.t0000644000175000017500000000213011556073065014647 0ustar rrrruse warnings; use strict; use Test::More tests => 752; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; } my $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source = Data::Entropy::Source->new($rawsource, "getc"); ok $source; while() { while(/([0-9])/g) { is $source->get_prob(3, 1000), $1; } } 1; __DATA__ 111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111110101111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111 Data-Entropy-0.008/t/rs_randomnumbersinfo.t0000644000175000017500000000030711556073065016554 0ustar rrrruse warnings; use strict; use Test::More tests => 2; BEGIN { use_ok "Data::Entropy::RawSource::RandomnumbersInfo"; } my $rawsrc = Data::Entropy::RawSource::RandomnumbersInfo->new; ok $rawsrc; 1; Data-Entropy-0.008/t/rand_bits.t0000644000175000017500000000150711556073065014270 0ustar rrrruse warnings; use strict; use Test::More tests => 45; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; use_ok "Data::Entropy", qw(with_entropy_source); use_ok "Data::Entropy::Algorithms", qw(rand_bits); } with_entropy_source +Data::Entropy::Source->new( IO::File->new("t/test0.entropy", "r") || die($!), "getc" ), sub { for(my $nbits = 1; ; $nbits++) { chop; is rand_bits($nbits), pack("h*", $_); } is rand_bits(0), ""; eval { rand_bits(-1); }; like $@, qr/\Aneed a non-negative number of bits to dispense/; }; 1; __DATA__ 10 00 40 e0 d0 c3 b4 aa 1710 2510 df30 f690 e050 97f1 82f2 6969 8f0600 e4ab20 392970 330480 9a0830 9104e2 e49800 799eb3 127e2710 093e3910 73224e30 b322ad60 802571c1 da60b0e0 8ef185f2 09ff56c1 dcdebc4710 e2ec56a720 b0d3a76940 cc023a1d30 ccb6bf6cc0 b77a0423d0 59f0e00911 253b85cd8d Data-Entropy-0.008/t/get_bits.t0000644000175000017500000001140111556073065014115 0ustar rrrruse warnings; use strict; use Test::More tests => 183; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; } my $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source = Data::Entropy::Source->new($rawsource, "getc"); ok $source; my $nbits; for($nbits = 1; ; $nbits++) { chop; is $source->get_bits($nbits), pack("h*", $_); } eval { $source->get_bits($nbits); }; like $@, qr/\Aentropy source failed:/; 1; __DATA__ 10 00 40 e0 d0 c3 b4 aa 1710 2510 df30 f690 e050 97f1 82f2 6969 8f0600 e4ab20 392970 330480 9a0830 9104e2 e49800 799eb3 127e2710 093e3910 73224e30 b322ad60 802571c1 da60b0e0 8ef185f2 09ff56c1 dcdebc4710 e2ec56a720 b0d3a76940 cc023a1d30 ccb6bf6cc0 b77a0423d0 59f0e00911 253b85cd8d 3214ac73da00 35c1eef68920 af740597b630 103a67759cf0 1fb07a4669c0 9c424a95cec2 0b4830d92ff4 4d43f5f52618 8052be94045600 0532773a08e230 8b139e707c7350 2fe835d47ffad0 e34484277c3ca0 ad893e3008f7e3 516123ca4e1036 00a73dbd4ff564 74d93f4d54f1bf10 63ef6e92cb5fb610 82095fc80da9cc60 95050a38376925b0 600fdcc1a433b310 88e5f2c487102b60 6341fc1ef2207143 08080fc32b3280f9 68f6a813d90ff2d610 11e5cf4326efd8f830 bc5372b6326f8bd270 980810b13e1ab75090 85c58314d8f92f2921 559d88c0eb671dd442 9acf3babe0c20748a2 5296e4038e00557ac7 d799a58a3a2a0b025210 68bf1f50c44cff187a30 d03006f3d9d58f945a00 16927e0d7682c35ab1e0 b481745d9bf8e81eacb1 f3cc919880befeae96d2 a86c79476b5f6297d133 5cedccb0b44f95d262a3 586181f4a4b372be72cb10 2c63857b7dd52ae9363b30 41e3c3f8195e0187d43670 165b81b07e5bae45057a10 8d084ce93bf6fdeda5d7d1 70dfc76cea619cf8931c03 44cf51fec3d062a0ae2b04 0c2d569d37c249f1c28c2b e192f92e9d2bb48cb7bd1b00 09bffaffadb47b648390d620 90866203666a42c24bf3f130 484646f263cae9c96309f2b0 ec71c1e1b40415566ec390a0 ba5579f3d4beb002d06406d0 7898d9deaba29badf044f0b4 9a3d4bb3b5c72cdd4581bda6 c045696f3ff072194c49bb0810 46302186a9066a4827dbc6c910 b5e4e20d2172f3deab79383700 c9ddc9315a58f5ab4f3ade4680 c49ce392ac3b00d2c99966abb0 b27ea60014eb75fe0d0c4b84d3 d359539565becb1a9925939701 79f74c8be06bf215186ceb8d3f e4097117799c183c35f577014f10 c913e1b0bd762d20bb7589fbe710 10c16382179e1c6f044b55d67160 5bf481eaadf5f4656ee8d72742d0 4a08e0110a5dfc78c55e57fedd81 9e2fee97cb0e34c609a11068c1c2 9a15350dc0c6e11a6421ad3ecad1 76706cb429c64edf750377d9fb2a 597c9a43e53cd24564804d68b69000 a6cc6b23ffbac9a97abb95886d1200 383ae49fcfc9b6bae7a3f89d2a5a00 1e5e97a92b28eceab6922045032340 3f7050a3979bb01eb5c0ffac607831 f4bbd24d3638795fea41ef0cf28773 474b149665ca207f3efdf7da3e8566 2141b103ac5ecf0c7c20d1e66ce435 0ed4acb43f81bfddddad4a7e40693e00 9e6cbd9bc8168026b6354f25410d9120 b96c013228085f28b34610826674d870 197ef6e9989326524ac5bc9f83b318a0 19a5993ab4d1ac2c535d6ed76f46b091 22900c377cfe5a9bf216f7e464ed78f3 7c50d5b2722a35c51f903b558cdb2f41 13c2150b6ca7789e8577bb0d9afb1004 bfb88c10a10afb38d0bdd4bff2dd94e700 e6a465b603f65fb5ff2e142934a6d87010 f2f073b4a0ccb8f5bb85cfffe0fae52220 bee8447d2a913664acee9b1774ccdf8200 31b34a6b37361742f51d4b0762ecbd8a01 1ee7af3f595dfe33709d92115b76ff7ee3 aded30b8fc284a81adc1173ad48ec4e191 b3ba5fb44fcc857f9bfe9c0466e75fbe51 933c98a6df1a7922f2f228ce506a865f3000 12c207c2e0798830fa6a5a1ff85d433b6d20 4aec7af96b156cde4204097894c66ce8e960 c8533a9ba4674dc7ec680fd3222d013a1640 c6375acd14a97183bee2b3e98960221613e0 4f82c5458b8ab1918349cc20891e6dde4181 dcb17a469448fa4ae0e723b086e08b05d935 04ea4d4b7f0a96134c06e233768ddbd6bc83 209259da3f156b57b843095ced20a79e031900 a5182a50f919956873976de0d95f5ce0555f10 79f103ee5b9617cd690a06c5d78a501932d350 be87e2080c6dd7784003d15f45247432b55620 80e78aa0119790d8200a3fd06911895531bc71 92d17bca4361318a3de9ad7f0a83eebf473be2 20c5522606c64451b9e18a7bb0ebcf63e00040 fc4bd8b5d6ed5fd0d53bfb6691e189f6acae5b 55f5fd758f5140c33e4920ebee37c129d8ec2a00 6e6e2182c191f464b7c4480194cb669318b35f00 b0b5ba083a59d3a189e069baade752a70d03b050 9b07da697d1f024a951c355e64b8ccf0863176f0 77bf57024d3944fd1d7714ff19128df8c1bc7240 2ae12bc33b442abf18b8f98b03b13d8433d1b932 3236a7d327ca788011419135c947b209fccd4e10 738aeb1b6b7e27dfb512b7ac8f29ae265d4b4b4b eab2cef5581fd5e4804d17866609b586835542d700 da46c808f4092185a7930df13961f926eca70da520 5e15d5814b8f6cea417b0c68e4360e3cd52318e210 54ec0b2397ad3f7e939d9d418352c04dbc502c1890 387cc88c0b25aab332a6f9e9ee4548a6e8915ffcf0 b6d7e6a09633cfbbacd65195ae6de23e30fc83fa73 f6f0fe7bd4a4801d781094754c1086f18891d87691 dc6b6dac6d733176ddb1f67233a5ead9a10f372480 5c56c592e9a7b860222ca5d341dfd9c5d81bd3c71400 09fda5bcd6d5eff9c17ba9de7a2775f5c674713be130 120958f6b7e075926f0a9d1f26040cf2cb50c3b36e40 ef347a971670bb6d126101f1902c9479c2f10d5aa6e0 9655b18890a62132a500092e4b7762e56b5d302bb211 8339391546b773124da99bf9cde2d1cc84ce0a527ee1 797c197e31c8e6edb925c5697f3d8dc5df08575c40c0 dadf44f63c7fe16f64fa3a81dc78f1b77c56c0e44123 b7959a80a6e25165b7a7b968eccdef72baaaf699ac3d00 ef65f2984b7ad99e89d3aa1ae4dc94d3052bbd291bee30 bffd476ea3515dd1da9020927c9ccd64df76273c96e930 c8eb4d3d7e51d7c83f35de3fff19cdfd779136f6e42020 Data-Entropy-0.008/t/get_int_large.t0000644000175000017500000001324011556073065015123 0ustar rrrruse warnings; use strict; use IO::File 1.03; use Test::More; BEGIN { eval "use Math::BigInt 1.16; 1" or plan skip_all => "Math::BigInt unavailable"; plan tests => 247; use_ok "Data::Entropy::Source"; } sub match($$) { my($a, $b) = @_; ok ref($a) eq ref($b) && $a == $b; } my $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source = Data::Entropy::Source->new($rawsource, "getc"); ok $source; my $limit = Math::BigInt->new("100000000000000000000"); while() { while(/([0-9]+)/g) { match $source->get_int($limit), Math::BigInt->new($1); } } eval { $source->get_int($limit); }; like $@, qr/\Aentropy source failed:/; 1; __DATA__ 68807314153453845935 44895925609758693014 91684367776668160563 56108518278522687113 28217278430494290576 71738743512311479074 74386544180255394792 39152281477817113805 90921893246479465065 82620448454531421388 44674519163021046525 84527795945300210520 34360252122495692115 38978214527762911353 79479987427485544715 12061931143224927321 53948765087340844500 80659296157555878729 78427179399174651950 91564990700810876914 61342958431468667976 63611026805453161344 27646495397604287489 00034572888809883207 85168650371487971070 90371971159857598709 88818527526349480067 26775678824341118026 59032056402338073720 55462451824035966722 07313987564148499208 29941741811947925551 19698459122094476687 95965855528171861688 46801408546928950021 86349868852075929586 65884805502039127761 24011972741068099116 46438345741891069952 48962147346469659554 31137929085322331468 51088695252392042559 62111475236908116455 33463759797132938008 60516479594089532156 33153680803275729513 09999846550164285049 39017997357351128052 80212810570948548687 04262634128232560216 50140647929376125828 96574694046705193080 07040560031874804308 24258363245774282419 71471662629467815110 49437923576492715332 55058175860685540074 12846166997005333292 20693135055196364770 89473660071366603152 86469071389269047305 26303669611864172068 03221269039267734628 77726674462648053710 57005471491899352550 41219655921244258125 00801655329590315421 35576795184082404367 57045358926108523714 79846810841985095414 54407749130308074368 25653368142908401284 08267883912107871790 19754828580754260851 85090338542803312570 36074938454109899070 69946250433522132666 21610357886296152047 33488965053531919669 43156795256455969145 20074654346905564719 79660170206891953808 94149942094182178679 75008749428533877607 70473095903946178049 03902494325911994548 79942577976886892718 52628871005128785266 85640465982952951687 25140630167931185650 35630717598308274202 09663785067193830508 57547354560312618023 93965290978176460029 21939177556150699945 03773668137237874900 83472822072734266111 29731260313142613537 50621483796171365483 67697611038185924065 82549488594723957545 18614556152846026501 99491565705555148746 37363920498848981891 10949849474217815928 82196394619727250167 90206959446074605330 56789037574258475207 57461082735383694794 42366233589642549924 71986828249420716985 06991946634602238484 33441931782992921216 54584255734386026055 28648683552806701369 30290309465037832593 43421916825287049781 89200121566754187298 13867647509695377249 09173347412574930269 40003120694067005875 97042986570022146480 93493188850632604624 49124984638990436353 85370097156995545903 15945414967840631600 44960943609493951043 10162356268605852426 88525955758594785038 31083320073257277346 62493860405915502540 92028970495339968115 80952524770920132646 14905693078164272021 54129616975574447463 73780099789634112463 46307164593589429069 95917326470443518964 14724791359651790950 27595220768178538858 94510046091262749701 81349930885091175438 46694358491790938069 22244358987843084214 61232890123547346761 44731597159561704867 05365709638564507709 39402574383718101925 71211368207488855611 85214867094020109556 06653145581681719444 51593968376850748621 57332903848184882190 22052834412780887471 04660896538088728881 69490593048647220589 59376066160051311030 26916665394309497466 16803090027627283871 43344392660095770101 32646125261499604784 17200770289564557408 30553986827513722926 27724395140717228061 91464803605477549377 00612111360565250445 37082906571446523989 88426241033288029715 85952217976590579950 36566048619724809570 63141616431619684107 87548910289942597556 65526088007718624691 94546633892238650037 06151881184928662588 53292223309649484946 51783205341280869401 98594627460818553276 62706292981184027563 67127627005270333099 15744062556742880129 87149347252626071716 87717706458381160296 38291706278626514067 95827541706351284513 84099316911158992562 04373915129901845407 68612370917252865435 62508341540772317201 38341768834024444111 15916951675693085110 35124415011661531896 16889296524695350827 90819455882275719380 45065382441477748821 45949493127741935634 61715704009670727327 07119763096213251409 68380623393154121862 05648605487339569454 41923639712077771751 97915315004824671435 74202012898260651208 12705404669739573150 61430341975793848171 45931661096558312394 75325495248192472015 59424779856860133197 05334744136392726468 81289841442388651981 68515173002443450333 38870330010376248602 26751954380436285854 82617134535587544340 18274864626573081665 28885906364737388191 50123636306207006572 42016248190569842031 45760608701501200881 60006013919672679398 56276492380243298235 15429638056844051017 21626233344529880347 92912095005463580898 99328902294729458610 58469170268727239803 77759666402160008238 70060507775763978183 28960137422705695570 43565280534655204736 87983599600588320707 54700428907543468237 46630125163141418516 08888321193198622038 82684571311960555047 67621436026410391087 86804523169383033505 92435618454545030034 12821221455328241210 33803364632315414473 97081561038207543710 47035265564884172172 42941246301036928887 1829428254474718444 Data-Entropy-0.008/t/choose.t0000644000175000017500000000270511556073065013604 0ustar rrrruse warnings; use strict; use Test::More tests => 54; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; use_ok "Data::Entropy", qw(with_entropy_source); use_ok "Data::Entropy::Algorithms", qw(choose choose_r); } with_entropy_source +Data::Entropy::Source->new( IO::File->new("t/test0.entropy", "r") || die($!), "getc" ), sub { my @items = qw(a b c d e f g h i j); $_ = ; while(/([a-z]+)/g) { is join("", choose(3, @items)), $1; } $_ = ; while(/([a-z]+)/g) { is join("", @{choose_r(3, \@items)}), $1; } is_deeply [ choose(1, qw(a)) ], [ qw(a) ]; is_deeply choose_r(1, [qw(a)]), [ qw(a) ]; is_deeply [ choose(3, qw(a b c)) ], [ qw(a b c) ]; is_deeply choose_r(3, [qw(a b c)]), [ qw(a b c) ]; is_deeply [ choose(0, qw(a b c)) ], []; is_deeply choose_r(0, [qw(a b c)]), []; eval { choose(-1, qw(a b c)); }; like $@, qr/\Aneed a non-negative number of items to choose/; eval { choose_r(-1, [qw(a b c)]); }; like $@, qr/\Aneed a non-negative number of items to choose/; eval { choose(4, qw(a b c)); }; like $@, qr/\Aneed a sufficiently large array to pick from/; eval { choose_r(4, [qw(a b c)]); }; like $@, qr/\Aneed a sufficiently large array to pick from/; eval { choose_r(4, "a"); }; like $@, qr/\Aneed a sufficiently large array to pick from/; }; 1; __DATA__ bci abg abi fgh fgj chj bce dfh bhj adj dij cde ceh acd adi cij cdg beh acf egi egj efj abe bcf dgj abd abd acf adi ehj eij bef bei bhi bcf cde bfj ach eij ahi Data-Entropy-0.008/t/rand_prob.t0000644000175000017500000000152311556073065014267 0ustar rrrruse warnings; use strict; use Test::More tests => 157; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; use_ok "Data::Entropy", qw(with_entropy_source); use_ok "Data::Entropy::Algorithms", qw(rand_prob); } with_entropy_source +Data::Entropy::Source->new( IO::File->new("t/test0.entropy", "r") || die($!), "getc" ), sub { $_ = ; while(/([0-9])/g) { is rand_prob(1, 2, 0, 3, 4), $1; } $_ = ; while(/([0-9])/g) { is rand_prob([ 1, 2, 0, 3, 4 ]), $1; } is rand_prob(1), 0; is rand_prob([1]), 0; eval { rand_prob(-1); }; like $@, qr/\Aprobabilities must be non-negative/; eval { rand_prob(0); }; like $@, qr/\Acan't have nothing possible/; }; 1; __DATA__ 334004330330101331104144441041440443440340311333014430141343331033433134434 034443443110114433133310340433331041443030303433344343333441344341334414034 Data-Entropy-0.008/t/get_int_small.t0000644000175000017500000001256011556073065015145 0ustar rrrruse warnings; use strict; use Test::More tests => 4930; use IO::File 1.03; BEGIN { use_ok "Data::Entropy::Source"; } sub match($$) { my($a, $b) = @_; ok ref($a) eq ref($b) && $a == $b; } my $rawsource = IO::File->new("t/test0.entropy", "r") or die $!; my $source = Data::Entropy::Source->new($rawsource, "getc"); ok $source; while() { while(/([0-9])/g) { match $source->get_int(10), $1; } } eval { $source->get_int(10); }; like $@, qr/\Aentropy source failed:/; 1; __DATA__ 576597749637294638347592570212132217704252351927564932761346046298673314465 668853933377323224597373282421406979484664696530643140294636676733089781390 852819136829337430031748018528742296912772037431612173090375601966749578637 815623470219055917566908369838793829442964859636606869243810773032374937201 076193983874217596160983742436116114156773008085562061188224112516226229305 718361413585456989575877886335362076026479937315689370071657265613304548936 568137516315943381369187098658096758809069585316441236980447977452657131262 905652003385539566854252647432736302517027765656896767008609235813694445014 829490805429464027338575093225826912766172652427107982571719391987722351043 670020937392214836321066739360057662681177640381147462712394026215222368020 157881317111179038329520086191206069805259435956853601726810222327780026821 430663074824731558095930818692624316936660123315956538309662497732408467331 146755109216229856043356788063193998090446339759745648041717846217679603008 616428919612421424014758440021788579501614143027226537621310022829054650454 599660884942423418004261941369390841427305430244643217785888619502069928776 566903089339448307731814385025882693970483249461624083221558060171319706314 740660963526378401055789048993012089307296041411564799705022404264062787675 080619918401314795239217804669105391335346148898445465499608595695282076180 457016966518952770534157751818707817489009789064178788942781407594171253563 125308120637277563115813179531789045256547221995565074925120161385529617183 331672918200815603355924071247669582379666274238894884344782887628239494364 884345026187619402727092325785367792870993356637753530433038715972965549728 616924843649643868274562032967376850571260700090393489208278649001446682735 175059354183105995182047903435672325342335281433915185767767131278031291665 208703556727160133812159876954529339917443504783565857143127826051431773011 425559878335514203523098740392278708001882708876313875419436430694731061138 423159153519017742100278509724360528336072639760096772502639662227151677307 836268659250483414343403203403915008979683602450844471056779861210013459941 954146126134392457465586792898761072578023722487804304688793071129636698546 436219205948195121259446000322082764860433365706313877183574574784207187469 743324067872288487111357661913643271801147404494810087698206708443525287507 512132693539143670352670040980452192898840958297086965092991030367438964637 223795055382043603274217109668777943114251395716318126247957017514507899143 230362139383134863712556324010095123401737878648973176507854842280379352023 333098467904595218491860236430065438046837148762445347034907530299407576778 909576740690121714138428543259652263153784885844437298224244551068096884843 629482030840564052864903443421809641523456540495783836439564675342401624030 829995415056812154130533262113690393095408764219978298857439395626722781062 900480723702801320729620679653170160439454997247424637834936855874611831344 654489013894154698762718860469863995180595113901198276225765045560214021792 410456690201629504172774055727875726333185421471607129616301444008779395296 654280608905036233077759759084559839521986247885626571935982230475929573606 507242697081690252574111568239906256544779596887511724870018169041571295481 707247861251723338197500897451226099242779600888155194986633688534499785720 492534506645195503069109866470340162514363169975039928866651494857827024760 083655162818953002483613336172370587636427406335669225107047581594604037645 193614405497277094659324420353959979544839216717162009449019160093832647259 549739780461144479998417501906909016629635330051142602194535041680562423216 250567151864781405656131439300603011049554734132816478805401026149704676531 752423307675078112287129247507525140640933193385141898874487307184862239590 629756268249988556621395785385456523937736027319361718265818971432802924044 767744716850343751557769951979948866182209106783517474904239105538265120602 433276833007670553207700029886459793054582148957352110688890415394407278665 636852421880007580077258978199711897738061108982873273478697780541277623790 138524099987743252437361285915159589645146335149846858572741923877234290861 081264507377264281363690904230135057584390065641780500051421010260704631553 747559980376518220436842767728903764441329913698161940478687402916953183517 729492931538678031158894971819348967338843150260580760575831075523584292605 154163776214818358356414157119953134966794347811680654359615379013710814850 224076935067055933765108565124870126600679741085999907333530555131128927968 201276073603100811782862584905512808550152002147784348720714076273677616048 259112737186912013219848430724442380382808511476199782062448469690616574012 224566789542992612679594747452284232670651581169121591210144316322242608972 747165916119711541986176068663516316233961013786299429149430020179604349191 494056916884590911617409837854749794512294784578045702889638972135346862374 6318881893957752968464847295145156893370957319113323 Data-Entropy-0.008/lib/0000755000175000017500000000000014771321107012431 5ustar rrrrData-Entropy-0.008/lib/Data/0000755000175000017500000000000014771321107013302 5ustar rrrrData-Entropy-0.008/lib/Data/Entropy.pm0000644000175000017500000001031314771320003015270 0ustar rrrr=head1 NAME Data::Entropy - entropy (randomness) management =head1 SYNOPSIS use Data::Entropy qw(entropy_source); $i = entropy_source->get_int(12345); use Data::Entropy qw(with_entropy_source); with_entropy_source $source, sub { @a = shuffle(@a); }; =head1 STATUS This module is deprecated. For most purposes (including cryptography and security), modules like L, L or L are more than adequate. Modern operating systems provide good sources of random bytes, and the above mentioned modules work on many kinds of systems, including Windows. There is no need to choose an entropy source, and some users of this module have omitted that step, and prior to version 0.008 they may have been relying on Perl's builtin C function. Please see CPAN Author's Guide to Random Data for Security L. =head1 DESCRIPTION This module maintains a concept of a current selection of entropy source. Algorithms that require entropy, such as those in L, can use the source nominated by this module, avoiding the need for entropy source objects to be explicitly passed around. This is convenient because usually one entropy source will be used for an entire program run and so an explicit entropy source parameter would rarely vary. There is also a default entropy source, avoiding the need to explicitly configure a source at all. If nothing is done to set a source then it defaults to the use of Rijndael (AES) in counter mode (see L and L), keyed using L. =cut package Data::Entropy; { use 5.006; } use warnings; use strict; use Carp qw(croak); use Params::Classify 0.000 qw(is_ref); our $VERSION = "0.008"; use parent "Exporter"; our @EXPORT_OK = qw(entropy_source with_entropy_source); our $entropy_source; =head1 FUNCTIONS =over =item entropy_source Returns the current entropy source, a C object. This will be the source passed to the innermost call to C, if any, or otherwise the default entropy source. =cut my $default_entropy_source; sub entropy_source() { if(is_ref($entropy_source, "CODE")) { my $source = $entropy_source->(); croak "entropy source thunk returned another thunk" if is_ref($source, "CODE"); $entropy_source = $source; } unless(defined $entropy_source) { unless(defined $default_entropy_source) { require Crypt::URandom; my $key = Crypt::URandom::urandom(32); require Crypt::Rijndael; require Data::Entropy::RawSource::CryptCounter; require Data::Entropy::Source; $default_entropy_source = Data::Entropy::Source->new( Data::Entropy::RawSource::CryptCounter ->new(Crypt::Rijndael ->new($key)), "getc"); } $entropy_source = $default_entropy_source; } return $entropy_source; } =item with_entropy_source SOURCE, CLOSURE The SOURCE is selected, so that it will be returned by C, and CLOSURE is called (with no arguments). The SOURCE is selected only during the dynamic scope of the call; after CLOSURE finishes, by whatever means, the previously selected entropy source is restored. SOURCE is normally a C object. Alternatively, it may be C to cause use of the default entropy source. It may also be a reference to a function of no arguments, which will be called to generate the actual source only if required. This avoids unnecessarily initialising the source object if it is uncertain whether any entropy will be required. The source-generating closure may return a normal source or C, but not another function reference. =cut sub with_entropy_source($&) { my($source, $closure) = @_; local $entropy_source = $source; $closure->(); } =back =head1 SEE ALSO L, L =head1 AUTHOR Andrew Main (Zefram) Maintained by Robert Rothenberg =head1 COPYRIGHT Copyright (C) 2006, 2007, 2009, 2011, 2025 Andrew Main (Zefram) =head1 LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Data-Entropy-0.008/lib/Data/Entropy/0000755000175000017500000000000014771321107014742 5ustar rrrrData-Entropy-0.008/lib/Data/Entropy/RawSource/0000755000175000017500000000000014771321107016654 5ustar rrrrData-Entropy-0.008/lib/Data/Entropy/RawSource/RandomnumbersInfo.pm0000644000175000017500000001314514771317774022665 0ustar rrrr=head1 NAME Data::Entropy::RawSource::RandomnumbersInfo - download entropy from randomnumbers.info =head1 SYNOPSIS use Data::Entropy::RawSource::RandomnumbersInfo; my $rawsrc = Data::Entropy::RawSource::RandomnumbersInfo->new; $c = $rawsrc->getc; # and the rest of the I/O handle interface =head1 DESCRIPTION This class provides an I/O handle connected to a stream of random octets being generated by a quantum random number generator (from the company id Quantique) connected to the randomnumbers.info server at the University of Geneva. This is a strong source of random bits, but is not suitable for security applications because the bits are passed over the Internet unencrypted. The handle implements a substantial subset of the interface described in L. For use as a general entropy source, it is recommended to wrap an object of this class using C, which provides methods to extract entropy in more convenient forms than mere octets. The bits generated at randomnumbers.info are, theoretically and as far as anyone can tell, totally unbiased and uncorrelated. However, they are sent over the Internet in the clear, and so are subject to interception and alteration by an adversary. This is therefore generally unsuitable for security applications. Applications requiring secret entropy should generate it locally (see L). Applications requiring a large amount of apparently-random data, but not true entropy, might prefer to fake it cryptographically (see L). =cut package Data::Entropy::RawSource::RandomnumbersInfo; { use 5.006; } use warnings; use strict; use Errno 1.00 qw(EIO); use HTTP::Lite 2.2 (); our $VERSION = "0.008"; =head1 CONSTRUCTOR =over =item Data::Entropy::RawSource::RandomnumbersInfo->new Creates and returns a handle object referring to a stream of random octets generated by randomnumbers.info. =cut sub new { my($class) = @_; my $http = HTTP::Lite->new; $http->http11_mode(1); return bless({ http => $http, buffer => "", bufpos => 0, error => 0, }, $class); } =back =head1 METHODS A subset of the interfaces described in L and L are provided: =over =item $rawsrc->read(BUFFER, LENGTH[, OFFSET]) =item $rawsrc->getc =item $rawsrc->ungetc(ORD) =item $rawsrc->eof Buffered reading from the source, as in L. =item $rawsrc->sysread(BUFFER, LENGTH[, OFFSET]) Unbuffered reading from the source, as in L. =item $rawsrc->close Does nothing. =item $rawsrc->opened Retruns true to indicate that the source is available for I/O. =item $rawsrc->clearerr =item $rawsrc->error Error handling, as in L. =back The buffered (C et al) and unbuffered (C et al) sets of methods are interchangeable, because no such distinction is made by this class. Methods to write to the file are unimplemented because the stream is fundamentally read-only. Methods to seek are unimplemented because the stream is non-rewindable; C works, however. =cut sub _ensure_buffer { my($self) = @_; return 1 unless $self->{bufpos} == length($self->{buffer}); $self->{http}->reset; unless($self->{http}->request( "http://www.randomnumbers.info/cgibin/wqrng.cgi?". "amount=256&limit=255" ) == 200) { $! = EIO; return 0; } my($numbers) = ($self->{http}->body =~ /((?:[0-9]+[\ \t\n]+){255}[0-9]+)/); unless(defined $numbers) { $! = EIO; return 0; } $self->{buffer} = ""; $self->{bufpos} = 0; while($numbers =~ /([0-9]+)/g) { if($1 >= 256) { $! = EIO; return $self->{buffer} ne ""; } $self->{buffer} .= chr($1); } return 1; } sub close { 1 } sub opened { 1 } sub error { $_[0]->{error} } sub clearerr { my($self) = @_; $self->{error} = 0; return 0; } sub getc { my($self) = @_; unless($self->_ensure_buffer) { $self->{error} = 1; return undef; } return substr($self->{buffer}, $self->{bufpos}++, 1); } sub ungetc { my($self, $cval) = @_; if($self->{bufpos} == 0) { $self->{buffer} = chr($cval).$self->{buffer}; } else { $self->{bufpos}--; } } sub read { my($self, undef, $length, $offset) = @_; return undef if $length < 0; $_[1] = "" unless defined $_[1]; if(!defined($offset)) { $offset = 0; $_[1] = ""; } elsif($offset < 0) { return undef if $offset < -length($_[1]); substr $_[1], $offset, -$offset, ""; $offset = length($_[1]); } elsif($offset > length($_[1])) { $_[1] .= "\0" x ($offset - length($_[1])); } else { substr $_[1], $offset, length($_[1]) - $offset, ""; } my $original_offset = $offset; while($length != 0) { unless($self->_ensure_buffer) { $self->{error} = 1; last; } my $avail = length($self->{buffer}) - $self->{bufpos}; if($length < $avail) { $_[1] .= substr($self->{buffer}, $self->{bufpos}, $length); $offset += $length; $self->{bufpos} += $length; last; } $_[1] .= substr($self->{buffer}, $self->{bufpos}, $avail); $offset += $avail; $length -= $avail; $self->{bufpos} += $avail; } my $nread = $offset - $original_offset; return $nread == 0 ? undef : $nread; } *sysread = \&read; sub eof { 0 } =head1 SEE ALSO L, L, L, L, L =head1 AUTHOR Andrew Main (Zefram) Maintained by Robert Rothenberg =head1 COPYRIGHT Copyright (C) 2006, 2007, 2009, 2011, 2025 Andrew Main (Zefram) =head1 LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Data-Entropy-0.008/lib/Data/Entropy/RawSource/Local.pm0000644000175000017500000000642114771317774020266 0ustar rrrr=head1 NAME Data::Entropy::RawSource::Local - read randomness from local device =head1 SYNOPSIS use Data::Entropy::RawSource::Local; my $rawsrc = Data::Entropy::RawSource::Local->new; $rawsrc->sysread($c, 1); # and the rest of the I/O handle interface =head1 DESCRIPTION This class provides a constructor to open an I/O handle connected to a local source of random octets. This may be a strong entropy source, depending on the OS, but not every OS has such a facility at all. There are no actual objects blessed into this class. Only the constructor belongs to this class; it returns C objects. For use as a general entropy source, it is recommended to wrap the handle using C, which provides methods to extract entropy in more convenient forms than mere octets. On systems with a blocking B, such as Linux, the bits generated can be totally unbiased and uncorrelated. Such an entropy stream is suitable for all uses, including security applications. However, the rate of entropy generation is limited, so applications requiring a large amount of apparently-random data might prefer to fake it cryptographically (see L). On systems where B does not block, the bits generated are necessarily correlated to some extent, but it should be cryptographically difficult to detect the correlation. Such an entropy source is not suitable for all applications. Some other systems lack B entirely. If satisfactory entropy cannot be generated locally, consider downloading it from a server (see L and L). =cut package Data::Entropy::RawSource::Local; { use 5.006; } use warnings; use strict; use Carp qw(croak); use IO::File 1.03; our $VERSION = "0.008"; =head1 CONSTRUCTOR =over =item Data::Entropy::RawSource::Local->new([FILENAME]) Opens a file handle referring to the randomness device, or Cs on error. The device opened is B by default, but this may be overridden by giving a FILENAME argument. The default device name may in the future be different on different OSes, if their equivalent devices are in different places. =cut sub new { my($class, $filename) = @_; $filename = "/dev/random" unless defined $filename; my $self = IO::File->new($filename, "r"); croak "can't open $filename: $!" unless defined $self; return $self; } =back =head1 METHODS There are no actual objects blessed into this class. The constuctor returns C objects. See L for the interface. It is recommended to use unbuffered reads (the C method) rather than buffered reads (the C method et al), to avoid wasting entropy that could be used by another process. =head1 SEE ALSO L, L, L, L, L =head1 AUTHOR Andrew Main (Zefram) Maintained by Robert Rothenberg =head1 COPYRIGHT Copyright (C) 2006, 2007, 2009, 2011, 2025 Andrew Main (Zefram) =head1 LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Data-Entropy-0.008/lib/Data/Entropy/RawSource/CryptCounter.pm0000644000175000017500000002126514771317774021700 0ustar rrrr=head1 NAME Data::Entropy::RawSource::CryptCounter - counter mode of block cipher as I/O handle =head1 SYNOPSIS use Data::Entropy::RawSource::CryptCounter; my $rawsrc = Data::Entropy::RawSource::CryptCounter ->new(Crypt::Rijndael->new($key)); $c = $rawsrc->getc; # and the rest of the I/O handle interface =head1 DESCRIPTION This class provides an I/O handle connected to a virtual file which contains the output of a block cipher in counter mode. This makes a good source of pseudorandom bits. The handle implements a substantial subset of the interfaces described in L and L. For use as a general entropy source, it is recommended to wrap an object of this class using C, which provides methods to extract entropy in more convenient forms than mere octets. The amount of entropy the virtual file actually contains is only the amount that is in the key, which is at most the length of the key. It superficially appears to be much more than this, if (and to the extent that) the block cipher is secure. This technique is not suitable for all problems, and requires a careful choice of block cipher and keying method. Applications requiring true entropy should generate it (see L) or download it (see L and L). =cut package Data::Entropy::RawSource::CryptCounter; { use 5.006; } use warnings; use strict; use Params::Classify 0.000 qw(is_number is_ref is_string); our $VERSION = "0.008"; =head1 CONSTRUCTOR =over =item Data::Entropy::RawSource::CryptCounter->new(KEYED_CIPHER) KEYED_CIPHER must be a cipher object supporting the standard C and C methods. For example, an instance of C (with the default C) would be appropriate. A handle object is created and returned which refers to a virtual file containing the output of the cipher's counter mode. =cut sub new { my($class, $cipher) = @_; return bless({ cipher => $cipher, blksize => $cipher->blocksize, counter => "\0" x $cipher->blocksize, subpos => 0, }, $class); } =back =head1 METHODS A subset of the interfaces described in L and L are provided: =over =item $rawsrc->read(BUFFER, LENGTH[, OFFSET]) =item $rawsrc->getc =item $rawsrc->ungetc(ORD) =item $rawsrc->eof Buffered reading from the source, as in L. =item $rawsrc->sysread(BUFFER, LENGTH[, OFFSET]) Unbuffered reading from the source, as in L. =item $rawsrc->close Does nothing. =item $rawsrc->opened Retruns true to indicate that the source is available for I/O. =item $rawsrc->clearerr =item $rawsrc->error Error handling, as in L. =item $rawsrc->getpos =item $rawsrc->setpos(POS) =item $rawsrc->tell =item $rawsrc->seek(POS, WHENCE) Move around within the buffered source, as in L. =item $rawsrc->sysseek(POS, WHENCE) Move around within the unbuffered source, as in L. =back The buffered (C et al) and unbuffered (C et al) sets of methods are interchangeable, because no such distinction is made by this class. C, C, and C only work within the first 4 GiB of the virtual file. The file is actually much larger than that: for Rijndael (AES), or any other cipher with a 128-bit block, the file is 2^52 YiB (2^132 B). C and C work throughout the file. Methods to write to the file are unimplemented because the virtual file is fundamentally read-only. =cut sub _ensure_buffer { my($self) = @_; $self->{buffer} = $self->{cipher}->encrypt($self->{counter}) unless exists $self->{buffer}; } sub _clear_buffer { my($self) = @_; delete $self->{buffer}; } sub _increment_counter { my($self) = @_; for(my $i = 0; $i != $self->{blksize}; $i++) { my $c = ord(substr($self->{counter}, $i, 1)); unless($c == 255) { substr $self->{counter}, $i, 1, chr($c + 1); return; } substr $self->{counter}, $i, 1, "\0"; } $self->{counter} = undef; } sub _decrement_counter { my($self) = @_; for(my $i = 0; ; $i++) { my $c = ord(substr($self->{counter}, $i, 1)); unless($c == 0) { substr $self->{counter}, $i, 1, chr($c - 1); return; } substr $self->{counter}, $i, 1, "\xff"; } } sub close { 1 } sub opened { 1 } sub error { 0 } sub clearerr { 0 } sub getc { my($self) = @_; return undef unless defined $self->{counter}; $self->_ensure_buffer; my $ret = substr($self->{buffer}, $self->{subpos}, 1); if(++$self->{subpos} == $self->{blksize}) { $self->_increment_counter; $self->{subpos} = 0; $self->_clear_buffer; } return $ret; } sub ungetc { my($self, undef) = @_; unless($self->{subpos} == 0) { $self->{subpos}--; return; } return if $self->{counter} =~ /\A\0*\z/; $self->_decrement_counter; $self->{subpos} = $self->{blksize} - 1; $self->_clear_buffer; } sub read { my($self, undef, $length, $offset) = @_; return undef if $length < 0; $_[1] = "" unless defined $_[1]; if(!defined($offset)) { $offset = 0; $_[1] = ""; } elsif($offset < 0) { return undef if $offset < -length($_[1]); substr $_[1], $offset, -$offset, ""; $offset = length($_[1]); } elsif($offset > length($_[1])) { $_[1] .= "\0" x ($offset - length($_[1])); } else { substr $_[1], $offset, length($_[1]) - $offset, ""; } my $original_offset = $offset; while($length != 0 && defined($self->{counter})) { $self->_ensure_buffer; my $avail = $self->{blksize} - $self->{subpos}; if($length < $avail) { $_[1] .= substr($self->{buffer}, $self->{subpos}, $length); $offset += $length; $self->{subpos} += $length; last; } $_[1] .= substr($self->{buffer}, $self->{subpos}, $avail); $offset += $avail; $length -= $avail; $self->_increment_counter; $self->{subpos} = 0; $self->_clear_buffer; } return $offset - $original_offset; } *sysread = \&read; sub tell { my($self) = @_; use integer; my $ctr = $self->{counter}; my $nblocks; if(defined $ctr) { return -1 if $ctr =~ /\A.{4,}[^\0]/s; $ctr .= "\0\0\0\0" if $self->{blksize} < 4; $nblocks = unpack("V", $ctr); } else { return -1 if $self->{blksize} >= 4; $nblocks = 1 << ($self->{blksize} << 3); } my $pos = $nblocks * $self->{blksize} + $self->{subpos}; return -1 unless ($pos-$self->{subpos}) / $self->{blksize} == $nblocks; return $pos; } use constant SEEK_SET => 0; use constant SEEK_CUR => 1; use constant SEEK_END => 2; sub sysseek { my($self, $offset, $whence) = @_; if($whence == SEEK_SET) { use integer; return undef if $offset < 0; my $ctr = $offset / $self->{blksize}; my $subpos = $offset % $self->{blksize}; $ctr = pack("V", $ctr); if($self->{blksize} < 4) { return undef unless my $chopped = substr($ctr, $self->{blksize}, 4-$self->{blksize}, ""); if($chopped =~ /\A\x{01}\0*\z/ && $subpos == 0) { $self->{counter} = undef; $self->{subpos} = 0; $self->_clear_buffer; return $offset; } elsif($chopped !~ /\A\0+\z/) { return undef; } } else { $ctr .= "\0" x ($self->{blksize} - 4); } $self->{counter} = $ctr; $self->{subpos} = $subpos; $self->_clear_buffer; return $offset || "0 but true"; } elsif($whence == SEEK_CUR) { my $pos = $self->tell; return undef if $pos == -1; return $self->sysseek($pos + $offset, SEEK_SET); } elsif($whence == SEEK_END) { use integer; return undef if $offset > 0; return undef if $self->{blksize} >= 4; my $nblocks = 1 << ($self->{blksize} << 3); my $pos = $nblocks * $self->{blksize}; return undef unless $pos/$self->{blksize} == $nblocks; return $self->sysseek($pos + $offset, SEEK_SET); } else { return undef; } } sub seek { shift->sysseek(@_) ? 1 : 0 } sub getpos { my($self) = @_; return [ $self->{counter}, $self->{subpos} ]; } sub setpos { my($self, $pos) = @_; return undef unless is_ref($pos, "ARRAY") && @$pos == 2; my($ctr, $subpos) = @$pos; unless(!defined($ctr) && $subpos == 0) { return undef unless is_string($ctr) && length($ctr) == $self->{blksize} && is_number($subpos) && $subpos >= 0 && $subpos < $self->{blksize}; } $self->{counter} = $ctr; $self->{subpos} = $subpos; $self->_clear_buffer; return "0 but true"; } sub eof { my($self) = @_; return !defined($self->{counter}); } =head1 SEE ALSO L, L, L, L, L =head1 AUTHOR Andrew Main (Zefram) Maintained by Robert Rothenberg =head1 COPYRIGHT Copyright (C) 2006, 2007, 2009, 2011, 2025 Andrew Main (Zefram) =head1 LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Data-Entropy-0.008/lib/Data/Entropy/RawSource/RandomOrg.pm0000644000175000017500000001430114771317774021120 0ustar rrrr=head1 NAME Data::Entropy::RawSource::RandomOrg - download entropy from random.org =head1 SYNOPSIS use Data::Entropy::RawSource::RandomOrg; my $rawsrc = Data::Entropy::RawSource::RandomOrg->new; $c = $rawsrc->getc; # and the rest of the I/O handle interface =head1 DESCRIPTION This class provides an I/O handle connected to a stream of random octets being generated by an electromagnetic noise detector connected to the random.org server. This is a strong source of random bits, but is not suitable for security applications because the bits are passed over the Internet unencrypted. The handle implements a substantial subset of the interface described in L. For use as a general entropy source, it is recommended to wrap an object of this class using C, which provides methods to extract entropy in more convenient forms than mere octets. The bits generated at random.org are, theoretically and as far as anyone can tell, totally unbiased and uncorrelated. However, they are sent over the Internet in the clear, and so are subject to interception and alteration by an adversary. This is therefore generally unsuitable for security applications. The capacity of the random bit server is also limited. This class will slow down requests if the server's entropy pool is less than half full, and (as requested by the server operators) pause entirely if the entropy pool is less than 20% full. Applications requiring secret entropy should generate it locally (see L). Applications requiring a large amount of entropy should generate it locally or download it from randomnumbers.info (see L). Applications requiring a large amount of apparently-random data, but not true entropy, might prefer to fake it cryptographically (see L). =cut package Data::Entropy::RawSource::RandomOrg; { use 5.006; } use warnings; use strict; use Errno 1.00 qw(EIO); use HTTP::Lite 2.2 (); our $VERSION = "0.008"; =head1 CONSTRUCTOR =over =item Data::Entropy::RawSource::RandomOrg->new Creates and returns a handle object referring to a stream of random octets generated by random.org. =cut sub new { my($class) = @_; my $http = HTTP::Lite->new; $http->http11_mode(1); return bless({ http => $http, buffer => "", bufpos => 0, error => 0, }, $class); } =back =head1 METHODS A subset of the interfaces described in L and L are provided: =over =item $rawsrc->read(BUFFER, LENGTH[, OFFSET]) =item $rawsrc->getc =item $rawsrc->ungetc(ORD) =item $rawsrc->eof Buffered reading from the source, as in L. =item $rawsrc->sysread(BUFFER, LENGTH[, OFFSET]) Unbuffered reading from the source, as in L. =item $rawsrc->close Does nothing. =item $rawsrc->opened Retruns true to indicate that the source is available for I/O. =item $rawsrc->clearerr =item $rawsrc->error Error handling, as in L. =back The buffered (C et al) and unbuffered (C et al) sets of methods are interchangeable, because no such distinction is made by this class. Methods to write to the file are unimplemented because the stream is fundamentally read-only. Methods to seek are unimplemented because the stream is non-rewindable; C works, however. =cut sub _checkbuf { my($self) = @_; $self->{http}->reset; unless($self->{http}->request( "http://www.random.org/cgi-bin/checkbuf" ) == 200) { $! = EIO; return undef; } unless($self->{http}->body =~ /\A[\ \t\n]*([0-9]{1,3}(?:\.[0-9]+)?)\%[\ \t\n]*\z/) { $! = EIO; return undef; } return $1; } sub _ensure_buffer { my($self) = @_; return 1 unless $self->{bufpos} == length($self->{buffer}); while(1) { my $fillpct = $self->_checkbuf; return 0 unless defined $fillpct; if($fillpct >= 20) { sleep((50 - $fillpct)*0.2) if $fillpct < 50; last; } sleep 10; } $self->{http}->reset; unless($self->{http}->request( "http://www.random.org/cgi-bin/randbyte?nbytes=256&format=f" ) == 200) { $! = EIO; return 0; } $self->{buffer} = $self->{http}->body; $self->{bufpos} = 0; if($self->{buffer} !~ /\A[\x00-\xff]+\z/) { $self->{buffer} = ""; $! = EIO; return 0; } return 1; } sub close { 1 } sub opened { 1 } sub error { $_[0]->{error} } sub clearerr { my($self) = @_; $self->{error} = 0; return 0; } sub getc { my($self) = @_; unless($self->_ensure_buffer) { $self->{error} = 1; return undef; } return substr($self->{buffer}, $self->{bufpos}++, 1); } sub ungetc { my($self, $cval) = @_; if($self->{bufpos} == 0) { $self->{buffer} = chr($cval).$self->{buffer}; } else { $self->{bufpos}--; } } sub read { my($self, undef, $length, $offset) = @_; return undef if $length < 0; $_[1] = "" unless defined $_[1]; if(!defined($offset)) { $offset = 0; $_[1] = ""; } elsif($offset < 0) { return undef if $offset < -length($_[1]); substr $_[1], $offset, -$offset, ""; $offset = length($_[1]); } elsif($offset > length($_[1])) { $_[1] .= "\0" x ($offset - length($_[1])); } else { substr $_[1], $offset, length($_[1]) - $offset, ""; } my $original_offset = $offset; while($length != 0) { unless($self->_ensure_buffer) { $self->{error} = 1; last; } my $avail = length($self->{buffer}) - $self->{bufpos}; if($length < $avail) { $_[1] .= substr($self->{buffer}, $self->{bufpos}, $length); $offset += $length; $self->{bufpos} += $length; last; } $_[1] .= substr($self->{buffer}, $self->{bufpos}, $avail); $offset += $avail; $length -= $avail; $self->{bufpos} += $avail; } my $nread = $offset - $original_offset; return $nread == 0 ? undef : $nread; } *sysread = \&read; sub eof { 0 } =head1 SEE ALSO L, L, L, L, L =head1 AUTHOR Andrew Main (Zefram) Maintained by Robert Rothenberg =head1 COPYRIGHT Copyright (C) 2006, 2007, 2009, 2011, 2025 Andrew Main (Zefram) =head1 LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Data-Entropy-0.008/lib/Data/Entropy/Algorithms.pm0000644000175000017500000003275514771317774017444 0ustar rrrr=head1 NAME Data::Entropy::Algorithms - basic entropy-using algorithms =head1 SYNOPSIS use Data::Entropy::Algorithms qw(rand_bits rand_int rand_prob); $str = rand_bits(17); $i = rand_int(12345); $i = rand_int(Math::BigInt->new("1000000000000")); $j = rand_prob(1, 2, 3); $j = rand_prob([ 1, 2, 3 ]); use Data::Entropy::Algorithms qw(rand_fix rand rand_flt); $x = rand_fix(48); $x = rand(7); $x = rand_flt(0.0, 7.0); use Data::Entropy::Algorithms qw(pick pick_r choose choose_r shuffle shuffle_r); $item = pick($item0, $item1, $item2); $item = pick_r(\@items); @chosen = choose(3, $item0, $item1, $item2, $item3, $item4); $chosen = choose_r(3, \@items); @shuffled = shuffle($item0, $item1, $item2, $item3, $item4); $shuffled = shuffle_r(\@items); =head1 DESCRIPTION This module contains a collection of fundamental algorithms that use entropy. They all use the entropy source mechanism described in L. =cut package Data::Entropy::Algorithms; { use 5.006; } use warnings; use strict; use Carp qw(croak); use Data::Entropy qw(entropy_source); use Data::Float 0.008 qw( have_subnormal min_normal_exp significand_bits float_is_finite float_parts float_sign mult_pow2 copysign ); use Params::Classify 0.000 qw(is_ref); our $VERSION = "0.008"; use parent "Exporter"; our @EXPORT_OK = qw( rand_bits rand_int rand_prob rand_fix rand rand_flt pick_r pick choose_r choose shuffle_r shuffle ); =head1 FUNCTIONS All of these functions use entropy. The entropy source is not an explicit input in any case. All functions use the current entropy source maintained by the C module. To select an entropy source use the C function in that module, or alternatively do nothing to use the default source. =head2 Fundamental entropy extraction =over =item rand_bits(NBITS) Returns NBITS bits of entropy, as a string of octets. If NBITS is not a multiple of eight then the last octet in the string has its most significant bits set to zero. =cut sub rand_bits($) { my($nbits) = @_; croak "need a non-negative number of bits to dispense" unless $nbits >= 0; return entropy_source->get_bits($nbits); } =item rand_int(LIMIT) LIMIT must be a positive integer. Returns a uniformly-distributed random integer in the range [0, LIMIT). LIMIT may be either a native integer, a C object, or an integer-valued C object; the returned number is of the same type. =cut sub rand_int($) { my($limit) = @_; croak "need a positive upper limit for random variable" unless $limit > 0; return entropy_source->get_int($limit); } =item rand_prob(PROB ...) =item rand_prob(PROBS) Returns a random integer selected with non-uniform probability. The relative probabilities are supplied as a list of non-negative integers (multiple PROB arguments) or a reference to an array of integers (the PROBS argument). The relative probabilities may be native integers, C objects, or integer-valued C objects; they must all be of the same type. At least one probability value must be positive. The first relative probability value (the first PROB or the first element of PROBS) is the relative probability of returning 0. The absolute probability of returning 0 is this value divided by the total of all the relative probability values. Similarly the second value controls the probability of returning 1, and so on. =cut sub rand_prob(@) { my $probs = @_ == 1 && is_ref($_[0], "ARRAY") ? $_[0] : \@_; my $total = 0; for(my $i = @$probs; $i--; ) { my $prob = $probs->[$i]; croak "probabilities must be non-negative" unless $prob >= 0; $total += $prob; } croak "can't have nothing possible" if $total == 0; for(my $i = @$probs; $i--; ) { my $prob = $probs->[$i]; $total -= $prob; return $i if entropy_source->get_prob($total, $prob); } } =back =head2 Numbers =over =item rand_fix(NBITS) Returns a uniformly-distributed random NBITS-bit fixed-point fraction in the range [0, 1). That is, the result is a randomly-chosen multiple of 2^-NBITS, the multiplier being a random integer in the range [0, 2^NBITS). The value is returned in the form of a native floating point number, so NBITS can be at most one greater than the number of bits of significand in the floating point format. With NBITS = 48 the range of output values is the same as that of the Unix C function. =cut sub rand_fix($) { my($nbits) = @_; croak "need a non-negative number of bits to dispense" unless $nbits >= 0; croak "can't generate more than ".(significand_bits+1). " bits of fixed-point fraction" if $nbits > significand_bits+1; my $frac = 0.0; for(my $pos = 24; $pos <= $nbits; $pos += 24) { $frac += mult_pow2(rand_int(1 << 24), -$pos); } $frac += mult_pow2(rand_int(1 << ($nbits % 24)), -$nbits); return $frac; } =item rand([LIMIT]) Generates a random fixed-point fraction by C and then multiplies it by LIMIT, returning the result. LIMIT defaults to 1, and if it is 0 then that is also treated as 1. The length of the fixed-point fraction is 48 bits, unless that can't be represented in the native floating point type, in which case the longest possible fraction will be generated instead. This is a drop-in replacement for C: it produces exactly the same range of output values, but using the current entropy source instead of a sucky PRNG with linear relationships between successive outputs. (C does the type of calculation described, but using the PRNG C to generate the fixed-point fraction.) The details of behaviour may change in the future if the behaviour of C changes, to maintain the match. Where the source of a module can't be readily modified, it can be made to use this C by an incantation such as *Foreign::Module::rand = \&Data::Entropy::Algorithms::rand; This must be done before the module is loaded, most likely in a C block. It is also possible to override C for all modules, by performing this similarly early: *CORE::GLOBAL::rand = \&Data::Entropy::Algorithms::rand; This function should not be used in any new code, because the kind of output supplied by C is hardly ever the right thing to use. The C idiom to generate a random integer has non-uniform probabilities of generating each possible value, except when C<$n> is a power of two. For floating point numbers, C can't generate most representable numbers in its output range, and the output is biased towards zero. In new code use C to generate integers and C to generate floating point numbers. =cut use constant RAND_NBITS => 48 > significand_bits+1 ? significand_bits+1 : 48; sub rand(;$) { my($limit) = @_; return rand_fix(RAND_NBITS) * (!defined($limit) || $limit == 0.0 ? 1.0 : $limit); } =item rand_flt(MIN, MAX) Selects a uniformly-distributed real number (with infinite precision) in the range [MIN, MAX] and then rounds this number to the nearest representable floating point value, which it returns. (Actually it is only I the function worked this way: in fact it never generates the number with infinite precision. It selects between the representable floating point values with the probabilities implied by this process.) This can return absolutely any floating point value in the range [MIN, MAX]; both MIN and MAX themselves are possible return values. All bits of the floating point type are filled randomly, so the range of values that can be returned depends on the details of the floating point format. (See L for low-level floating point utilities.) The function Cs if MIN and MAX are not both finite. If MIN is greater than MAX then their roles are swapped: the order of the limit parameters actually doesn't matter. If the limits are identical then that value is always returned. As a special case, if the limits are positive zero and negative zero then a zero will be returned with a randomly-chosen sign. =cut sub rand_flt($$) { my($a, $b) = @_; croak "bounds for rand_flt() must be finite" unless float_is_finite($a) && float_is_finite($b); if($a == $b) { return $_[rand_int(2)] if $a == 0.0 && float_sign($a) ne float_sign($b); return $_[0]; } ($a, $b) = ($b, $a) if abs($a) < abs($b); my($prm_sign, $prm_max_exp, $prm_max_sgnf) = $a == 0.0 ? ("+", min_normal_exp, 0.0) : float_parts($a); my($b_sign, $b_exp, $b_sgnf) = $b == 0.0 ? ("+", min_normal_exp, 0.0) : float_parts($b); my($min_exp, $min_sgnf); my($opp_max_exp, $opp_max_sgnf); if($b_sign eq $prm_sign) { ($min_exp, $min_sgnf) = ($b_exp, $b_sgnf); ($opp_max_exp, $opp_max_sgnf) = (min_normal_exp, 0.0); } else { ($min_exp, $min_sgnf) = (min_normal_exp, 0.0); ($opp_max_exp, $opp_max_sgnf) = ($b_exp, $b_sgnf); } TRY_AGAIN: my $exp = $prm_max_exp; my $bdone = significand_bits; $bdone = 28 if $bdone > 28; my $prm_frng = $prm_max_sgnf * (1 << $bdone); if($prm_max_sgnf < 1.0) { # subnormal limit my $desired_rng = 1 << $bdone; while($bdone != significand_bits) { $bdone++; $prm_frng += $prm_frng; last if $prm_frng >= $desired_rng; } } my $prm_rng = int($prm_frng); $prm_rng++ if $prm_frng != $prm_rng; my $min_b = $bdone - ($exp - $min_exp); my $min_rng = $min_b >= 0 ? int(mult_pow2($min_sgnf, $min_b)) : 0; my $opp_b = $bdone - ($exp - $opp_max_exp); my $opp_frng = $opp_b >= 0 ? mult_pow2($opp_max_sgnf, $opp_b) : 0; my $opp_rng = int($opp_frng); $opp_rng++ if $opp_frng != $opp_rng; my $n = $min_rng + rand_int($prm_rng - $min_rng + $opp_rng); my($sg, $max_exp, $max_sgnf) = ($a, $prm_max_exp, $prm_max_sgnf); if($n >= $prm_rng) { $n -= $prm_rng; ($sg, $max_exp, $max_sgnf) = ($b, $opp_max_exp, $opp_max_sgnf); } while($n == 0 && $exp - $bdone - 1 >= min_normal_exp) { $exp -= $bdone + 1; $n = rand_int(2 << $bdone); } for(my $bit = 16; $bit; $bit >>= 1) { if($bdone >= $bit && $exp - $bit >= min_normal_exp && $n < (2 << ($bdone - $bit))) { $bdone -= $bit; $exp -= $bit; } } goto TRY_AGAIN if $exp < $min_exp; my $top_sgnf = $exp == $max_exp ? $max_sgnf : 2.0; my $bot_sgnf = $exp == $min_exp ? $min_sgnf : 1.0; my $sgnf = mult_pow2($n, -$bdone); if(!have_subnormal && $exp == min_normal_exp && $sgnf < 1.0) { $top_sgnf = 1.0; $sgnf = 0.0; } else { $bot_sgnf = 1.0 if !have_subnormal && $exp == min_normal_exp && $bot_sgnf < 1.0; while($bdone != significand_bits) { my $bseg = significand_bits - $bdone; $bseg = 28 if $bseg > 28; $bdone += $bseg; $sgnf += mult_pow2(rand_int(1 << $bseg), -$bdone); } } goto TRY_AGAIN if $sgnf < $bot_sgnf || $sgnf >= $top_sgnf; $sgnf = $top_sgnf if $sgnf == $bot_sgnf && rand_int(2); return copysign($sgnf == 0.0 ? 0.0 : mult_pow2($sgnf, $exp), $sg); } =back =head2 Combinatorics =over =item pick(ITEM ...) Randomly selects and returns one of the ITEMs. Each ITEM has equal probability of being selected. =item pick_r(ITEMS) ITEMS must be a reference to an array. Randomly selects and returns one of the elements of the array. Each element has equal probability of being selected. This is the same operation as that performed by C, but using references to avoid expensive copying of arrays. =cut sub pick_r($) { my($a) = @_; croak "need a non-empty array to pick from" unless is_ref($a, "ARRAY") && @$a; return $a->[rand_int(@$a)]; } sub pick(@) { pick_r(\@_) } =item choose(NCHOOSE, ITEM ...) Randomly selects NCHOOSE of the ITEMs. Each ITEM has equal probability of being selected. The chosen items are returned in a list in the same order in which they appeared in the argument list. =item choose_r(NCHOOSE, ITEMS) ITEMS must be a reference to an array. Randomly selects NCHOOSE of the elements in the array. Each element has equal probability of being selected. Returns a reference to an array containing the chosen items in the same order in which they appeared in the input array. This is the same operation as that performed by C, but using references to avoid expensive copying of arrays. =cut sub choose_r($$) { my($nchoose, $a) = @_; croak "need a non-negative number of items to choose" unless $nchoose >= 0; croak "need a sufficiently large array to pick from" unless is_ref($a, "ARRAY") && @$a >= $nchoose; my $ntotal = @$a; my $nleave = $ntotal - $nchoose; my @chosen; for(my $i = 0; $i != $ntotal; $i++) { if(entropy_source->get_prob($nleave, $nchoose)) { push @chosen, $a->[$i]; $nchoose--; } else { $nleave--; } } return \@chosen; } sub choose(@) { @{choose_r(shift, \@_)} } =item shuffle(ITEM ...) Reorders the ITEMs randomly, and returns them in a list in random order. Each possible order has equal probability. =item shuffle_r(ITEMS) ITEMS must be a reference to an array. Reorders the elements of the array randomly. Each possible order has equal probability. Returns a reference to an array containing the elements in random order. This is the same operation as that performed by C, but using references to avoid expensive copying of arrays. =cut sub shuffle_r($) { my($a) = @_; croak "need an array to shuffle" unless is_ref($a, "ARRAY"); $a = [ @$a ]; for(my $i = @$a; $i > 1; ) { my $j = rand_int($i--); @{$a}[$i, $j] = @{$a}[$j, $i]; } return $a; } sub shuffle(@) { @{shuffle_r(\@_)} } =back =head1 SEE ALSO L, L =head1 AUTHOR Andrew Main (Zefram) Maintained by Robert Rothenberg =head1 COPYRIGHT Copyright (C) 2006, 2007, 2009, 2011, 2025 Andrew Main (Zefram) =head1 LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Data-Entropy-0.008/lib/Data/Entropy/Source.pm0000644000175000017500000002166214771317774016566 0ustar rrrr=head1 NAME Data::Entropy::Source - encapsulated source of entropy =head1 SYNOPSIS use Data::Entropy::Source; $source = Data::Entropy::Source->new($handle, "sysread"); $c = $source->get_octet; $str = $source->get_bits(17); $i = $source->get_int(12345); $i = $source->get_int(Math::BigInt->new("1000000000000")); $j = $source->get_prob(1, 2); =head1 DESCRIPTION An object of this class encapsulates a source of entropy (randomness). Methods allow entropy to be dispensed in any quantity required, even fractional bits. An entropy source object should not normally be used directly. Rather, it should be used to support higher-level entropy-consuming algorithms, such as those in L. This type of object is constructed as a layer over a raw entropy source which does not supply methods to extract arbitrary amounts of entropy. The raw entropy source is expected to dispense only entire octets at a time. The B devices on some versions of Unix constitute such a source, for example. The raw entropy source is accessed via the C interface. This interface may be supplied by classes other than C itself, as is done for example by C. If two entropy sources of this class are given exactly the same raw entropy data, for example by reading from the same file, and exactly the same sequence of C method calls is made to them, then they will return exactly the same values from those calls. (Calls with numerical arguments that have the same numerical value but are of different types count as the same for this purpose.) This means that a run of an entropy-using algorithm can be made completely deterministic if desired. =cut package Data::Entropy::Source; { use 5.006; } use warnings; use strict; use Carp qw(croak); our $VERSION = "0.008"; =head1 CONSTRUCTOR =over =item Data::Entropy::Source->new(RAW_SOURCE, READ_STYLE) Constructs and returns an entropy source object based on the given raw source. RAW_SOURCE must be an I/O handle referring to a source of entropy that can be read one octet at a time. Specifically, it must support either the C or C method described in L. READ_STYLE must be a string, either "getc" or "sysread", indicating which method should be used to read from the raw source. No methods other than the one specified will ever be called on the raw source handle, so a full implementation of C is not required. The C method should be used with B and its ilk, because buffering would be very wasteful of entropy and might consequently block other processes that require entropy. C should be preferred when reading entropy from a regular file, and it is the more convenient interface to implement when a non-I/O object is being used for the handle. =cut sub new { my($class, $rawsrc, $readstyle) = @_; croak "no raw entropy source given" unless defined $rawsrc; croak "read style `$readstyle' not recognised" unless $readstyle =~ /\A(?:getc|sysread)\z/; return bless({ rawsrc => $rawsrc, readstyle => $readstyle, limit => 1, num => 0, }, $class); } =back =head1 METHODS =over =item $source->get_octet Returns an octet of entropy, as a string of length one. This provides direct access to the raw entropy source. =cut sub get_octet { my($self) = @_; if($self->{readstyle} eq "getc") { my $errno = $!; $! = 0; my $octet = $self->{rawsrc}->getc; unless(defined $octet) { my $errmsg = $!; unless($errmsg) { $errmsg = "EOF"; $! = $errno; } croak "entropy source failed: $errmsg"; } $! = $errno; return $octet; } elsif($self->{readstyle} eq "sysread") { my $octet; my $n = $self->{rawsrc}->sysread($octet, 1); croak "entropy source failed: ".(defined($n) ? $! : "EOF") unless $n; return $octet; } } # ->_get_small_int may be used only with a native integer argument, up to 256. sub _get_small_int { my($self, $limit) = @_; use integer; my $reqlimit = $limit << 15; while(1) { while($self->{limit} < $reqlimit) { $self->{num} = ($self->{num} << 8) + ord($self->get_octet); $self->{limit} <<= 8; } my $rep = $self->{limit} / $limit; my $uselimit = $rep * $limit; if($self->{num} < $uselimit) { my $num = $self->{num} / $rep; $self->{num} %= $rep; $self->{limit} = $rep; return $num; } $self->{num} -= $uselimit; $self->{limit} -= $uselimit; } } # ->_put_small_int is used to return the unused portion of some entropy that # was extracted using ->_get_small_int. sub _put_small_int { my($self, $limit, $num) = @_; $self->{limit} *= $limit; $self->{num} = $self->{num} * $limit + $num; } =item $source->get_bits(NBITS) Returns NBITS bits of entropy, as a string of octets. If NBITS is not a multiple of eight then the last octet in the string has its most significant bits set to zero. =cut sub get_bits { my($self, $nbits) = @_; my $nbytes = $nbits >> 3; $nbits &= 7; my $str = ""; $str .= $self->get_octet while $nbytes--; $str .= chr($self->_get_small_int(1 << $nbits)) if $nbits; return $str; } =item $source->get_int(LIMIT) LIMIT must be a positive integer. Returns a uniformly-distributed random number between zero inclusive and LIMIT exclusive. LIMIT may be either a native integer, a C object, or an integer-valued C object; the returned number is of the same type. This method dispenses a non-integer number of bits of entropy. For example, if LIMIT is 10 then the result contains approximately 3.32 bits of entropy. The minimum non-zero amount of entropy that can be obtained is 1 bit, with LIMIT = 2. =cut sub _break_int { my($num) = @_; my $type = ref($num); $num = $num->as_number if $type eq "Math::BigRat"; my @limbs; while($num != 0) { my $l = $num & 255; $l = $l->numify if $type ne ""; push @limbs, $l; $num >>= 8; } return \@limbs; } sub get_int { my($self, $limit) = @_; my $type = ref($limit); my $max = _break_int($limit - 1); my $len = @$max; my @num_limbs; if($len) { TRY_AGAIN: my $i = $len; my $ml = $max->[--$i]; my $nl = $self->_get_small_int($ml + 1); @num_limbs = ($nl); while($i && $nl == $ml) { $ml = $max->[--$i]; $nl = $self->_get_small_int(256); if($nl > $ml) { $self->_put_small_int(255-$ml, $nl-$ml-1); goto TRY_AGAIN; } push @num_limbs, $nl; } push @num_limbs, ord($self->get_octet) while $i--; } my $num = $type eq "" ? 0 : Math::BigInt->new(0); for(my $i = $len; $i--; ) { my $l = $num_limbs[$len-1-$i]; $l = Math::BigInt->new($l) if $type ne ""; $num += $l << ($i << 3); } $num = Math::BigRat->new($num) if $type eq "Math::BigRat"; return $num; } =item $source->get_prob(PROB0, PROB1) PROB0 and PROB1 must be non-negative integers, not both zero. They may each be either a native integer, a C object, or an integer-valued C objects; types may be mixed. Returns either 0 or 1, with relative probabilities PROB0 and PROB1. That is, the probability of returning 0 is PROB0/(PROB0+PROB1), and the probability of returning 1 is PROB1/(PROB0+PROB1). This method dispenses a fraction of a bit of entropy. The maximum amount of entropy that can be obtained is 1 bit, with PROB0 = PROB1. The more different the probabilities are the less entropy is obtained. For example, if PROB0 = 1 and PROB1 = 2 then the result contains approximately 0.918 bits of entropy. =cut sub get_prob { my($self, $prob0, $prob1) = @_; croak "probabilities must be non-negative" unless $prob0 >= 0 && $prob1 >= 0; if($prob0 == 0) { croak "can't have nothing possible" if $prob1 == 0; return 1; } elsif($prob1 == 0) { return 0; } my $max0 = _break_int($prob0 - 1); my $maxt = _break_int($prob0 + $prob1 - 1); my $len = @$maxt; push @$max0, (0) x ($len - @$max0) unless @$max0 == $len; TRY_AGAIN: my $maybe0 = 1; my $maybebad = 1; my($mtl, $m0l, $nl); for(my $i = $len - 1; ; $i--) { $nl = $self->_get_small_int( $i == $len-1 ? $maxt->[-1] + 1 : 256); $m0l = $maybe0 ? $max0->[$i] : -1; $mtl = $maybebad ? $maxt->[$i] : 256; my $lastlimb = $i ? 0 : 1; if($nl < $m0l + $lastlimb) { $self->_put_small_int($m0l + $lastlimb, $nl); return 0; } elsif($nl > $m0l && $nl < $mtl + $lastlimb) { $self->_put_small_int($mtl + $lastlimb - $m0l - 1, $nl - $m0l - 1); return 1; } elsif($nl > $mtl) { $self->_put_small_int(255 - $mtl, $nl - $mtl - 1); goto TRY_AGAIN; } $maybe0 = 0 if $nl > $m0l; $maybebad = 0 if $nl < $mtl; } } =back =head1 SEE ALSO L, L, L, L, L, L =head1 AUTHOR Andrew Main (Zefram) Maintained by Robert Rothenberg =head1 COPYRIGHT Copyright (C) 2006, 2007, 2009, 2011, 2025 Andrew Main (Zefram) =head1 LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Data-Entropy-0.008/MANIFEST.SKIP0000644000175000017500000000012614771320002013551 0ustar rrrrData-Entropy-* Makefile MYMETA pm_to_blib blib/ .git/ _build/ MANIFEST.bak .gitignore Data-Entropy-0.008/Changes0000644000175000017500000000776114771320757013203 0ustar rrrrversion 0.008; 2025-03-27 * Use Crypt::URandom to seed the default algorithm with cryptographically secure random bytes instead of the builtin rand() function [CVE 2025-1860]. * This module has been marked as deprecated. * A security policy was added. * Remove use of Module::Build. * Updated maintainer information. version 0.007; 2011-04-27 * update D::E::RS::RandomOrg to cope with fractional fill percentage currently being returned by the website * in D::E::RS::RandomOrg and D::E::RS::RandomnumbersInfo, use HTTP::Lite instead of heavyweight LWP * use full stricture in test suite * in Build.PL, complete declaration of configure-time requirements * explicitly state version required of Params::Classify * include META.json in distribution * add MYMETA.json and MYMETA.yml to .cvsignore version 0.006; 2009-11-21 * be more stringent in parsing responses from networked entropy sources * in documentation, point more prominently to Data::Entropy::Algorithms * in documentation of Data::Entropy::Algorithms, more discussion of overriding CORE::rand, including how to override it globally * abandon use of the "fields" module * use simpler "parent" pragma in place of "base" * check for required Perl version at runtime * in test suite, properly quote first argument to use_ok (lack of quoting caused false test failures on Perl 5.11.2) * in Build.PL, explicitly declare configure-time requirements * remove bogus "exit 0" from Build.PL version 0.005; 2009-03-03 * bugfix: require bugfixed version of Data::Float (for $SIG{__DIE__} handling) * in D::E::RS::RandomOrg and D::E::RS::RandomnumbersInfo, be more stringent in parsing the returned data, to avoid potentially generating non-byte bytes * test POD syntax and coverage, and rename some internal functions and make a small style change in documentation to satisfy the coverage test * drop prototypes from method subs (where the prototypes have no effect) * in tests, avoid unreliable "\d" and "\w" regexp elements * remove a stray "use Crypt::Rijndael" from one of the test scripts * build with Module::Build instead of ExtUtils::MakeMaker * complete dependency list * express relationship with versions of Math::BigInt and Math::BigRat as conflicts rather than dependencies * include signature in distribution * in documentation, separate "license" section from "copyright" section version 0.004; 2007-09-03 * in D::E::RS::CryptCounter, construct the SEEK_* constants explicitly instead of importing from Fcntl, to avoid requiring a version of Fcntl that is only supplied with perl v5.8 * test explicitly for correct class of results version 0.003; 2007-01-21 * avoid "my __PACKAGE__", for compatibility with perl v5.6 * markup fix in documentation for rand_flt() version 0.002; 2006-08-05 * bugfix: rand_flt() with subnormal limits was horribly inefficient * in rand(), don't attempt to generate a 48-bit fraction on systems where it can't be represented, fall back to the longest possible fraction * in rand_fix(), use low-level floating point code from Data::Float instead of doing it here * expand documentation of rand() version 0.001; 2006-08-03 * new function rand_flt() to generate a random floating point value in a floating point way * bugfix: in BigRat handling, use ->as_number instead of ->as_int for BigRat->BigInt conversion, because ->as_int is faulty before Math::BigRat version 0.14 but ->as_number is available in much earlier versions (the version specified in Makefile.PL was one where ->as_int was faulty) * use standard interval notation in the Data::Entropy::Algorithms documentation * use "=> 0" instead of "=> undef" in unversioned dependencies in Makefile.PL * don't include underscore in string version of module version numbers in Makefile.PL * remove a redundant BigRat->BigInt conversion version 0.000; 2006-07-19 * initial released version Data-Entropy-0.008/README0000644000175000017500000000466114771321051012550 0ustar rrrrNAME Data::Entropy - entropy (randomness) management STATUS This module is deprecated. For most purposes (including cryptography and security), modules like Crypt::URandom, Crypt::SysRandom or Crypt::PRNG are more than adequate. Modern operating systems provide good sources of random bytes, and the above mentioned modules work on many kinds of systems, including Windows. There is no need to choose an entropy source, and some users of this module have omitted that step, and prior to version 0.008 they may have been relying on Perl's builtin "rand" function. Please see CPAN Author's Guide to Random Data for Security . DESCRIPTION This distribution includes modules relating to sources and use of entropy. They all interoperate, but can also be used independently. The Data::Entropy module maintains a concept of a current selection of entropy source. Algorithms that require entropy, such as those in Data::Entropy::Algorithms, can use the source nominated by this module, avoiding the need for entropy source objects to be explicitly passed around. This is convenient because usually one entropy source will be used for an entire program run and so an explicit entropy source parameter would rarely vary. There is also a default entropy source, avoiding the need to explicitly configure a source at all. The Data::Entropy::Source class manages the entropy coming from a particular source. Methods allow entropy to be dispensed in any quantity required, even fractional bits. This class acts as a layer over a raw entropy source, which may be a normal I/O handle or a special-purpose class. The Data::Entropy::RawSource::* classes provide fundamental sources of entropy. The sources specially supported are an OS-supplied entropy collector, downloads from servers on the Internet, and cryptographic fake entropy. The Data::Entropy::Algorithms module contains a collection of fundamental algorithms that use entropy. There are random number generators, and functions to shuffle arrays and perform related tasks. INSTALLATION perl Module.PL make make test make install AUTHOR Andrew Main (Zefram) Maintained by Robert Rothenberg COPYRIGHT Copyright (C) 2006, 2007, 2009, 2011, 2025 Andrew Main (Zefram) LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Data-Entropy-0.008/SECURITY.md0000644000175000017500000000721714771320421013461 0ustar rrrr# Security Policy for the Data-Entropy distribution. Report issues via email at: Robert Rothenberg . This is the Security Policy for Data-Entropy. This text is based on the CPAN Security Group's Guidelines for Adding a Security Policy to Perl Distributions (version 1.0.0) https://security.metacpan.org/docs/guides/security-policy-for-authors.html # How to Report a Security Vulnerability Security vulnerabilities can be reported via the project GitHub repository [Security Advisories](https://github.com/robrwo/Data-Entropy/security/advisories). Please include as many details as possible, including code samples or test cases, so that we can reproduce the issue. Check that your report does not expose any sensitive data, such as passwords, tokens, or personal information. If you would like any help with triaging the issue, or if the issue is being actively exploited, please copy the report to the CPAN Security Group (CPANSec) at . Please *do not* use the public issue reporting system on RT or GitHub issues for reporting security vulnerabilities. Please do not disclose the security vulnerability in public forums until past any proposed date for public disclosure, or it has been made public by the maintainers or CPANSec. That includes patches or pull requests. For more information, see [Report a Security Issue](https://security.metacpan.org/docs/report.html) on the CPANSec website. ## Response to Reports The maintainer(s) aim to acknowledge your security report as soon as possible. However, this project is maintained by a single person in their spare time, and they cannot guarantee a rapid response. If you have not received a response from them within one week, then please send a reminder to them and copy the report to CPANSec at . Please note that the initial response to your report will be an acknowledgement, with a possible query for more information. It will not necessarily include any fixes for the issue. The project maintainer(s) may forward this issue to the security contacts for other projects where we believe it is relevant. This may include embedded libraries, system libraries, prerequisite modules or downstream software that uses this software. They may also forward this issue to CPANSec. # Which Software This Policy Applies To Any security vulnerabilities in Data-Entropy are covered by this policy. Security vulnerabilities are considered anything that allows users to execute unauthorised code, access unauthorised resources, or to have an adverse impact on accessibility or performance of a system. Security vulnerabilities in upstream software (embedded libraries, prerequisite modules or system libraries, or in Perl), are not covered by this policy unless they affect Data-Entropy, or Data-Entropy can be used to exploit vulnerabilities in them. Security vulnerabilities in downstream software (any software that uses Data-Entropy, or plugins to it that are not included with the Data-Entropy distribution) are not covered by this policy. ## Supported Versions of Data-Entropy The maintainer(s) will only commit to releasing security fixes for the latest version of Data-Entropy. # Installation and Usage Issues The distribution metadata specifies minimum versions of prerequisites that are required for Data-Entropy to work. However, some of these prerequisites may have security vulnerabilities, and you should ensure that you are using up-to-date versions of these prerequisites. Where security vulnerabilities are known, the metadata may indicate newer versions as recommended. ## Usage Please see the software documentation for further information. Data-Entropy-0.008/META.yml0000664000175000017500000000174614771321107013146 0ustar rrrr--- abstract: 'entropy (randomness) management' author: - 'Robert Rothenberg ' build_requires: ExtUtils::MakeMaker: '0' Test::More: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.72, CPAN::Meta::Converter version 2.150010' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Data-Entropy no_index: directory: - t - inc requires: Carp: '0' Crypt::Rijndael: '0' Crypt::URandom: '0.36' Data::Float: '0.008' Errno: '1.00' Exporter: '0' HTTP::Lite: '2.2' IO::File: '1.03' Module::Build: '0' Params::Classify: '0' Test::More: '0' constant: '0' integer: '0' parent: '0' strict: '0' warnings: '0' resources: bugtracker: https://github.com/robrwo/Data-Entropy/issues repository: git://github.com/robrwo/Data-Entropy.git version: '0.008' x_deprecated: 1 x_serialization_backend: 'CPAN::Meta::YAML version 0.020' Data-Entropy-0.008/Makefile.PL0000644000175000017500000000232314771320003013627 0ustar rrrr require 5.006; use ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'Data::Entropy', 'AUTHOR' => 'Robert Rothenberg ', 'ABSTRACT_FROM' => 'lib/Data/Entropy.pm', 'VERSION_FROM' => 'lib/Data/Entropy.pm', 'PREREQ_PM' => { 'Carp' => 0, 'Crypt::Rijndael' => 0, 'Crypt::URandom' => '0.36', 'Data::Float' => '0.008', 'Errno' => '1.00', 'Exporter' => 0, 'HTTP::Lite' => '2.2', 'IO::File' => '1.03', 'Module::Build' => 0, 'Params::Classify' => 0, 'Test::More' => 0, 'constant' => 0, 'integer' => 0, 'parent' => 0, 'strict' => 0, 'warnings' => 0 }, TEST_REQUIRES => { 'Test::More' => 0, }, 'INSTALLDIRS' => 'site', 'EXE_FILES' => [], 'PL_FILES' => {}, 'SIGN' => 1, 'META_MERGE' => { x_deprecated => 1, resources => { repository => 'git://github.com/robrwo/Data-Entropy.git', bugtracker => 'https://github.com/robrwo/Data-Entropy/issues', }, } );