Compare commits

...
This repository has been archived on 2022-02-10. You can view files and clone it, but cannot push or open issues or pull requests.

7 Commits

Author SHA1 Message Date
surtur d257b4b113
add README.md [skip ci] 2022-09-07 10:10:10 +02:00
surtur 055fba29fe
fmtlib: bump submodule to version 9.1.0
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-06 20:45:22 +02:00
surtur 5e2e6c264d
fmtlib: bump submodule to version 9.0.0
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-09 15:43:28 +02:00
surtur 1cb4c841c5
chore: copyright current year
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-22 17:53:16 +01:00
surtur 7551c1e9b2
ci: pull dep images in separate steps
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-22 17:49:56 +01:00
surtur 3702bf1524
ci: update submodules using alpine/git image
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-22 17:41:26 +01:00
surtur 987bfe673e
meson: add '-DNDEBUG' on release builds
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-03 17:33:14 +01:00
5 changed files with 154 additions and 15 deletions

View File

@ -7,22 +7,39 @@ def main(ctx):
"steps": [ "steps": [
{ {
"name": "update submodules", "name": "update submodules",
"image": "alpine/git",
"pull": "always",
"depends_on": ["clone"],
"commands": [
"git --version",
"git submodule update --init --recursive"
]
},
{
"name": "pull archlinux",
"image": "docker.io/archlinux:base-devel",
"pull": "always",
"depends_on": ["clone"],
"commands": [
"uname -r",
]
},
{
"name": "pull fedora-cpp",
"image": "docker.io/immawanderer/fedora-cpp:linux-amd64", "image": "docker.io/immawanderer/fedora-cpp:linux-amd64",
"pull": "always", "pull": "always",
"depends_on": ["clone"], "depends_on": ["clone"],
"commands": [ "commands": [
"uname -r", "uname -r",
"git submodule update --init --recursive"
] ]
}, },
{ {
"name": "cppcheck", "name": "cppcheck",
"image": "docker.io/archlinux:base-devel", "image": "docker.io/archlinux:base-devel",
"pull": "always", "pull": "if-not-exists",
"depends_on": ["update submodules"], "depends_on": ["update submodules", "pull archlinux"],
"commands": [ "commands": [
"pacman -Sy cppcheck --noconfirm --needed", "pacman -Sy cppcheck --noconfirm --needed",
"uname -r",
"cppcheck --version", "cppcheck --version",
"cppcheck --language=c++ --std=c++20 --enable=all --verbose ./*.{cpp,h}" "cppcheck --language=c++ --std=c++20 --enable=all --verbose ./*.{cpp,h}"
] ]
@ -30,30 +47,27 @@ def main(ctx):
{ {
"name": "make debug", "name": "make debug",
"image": "docker.io/immawanderer/fedora-cpp:linux-amd64", "image": "docker.io/immawanderer/fedora-cpp:linux-amd64",
"pull": "always", "pull": "if-not-exists",
"depends_on": ["cppcheck"], "depends_on": ["cppcheck", "pull fedora-cpp"],
"commands": [ "commands": [
"uname -r",
"make debug" "make debug"
] ]
}, },
{ {
"name": "make release", "name": "make release",
"image": "docker.io/immawanderer/fedora-cpp:linux-amd64", "image": "docker.io/immawanderer/fedora-cpp:linux-amd64",
"pull": "always", "pull": "if-not-exists",
"depends_on": ["cppcheck"], "depends_on": ["cppcheck", "pull fedora-cpp"],
"commands": [ "commands": [
"uname -r",
"make release" "make release"
] ]
}, },
{ {
"name": "make san", "name": "make san",
"image": "docker.io/immawanderer/fedora-cpp:linux-amd64", "image": "docker.io/immawanderer/fedora-cpp:linux-amd64",
"pull": "always", "pull": "if-not-exists",
"depends_on": ["cppcheck"], "depends_on": ["cppcheck", "pull fedora-cpp"],
"commands": [ "commands": [
"uname -r",
"make san" "make san"
] ]
} }

View File

@ -2,7 +2,7 @@ GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright © 2021 Adam Mirre <a_mirre@utb.cz> Copyright © 2021-2022 Adam Mirre <a_mirre@utb.cz>
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.

121
README.md Normal file
View File

@ -0,0 +1,121 @@
# [`fortuna`](https://git.dotya.ml/wanderer/fortuna)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
[![Build Status](https://drone.dotya.ml/api/badges/wanderer/fortuna/status.svg?ref=refs/heads/development)](https://drone.dotya.ml/wanderer/fortuna)
this repo contains the *sawce* of the Fortuna CSPRNG implementation in C++.
multi-threaded.<br>
adherent to C++20 (best effort).<br>
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`](https://git.dotya.ml/wanderer/fortuna/src/commit/055fba29fe44e23730fe1ec493e16d0dc23dd3c1/accumulator.h#L27),
bytes remaining, and Pool 0 (`p0`) size:
[![asciicast](https://asciinema.org/a/V0fK2O8ahMMN2VFebAvkq4BIb.svg)](https://asciinema.org/a/V0fK2O8ahMMN2VFebAvkq4BIb)
## 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)](https://webhome.phy.duke.edu/~rgb/General/dieharder.php) -
on a ~243GiB stream of random material that the program kept producing until
`dieharder` finished testing ([log](https://git.dotya.ml/attachments/31f4fc32-f479-4bba-8359-02476bfa7e34))<br>
command used:
```shell
➜ 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)](https://git.dotya.ml/ak-fortuna/presentation/raw/commit/53294f9e346a5122705ca2d61a659ca0b6047323/img/dieharder-xtrategy.png)
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*](https://www.fourmilab.ch/random/) -
on a sample of 1000MiB of random data
![ent run](https://git.dotya.ml/ak-fortuna/presentation/raw/commit/53294f9e346a5122705ca2d61a659ca0b6047323/img/ent1000M.png)
### disclaimer
note that this project is a direct continuation of the [semestral work](https://git.dotya.ml/ak-fortuna/fortuna)
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`](https://ninja-build.org/)
* CMake
* `make`
* `libc++` (only tested with [`libcxx`](https://libcxx.llvm.org/))
* `libc`
* `libm`
* [`cryptopp`](https://cryptopp.com/)
* `lib{a,l,t,ub}san` on fedora, `gcc-libs` on archlinux
* [`{fmt}`](https://fmt.dev/latest/index.html) - 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](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](https://www.usenix.org/sites/default/files/conference/protected-files/enigma_slides_serebryany.pdf)
* `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)
```shell
➜ clang-format *.cpp *.h
```
## LICENSE
GPL-3.0-or-later (see [LICENSE](LICENSE) for details).

@ -1 +1 @@
Subproject commit c28500556a027fc3b84dc06e0021c719480fd1f3 Subproject commit a33701196adfad74917046096bf5a2aa0ab0bb50

View File

@ -26,6 +26,10 @@ sources = [
'do_task.cpp', 'do_task.cpp',
] ]
if get_option('buildtype').startswith('release')
add_project_arguments('-DNDEBUG', language : ['cpp'])
endif
cc_args = ['-std=c++20'] cc_args = ['-std=c++20']
incdir = include_directories('.') incdir = include_directories('.')