Update README
This commit is contained in:
@@ -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.
|
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
|
## CLI: randquik
|
||||||
|
|
||||||
@@ -28,4 +30,56 @@ Alternatively you may compile it by hand with `gcc *.c -o randquik -O3 -pthread`
|
|||||||
|
|
||||||
## Python module
|
## 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.
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from randquik.cha import Cha, generate, generate_into
|
||||||
|
|
||||||
|
__all__ = ["Cha", "generate_into", "generate"]
|
||||||
|
|||||||
Reference in New Issue
Block a user