a C++ take on Fortuna CSPRNG implementation, as devised by Niels Fergusson and Bruce Schneier in Practical Cryptography 🍀
Go to file
surtur d257b4b113
add README.md [skip ci]
2022-09-07 10:10:10 +02:00
lib fmtlib: bump submodule to version 9.1.0 2022-09-06 20:45:22 +02:00
.clang-format clang-format: BinPack{Arguments,Parameters}: false 2022-01-13 06:04:18 +01:00
.clang-tidy chore(clang-tidy): unify flags 2021-12-10 18:57:25 +01:00
.drone.starlark ci: pull dep images in separate steps 2022-03-22 17:49:56 +01:00
.editorconfig add .editorconfig [skip ci] 2022-01-10 08:55:07 +01:00
.gitattributes add .gitattributes file 2021-10-24 21:34:16 +02:00
.gitignore add proper SeedFileManager implementation 2022-01-09 11:58:38 +01:00
.gitmodules feat: use fmt instead of iostreams 2021-11-18 22:05:05 +01:00
.pre-commit-config.yaml chore(.pre-commit-config.yaml): bump hook versions 2022-01-21 05:44:28 +01:00
CMakeLists.txt cmake: add more diagnostic warning flags 2022-02-03 01:43:21 +01:00
LICENSE chore: copyright current year 2022-03-22 17:53:16 +01:00
Makefile makefile: build in tmp when not in CI 2022-01-21 19:14:55 +01:00
README.md add README.md [skip ci] 2022-09-07 10:10:10 +02:00
accumulator.cpp chore: print info msgs to stderr 2022-02-03 00:37:20 +01:00
accumulator.h chore: print info msgs to stderr 2022-02-03 00:37:20 +01:00
do_task.cpp DoTask: timed_mutex -> recursive_timed_mutex 2022-01-21 02:54:15 +01:00
do_task.h DoTask: timed_mutex -> recursive_timed_mutex 2022-01-21 02:54:15 +01:00
entropy_src.h fix: -Wnon-virtual-dtor 2022-02-03 01:11:39 +01:00
event_adder.h fix: -Wnon-virtual-dtor 2022-02-03 01:11:39 +01:00
event_adder_impl.h chore: print info msgs to stderr 2022-02-03 00:37:20 +01:00
fortuna.cpp fortuna: rethrow on error in ctor 2022-02-08 00:40:11 +01:00
fortuna.h fortuna: add moar_random_data() fun 2022-02-03 02:10:06 +01:00
generator.cpp fortuna,generator({fmt}) print with colours 2022-02-03 04:52:19 +01:00
generator.h chore(generator): rm comment [skip ci] 2022-02-03 02:06:19 +01:00
main.cpp main: use moar_random_data() 2022-02-03 03:15:53 +01:00
meson.build meson: add '-DNDEBUG' on release builds 2022-03-03 17:33:14 +01:00
pool.cpp pool: rm event_str remnants 2022-02-07 23:44:17 +01:00
pool.h fix: -Wextra-semi 2022-02-03 00:49:40 +01:00
seed_file_management.cpp fix(SeedFileManager): 6-byte seed file issue 2022-02-07 23:00:01 +01:00
seed_file_management.h sfm: new seed_f_path "/var/tmp/.fortuna.seed" 2022-02-07 23:16:03 +01:00
urandom_entropy_src.cpp fix(-Wuseless-cast) rm a cast in UrandomEntropySrc 2022-02-03 01:26:06 +01:00
urandom_entropy_src.h fix(-Wsuggest-override): override virtual base fun 2022-02-03 01:17:47 +01:00
util.h Util: add de_hex() fun 2022-01-30 21:56:20 +01:00

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).