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
use crate::{bits_to_rate, keccakf::KeccakF, left_encode, Hasher, KeccakState, Xof};
#[derive(Clone)]
pub struct CShake {
state: KeccakState<KeccakF>,
}
impl CShake {
const DELIM: u8 = 0x04;
pub fn v128(name: &[u8], custom_string: &[u8]) -> CShake {
CShake::new(name, custom_string, 128)
}
pub fn v256(name: &[u8], custom_string: &[u8]) -> CShake {
CShake::new(name, custom_string, 256)
}
pub(crate) fn new(name: &[u8], custom_string: &[u8], bits: usize) -> CShake {
let rate = bits_to_rate(bits);
if name.is_empty() && custom_string.is_empty() {
let state = KeccakState::new(rate, 0x1f);
return CShake { state };
}
let mut state = KeccakState::new(rate, Self::DELIM);
state.update(left_encode(rate).value());
state.update(left_encode(name.len() * 8).value());
state.update(name);
state.update(left_encode(custom_string.len() * 8).value());
state.update(custom_string);
state.fill_block();
CShake { state }
}
pub(crate) fn fill_block(&mut self) {
self.state.fill_block();
}
}
impl Hasher for CShake {
fn update(&mut self, input: &[u8]) {
self.state.update(input);
}
fn finalize(self, output: &mut [u8]) {
self.state.finalize(output);
}
}
impl Xof for CShake {
fn squeeze(&mut self, output: &mut [u8]) {
self.state.squeeze(output);
}
}