From b56d1b131476ad32248bbfd8106669491f631dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charlotte=20=F0=9F=A6=9D=20Delenk?= Date: Fri, 6 Sep 2024 10:20:10 +0200 Subject: [PATCH] add monobit test --- CHANGELOG.md | 5 +- CONTRIBUTING.md | 2 +- Cargo.lock | 200 +++++++++++++++++++++- Cargo.nix | 391 ++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 30 +++- README.md | 80 +++------ SECURITY.md | 22 +-- flake.nix | 6 +- src/lib.rs | 48 ++++-- src/rand_core.rs | 41 +++++ src/tests.rs | 55 ++++++ src/tests/monobit.rs | 52 ++++++ 12 files changed, 831 insertions(+), 101 deletions(-) create mode 100644 src/rand_core.rs create mode 100644 src/tests.rs create mode 100644 src/tests/monobit.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 5046eab..c07ed86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,4 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -[Unreleased]: https://git.chir.rs/ProcyOS/rust-template +### Added +- Added a simple monobit test. + +[Unreleased]: https://git.chir.rs/ProcyOS/rand_testsuite diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4545d55..dc5cad2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to [Project] +# Contributing to `rand_testsuite` Thank you for considering to contribute to our project! diff --git a/Cargo.lock b/Cargo.lock index be35886..7fc2810 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,5 +3,203 @@ version = 3 [[package]] -name = "rust-template" +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_testsuite" version = "0.1.0" +dependencies = [ + "bitvec", + "libm", + "num-traits", + "rand", + "rand_core", +] + +[[package]] +name = "syn" +version = "2.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.nix b/Cargo.nix index b600c1c..6d7ea98 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -3,7 +3,7 @@ args @ { release ? true, rootFeatures ? [ - "rust-template/default" + "rand_testsuite/default" ], rustPackages, buildRustPackages, @@ -22,7 +22,7 @@ args @ { workspaceSrc, ignoreLockHash, }: let - nixifiedLockHash = "4598ab22b158163d169b6aea289131643ca58806898bb56966fba495f4660c02"; + nixifiedLockHash = "0c97699175df8652eb6708b342caa7bcc3794d5a6bd83ecc4362d8cf3b262349"; workspaceSrc = if args.workspaceSrc == null then ./. @@ -59,12 +59,393 @@ in in { cargo2nixVersion = "0.11.0"; workspace = { - rust-template = rustPackages.unknown.rust-template."0.1.0"; + rand_testsuite = rustPackages.unknown.rand_testsuite."0.1.0"; }; - "unknown".rust-template."0.1.0" = overridableMkRustCrate (profileName: rec { - name = "rust-template"; + "registry+https://github.com/rust-lang/crates.io-index".autocfg."1.3.0" = overridableMkRustCrate (profileName: rec { + name = "autocfg"; + version = "1.3.0"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".bitvec."1.0.1" = overridableMkRustCrate (profileName: rec { + name = "bitvec"; + version = "1.0.1"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"; + }; + features = builtins.concatLists [ + ["alloc"] + ["atomic"] + ["default"] + ["std"] + ]; + dependencies = { + funty = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".funty."2.0.0" {inherit profileName;}).out; + radium = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".radium."0.7.0" {inherit profileName;}).out; + tap = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".tap."1.0.1" {inherit profileName;}).out; + wyz = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".wyz."0.5.1" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".byteorder."1.5.0" = overridableMkRustCrate (profileName: rec { + name = "byteorder"; + version = "1.5.0"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".cfg-if."1.0.0" = overridableMkRustCrate (profileName: rec { + name = "cfg-if"; + version = "1.0.0"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".funty."2.0.0" = overridableMkRustCrate (profileName: rec { + name = "funty"; + version = "2.0.0"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".getrandom."0.2.15" = overridableMkRustCrate (profileName: rec { + name = "getrandom"; + version = "0.2.15"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"; + }; + features = builtins.concatLists [ + ["std"] + ]; + dependencies = { + cfg_if = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".cfg-if."1.0.0" {inherit profileName;}).out; + ${ + if hostPlatform.isUnix + then "libc" + else null + } = + (rustPackages."registry+https://github.com/rust-lang/crates.io-index".libc."0.2.158" {inherit profileName;}).out; + ${ + if hostPlatform.parsed.kernel.name == "wasi" + then "wasi" + else null + } = + (rustPackages."registry+https://github.com/rust-lang/crates.io-index".wasi."0.11.0+wasi-snapshot-preview1" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".libc."0.2.158" = overridableMkRustCrate (profileName: rec { + name = "libc"; + version = "0.2.158"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".libm."0.2.8" = overridableMkRustCrate (profileName: rec { + name = "libm"; + version = "0.2.8"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"; + }; + features = builtins.concatLists [ + ["default"] + ]; + }); + + "registry+https://github.com/rust-lang/crates.io-index".num-traits."0.2.19" = overridableMkRustCrate (profileName: rec { + name = "num-traits"; + version = "0.2.19"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"; + }; + features = builtins.concatLists [ + ["libm"] + (lib.optional (rootFeatures' ? "rand_testsuite/full" || rootFeatures' ? "rand_testsuite/std") "std") + ]; + dependencies = { + libm = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".libm."0.2.8" {inherit profileName;}).out; + }; + buildDependencies = { + autocfg = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".autocfg."1.3.0" {profileName = "__noProfile";}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".ppv-lite86."0.2.20" = overridableMkRustCrate (profileName: rec { + name = "ppv-lite86"; + version = "0.2.20"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"; + }; + features = builtins.concatLists [ + ["simd"] + ["std"] + ]; + dependencies = { + zerocopy = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".zerocopy."0.7.35" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".proc-macro2."1.0.86" = overridableMkRustCrate (profileName: rec { + name = "proc-macro2"; + version = "1.0.86"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"; + }; + features = builtins.concatLists [ + ["default"] + ["proc-macro"] + ]; + dependencies = { + unicode_ident = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".unicode-ident."1.0.12" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".quote."1.0.37" = overridableMkRustCrate (profileName: rec { + name = "quote"; + version = "1.0.37"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"; + }; + features = builtins.concatLists [ + ["default"] + ["proc-macro"] + ]; + dependencies = { + proc_macro2 = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".proc-macro2."1.0.86" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".radium."0.7.0" = overridableMkRustCrate (profileName: rec { + name = "radium"; + version = "0.7.0"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".rand."0.8.5" = overridableMkRustCrate (profileName: rec { + name = "rand"; + version = "0.8.5"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"; + }; + features = builtins.concatLists [ + ["alloc"] + ["default"] + ["getrandom"] + ["libc"] + ["rand_chacha"] + ["std"] + ["std_rng"] + ]; + dependencies = { + ${ + if hostPlatform.isUnix + then "libc" + else null + } = + (rustPackages."registry+https://github.com/rust-lang/crates.io-index".libc."0.2.158" {inherit profileName;}).out; + rand_chacha = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".rand_chacha."0.3.1" {inherit profileName;}).out; + rand_core = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".rand_core."0.6.4" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".rand_chacha."0.3.1" = overridableMkRustCrate (profileName: rec { + name = "rand_chacha"; + version = "0.3.1"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"; + }; + features = builtins.concatLists [ + ["std"] + ]; + dependencies = { + ppv_lite86 = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".ppv-lite86."0.2.20" {inherit profileName;}).out; + rand_core = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".rand_core."0.6.4" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".rand_core."0.6.4" = overridableMkRustCrate (profileName: rec { + name = "rand_core"; + version = "0.6.4"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"; + }; + features = builtins.concatLists [ + ["alloc"] + ["getrandom"] + ["std"] + ]; + dependencies = { + getrandom = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".getrandom."0.2.15" {inherit profileName;}).out; + }; + }); + + "unknown".rand_testsuite."0.1.0" = overridableMkRustCrate (profileName: rec { + name = "rand_testsuite"; version = "0.1.0"; registry = "unknown"; src = fetchCrateLocal workspaceSrc; + features = builtins.concatLists [ + (lib.optional (rootFeatures' ? "rand_testsuite/alloc" || rootFeatures' ? "rand_testsuite/full" || rootFeatures' ? "rand_testsuite/rand_core") "alloc") + (lib.optional (rootFeatures' ? "rand_testsuite/full") "full") + (lib.optional (rootFeatures' ? "rand_testsuite/full" || rootFeatures' ? "rand_testsuite/rand_core") "rand_core") + (lib.optional (rootFeatures' ? "rand_testsuite/full" || rootFeatures' ? "rand_testsuite/std") "std") + ]; + dependencies = { + bitvec = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".bitvec."1.0.1" {inherit profileName;}).out; + libm = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".libm."0.2.8" {inherit profileName;}).out; + num_traits = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".num-traits."0.2.19" {inherit profileName;}).out; + ${ + if rootFeatures' ? "rand_testsuite/full" || rootFeatures' ? "rand_testsuite/rand_core" + then "rand_core" + else null + } = + (rustPackages."registry+https://github.com/rust-lang/crates.io-index".rand_core."0.6.4" {inherit profileName;}).out; + }; + devDependencies = { + bitvec = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".bitvec."1.0.1" {inherit profileName;}).out; + rand = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".rand."0.8.5" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".syn."2.0.77" = overridableMkRustCrate (profileName: rec { + name = "syn"; + version = "2.0.77"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"; + }; + features = builtins.concatLists [ + ["clone-impls"] + ["default"] + ["derive"] + ["parsing"] + ["printing"] + ["proc-macro"] + ]; + dependencies = { + proc_macro2 = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".proc-macro2."1.0.86" {inherit profileName;}).out; + quote = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".quote."1.0.37" {inherit profileName;}).out; + unicode_ident = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".unicode-ident."1.0.12" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".tap."1.0.1" = overridableMkRustCrate (profileName: rec { + name = "tap"; + version = "1.0.1"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".unicode-ident."1.0.12" = overridableMkRustCrate (profileName: rec { + name = "unicode-ident"; + version = "1.0.12"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".wasi."0.11.0+wasi-snapshot-preview1" = overridableMkRustCrate (profileName: rec { + name = "wasi"; + version = "0.11.0+wasi-snapshot-preview1"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".wyz."0.5.1" = overridableMkRustCrate (profileName: rec { + name = "wyz"; + version = "0.5.1"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"; + }; + dependencies = { + tap = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".tap."1.0.1" {inherit profileName;}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".zerocopy."0.7.35" = overridableMkRustCrate (profileName: rec { + name = "zerocopy"; + version = "0.7.35"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"; + }; + features = builtins.concatLists [ + ["byteorder"] + ["default"] + ["derive"] + ["simd"] + ["zerocopy-derive"] + ]; + dependencies = { + byteorder = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".byteorder."1.5.0" {inherit profileName;}).out; + zerocopy_derive = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".zerocopy-derive."0.7.35" {profileName = "__noProfile";}).out; + }; + }); + + "registry+https://github.com/rust-lang/crates.io-index".zerocopy-derive."0.7.35" = overridableMkRustCrate (profileName: rec { + name = "zerocopy-derive"; + version = "0.7.35"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { + inherit name version; + sha256 = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"; + }; + dependencies = { + proc_macro2 = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".proc-macro2."1.0.86" {inherit profileName;}).out; + quote = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".quote."1.0.37" {inherit profileName;}).out; + syn = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".syn."2.0.77" {inherit profileName;}).out; + }; }); } diff --git a/Cargo.toml b/Cargo.toml index f0a7390..3795b40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,27 @@ [package] -name = "rust-template" +name = "rand_testsuite" version = "0.1.0" edition = "2021" authors = ["Charlotte 🦝 Delenk "] -description = "Template for rust libraries" +description = "A statistical randomness tester for testsuites" license = "MIT OR Apache-2.0" -repository = "https://git.chir.rs/ProcyOS/rust-template" -keywords = ["template"] -categories = ["template"] +repository = "https://git.chir.rs/ProcyOS/rand_testsuite" +keywords = ["testing", "rand"] +categories = ["development-tools::testing", "no-std", "no-std::no-alloc"] [dependencies] +bitvec = { version = "1.0.1", default-features = false } +libm = "0.2.8" +num-traits = { version = "0.2.19", default-features = false, features = [ + "libm", +] } +rand_core = { version = "0.6.4", optional = true } + +[features] +rand_core = ["dep:rand_core", "alloc"] +alloc = ["bitvec/alloc"] +std = ["num-traits/std"] +full = ["rand_core", "std"] [lints.rust] deprecated-safe = "forbid" @@ -33,8 +45,7 @@ trivial-numeric-casts = "warn" unit-bindings = "deny" unnameable-types = "warn" unreachable-pub = "warn" -unsafe-code = "deny" -unsafe-op-in-unsafe-fn = "warn" +unsafe-code = "forbid" unused-crate-dependencies = "warn" unused-extern-crates = "warn" unused-import-braces = "warn" @@ -62,5 +73,8 @@ rc-buffer = "warn" rc-mutex = "deny" std-instead-of-alloc = "warn" std-instead-of-core = "warn" -undocumented-unsafe-blocks = "deny" unwrap-used = "forbid" + +[dev-dependencies] +bitvec = "1.0.1" +rand = "0.8.5" diff --git a/README.md b/README.md index af24f77..6b7a738 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,45 @@ -# Project Title +# rand_testsuite -One Paragraph of the project description +A Testsuite for random number generators. It implements NIST 800-22. -Initially appeared on -[gist](https://gist.github.com/PurpleBooth/109311bb0361f32d87a2). But the page cannot open anymore so that is why I have moved it here. +It is intended to be more as a smoketest to ensure that random number generation isn’t completely broken. + +## Crate Features + +rand_testsuite defines the following features: + +- `std`: Uses the `std` library’s maths routines instead of a freestanding pure-rust implementation. +- `rand_core`: Allows you to directly test `RngCore` trait implementations. Enables allocations. ## Getting Started -These instructions will give you a copy of the project up and running on -your local machine for development and testing purposes. See deployment -for notes on deploying the project on a live system. +This is how you may use this crate to evaluate a random number generator (requires `rand_core`!) -### Prerequisites - -Requirements for the software and other tools to build, test and push -- [Example 1](https://www.example.com) -- [Example 2](https://www.example.com) +```rust,ignore +let mut rng = rand::thread_rng(); +assert!(CombinedRandomTest::default().evaluate_rng(&mut rng).unwrap_or_default() > 0.01); +``` ### Installing -A step by step series of examples that tell you how to get a development -environment running +You can add this library to your crate with the following command: -Say what the step will be +```sh,ignore +cargo add rand_testsuite --dev +``` - Give the example - -And repeat - - until finished - -End with an example of getting some data out of the system or using it -for a little demo +This makes the dependency available in testsuites. ## Running the tests -Explain how to run the automated tests for this system - -### Sample Tests - -Explain what these tests test and why - - Give an example - -### Style test - -Checks if the best practices and the right coding style has been used. - - Give an example - -## Deployment - -Add additional notes to deploy this on a live system +```sh,ignore +cargo test +nix flake check . +``` ## Built With - - [Contributor Covenant](https://www.contributor-covenant.org/) - Used - for the Code of Conduct - - [Creative Commons](https://creativecommons.org/) - Used to choose - the license + - [Contributor Covenant](https://www.contributor-covenant.org/) - Used for the Code of Conduct ## Contributing @@ -73,11 +54,10 @@ repository](https://github.com/PurpleBooth/a-good-readme-template/tags). ## Authors - - **Billie Thompson** - *Provided README Template* - - [PurpleBooth](https://github.com/PurpleBooth) +- **Charlotte 🦝 Delenk** [DarkKirb](https://lotte.chir.rs) See also the list of -[contributors](https://github.com/PurpleBooth/a-good-readme-template/contributors) +[contributors](https://git.chir.rs/ProcyOS/rand_testsuite/activity/contributors) who participated in this project. ## License @@ -90,9 +70,3 @@ Licensed under either of [LICENSE-MIT](LICENSE-MIT) at your option. - -## Acknowledgments - - - Hat tip to anyone whose code is used - - Inspiration - - etc diff --git a/SECURITY.md b/SECURITY.md index 189261f..7fc0446 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,23 +1,5 @@ # Reporting a Vulnerability -To report a security issue, please contact me via E-Mail (security@chir.rs) or Matrix (@lotte:chir.rs) with either a standard bug report, or by pointing at the vulnerable code. +This is a development tool for regression-testing other code. As such this crate is not part of our security policy. -A proof of concept is appreciated, but not required. Please be available for further questions. - -This project follows a 90 day disclosure policy. You can publically disclose the issue after 90 days, or when we disclose it ourselves. - -## Security Hall of Fame - -1. and you? - -## Threat Model - -[Insert as appropriate] - -## Scope - -We do not consider tests to be in scope for security vulnerabilities. If you think a test is missing, feel free to [contribute](./CONTRIBUTING.md) it. - -## Supported Versions - -We support the latest released version, as well as the most recent development versions. If the vulnerability only affects an older version with still sees some use (for example the previous major version), we may consider supporting it on a “best effort” basis. \ No newline at end of file +If you believe you have found a security vulnerability, just report it as an issue to the repository directly. \ No newline at end of file diff --git a/flake.nix b/flake.nix index 7d3c0b2..51aee8d 100644 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,5 @@ { - description = "rust-template"; + description = "rand-testsuite"; inputs = { nixpkgs.url = github:NixOS/nixpkgs; @@ -41,6 +41,10 @@ rustChannel = "nightly"; rustVersion = "latest"; packageOverrides = pkgs: pkgs.rustBuilder.overrides.all; + rootFeatures = [ + "rand_testsuite/default" + "rand_testsuite/full" + ]; }; in rec { devShells.default = with pkgs; diff --git a/src/lib.rs b/src/lib.rs index b93cf3f..454c940 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,40 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} +#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))] +#![no_std] -#[cfg(test)] -mod tests { - use super::*; +use bitvec::{order::BitOrder, slice::BitSlice, store::BitStore}; - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } +#[cfg(feature = "rand_core")] +mod rand_core; + +pub mod tests; + +#[cfg(feature = "rand_core")] +pub use rand_core::RandomTestExt; + +/// A single statistical random test. +pub trait RandomTest { + /// The amount of bits that are recommended to be used with this test. + /// + /// If you pass fewer bits, the estimations may be wildly inaccurate and may cause your tests + /// with actual random data to fail. + const RECOMMENDED_BIT_SIZE: usize; + + /// The absolute minimum amount of bits that you need to pass to the evaluator. + /// + /// If you pass fewer bits, [`evaluate()`](RandomTest::evaluate) should return `None`. + const MINIMUM_BIT_SIZE: usize; + + /// Evaluates provided random data. + /// + /// # Return Value + /// + /// This function returns a p-value, with lower values indicating a higher chance of it being predictable. + /// + /// The recommended cutoff for randomness is the value `0.01`. + /// + /// This function returns `None` if the provided amount of bits is insufficient to make any predictions. + /// + /// # Implementation Requirements + /// Implementors need to work with bit slices of any size. Should the provided + fn evaluate(&self, bs: &BitSlice) -> Option; } diff --git a/src/rand_core.rs b/src/rand_core.rs new file mode 100644 index 0000000..0d0a927 --- /dev/null +++ b/src/rand_core.rs @@ -0,0 +1,41 @@ +//! Special `rand_core` types and definitions. + +extern crate alloc; + +use alloc::vec; +use bitvec::{order::Lsb0, vec::BitVec}; +use rand_core::RngCore; + +use crate::RandomTest; + +/// Extension trait for random tests. +/// +/// This allows you to run tests directly against [`RngCore`](RngCore) types. +pub trait RandomTestExt: RandomTest { + /// Evaluates the provided Random Number Generator. + /// + /// # Return Value + /// + /// This function returns a p-value, with lower values indicating a higher chance of it being predictable. + /// + /// The recommended cutoff for randomness is the value `0.01`. + /// + /// # Errors + /// This function returns an error if the random number generator fails to generate enough random bytes. + /// + /// See [`try_fill_bytes`](RngCore::try_fill_bytes). + fn evaluate_rng(&self, rng: &mut R) -> Result { + let byte_size = Self::RECOMMENDED_BIT_SIZE.div_ceil(8); + let mut rand_buf = vec![0u8; byte_size]; + rng.try_fill_bytes(&mut rand_buf)?; + + let bitvec_buf: BitVec<_, Lsb0> = BitVec::from_vec(rand_buf); + + match self.evaluate(bitvec_buf.as_bitslice()) { + Some(p) => Ok(p), + None => unreachable!(), + } + } +} + +impl RandomTestExt for T {} diff --git a/src/tests.rs b/src/tests.rs new file mode 100644 index 0000000..e3c898f --- /dev/null +++ b/src/tests.rs @@ -0,0 +1,55 @@ +//! All supported tests are available in this module. + +mod monobit; + +use bitvec::prelude::{BitOrder, BitSlice, BitStore}; +pub use monobit::*; + +use crate::RandomTest; + +/// This combines all supported tests into one +/// +/// Specifically it returns the lowest metric and stops if it goes below the p-value threshold. +#[derive(Copy, Clone, Debug)] +pub struct CombinedRandomTest(f64); + +impl CombinedRandomTest { + /// Creates a new combined random test + pub fn new(p_threshold: f64) -> Self { + Self(p_threshold) + } +} + +impl RandomTest for CombinedRandomTest { + const RECOMMENDED_BIT_SIZE: usize = Monobit::RECOMMENDED_BIT_SIZE; + + const MINIMUM_BIT_SIZE: usize = Monobit::MINIMUM_BIT_SIZE; + + fn evaluate(&self, bs: &BitSlice) -> Option { + Monobit.evaluate(bs) + } +} + +impl Default for CombinedRandomTest { + fn default() -> Self { + Self(0.01) + } +} + +#[cfg(test)] +mod tests { + #[cfg(feature = "rand_core")] + #[test] + fn combined_test() { + use crate::RandomTestExt; + + use super::CombinedRandomTest; + let mut rng = rand::thread_rng(); + assert!( + CombinedRandomTest::default() + .evaluate_rng(&mut rng) + .unwrap_or_default() + > 0.01 + ); + } +} diff --git a/src/tests/monobit.rs b/src/tests/monobit.rs new file mode 100644 index 0000000..3fab334 --- /dev/null +++ b/src/tests/monobit.rs @@ -0,0 +1,52 @@ +//! Monobit test + +use core::f64::consts::FRAC_1_SQRT_2; + +use bitvec::prelude::{BitOrder, BitSlice, BitStore}; +use libm::erfc; +#[allow(unused_imports, reason = "redundant in std use cases")] +use num_traits::Float; + +use crate::RandomTest; + +/// The Monobit test counts the amount of 0s and 1s in a bit sequence and checks if they are present in roughly equal amounts. +/// +/// This test is defined in the [NIST Special Publication 800-22](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-22r1a.pdf). +#[derive(Copy, Clone, Debug)] +pub struct Monobit; + +impl RandomTest for Monobit { + const RECOMMENDED_BIT_SIZE: usize = 100; + + const MINIMUM_BIT_SIZE: usize = 0; + + fn evaluate(&self, bs: &BitSlice) -> Option { + let bit_sum: isize = bs.into_iter().map(|v| if *v { 1 } else { -1 }).sum(); + let statistic = (bit_sum.abs() as f64) / (bs.len() as f64).sqrt(); + + Some(erfc(statistic * FRAC_1_SQRT_2)) + } +} + +#[cfg(test)] +mod tests { + use bitvec::prelude::*; + + use crate::RandomTest; + + use super::Monobit; + + #[test] + fn monobit_test_vector() { + let epsilon = bitvec![ + 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, + 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0 + ]; + let res = Monobit.evaluate(epsilon.as_bitslice()); + assert!(res.is_some()); + let res = res.unwrap(); + assert!(res > 0.01, "Data should be evaluated as random"); + } +}