Skip to content

Commit 075f14c

Browse files
committed
tweak code
1 parent fbb0fad commit 075f14c

2 files changed

Lines changed: 52 additions & 41 deletions

File tree

sponge-cursor/src/lib.rs

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
66
)]
77

8-
mod utils;
8+
mod u64_le_utils;
99

1010
/// Cursor for implementing sponge-based absorption and squeezing.
1111
///
12-
/// This type wraps `u8` and enforces that its value is always smaller than `Rate`.
12+
/// This type wraps `u8` and enforces that its value is always smaller than `RATE`.
1313
///
14-
/// `Rate` MUST be smaller than `U256`, trying to initialize cursor with an invalid rate will
14+
/// `RATE` MUST be smaller than `256`, trying to initialize cursor with an invalid rate will
1515
/// result in a compilation error.
1616
#[derive(Debug, Clone)]
1717
pub struct SpongeCursor<const RATE: usize> {
@@ -30,11 +30,11 @@ impl<const RATE: usize> Default for SpongeCursor<RATE> {
3030
}
3131

3232
// Note that the methods should compile into a panic-free code,
33-
// see: https://rust.godbolt.org/z/3v4zWr4ox
33+
// see: https://rust.godbolt.org/z/r93WE8zq3
3434
impl<const RATE: usize> SpongeCursor<RATE> {
3535
/// Create new cursor with the provided position.
3636
///
37-
/// Returns `None` if `pos` is bigger or equal to `Rate`.
37+
/// Returns `None` if `pos` is bigger or equal to `RATE`.
3838
#[must_use]
3939
pub fn new(pos: u8) -> Option<Self> {
4040
if usize::from(pos) < RATE {
@@ -54,7 +54,7 @@ impl<const RATE: usize> SpongeCursor<RATE> {
5454
if self.pos < rate_u8 {
5555
self.pos
5656
} else {
57-
// SAFETY: the type enforces that `pos` is always smaller than `Rate`
57+
// SAFETY: the type enforces that `pos` is always smaller than `RATE`
5858
unsafe { core::hint::unreachable_unchecked() };
5959
}
6060
}
@@ -68,19 +68,25 @@ impl<const RATE: usize> SpongeCursor<RATE> {
6868
if pos < RATE {
6969
pos
7070
} else {
71-
// SAFETY: the type enforces that `pos` is always smaller than `Rate`
71+
// SAFETY: the type enforces that `pos` is always smaller than `RATE`
7272
unsafe { core::hint::unreachable_unchecked() };
7373
}
7474
}
7575

76-
/// Absorb bytes from `data` into a `u64`-based state using little ednian byte order.
76+
/// Set new cursor position.
7777
///
78-
/// Size of state MUST be greater or equal to `Rate`. Using an invalid `N` will result in
79-
/// a compilation error.
80-
#[allow(
81-
clippy::missing_panics_doc,
82-
reason = "the method is panic-free, see: https://rust.godbolt.org/z/88Wf1qEsr"
83-
)]
78+
/// # Panics
79+
/// If `new_pos` is greater or equal to `RATE`.
80+
fn set_pos(&mut self, new_pos: usize) {
81+
assert!(new_pos < RATE);
82+
self.pos = u8::try_from(new_pos).expect("`new_pos` is smaller than `RATE`");
83+
}
84+
85+
/// Absorb bytes from `data` into `state` using little-endian byte order.
86+
///
87+
/// Size of `state` in bytes MUST be greater or equal to `RATE`.
88+
/// Using an invalid `N` will result in a compilation error.
89+
#[allow(clippy::missing_panics_doc, reason = "the method is panic-free")]
8490
#[inline]
8591
pub fn absorb_u64_le<const N: usize>(
8692
&mut self,
@@ -96,44 +102,44 @@ impl<const RATE: usize> SpongeCursor<RATE> {
96102

97103
if self.pos != 0 {
98104
let pos = self.pos();
99-
let rem_len = RATE - pos;
100-
101-
let is_partial = data.len() < rem_len;
102-
let head = if is_partial {
103-
data
104-
} else {
105-
let (head, tail) = data.split_at(rem_len);
106-
data = tail;
107-
head
108-
};
105+
let rem_len = RATE
106+
.checked_sub(pos)
107+
.expect("`pos` is always smaller than `RATE`");
109108

110-
utils::absorb_partial::<N, RATE>(state, pos, head);
111-
112-
if is_partial {
113-
self.pos = u8::try_from(pos + head.len()).expect("the sum is smaller than Rate");
109+
if data.len() < rem_len {
110+
u64_le_utils::absorb_partial::<N, RATE>(state, pos, data);
111+
self.set_pos(pos + data.len());
114112
return;
115113
}
116114

115+
let (head, tail) = data.split_at(rem_len);
116+
data = tail;
117+
u64_le_utils::absorb_partial::<N, RATE>(state, pos, head);
118+
117119
sponge(state);
118120
}
119121

120122
let blocks = data.chunks_exact(RATE);
121123
let tail = blocks.remainder();
122124

123125
for block in blocks {
124-
let block: &[u8; RATE] = block.try_into().expect("block has correct size");
125-
utils::absorb_full(state, block);
126+
let block: &[u8; RATE] = block.try_into().expect("`block` has correct size");
127+
u64_le_utils::absorb_full(state, block);
126128
sponge(state);
127129
}
128130

129131
if !tail.is_empty() {
130-
utils::absorb_partial::<N, RATE>(state, 0, tail);
132+
u64_le_utils::absorb_partial::<N, RATE>(state, 0, tail);
131133
}
132134

133-
self.pos = u8::try_from(tail.len()).expect("tail.len() is smaller than RATE");
135+
self.set_pos(tail.len());
134136
}
135137

136-
/// Squeeze data by reading it into `buf`.
138+
/// Squeeze data from `state` by reading it into `buf` using little-endian byte order.
139+
///
140+
/// Size of `state` in bytes MUST be greater or equal to `RATE`.
141+
/// Using an invalid `N` will result in a compilation error.
142+
#[inline]
137143
pub fn squeeze_read_u64_le<const N: usize>(
138144
&mut self,
139145
state: &mut [u64; N],
@@ -144,12 +150,16 @@ impl<const RATE: usize> SpongeCursor<RATE> {
144150
state,
145151
sponge,
146152
buf,
147-
utils::squeeze_read_partial::<N, RATE>,
148-
utils::squeeze_read_full,
153+
u64_le_utils::squeeze_read_partial::<N, RATE>,
154+
u64_le_utils::squeeze_read_full,
149155
);
150156
}
151157

152-
/// Squeeze data by XOR-ing it with data in `buf`.
158+
/// Squeeze data from `state` by XOR-ing it with data in `buf` using little-endian byte order.
159+
///
160+
/// Size of `state` in bytes MUST be greater or equal to `RATE`.
161+
/// Using an invalid `N` will result in a compilation error.
162+
#[inline]
153163
pub fn squeeze_xor_u64_le<const N: usize>(
154164
&mut self,
155165
state: &mut [u64; N],
@@ -160,11 +170,12 @@ impl<const RATE: usize> SpongeCursor<RATE> {
160170
state,
161171
sponge,
162172
buf,
163-
utils::squeeze_xor_partial::<N, RATE>,
164-
utils::squeeze_xor_full,
173+
u64_le_utils::squeeze_xor_partial::<N, RATE>,
174+
u64_le_utils::squeeze_xor_full,
165175
);
166176
}
167177

178+
/// Squeeze data by calling custom functions using little-endian byte order.
168179
#[inline(always)]
169180
fn squeeze_inner_u64_le<const N: usize>(
170181
&mut self,
@@ -186,7 +197,7 @@ impl<const RATE: usize> SpongeCursor<RATE> {
186197

187198
if buf.len() < rem_len {
188199
process_partial(state, pos, buf);
189-
self.pos = u8::try_from(pos + buf.len()).expect("the sum is smaller than RATE");
200+
self.set_pos(pos + buf.len());
190201
return;
191202
}
192203

@@ -200,7 +211,7 @@ impl<const RATE: usize> SpongeCursor<RATE> {
200211

201212
for block in &mut blocks {
202213
sponge(state);
203-
let block = block.try_into().expect("block has correct size");
214+
let block = block.try_into().expect("`block` has correct size");
204215
process_full(state, block);
205216
}
206217

@@ -211,7 +222,7 @@ impl<const RATE: usize> SpongeCursor<RATE> {
211222
process_partial(state, 0, tail);
212223
}
213224

214-
self.pos = u8::try_from(tail.len()).expect("tail.len() is smaller than RATE");
225+
self.set_pos(tail.len());
215226
}
216227
}
217228

0 commit comments

Comments
 (0)