diff --git a/number/src/goldilocks.rs b/number/src/goldilocks.rs index 77135733d7..47a5259f1b 100644 --- a/number/src/goldilocks.rs +++ b/number/src/goldilocks.rs @@ -366,9 +366,12 @@ impl FieldElement for GoldilocksField { } fn from_str_radix(s: &str, radix: u32) -> Result { - u64::from_str_radix(s, radix) - .map(Self) - .map_err(|e| e.to_string()) + let n = u64::from_str_radix(s, radix).map_err(|e| e.to_string())?; + if n < Self::ORDER { + Ok(Self::from_canonical_u64(n)) + } else { + Err(format!("Number \"{s}\" too large for Goldilocks field.")) + } } fn checked_from(value: ibig::UBig) -> Option { @@ -625,6 +628,19 @@ mod test { assert!(!(y + 1.into()).is_in_lower_half()); } + #[test] + fn from_str_radix_rejects_modulus() { + // ORDER = 0xffffffff00000001, should be rejected + assert!(GoldilocksField::from_str_radix("ffffffff00000001", 16).is_err()); + } + + #[test] + fn from_str_radix_accepts_order_minus_one() { + // ORDER - 1 = 0xffffffff00000000, should be accepted and equal to the literal value + let v = GoldilocksField::from_str_radix("ffffffff00000000", 16).unwrap(); + assert_eq!(v.to_canonical_u64(), 0xffff_ffff_0000_0000); + } + #[test] #[should_panic] fn integer_div_by_zero() {