crypto/chacha/
hchacha20.rs1pub fn hchacha20(key: &[u8; 32], input: &[u8; 16]) -> [u8; 32] {
14 use super::{CONSTANT, STATE_WORDS, quarter_round};
15
16 let mut state = [0u32; STATE_WORDS];
17
18 state[..4].copy_from_slice(&CONSTANT);
19
20 for (state_word, key_chunk) in state[4..12].iter_mut().zip(key.chunks_exact(4)) {
21 *state_word = u32::from_le_bytes(key_chunk.try_into().unwrap());
22 }
23
24 state[12] = u32::from_le_bytes(input[0..4].try_into().unwrap());
25 state[13] = u32::from_le_bytes(input[4..8].try_into().unwrap());
26 state[14] = u32::from_le_bytes(input[8..12].try_into().unwrap());
27 state[15] = u32::from_le_bytes(input[12..16].try_into().unwrap());
28
29 for _ in 0..10 {
30 quarter_round(&mut state, 0, 4, 8, 12);
31 quarter_round(&mut state, 1, 5, 9, 13);
32 quarter_round(&mut state, 2, 6, 10, 14);
33 quarter_round(&mut state, 3, 7, 11, 15);
34
35 quarter_round(&mut state, 0, 5, 10, 15);
36 quarter_round(&mut state, 1, 6, 11, 12);
37 quarter_round(&mut state, 2, 7, 8, 13);
38 quarter_round(&mut state, 3, 4, 9, 14);
39 }
40
41 let mut output = [0u8; 32];
42 for i in 0..4 {
43 output[i * 4..(i + 1) * 4].copy_from_slice(&state[i].to_le_bytes());
44 }
45 for i in 0..4 {
46 output[16 + i * 4..16 + (i + 1) * 4].copy_from_slice(&state[12 + i].to_le_bytes());
47 }
48
49 return output;
50}
51
52#[cfg(test)]
53mod test {
54 use super::hchacha20;
55
56 #[test]
58 fn hchacha20_test_vector_1() {
59 let key: [u8; 32] =
60 hex::decode_array(b"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap();
61 let input: [u8; 16] = hex::decode_array(b"000000090000004a0000000031415927").unwrap();
62 let expected: [u8; 32] =
63 hex::decode_array(b"82413b4227b27bfed30e42508a877d73a0f9e4d58a74a853c12ec41326d3ecdc").unwrap();
64
65 assert_eq!(hchacha20(&key, &input), expected);
66 }
67
68 #[test]
70 fn hchacha20_all_zeros() {
71 let key = [0u8; 32];
72 let input = [0u8; 16];
73 let expected: [u8; 32] =
74 hex::decode_array(b"1140704c328d1d5d0e30086cdf209dbd6a43b8f41518a11cc387b669b2ee6586").unwrap();
75
76 assert_eq!(hchacha20(&key, &input), expected);
77 }
78}