{"id":24480898,"url":"https://github.com/randogoth/onod3000","last_synced_at":"2025-09-10T13:35:51.706Z","repository":{"id":273112734,"uuid":"918379437","full_name":"randogoth/onod3000","owner":"randogoth","description":"Rust port of Paul Uszak's randomness testing suite ent3000","archived":false,"fork":false,"pushed_at":"2025-08-27T18:40:40.000Z","size":561,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-28T03:29:31.980Z","etag":null,"topics":["ent","ent3000","entropy","nist","prng","qrng","randomness","randomness-testing","trng"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/randogoth.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-17T20:09:11.000Z","updated_at":"2025-08-27T18:40:44.000Z","dependencies_parsed_at":"2025-01-18T19:28:06.510Z","dependency_job_id":"9164a74d-ca00-4dcc-befe-d5d17c6fa9ea","html_url":"https://github.com/randogoth/onod3000","commit_stats":null,"previous_names":["randogoth/onod3000"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/randogoth/onod3000","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randogoth%2Fonod3000","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randogoth%2Fonod3000/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randogoth%2Fonod3000/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randogoth%2Fonod3000/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/randogoth","download_url":"https://codeload.github.com/randogoth/onod3000/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randogoth%2Fonod3000/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274470655,"owners_count":25291610,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-10T02:00:12.551Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ent","ent3000","entropy","nist","prng","qrng","randomness","randomness-testing","trng"],"created_at":"2025-01-21T11:17:41.355Z","updated_at":"2025-09-10T13:35:51.668Z","avatar_url":"https://github.com/randogoth.png","language":"Rust","readme":"```\n                                ____                        \n                           |\\   ` //  /\\\\   /\\\\   /\\\\       \n                            \\\\   //  || || || || || ||      \n         /'\\\\ \\\\/\\\\  /'\\\\  / \\\\  \\\\  || || || || || ||      \n        || || || || || || || ||   )) || || || || || ||      \n        || || || || || || || ||  //  || || || || || ||      \n        \\\\,/  \\\\ \\\\ \\\\,/   \\\\/  /'    \\\\/   \\\\/   \\\\/       \n                                                             \n\n    Rust port of Paul Uszak's new randomness testing suite for TRNG Makers \n    generating in the sub 1 MB space. Successor to John Walker’s venerable `ent`.\n\n    Pipe binary entropy data into the `onod3000` command line tool or call it\n    with `-f \u003cfilename\u003e` to load entropy from a file.\n\n```\n\n`Onod3000` provides multiple randomness tests, each outputting a statistic, a z-score andd a p-value to assess the conformity of the data to random behavior.\n\n## Testing Methodology\n\n- **Null Hypothesis**: The data conforms to random behavior.\n- **P-Value Interpretation**: Low p-values (\u003c 0.01) indicate a significant deviation from randomness.\n\nAll tests have been carefully ported from [Paul Uszak's Java code](http://www.reallyreallyrandom.com/gitbucketlabhub/) (ent3000-0.6.0-beta). Java libraries were substituted with Rust crate equivalents when possible. The suite includes the following tests:\n\n- **Monobit Test**: Evaluates the balance of 0s and 1s.\n- **Chi-Square Tests**: Tests the uniformity of bits and bytes.\n- **MeanByte Test**: Checks if the mean byte value aligns with expected randomness.\n- **Kolmogorov-Smirnov (KS) Test**: Assesses uniformity of data distribution.\n- **Pi Test**: Uses Monte Carlo methods to approximate π.\n- **Shells Test**: Analyzes distances in 3D space.\n- **Gaps Test**: Measures gaps between occurrences of a specific value.\n- **Avalanche Test**: Analyzes bit-level changes in data chunks.\n- **Runs and RunUps Tests**: Checks for sequential patterns in data.\n- **Prediction Test**: Assesses the predictability of next bits.\n- **UnCorrelation Test**: Evaluates correlation between shifted data.\n\nMore details on some individual tests [available here](http://www.reallyreallyrandom.com/ent3000/the-tests/index.html)\n\n### Sample Output\n```bash\ncat /dev/random | head -c 259200 | onod3000\n\nTesting 259200 bytes from stdin.\n--------------------------------------------------------\nRandomness Test           Value   Z-Score   P-Value Pass\n--------------------------------------------------------\nShannon                   7.999   -0.3669   0.7137   ✅\nMonobit                   0.500    0.9000   0.3681   ✅\nChiBit                    4.555   -0.8612   0.8039   ✅\nChiByte                 236.288   -0.8286   0.7939   ✅\nMeanByte                127.312   -1.2970   0.1946   ✅\nCompression               1.000    0.0868   0.9308   ✅\nKolm.-Smirnov             0.004    2.0722   0.0272   ✅\nPi                        3.139   -1.3171   0.1878   ✅\nShells                   33.593   -0.0493   0.4874   ✅\nGaps                      7.402   -0.3767   0.5954   ✅\nAvalanche                80.006    0.0009   0.9993   ✅\nRuns                 129288.000    0.8208   0.4118   ✅\nRunUps                    2.647    1.1645   0.1038   ✅\nPrediction                0.500   -0.0255   0.9796   ✅\nUnCorrelation            -0.001   -0.3725   0.7096   ✅\n--------------------------------------------------------\n15/15 tests passed.\n--------------------------------------------------------\n```\n\n## Rust Library\n\n```rust\nuse onod3000::Onod;\n\nfn main() {\n    let data = vec![...]; // Your binary data\n    let p_value = Onod::monobit(\u0026data);\n    println!(\"Monobit Test P-Value: {:.4}\", p_value);\n}\n```\n\n## Bindings\n\nThe library ships with FFI and optional Python bindings so it can be used as C or Python library.\n\n### Python\nInstall using `maturin`:\n```bash\nmaturin build --release --features python\n```\n\n## Comparison\n\nTo test the implementation three files of binary random data have been analyzed using the original Java program (version 0.6.0-beta) and this Rust port, expecting the same p-values. The test files can be found in the test folder.\n\n### Testing 1024 bytes from test1.bin (/dev/random)\n\nTest          | Java ent3000 | Rust onod3000 | Note          |\n------------- | ------------ | ------------- | ------------- |\nShannon       | N/A          | 0.0000        |               |\nMonobit       | 0.6746       | 0.6746        |               |\nChiBit        | 0.9299       | 0.9299        |               |\nChiByte       | 0.9819       | 0.9819        |               |\nMeanByte      | 0.7964       | 0.7964        |               |\nCompression   | N/A          | 0.0146        |               |\nKS            | 0.5313       | 0.2476        | Mismatch      |\nPi            | 0.3784       | 0.3784        |               |\nShells        | 0.7559       | 0.7559        |               |\nGaps          | 0.0000       | 0.0000        |               |\nAvalanche     | 0.8794       | 0.8794        |               |\nRuns          | 0.0850       | 0.0850        |               |\nRunUps        | 0.6537       | 0.6537        |               |\nPrediction    | 0.6164       | 0.6164        |               |\nUnCorrelation | 0.0921       | 0.0918        | Close enough  |\n\nFeel free to provide more results, and I'll continue updating the table!\n\n### Testing 259,200 bytes from test2.bin (/dev/random)\n\nTest          | Java ent3000 | Rust onod3000 | Note          |\n------------- | ------------ | ------------- | ------------- |\nShannon       | N/A          | 0.6853        |               |\nMonobit       | 0.2103       | 0.2103        |               |\nChiBit        | 0.5590       | 0.5590        |               |\nChiByte       | 0.3748       | 0.3748        |               |\nMeanByte      | 0.0183       | 0.0183        |               |\nCompression   | N/A          | 0.9308        |               |\nKS            | 0.2900       | 0.0178        | Mismatch      |\nPi            | 0.9765       | 0.9765        |               |\nShells        | 0.7235       | 0.7235        |               |\nGaps          | 0.6425       | 0.6425        |               |\nAvalanche     | 0.9995       | 0.9995        |               |\nRuns          | 0.3310       | 0.3310        |               |\nRunUps        | 0.9393       | 0.9393        |               |\nPrediction    | 0.1519       | 0.1519        |               |\nUnCorrelation | 0.4497       | 0.4497        |               |\n\n### Testing 259,200 bytes from test3.bin (Hardware QRNG)\n\nTest          | Java ent3000 | Rust onod3000 | Note |\n------------- | ------------ | ------------- | ---- |\nShannon       | N/A          | 0.6978        |      |\nMonobit       | 0.4926       | 0.4926        |      |\nChiBit        | 0.8428       | 0.8428        |      |\nChiByte       | 0.5785       | 0.5785        |      |\nMeanByte      | 0.9601       | 0.9601        |      |\nCompression   | N/A          | 0.9308        |      |\nKS            | 0.7395       | 0.0441        | Mismatch |\nPi            | 0.2806       | 0.2806        |      |\nShells        | 0.7711       | 0.7711        |      |\nGaps          | 0.1937       | 0.1937        |      |\nAvalanche     | 0.9932       | 0.9932        |      |\nRuns          | 0.2500       | 0.2500        |      |\nRunUps        | 0.9710       | 0.9710        |      |\nPrediction    | 0.7173       | 0.7173        |      |\nUnCorrelation | 0.4674       | 0.4674        |      |\n\n### Conclusions\n\nAlthough the implementation of the randomness tests closely follows the original Java logic, differences in the results arise in the Kolmogorov-Smirnov test. The external libraries used for running the test probably differ in their implementation. Also the uniform distribution to test against is provided by the Apache Commons Math library. Since it would be way beyond the scope of this porting project to try to fully match the functionality of the dependencies used we just accept the minor difference. Another issue might be that Java emphasizes predictability and portability, enforcing strict IEEE 754 behavior across platforms. Rust on the other hand prioritizes performance and flexibility, allowing platform-specific optimizations that may deviate slightly from strict IEEE semantics.\n\nThese differences are generally negligible for practical purposes and do not affect the overall functionality or \nstatistical significance of the test.\n\n### Bonus\n\nWe implemented a Well Equidistributed Long-period Linear pseudo-random number generator that is used with a random seed derived from an epoch timestamp that is being used as uniform distribution for the KS test.\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n### License of Original Java Implementation\n\n```\nCopyright (c) 2023 Paul Uszak.    \n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n\n## Credits\n\nThis work was made possible with the invaluable assistance of OpenAI's ChatGPT, which provided guidance, debugging help, and inspiration throughout the development process.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandogoth%2Fonod3000","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frandogoth%2Fonod3000","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandogoth%2Fonod3000/lists"}