Skip to content

Commit

Permalink
internals: Replace use of as_rchunks polyfill.
Browse files Browse the repository at this point in the history
Eliminate some uneeded `unsafe` code.
  • Loading branch information
briansmith committed Jan 25, 2025
1 parent c329c65 commit a4567be
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 45 deletions.
46 changes: 16 additions & 30 deletions src/limb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
use crate::{
c, constant_time,
error::{self, LenMismatchError},
polyfill::{slice, usize_from_u32, ArrayFlatMap},
polyfill::{sliceutil, usize_from_u32, ArrayFlatMap},
};
use core::num::NonZeroUsize;
use core::{iter, num::NonZeroUsize};

#[cfg(any(test, feature = "alloc"))]
use crate::bits;
Expand Down Expand Up @@ -201,37 +201,23 @@ pub fn parse_big_endian_and_pad_consttime(
input: untrusted::Input,
result: &mut [Limb],
) -> Result<(), error::Unspecified> {
let (partial, whole) = slice::as_rchunks(input.as_slice_less_safe());

let mut partial_padded: [u8; LIMB_BYTES];
let partial_padded = match (partial, whole) {
(partial @ [_, ..], _) => {
partial_padded = [0; LIMB_BYTES];
partial_padded[(LIMB_BYTES - partial.len())..].copy_from_slice(partial);
Some(partial_padded)
}
([], [_, ..]) => None,
([], []) => {
// Empty input is not allowed.
return Err(error::Unspecified);
}
};

let mut result = result.iter_mut();

for input in whole.iter().rev().chain(partial_padded.iter()) {
// The result isn't allowed to be shorter than the input.
match result.next() {
Some(r) => *r = Limb::from_be_bytes(*input),
None => return Err(error::Unspecified),
}
if input.is_empty() {
return Err(error::Unspecified);
}

// Pad the result.
for r in result {
*r = 0;
let input_limbs = input.as_slice_less_safe().rchunks(LIMB_BYTES).map(|chunk| {
let mut padded = [0; LIMB_BYTES];
sliceutil::overwrite_at_start(&mut padded[(LIMB_BYTES - chunk.len())..], chunk);
Limb::from_be_bytes(padded)
});
if input_limbs.len() > result.len() {
return Err(error::Unspecified);
}

result
.iter_mut()
.zip(input_limbs.chain(iter::repeat(0)))
.for_each(|(r, i)| *r = i);

Ok(())
}

Expand Down
15 changes: 0 additions & 15 deletions src/polyfill/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,6 @@ pub fn as_chunks_mut<T, const N: usize>(slice: &mut [T]) -> (&mut [[T; N]], &mut
(chunked, remainder)
}

// TODO(MSRV feature(slice_as_chunks)): Use `slice::as_rchunks` instead.
// This is adapted from the above implementation of `as_chunks`.
#[inline(always)]
pub fn as_rchunks<T, const N: usize>(slice: &[T]) -> (&[T], &[[T; N]]) {
assert!(N != 0, "chunk size must be non-zero");
let len = slice.len() / N;
let (remainder, multiple_of_n) = slice.split_at(slice.len() - (len * N));
// SAFETY: We already panicked for zero, and ensured by construction
// that the length of the subslice is a multiple of N.
// SAFETY: We cast a slice of `new_len * N` elements into
// a slice of `new_len` many `N` elements chunks.
let chunked = unsafe { core::slice::from_raw_parts(multiple_of_n.as_ptr().cast(), len) };
(remainder, chunked)
}

// TODO(MSRV feature(slice_flatten)): Use `slice::flatten` instead.
// This is derived from the libcore implementation, using only stable APIs.
pub fn flatten<T, const N: usize>(slice: &[[T; N]]) -> &[T] {
Expand Down

0 comments on commit a4567be

Please sign in to comment.