1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use core::slice;
use rand_core::block::{BlockRng, BlockRngCore};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
use crate::{
block::{Block, BUFFER_SIZE},
KEY_SIZE,
};
macro_rules! impl_chacha_rng {
($name:ident, $core:ident, $rounds:expr, $doc:expr) => {
#[doc = $doc]
#[derive(Clone, Debug)]
pub struct $name(BlockRng<$core>);
impl SeedableRng for $name {
type Seed = [u8; KEY_SIZE];
#[inline]
fn from_seed(seed: Self::Seed) -> Self {
let core = $core::from_seed(seed);
Self(BlockRng::new(core))
}
}
impl RngCore for $name {
#[inline]
fn next_u32(&mut self) -> u32 {
self.0.next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
self.0.next_u64()
}
#[inline]
fn fill_bytes(&mut self, bytes: &mut [u8]) {
self.0.fill_bytes(bytes)
}
#[inline]
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> Result<(), Error> {
self.0.try_fill_bytes(bytes)
}
}
impl CryptoRng for $name {}
#[doc = "Core random number generator, for use with [`rand_core::block::BlockRng`]"]
#[derive(Clone, Debug)]
pub struct $core {
block: Block,
counter: u64,
}
impl SeedableRng for $core {
type Seed = [u8; KEY_SIZE];
#[inline]
fn from_seed(seed: Self::Seed) -> Self {
let block = Block::new(&seed, Default::default(), $rounds);
Self { block, counter: 0 }
}
}
impl BlockRngCore for $core {
type Item = u32;
type Results = [u32; BUFFER_SIZE / 4];
fn generate(&mut self, results: &mut Self::Results) {
self.block.generate(self.counter, unsafe {
slice::from_raw_parts_mut(results.as_mut_ptr() as *mut u8, BUFFER_SIZE)
});
self.counter += 1;
}
}
impl CryptoRng for $core {}
}
}
impl_chacha_rng!(
ChaCha8Rng,
ChaCha8RngCore,
8,
"Random number generator over the ChaCha8 stream cipher."
);
impl_chacha_rng!(
ChaCha12Rng,
ChaCha12RngCore,
12,
"Random number generator over the ChaCha12 stream cipher."
);
impl_chacha_rng!(
ChaCha20Rng,
ChaCha20RngCore,
20,
"Random number generator over the ChaCha20 stream cipher."
);