1use aes::cipher::generic_array::GenericArray;
7use aes::cipher::{BlockEncrypt, KeyInit};
8use aes::Aes256;
9use bitvec::prelude::*;
10use group::byte::utils::{xor, xor_inplace};
11
12use crate::Prg;
13
14pub struct Aes256HirosePrg<const LAMBDA: usize, const N: usize> {
23 ciphers: [Aes256; N],
24}
25
26impl<const LAMBDA: usize, const N: usize> Aes256HirosePrg<LAMBDA, N> {
27 pub fn new(keys: [&[u8; 32]; N]) -> Self {
28 let ciphers = std::array::from_fn(|i| {
29 let key_block = GenericArray::from_slice(keys[i]);
30 Aes256::new(key_block)
31 });
32 Self { ciphers }
33 }
34
35 fn c() -> [u8; LAMBDA] {
37 std::array::from_fn(|_| 0xff)
38 }
39}
40
41impl<const LAMBDA: usize, const N: usize> Prg<LAMBDA> for Aes256HirosePrg<LAMBDA, N> {
42 fn gen(&self, seed: &[u8; LAMBDA]) -> [([u8; LAMBDA], [u8; LAMBDA], bool); 2] {
43 let seed_p = xor(&[seed, &Self::c()]);
45 let mut result_buf0 = [[0; LAMBDA]; 2];
46 let mut result_buf1 = [[0; LAMBDA]; 2];
47 let mut out_blocks = [GenericArray::default(); 2];
48 (0..2usize).for_each(|i| {
49 (0..LAMBDA / 16).for_each(|j| {
50 let in_block0 = GenericArray::from_slice(&seed[j * 16..(j + 1) * 16]);
51 let in_block1 = GenericArray::from_slice(&seed_p[j * 16..(j + 1) * 16]);
52 self.ciphers[i * (LAMBDA / 16) + j]
53 .encrypt_blocks_b2b(&[*in_block0, *in_block1], &mut out_blocks)
54 .unwrap();
55 result_buf0[i][j * 16..(j + 1) * 16].copy_from_slice(out_blocks[0].as_ref());
56 result_buf1[i][j * 16..(j + 1) * 16].copy_from_slice(out_blocks[1].as_ref());
57 });
58 });
59 result_buf0
60 .iter_mut()
61 .for_each(|buf| xor_inplace(buf, &[seed]));
62 result_buf1
63 .iter_mut()
64 .for_each(|buf| xor_inplace(buf, &[&seed_p]));
65 let bit0 = result_buf0[0].view_bits::<Lsb0>()[0];
66 let bit1 = result_buf1[0].view_bits::<Lsb0>()[0];
67 result_buf0
68 .iter_mut()
69 .chain(result_buf1.iter_mut())
70 .for_each(|buf| buf[LAMBDA - 1].view_bits_mut::<Lsb0>().set(0, false));
71 [
72 (result_buf0[0], result_buf1[0], bit0),
73 (result_buf0[1], result_buf1[1], bit1),
74 ]
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 const KEYS: [&[u8; 32]; 2] = [
83 b"j9\x1b_\xb3X\xf33\xacW\x15\x1b\x0812K\xb3I\xb9\x90r\x1cN\xb5\xee9W\xd3\xbb@\xc6d",
84 b"\x9b\x15\xc8\x0f\xb7\xbc!q\x9e\x89\xb8\xf7\x0e\xa0S\x9dN\xfa\x0c;\x16\xe4\x98\x82b\xfcdy\xb5\x8c{\xc2",
85 ];
86 const SEED: &[u8; 16] = b"*L\x8f%y\x12Z\x94*E\x8f$+NH\x19";
87
88 #[test]
89 fn test_prg_gen_not_zeros() {
90 let prg = Aes256HirosePrg::<16, 2>::new(KEYS);
91 let out = prg.gen(SEED);
92 (0..2).for_each(|i| {
93 assert_ne!(out[i].0, [0; 16]);
94 assert_ne!(out[i].1, [0; 16]);
95 assert_ne!(xor(&[&out[i].0, SEED]), [0; 16]);
96 assert_ne!(xor(&[&out[i].1, SEED]), [0; 16]);
97 assert_ne!(xor(&[&out[i].0, SEED]), [0xff; 16]);
98 assert_ne!(xor(&[&out[i].1, SEED]), [0xff; 16]);
99 });
100 }
101}