|
| 1 | +# ChaChaCiphers |
| 2 | + |
| 3 | +[ChaChaCiphers](https://github.com/kernelmethod/ChaChaCiphers.jl) is a |
| 4 | +CUDA-compatible, pure-Julia implementation of the ChaCha family of stream |
| 5 | +ciphers. This package provides: |
| 6 | + |
| 7 | +- fast, cryptographically-secure, and reproducible random number generators |
| 8 | + implementing Julia's `AbstractRNG` interface for both CPU and GPU, and |
| 9 | +- implementations of ChaCha stream ciphers such as ChaCha20 that can be used as |
| 10 | + building blocks for other cryptographic primitives, such as ChaCha20-Poly1305. |
| 11 | + |
| 12 | +!!! warning |
| 13 | + ChaCha is not sufficient by itself for encrypting data, and misuse can |
| 14 | + compromise application security. Please review [the warnings |
| 15 | + section](#warnings-and-disclaimers) for more details. |
| 16 | + |
| 17 | +## Basic usage |
| 18 | + |
1 | 19 | ```@meta
|
2 |
| -CurrentModule = ChaChaCiphers |
| 20 | +DocTestSetup = quote |
| 21 | + using ChaChaCiphers |
| 22 | + key = UInt32.([ |
| 23 | + 0xe2e39848, 0x70bb974d, 0x845f88b4, 0xb30725e4, |
| 24 | + 0x15c309dc, 0x72d545bb, 0x466e99e3, 0x6a759f91 |
| 25 | + ]); |
| 26 | + nonce = UInt64(0); |
| 27 | + rng = ChaCha20Stream(key, nonce); |
| 28 | +end |
3 | 29 | ```
|
4 | 30 |
|
5 |
| -# ChaChaCiphers |
| 31 | +To start generating random numbers with ChaChaCiphers, create a new keystream |
| 32 | +with a function like [`ChaCha20Stream`](@ref) or [`ChaCha12Stream`](@ref): |
| 33 | + |
| 34 | +```jldoctest |
| 35 | +julia> using ChaChaCiphers |
6 | 36 |
|
7 |
| -Documentation for [ChaChaCiphers](https://github.com/kernelmethod/ChaChaCiphers.jl). |
| 37 | +julia> rng = ChaCha20Stream(); |
| 38 | +``` |
| 39 | + |
| 40 | +This will generate a keystream using a key sampled from the operating system's |
| 41 | +random stream. Alternatively, you can explicitly specify a `key` and `nonce` as |
| 42 | +follows: |
| 43 | + |
| 44 | +```jldoctest |
| 45 | +julia> key = UInt32.([ |
| 46 | + 0xe2e39848, 0x70bb974d, 0x845f88b4, 0xb30725e4, |
| 47 | + 0x15c309dc, 0x72d545bb, 0x466e99e3, 0x6a759f91 |
| 48 | + ]); |
| 49 | +
|
| 50 | +julia> nonce = UInt64(0); |
8 | 51 |
|
9 |
| -```@index |
| 52 | +julia> rng = ChaCha20Stream(key, nonce); |
10 | 53 | ```
|
11 | 54 |
|
12 |
| -```@autodocs |
13 |
| -Modules = [ChaChaCiphers] |
| 55 | +After generating a keystream, you can supply it as the `rng` parameter to |
| 56 | +`Random` functions like `rand` and `randn`: |
| 57 | + |
| 58 | +```jldoctest |
| 59 | +julia> using Random |
| 60 | +
|
| 61 | +julia> rand(rng, 1:10) |
| 62 | +3 |
| 63 | +
|
| 64 | +julia> randn(rng, Float32, 3) |
| 65 | +3-element Vector{Float32}: |
| 66 | + -0.50947624 |
| 67 | + -0.9306026 |
| 68 | + -0.084067896 |
14 | 69 | ```
|
| 70 | + |
| 71 | +Review the API documentation for more details. |
| 72 | + |
| 73 | +## About ChaCha |
| 74 | + |
| 75 | +ChaCha was first introduced as a variant of the Salsa20 stream cipher by Daniel |
| 76 | +Bernstein in 2008[^Bernstein08]. ChaCha produces a stream of 512-bit blocks that |
| 77 | +act as a CRNG seeded with a key and nonce. |
| 78 | + |
| 79 | +ChaCha is used as the basis for the Linux kernel's CRNG[^LWN16]. It is one of |
| 80 | +the two major components of the ChaCha20-Poly1305 Authenticated Encryption with |
| 81 | +Associated Data (AEAD) algorithm specified by IETF RFC 8439[^RFC8439], which in |
| 82 | +turn is used by [TLS](https://datatracker.ietf.org/doc/html/rfc7905), |
| 83 | +[OpenSSH](http://bxr.su/OpenBSD/usr.bin/ssh/PROTOCOL.chacha20poly1305), |
| 84 | +[Wireguard](https://www.wireguard.com/protocol/), and more. |
| 85 | + |
| 86 | +ChaCha makes it easy to seek to any given portion of the keystream, which allows |
| 87 | +extremely efficient parallel computation on CPU and GPU. It can also be computed |
| 88 | +in constant time very efficiently in software, whereas comparable symmetric |
| 89 | +ciphers (e.g. AES-CTR) require hardware support to achieve the same performance. |
| 90 | + |
| 91 | +[^Bernstein08]: |
| 92 | + "ChaCha, a variant of Salsa20": |
| 93 | + [https://cr.yp.to/chacha/chacha-20080128.pdf](https://cr.yp.to/chacha/chacha-20080128.pdf) |
| 94 | + |
| 95 | +[^LWN16]: |
| 96 | + "Replacing /dev/urandom": |
| 97 | + [https://lwn.net/Articles/686033/](https://lwn.net/Articles/686033/) |
| 98 | + |
| 99 | +[^RFC8439]: |
| 100 | + [IETF RFC 8439](https://datatracker.ietf.org/doc/html/rfc8439) |
| 101 | + |
| 102 | +## Warnings and disclaimers |
| 103 | + |
| 104 | +### Security |
| 105 | + |
| 106 | +ChaCha is not by itself sufficient to keep your data secure. In particular, it |
| 107 | +doesn't provide any guarantees of data integrity or authenticity, and the |
| 108 | +ciphertexts it produces are |
| 109 | +[malleable](https://en.wikipedia.org/wiki/Malleability_%28cryptography%29_). |
| 110 | + |
| 111 | +Most likely, if you are looking for an algorithm to encrypt your data, you'll |
| 112 | +want an [AEAD algorithm](https://en.wikipedia.org/wiki/Authenticated_encryption) |
| 113 | +such as [ChaCha20-Poly1305](https://datatracker.ietf.org/doc/html/rfc8439) or |
| 114 | +[AES-GCM](https://datatracker.ietf.org/doc/html/rfc8452). |
| 115 | + |
| 116 | +This package has not received a formal security analysis from an external party. |
| 117 | +Please use with caution. |
| 118 | + |
| 119 | +### Alternatives |
| 120 | + |
| 121 | +If you don't strictly need a cryptographically secure random number generator, |
| 122 | +you should consider using [Julia's built-in |
| 123 | +RNG](https://docs.julialang.org/en/v1/stdlib/Random/), which as of v1.7 uses |
| 124 | +[Xoshiro256++](https://prng.di.unimi.it/) and can easily beat ChaCha by an order |
| 125 | +of magnitude or more in speed. |
| 126 | + |
| 127 | +Alternatively, if you need a CRNG but don't care about reproducibility, you may |
| 128 | +wish to consider using |
| 129 | +[`RandomDevice`](https://docs.julialang.org/en/v1/stdlib/Random/#Random.RandomDevice) |
| 130 | +from Julia's standard library, which pulls from the operating system's random |
| 131 | +stream. In practice however [`ChaChaStream`](@ref) may be much faster than using |
| 132 | +`RandomDevice`. |
0 commit comments