Update README

This commit is contained in:
2023-11-29 23:31:12 +00:00
parent 46af28f19c
commit 372ea4a18d
2 changed files with 59 additions and 2 deletions
+56 -2
View File
@@ -4,7 +4,9 @@ I was disappointed with the sad state of random number generators. Many language
To give some perspective, my tool reaches 37.8 GB/s, writing /dev/null. Several gigabytes per second also on actual SSDs.
Secondly, flaws have been found in non-cryptographic algorithms, especially on Mersenne Twister. The cryptographic options are simply better, being free of such issues as sequences repeating, and additionally being, well, cryptographically secure. Surprisingly, they appear even to be faster now, so there really ought to be no reason to stick with the old.
Secondly, [flaws have been found](https://numpy.org/doc/stable/reference/random/upgrading-pcg64.html) in non-cryptographic algorithms such as the popular Mersenne Twister and PCG64 algorithms.
The cryptographic alternative is simply better, being free of such issues as sequences repeating, and additionally being, well, cryptographically secure. Surprisingly, they appear even to be faster now, so there really ought to be no reason to stick with the old.
## CLI: randquik
@@ -28,4 +30,56 @@ Alternatively you may compile it by hand with `gcc *.c -o randquik -O3 -pthread`
## Python module
I have a Python binding to this in the works, with the intention of being able to use these faster random numbers also for creating byte buffers and with numpy.random there. The module now offers functional Numpy BitGenerator adaptor, and a friendly general purpose Python API that can fill up any buffer with random bytes.
Python module fills any buffers with random data very quickly,
```python
from randquik import Cha, generate
import secrets
key = secrets.token_bytes(32)
# Allocate bytearray and fill with random
data = generate(1_000_000, key)
# Replace with new random bytes
generate_into(data)
```
Or with incremental updates, using only 8 rounds for even higher performance
```python
rng = Cha(key, b"SomeInit", rounds=8) # IV and rounds optional
# Fill some buffer with next bytes iteratively
rng(data)
rng(data)
...
```
## Numpy module
Numpy.Random BitGenerator is also provided for use with Numpy distributions. We do not recommend using it for filling byte buffers, where the Python module and the C code are far faster, but it will still provide better quality random numbers and faster than Numpy's own PCG64.
```python
import numpy as np
from nprand import Cha
gen = np.random.Generator(Cha())
gen.normal(size=10)
```
This module needs to be built by hand with Cython for now. Will be packaged properly in randquik module eventually.
## Tests
Some pytest tests are provided for verifying ChaCha20 implementation correctness against the Cryptography module. Run by `pytest` in the main folder after installation.
## Performance
ChaCha20 as its name implies uses 20 "rounds" of shuffling for each output block. A lower number of rounds can be used for extra performance, where 8 is the minimum that is considered secure, and 12 provides a balanced option, while 20 has comfortable headroom to stay cryptographically secure.
All functions and constructors of this module take `rounds` kwarg for adjusting this. On CLI the equivalent option is `-r`. By default 20 rounds are used.
The CLI uses a configurable number of threads for extremely high performance, while the Python and Numpy modules don't - for now at least.
The implementation is optimized for Apple Silicon SIMD (Neon) and x86 CPUs using AVX2 where available, falling back to SSSE3 and ultimately plain C on other platforms. The implementation is loosely based on code from libsodium but runs faster than the library can.
+3
View File
@@ -0,0 +1,3 @@
from randquik.cha import Cha, generate, generate_into
__all__ = ["Cha", "generate_into", "generate"]