Skip to content

Commit 6757267

Browse files
committed
limbs: Create an Iterator-based interface for big endian limbs.
We should probably, eventually, remove the old/current `parse_big_endian_and_pad_consttime` in favor of using this new interface in conjunction with upcoming interfaces.
1 parent dfacb77 commit 6757267

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

src/limb.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use core::{iter, num::NonZeroUsize};
2929

3030
#[cfg(feature = "alloc")]
3131
use core::num::Wrapping;
32+
use core::ops::RangeInclusive;
3233

3334
// XXX: Not correct for x32 ABIs.
3435
pub type Limb = bb::Word;
@@ -167,26 +168,30 @@ pub fn parse_big_endian_and_pad_consttime(
167168
input: untrusted::Input,
168169
result: &mut [Limb],
169170
) -> Result<(), LenMismatchError> {
170-
if input.is_empty() {
171-
return Err(LenMismatchError::new(input.len()));
172-
}
173-
let input_limbs = input.as_slice_less_safe().rchunks(LIMB_BYTES).map(|chunk| {
174-
let mut padded = [0; LIMB_BYTES];
175-
sliceutil::overwrite_at_start(&mut padded[(LIMB_BYTES - chunk.len())..], chunk);
176-
Limb::from_be_bytes(padded)
177-
});
178-
if input_limbs.len() > result.len() {
179-
return Err(LenMismatchError::new(input.len()));
180-
}
181-
171+
let input_limbs = limbs_from_big_endian(input, 1..=result.len())?;
182172
result
183173
.iter_mut()
184174
.zip(input_limbs.chain(iter::repeat(0)))
185175
.for_each(|(r, i)| *r = i);
186-
187176
Ok(())
188177
}
189178

179+
fn limbs_from_big_endian<'a>(
180+
input: untrusted::Input<'a>,
181+
len_bounds: RangeInclusive<usize>,
182+
) -> Result<impl ExactSizeIterator<Item = Limb> + 'a, LenMismatchError> {
183+
let r = input.as_slice_less_safe().rchunks(LIMB_BYTES).map(|chunk| {
184+
let mut padded = [0; LIMB_BYTES];
185+
sliceutil::overwrite_at_start(&mut padded[(LIMB_BYTES - chunk.len())..], chunk);
186+
Limb::from_be_bytes(padded)
187+
});
188+
let len = r.len();
189+
if !len_bounds.contains(&len) {
190+
return Err(LenMismatchError::new(len));
191+
}
192+
Ok(r)
193+
}
194+
190195
pub fn big_endian_from_limbs(limbs: &[Limb], out: &mut [u8]) {
191196
let be_bytes = unstripped_be_bytes(limbs);
192197
assert_eq!(out.len(), be_bytes.len());

0 commit comments

Comments
 (0)