diff --git a/acvm-repo/acir_field/src/generic_ark.rs b/acvm-repo/acir_field/src/generic_ark.rs index e3e66fe7a92..5c70d3cda37 100644 --- a/acvm-repo/acir_field/src/generic_ark.rs +++ b/acvm-repo/acir_field/src/generic_ark.rs @@ -272,7 +272,10 @@ impl FieldElement { } pub fn from_hex(hex_str: &str) -> Option> { let value = hex_str.strip_prefix("0x").unwrap_or(hex_str); - let hex_as_bytes = hex::decode(value).ok()?; + // Values of odd length require an additional "0" prefix + let sanitized_value = + if value.len() % 2 == 0 { value.to_string() } else { format!("0{}", value) }; + let hex_as_bytes = hex::decode(sanitized_value).ok()?; Some(FieldElement::from_be_bytes_reduce(&hex_as_bytes)) } @@ -446,6 +449,25 @@ mod tests { assert_eq!(minus_i_field_element.to_hex(), string); } } + + #[test] + fn deserialize_even_and_odd_length_hex() { + // Test cases of (odd, even) length hex strings + let hex_strings = + vec![("0x0", "0x00"), ("0x1", "0x01"), ("0x002", "0x0002"), ("0x00003", "0x000003")]; + for (i, case) in hex_strings.into_iter().enumerate() { + let i_field_element = + crate::generic_ark::FieldElement::::from(i as i128); + let odd_field_element = + crate::generic_ark::FieldElement::::from_hex(case.0).unwrap(); + let even_field_element = + crate::generic_ark::FieldElement::::from_hex(case.1).unwrap(); + + assert_eq!(i_field_element, odd_field_element); + assert_eq!(odd_field_element, even_field_element); + } + } + #[test] fn max_num_bits_smoke() { let max_num_bits_bn254 = crate::generic_ark::FieldElement::::max_num_bits(); diff --git a/test_programs/execution_success/strings/src/main.nr b/test_programs/execution_success/strings/src/main.nr index c35f59dd8c5..cff229d368a 100644 --- a/test_programs/execution_success/strings/src/main.nr +++ b/test_programs/execution_success/strings/src/main.nr @@ -34,6 +34,10 @@ fn main(message: pub str<11>, y: Field, hex_as_string: str<4>, hex_as_field: Fie assert(hex_as_string == "0x41"); // assert(hex_as_string != 0x41); This will fail with a type mismatch between str[4] and Field assert(hex_as_field == 0x41); + + // Single digit & odd length hex literals are valid + assert(hex_as_field == 0x041); + assert(hex_as_field != 0x1); } #[test]