Skip to content

Commit

Permalink
Add error to UnsInt from_hex when hex too big (#880)
Browse files Browse the repository at this point in the history
* Add error to UnsInt from_hex when hex too big

* Format and add function docs

* Format and add function docs

* chore: add same docs in from_hex function in field/element.rs

* Update math/src/field/element.rs

* Update math/src/unsigned_integer/element.rs

* Add tests from hex in montgomery backend

* Lint

---------

Co-authored-by: Mariano Nicolini <[email protected]>
  • Loading branch information
MauroToscano and entropidelic authored Jul 17, 2024
1 parent dfe4f0e commit 712d894
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
1 change: 1 addition & 0 deletions math/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub enum ByteConversionError {
pub enum CreationError {
InvalidHexString,
InvalidDecString,
HexStringIsTooBig,
EmptyString,
}

Expand Down
10 changes: 5 additions & 5 deletions math/src/field/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,14 +509,14 @@ impl<F: IsPrimeField> FieldElement<F> {
/// Creates a `FieldElement` from a hexstring. It can contain `0x` or not.
/// Returns an `CreationError::InvalidHexString`if the value is not a hexstring.
/// Returns a `CreationError::EmptyString` if the input string is empty.
/// Returns a `CreationError::HexStringIsTooBig` if the the input hex string is bigger
/// than the maximum amount of characters for this element.
pub fn from_hex(hex_string: &str) -> Result<Self, CreationError> {
if hex_string.is_empty() {
return Err(CreationError::EmptyString)?;
return Err(CreationError::EmptyString);
}

Ok(Self {
value: F::from_hex(hex_string)?,
})
let value = F::from_hex(hex_string)?;
Ok(Self { value })
}

#[cfg(feature = "std")]
Expand Down
16 changes: 16 additions & 0 deletions math/src/field/fields/montgomery_backed_prime_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,22 @@ mod tests_u256_prime_fields {
assert_eq!(a, b);
}

#[test]
fn creating_a_field_element_from_hex_too_big_errors() {
let a = U256FP1Element::from_hex(&"f".repeat(65));
assert!(a.is_err());
assert_eq!(
a.unwrap_err(),
crate::errors::CreationError::HexStringIsTooBig
)
}

#[test]
fn creating_a_field_element_from_hex_works_on_the_size_limit() {
let a = U256FP1Element::from_hex(&"f".repeat(64));
assert!(a.is_ok());
}

#[test]
fn creating_a_field_element_from_hex_works_2() {
let a = U256F29Element::from_hex_unchecked("aa");
Expand Down
27 changes: 26 additions & 1 deletion math/src/unsigned_integer/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ impl<const NUM_LIMBS: usize> UnsignedInteger<NUM_LIMBS> {
/// Creates an `UnsignedInteger` from a hexstring. It can contain `0x` or not.
/// Returns an `CreationError::InvalidHexString`if the value is not a hexstring.
/// Returns a `CreationError::EmptyString` if the input string is empty.
/// Returns a `CreationError::HexStringIsTooBig` if the the input hex string is bigger
/// than the maximum amount of characters for this element.
pub fn from_hex(value: &str) -> Result<Self, CreationError> {
let mut string = value;
let mut char_iterator = value.chars();
Expand All @@ -440,6 +442,14 @@ impl<const NUM_LIMBS: usize> UnsignedInteger<NUM_LIMBS> {
if !Self::is_hex_string(string) {
return Err(CreationError::InvalidHexString);
}

// Limbs are of 64 bits - 8 bytes
// We have 16 nibbles per bytes
let max_amount_of_hex_chars = NUM_LIMBS * 16;
if string.len() > max_amount_of_hex_chars {
return Err(CreationError::HexStringIsTooBig);
}

Ok(Self::from_hex_unchecked(string))
}

Expand Down Expand Up @@ -1001,7 +1011,7 @@ impl<const NUM_LIMBS: usize> Arbitrary for UnsignedInteger<NUM_LIMBS> {
#[cfg(test)]
mod tests_u384 {
use crate::traits::ByteConversion;
use crate::unsigned_integer::element::{UnsignedInteger, U384};
use crate::unsigned_integer::element::{UnsignedInteger, U256, U384};
#[cfg(feature = "proptest")]
use proptest::prelude::*;
#[cfg(feature = "proptest")]
Expand Down Expand Up @@ -1246,6 +1256,21 @@ mod tests_u384 {
);
}

#[test]
fn from_hex_with_overflowing_hexstring_should_error() {
let u256_from_big_string = U256::from_hex(&"f".repeat(65));
assert!(u256_from_big_string.is_err());
assert!(
u256_from_big_string
== Err(crate::unsigned_integer::element::CreationError::HexStringIsTooBig)
);
}

#[test]
fn from_hex_with_non_overflowing_hexstring_should_work() {
assert_eq!(U256::from_hex(&"0".repeat(64)).unwrap().limbs, [0, 0, 0, 0])
}

#[test]
fn construct_new_integer_from_dec_1() {
let a = U384::from_dec_str("1").unwrap();
Expand Down

0 comments on commit 712d894

Please sign in to comment.