Skip to content

Commit 74c7253

Browse files
authored
Add modulus range check when creating FieldElement from hex (#1020)
* Add modulus range check when creating Felt from hex * Adapt from_hex test case that uses str with 64 ones
1 parent 160bb5c commit 74c7253

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

crates/math/src/errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub enum CreationError {
1313
InvalidHexString,
1414
InvalidDecString,
1515
HexStringIsTooBig,
16+
RepresentativeOutOfRange,
1617
EmptyString,
1718
}
1819

crates/math/src/field/element.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,8 @@ impl<F: IsPrimeField> FieldElement<F> {
608608
/// Returns a `CreationError::EmptyString` if the input string is empty.
609609
/// Returns a `CreationError::HexStringIsTooBig` if the the input hex string is bigger than the
610610
/// maximum amount of characters for this element.
611+
/// Returns a `CreationError::RepresentativeOutOfRange` if the representative of the value is
612+
/// out of the range [0, p-1] where p is the modulus.
611613
pub fn from_hex(hex_string: &str) -> Result<Self, CreationError> {
612614
if hex_string.is_empty() {
613615
return Err(CreationError::EmptyString);
@@ -980,6 +982,14 @@ mod tests {
980982
assert!(FE::from_hex("").is_err());
981983
}
982984

985+
#[test]
986+
fn construct_new_field_element_from_value_bigger_than_modulus() {
987+
type F = Stark252PrimeField;
988+
type FE = FieldElement<F>;
989+
// A number that consists of 255 1s is bigger than the `Stark252PrimeField` modulus
990+
assert!(FE::from_hex(&format!("0x{}", "f".repeat(65))).is_err());
991+
}
992+
983993
prop_compose! {
984994
fn field_element()(num in any::<u64>().prop_filter("Avoid null coefficients", |x| x != &0)) -> FieldElement::<Stark252PrimeField> {
985995
FieldElement::<Stark252PrimeField>::from(num)

crates/math/src/field/fields/montgomery_backed_prime_fields.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::errors::CreationError;
12
use crate::field::element::FieldElement;
23
use crate::field::errors::FieldError;
34
use crate::field::traits::{HasDefaultTranscript, IsPrimeField};
@@ -305,8 +306,12 @@ where
305306
evaluated_bit + 1
306307
}
307308

308-
fn from_hex(hex_string: &str) -> Result<Self::BaseType, crate::errors::CreationError> {
309+
fn from_hex(hex_string: &str) -> Result<Self::BaseType, CreationError> {
309310
let integer = Self::BaseType::from_hex(hex_string)?;
311+
if integer > M::MODULUS {
312+
return Err(CreationError::RepresentativeOutOfRange);
313+
}
314+
310315
Ok(MontgomeryAlgorithms::cios(
311316
&integer,
312317
&MontgomeryBackendPrimeField::<M, NUM_LIMBS>::R2,
@@ -1294,9 +1299,14 @@ mod tests_u256_prime_fields {
12941299
}
12951300

12961301
#[test]
1297-
fn creating_a_field_element_from_hex_works_on_the_size_limit() {
1302+
fn creating_a_field_element_from_hex_bigger_than_modulus_errors() {
1303+
// A number that consists of 255 1s is bigger than the `U256FP1` modulus
12981304
let a = U256FP1Element::from_hex(&"f".repeat(64));
1299-
assert!(a.is_ok());
1305+
assert!(a.is_err());
1306+
assert_eq!(
1307+
a.unwrap_err(),
1308+
crate::errors::CreationError::RepresentativeOutOfRange
1309+
)
13001310
}
13011311

13021312
#[test]

0 commit comments

Comments
 (0)