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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! Block RNG based on rand_core::BlockRng

use rand_core::block::{BlockRng, BlockRngCore};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};

use crate::{
    block::{Block, BUFFER_SIZE},
    rounds::{R12, R20, R8},
    KEY_SIZE, MAX_BLOCKS,
};

macro_rules! impl_chacha_rng {
    ($name:ident, $core:ident, $rounds:ident, $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<$rounds>,
            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());
                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) {
                assert!(self.counter <= MAX_BLOCKS as u64, "maximum number of allowed ChaCha blocks exceeded");

                // TODO(tarcieri): eliminate unsafety (replace w\ [u8; BLOCK_SIZE)
                self.block.generate(self.counter, unsafe {
                    &mut *(results.as_mut_ptr() as *mut [u8; BUFFER_SIZE])
                });
                self.counter += 1;
            }
        }

        impl CryptoRng for $core {}
    }
}

impl_chacha_rng!(
    ChaCha8Rng,
    ChaCha8RngCore,
    R8,
    "Random number generator over the ChaCha8 stream cipher."
);

impl_chacha_rng!(
    ChaCha12Rng,
    ChaCha12RngCore,
    R12,
    "Random number generator over the ChaCha12 stream cipher."
);

impl_chacha_rng!(
    ChaCha20Rng,
    ChaCha20RngCore,
    R20,
    "Random number generator over the ChaCha20 stream cipher."
);

#[cfg(test)]
mod tests {
    use super::ChaCha20Rng;
    use crate::KEY_SIZE;
    use rand_core::{RngCore, SeedableRng};

    const KEY: [u8; KEY_SIZE] = [
        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,
    ];

    #[test]
    fn test_rng_output() {
        let mut rng = ChaCha20Rng::from_seed(KEY);
        let mut bytes = [0u8; 13];

        rng.fill_bytes(&mut bytes);
        assert_eq!(
            bytes,
            [177, 105, 126, 159, 198, 70, 30, 25, 131, 209, 49, 207, 105]
        );

        rng.fill_bytes(&mut bytes);
        assert_eq!(
            bytes,
            [167, 163, 252, 19, 79, 20, 152, 128, 232, 187, 43, 93, 35]
        );
    }
}