Skip to content

Commit

Permalink
add _vartime suffix; minor cleanups
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Whitehead <[email protected]>
  • Loading branch information
andrewwhitehead committed Aug 28, 2023
1 parent 41459b9 commit 081ccf3
Show file tree
Hide file tree
Showing 3 changed files with 565 additions and 16 deletions.
32 changes: 16 additions & 16 deletions src/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ impl Display for ParseDecimalError {
/// Support for parsing decimal strings
pub trait FromDecimal: Sized {
/// Parse an instance of this data type from a decimal string
fn from_decimal(value: &str) -> Result<Self, ParseDecimalError> {
Self::from_decimal_bytes(value.as_bytes())
fn from_decimal_vartime(value: &str) -> Result<Self, ParseDecimalError> {
Self::from_decimal_bytes_vartime(value.as_bytes())
}

/// Parse an instance of this data type from a string of utf-8 bytes
fn from_decimal_bytes(value: &[u8]) -> Result<Self, ParseDecimalError>;
fn from_decimal_bytes_vartime(value: &[u8]) -> Result<Self, ParseDecimalError>;
}

impl<const LIMBS: usize> FromDecimal for Uint<LIMBS> {
fn from_decimal_bytes(value: &[u8]) -> Result<Self, ParseDecimalError> {
fn from_decimal_bytes_vartime(value: &[u8]) -> Result<Self, ParseDecimalError> {
let mut res = Self::ZERO;
ParseDecimal::parse_into(value, res.as_limbs_mut())?;
Ok(res)
Expand All @@ -65,7 +65,7 @@ impl<const LIMBS: usize> FromDecimal for Uint<LIMBS> {

#[cfg(feature = "alloc")]
impl FromDecimal for BoxedUint {
fn from_decimal_bytes(value: &[u8]) -> Result<Self, ParseDecimalError> {
fn from_decimal_bytes_vartime(value: &[u8]) -> Result<Self, ParseDecimalError> {
let parse = ParseDecimal::new(value)?;
let bits = parse.len() * Limb::BITS;
if bits > 0 {
Expand All @@ -81,13 +81,13 @@ impl FromDecimal for BoxedUint {
struct ParseDecimal<'p>(RChunks<'p, u8>);

impl<'p> ParseDecimal<'p> {
pub(crate) fn new(dec: &'p [u8]) -> Result<Self, ParseDecimalError> {
fn new(dec: &'p [u8]) -> Result<Self, ParseDecimalError> {
if dec.is_empty() {
return Err(ParseDecimalError::InvalidInput);
}
let mut start = dec.len();
for (idx, c) in dec.iter().enumerate().rev() {
if !matches!(c, b'0'..=b'9') {
if !c.is_ascii_digit() {
return Err(ParseDecimalError::InvalidInput);
}
if *c != b'0' {
Expand All @@ -97,11 +97,11 @@ impl<'p> ParseDecimal<'p> {
Ok(Self(dec[start..].rchunks(LIMB_LOG10)))
}

pub(crate) fn parse_into(dec: &'p [u8], limbs: &mut [Limb]) -> Result<(), ParseDecimalError> {
fn parse_into(dec: &'p [u8], limbs: &mut [Limb]) -> Result<(), ParseDecimalError> {
Self::new(dec)?.read_into(limbs)
}

pub(crate) fn read_into(self, limbs: &mut [Limb]) -> Result<(), ParseDecimalError> {
fn read_into(self, limbs: &mut [Limb]) -> Result<(), ParseDecimalError> {
for l in limbs.iter_mut() {
*l = Limb::ZERO;
}
Expand Down Expand Up @@ -154,7 +154,7 @@ impl<T: FromDecimal> Visitor<'_> for DecimalUintVisitor<T> {
where
E: Error,
{
T::from_decimal(dec).map_err(|_| E::invalid_value(Unexpected::Str(dec), &self))
T::from_decimal_vartime(dec).map_err(|_| E::invalid_value(Unexpected::Str(dec), &self))
}
}

Expand Down Expand Up @@ -410,19 +410,19 @@ mod tests {

#[test]
fn decode_empty() {
let res = crate::U64::from_decimal("");
let res = crate::U64::from_decimal_vartime("");
assert_eq!(res, Err(ParseDecimalError::InvalidInput));
}

#[test]
fn decode_invalid() {
let res = crate::U64::from_decimal("000notanumber");
let res = crate::U64::from_decimal_vartime("000notanumber");
assert_eq!(res, Err(ParseDecimalError::InvalidInput));
}

#[test]
fn decode_outside_range() {
let res = crate::U64::from_decimal("18446744073709551616"); // 2^64
let res = crate::U64::from_decimal_vartime("18446744073709551616"); // 2^64
assert_eq!(res, Err(ParseDecimalError::OutsideRange));
}

Expand All @@ -432,7 +432,7 @@ mod tests {
{
let mut buf = [0u8; 2560];
let len = write_decimal_bytes(uint, &mut buf);
let des = T::from_decimal_bytes(&buf[..len]).expect("Error deserializing");
let des = T::from_decimal_bytes_vartime(&buf[..len]).expect("Error deserializing");
assert_eq!(&des, uint);
}

Expand Down Expand Up @@ -464,7 +464,7 @@ mod tests {
fn serde_uint() {
type U = crate::U128;
let input = "123456789012345678901234567890";
let uint = U::from_decimal(input).unwrap();
let uint = U::from_decimal_vartime(input).unwrap();
let enc = bincode::serialize(&AsDecimal(&uint)).unwrap();
let dec: String = bincode::deserialize(&enc).unwrap();
assert_eq!(dec, input);
Expand All @@ -476,7 +476,7 @@ mod tests {
#[test]
fn serde_boxed() {
let input = "123456789012345678901234567890";
let uint = BoxedUint::from_decimal(input).unwrap();
let uint = BoxedUint::from_decimal_vartime(input).unwrap();
let enc = bincode::serialize(&AsDecimal(&uint)).unwrap();
let dec: String = bincode::deserialize(&enc).unwrap();
assert_eq!(dec, input);
Expand Down
Loading

0 comments on commit 081ccf3

Please sign in to comment.