Skip to content

Commit ddc5121

Browse files
committed
Migrate to closur-based keccak
1 parent 827c043 commit ddc5121

4 files changed

Lines changed: 58 additions & 41 deletions

File tree

Cargo.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@ opt-level = 2
3434
sha1 = { path = "sha1" }
3535
sha3 = { path = "sha3" }
3636
whirlpool = { path = "whirlpool" }
37+
38+
keccak = { git = "https://github.com/RustCrypto/sponges" }

sha3/src/block_api.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use digest::{
1111
common::hazmat::{DeserializeStateError, SerializableState, SerializedState},
1212
typenum::{IsLessOrEqual, True, U0, U200},
1313
};
14-
use keccak::KeccakP1600;
14+
use keccak::{Keccak, State1600};
1515

1616
pub use crate::cshake::{CShake128Core, CShake256Core};
1717

@@ -26,7 +26,8 @@ pub struct Sha3HasherCore<
2626
Rate: BlockSizes + IsLessOrEqual<U200, Output = True>,
2727
OutputSize: ArraySize + IsLessOrEqual<U200, Output = True>,
2828
{
29-
state: KeccakP1600,
29+
state: State1600,
30+
keccak: Keccak,
3031
_pd: PhantomData<(Rate, OutputSize)>,
3132
}
3233

@@ -73,10 +74,12 @@ where
7374
{
7475
#[inline]
7576
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
76-
for block in blocks {
77-
xor_block(self.state.as_mut(), block);
78-
self.state.p1600(ROUNDS);
79-
}
77+
self.keccak.with_p1600::<ROUNDS>(|p1600| {
78+
for block in blocks {
79+
xor_block(&mut self.state, block);
80+
p1600(&mut self.state);
81+
}
82+
});
8083
}
8184
}
8285

@@ -94,12 +97,14 @@ where
9497
let n = block.len();
9598
block[n - 1] |= 0x80;
9699

97-
xor_block(self.state.as_mut(), &block);
98-
self.state.p1600(ROUNDS);
100+
self.keccak.with_p1600::<ROUNDS>(|p1600| {
101+
xor_block(&mut self.state, &block);
102+
p1600(&mut self.state);
99103

100-
for (o, s) in out.chunks_mut(8).zip(self.state.as_mut().iter()) {
101-
o.copy_from_slice(&s.to_le_bytes()[..o.len()]);
102-
}
104+
for (o, s) in out.chunks_mut(8).zip(self.state.as_mut().iter()) {
105+
o.copy_from_slice(&s.to_le_bytes()[..o.len()]);
106+
}
107+
});
103108
}
104109
}
105110

@@ -118,10 +123,12 @@ where
118123
let n = block.len();
119124
block[n - 1] |= 0x80;
120125

121-
xor_block(self.state.as_mut(), &block);
122-
self.state.p1600(ROUNDS);
126+
self.keccak.with_p1600::<ROUNDS>(|p1600| {
127+
xor_block(&mut self.state, &block);
128+
p1600(&mut self.state);
129+
});
123130

124-
Sha3ReaderCore::new(self.state.as_ref())
131+
Sha3ReaderCore::new(&self.state, self.keccak)
125132
}
126133
}
127134

@@ -135,6 +142,7 @@ where
135142
fn default() -> Self {
136143
Self {
137144
state: Default::default(),
145+
keccak: Keccak::new(),
138146
_pd: PhantomData,
139147
}
140148
}
@@ -219,14 +227,15 @@ where
219227
fn deserialize(
220228
serialized_state: &SerializedState<Self>,
221229
) -> Result<Self, DeserializeStateError> {
222-
let mut state = [0; PLEN];
230+
let mut state = State1600::default();
223231
let chunks = serialized_state.chunks_exact(8);
224232
for (val, chunk) in state.iter_mut().zip(chunks) {
225233
*val = u64::from_le_bytes(chunk.try_into().unwrap());
226234
}
227235

228236
Ok(Self {
229-
state: KeccakP1600::from(state),
237+
state,
238+
keccak: Keccak::new(),
230239
_pd: PhantomData,
231240
})
232241
}
@@ -238,19 +247,18 @@ pub struct Sha3ReaderCore<Rate, const ROUNDS: usize = DEFAULT_ROUND_COUNT>
238247
where
239248
Rate: BlockSizes + IsLessOrEqual<U200, Output = True>,
240249
{
241-
state: [u64; PLEN],
250+
state: State1600,
251+
keccak: Keccak,
242252
_pd: PhantomData<Rate>,
243253
}
244254

