Skip to content

Commit ba83f9b

Browse files
committed
Fix a bug in keystream construction
Fix a small bug where the `doublerounds` keyword argument does not get propagated when no other arguments are provided. Add a little more documentation for ChaChaStream.
1 parent 85b7eba commit ba83f9b

File tree

3 files changed

+80
-7
lines changed

3 files changed

+80
-7
lines changed

src/core.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ abstract type AbstractChaChaStream <: AbstractRNG end
6565
# Constructors
6666

6767
(::Type{T})(; kws...) where {T <: AbstractChaChaStream} =
68-
T(SVector{8,UInt32}(rand(RandomDevice(), UInt32, 8)))
68+
T(SVector{8,UInt32}(rand(RandomDevice(), UInt32, 8)); kws...)
6969
(::Type{T})(key; kws...) where {T <: AbstractChaChaStream} =
7070
T(key, UInt64(0); kws...)
7171
(::Type{T})(state::ChaChaState) where {T <: AbstractChaChaStream} =

src/keystream.jl

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,47 @@ using StaticArrays
44
using ChaChaCiphers.ChaCha
55

66
"""
7-
ChaChaStream
7+
ChaChaStream <: AbstractChaChaStream
88
9-
A cryptographically secure pseudo-random number generator
10-
(CRNG) based on the ChaCha stream cipher.
9+
`ChaChaStream` provides access to the keystream generated by the
10+
ChaCha stream cipher. It can be used as a cryptographically
11+
secure random number generator (CRNG) for Julia's random number
12+
generation functions.
13+
14+
## Examples
15+
16+
Create a `ChaChaStream` with a randomly-generated key and nonce:
17+
18+
```@meta
19+
DocTestSetup = quote
20+
using ChaChaCiphers
21+
using Random
22+
end
23+
```
24+
25+
```jldoctest
26+
julia> stream = ChaCha20Stream();
27+
```
28+
29+
Create a `ChaChaStream` with a pre-specified key and nonce, and
30+
use it to generate random data:
31+
32+
```jldoctest
33+
julia> key = UInt32.([
34+
0xe2e39848, 0x70bb974d, 0x845f88b4, 0xb30725e4,
35+
0x15c309dc, 0x72d545bb, 0x466e99e3, 0x6a759f91
36+
]);
37+
38+
julia> nonce = UInt64(1234);
39+
40+
julia> stream = ChaCha20Stream(key, nonce);
41+
42+
julia> randn(stream)
43+
0.7689072580509484
44+
45+
julia> randstring(stream, 'a':'z', 8)
46+
"klmptewr"
47+
```
1148
"""
1249
mutable struct ChaChaStream <: AbstractChaChaStream
1350
key :: SVector{8,UInt32}
@@ -24,7 +61,7 @@ mutable struct ChaChaStream <: AbstractChaChaStream
2461
position = 1;
2562
doublerounds = 10
2663
)
27-
if doublerounds < 0 || !iseven(doublerounds)
64+
if doublerounds 0
2865
error("`doublerounds` must be an even positive number")
2966
end
3067

@@ -39,11 +76,32 @@ mutable struct ChaChaStream <: AbstractChaChaStream
3976
end
4077

4178
# Constructors
79+
80+
"""
81+
ChaCha20Stream(args...)
82+
83+
Create a keystream for a ChaCha20 stream cipher.
84+
"""
4285
ChaCha20Stream(args...) = ChaChaStream(args...; doublerounds=10)
86+
87+
"""
88+
ChaCha12Stream(args...)
89+
90+
Create a keystream for a ChaCha12 stream cipher.
91+
"""
4392
ChaCha12Stream(args...) = ChaChaStream(args...; doublerounds=6)
4493

45-
Base.show(io::IO, rng::ChaChaStream) =
46-
write(io, "ChaChaStream(key=$(rng.key), nonce=$(rng.nonce), counter=$(rng.counter))")
94+
function Base.show(io::IO, rng::ChaChaStream)
95+
msg = """
96+
ChaChaStream(
97+
key = $(key(rng))
98+
nonce = $(nonce(rng)),
99+
counter = $(counter(rng)),
100+
rounds = $(2 * doublerounds(rng))
101+
)"""
102+
103+
write(io, msg)
104+
end
47105

48106
buffer_size(stream::ChaChaStream) = length(stream.buffer) - stream.position + 1
49107

test/test_keystream.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,21 @@ using Statistics
66
using Test
77

88
@testset "ChaChaStream random number generation tests" begin
9+
@testset "Test create keystream" begin
10+
# Create a ChaChaStream with the default parameters
11+
stream = ChaChaStream()
12+
@test stream.nonce == 0
13+
@test stream.position == 1
14+
15+
stream = ChaChaStream(; doublerounds=4)
16+
@test stream.doublerounds == 4
17+
18+
# We should receive an error if we try to create a
19+
# keystream with non-positive number of doublerounds
20+
@test_throws ErrorException ChaChaStream(; doublerounds=0)
21+
@test_throws ErrorException ChaChaStream(; doublerounds=-10)
22+
end
23+
924
@testset "Sample random numbers from a collection" begin
1025
stream = ChaCha12Stream(zeros(8), 0)
1126
samples = rand(stream, Int(0):Int(1), 65536)

0 commit comments

Comments
 (0)