fortuna/README.md
2022-09-07 10:10:10 +02:00

5.6 KiB

fortuna

pre-commit Build Status

this repo contains the sawce of the Fortuna CSPRNG implementation in C++.

multi-threaded.
adherent to C++20 (best effort).
handles OS signals (SIGINT, SIGTERM, SIGUSR1, SIGUSR2).

the following asciicast shows fortuna provide a 100MiB of pseudo-random data along with useful debug insights on data retrieval times, the reseed_ctr, bytes remaining, and Pool 0 (p0) size: asciicast

validation

to ensure a fundamental soundness of the implementation, fortuna output has been statistically analysed using:

  • dieharder - A Random Number Test Suite (v3.31.1) - on a ~243GiB stream of random material that the program kept producing until dieharder finished testing (log)
    command used:

    ➜ fortuna | dieharder -a -g 200 -k 2 -Y 1
    

    parameter explanation:

    • -a: runs all available tests (including some from NIST's STS)
    • -g 200: a special mode to read raw data from standard input (where fortuna outputs its stream)
    • -k 2: speed and precision of sample reading, set to slow and precise:

      2 is slower still, but (we hope) accurate to machine precision for any number of psamples up to some as yet unknown numerical upper limit (it has been tested out to at least hundreds of thousands).

    • -Y 1: Xtrategy flag for the "test to failure" mode - set to "resolve ambiguity" (RA)

    dieharder warning:

    NOTE WELL: The assessment(s) for the rngs may, in fact, be completely incorrect or misleading. There are still "bad tests" in dieharder, although we are working to fix and improve them (and try to document them in the test descriptions visible with -g testnumber -h). In particular, 'Weak' pvalues should occur one test in two hundred, and 'Failed' pvalues should occur one test in a million with the default thresholds - that's what p MEANS. Use them at your Own Risk! Be Warned!

    that is, it appears fortuna can withstand this "dieharder battery of tests".

  • ent - A Pseudorandom Number Sequence Test Program - on a sample of 1000MiB of random data ent run

disclaimer

note that this project is a direct continuation of the semestral work originally created for my Applied Cryptography university course, which has since been archived as the course had concluded.

⚠ polite warning: this code is not production-ready and has not been professionally and thoroughly vetted.

be advised that while I do believe the implementation to be correct and valid, I would still recommend AGAINST USING this program to get entropy for any serious purpose, since the code has not undergone proper peer review.

please, be kind. this is my first larger-than-main.cpp C++ effort.

build 🔨

build-time dependencies

  • c++ compiler (note: only tested on fedora 35,36 and archlinux with g++ and clang++ (versions ~12.2.1 and ~14.0.5, respectively)
  • ninja
  • CMake
  • make
  • libc++ (only tested with libcxx)
  • libc
  • libm
  • cryptopp
  • lib{a,l,t,ub}san on fedora, gcc-libs on archlinux
  • {fmt} - this one's also present as a submodule at lib/fmt and automatically used if fmtlib is not already present on the system.
  • ldd - optional
  • git
  • implicitly pkg-conf to look for all the libraries

runtime dependencies

  • libc++
  • libm
  • cryptopp

make targets

there are multiple targets available in the Makefile that allow for a relatively straightforward (definitely room for improvement) development experience without the need to type g++ or (CMake, for that matter) incantations directly:

  • make clean - cleans up build objects, ninja and CMake-generated files
  • make build - a synonym for CMake's debug build (also make debug)
  • make release - builds a release-optimised binary
  • make san - builds a binary with sanitizers
  • make tidy - builds a binary with clang tidy checks
  • make check - checks code using cppcheck and runs make tidy
  • make test - doesn't run actual tests (🙈), instead checks code with make check and then builds a debug binary
  • make distclean - scrapes CMake build files from build directories

the debug/release/san targets each have a clang++ variant available, suffixed _cl, such that, e.g. make debug_cl would build a debug binary with clang++.

code formatting

see .clang-format

➜ clang-format *.cpp *.h

LICENSE

GPL-3.0-or-later (see LICENSE for details).