245255
impl<Rate, const ROUNDS: usize> Sha3ReaderCore<Rate, ROUNDS>
246256
where
247257
Rate: BlockSizes + IsLessOrEqual<U200, Output = True>,
248258
{
249-
pub(crate) fn new(state: &[u64; PLEN]) -> Self {
250-
Self {
251-
state: *state,
252-
_pd: PhantomData,
253-
}
259+
pub(crate) fn new(&state: &[u64; PLEN], keccak: Keccak) -> Self {
260+
let _pd = PhantomData;
261+
Self { state, keccak, _pd }
254262
}
255263
}
256264

@@ -271,7 +279,8 @@ where
271279
for (src, dst) in self.state.iter().zip(block.chunks_mut(8)) {
272280
dst.copy_from_slice(&src.to_le_bytes()[..dst.len()]);
273281
}
274-
keccak::p1600(&mut self.state, ROUNDS);
282+
self.keccak
283+
.with_p1600::<ROUNDS>(|p1600| p1600(&mut self.state));
275284
block
276285
}
277286
}

sha3/src/cshake.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use digest::{
1313
consts::{U16, U32, U136, U168, U400},
1414
typenum::Unsigned,
1515
};
16+
use keccak::{Keccak, State1600};
1617

1718
macro_rules! impl_cshake {
1819
(
@@ -22,8 +23,9 @@ macro_rules! impl_cshake {
2223
#[doc = " core hasher."]
2324
#[derive(Clone, Default)]
2425
pub struct $name {
25-
state: [u64; PLEN],
26-
initial_state: [u64; PLEN],
26+
state: State1600,
27+
initial_state: State1600,
28+
keccak: Keccak,
2729
}
2830

2931
impl $name {
@@ -87,10 +89,12 @@ macro_rules! impl_cshake {
8789
impl UpdateCore for $name {
8890
#[inline]
8991
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
90-
for block in blocks {
91-
xor_block(&mut self.state, block);
92-
keccak::p1600(&mut self.state, ROUNDS);
93-
}
92+
self.keccak.with_p1600::<ROUNDS>(|p1600| {
93+
for block in blocks {
94+
xor_block(&mut self.state, block);
95+
p1600(&mut self.state);
96+
}
97+
})
9498
}
9599
}
96100

@@ -110,10 +114,12 @@ macro_rules! impl_cshake {
110114
let n = block.len();
111115
block[n - 1] |= 0x80;
112116

113-
xor_block(&mut self.state, &block);
114-
keccak::p1600(&mut self.state, ROUNDS);
117+
self.keccak.with_p1600::<ROUNDS>(|p1600| {
118+
xor_block(&mut self.state, &block);
119+
p1600(&mut self.state);
120+
});
115121

116-
Sha3ReaderCore::new(&self.state)
122+
Sha3ReaderCore::new(&self.state, self.keccak)
117123
}
118124
}
119125

@@ -179,7 +185,7 @@ macro_rules! impl_cshake {
179185
let chunk = initial_state_src[8 * i..][..8].try_into().unwrap();
180186
u64::from_le_bytes(chunk)
181187
});
182-
Ok(Self{ state, initial_state })
188+
Ok(Self{ state, initial_state, keccak: Keccak::new() })
183189
}
184190
}
185191

0 commit comments

Comments
 (0)