Skip to content

Commit

Permalink
fix: deserialize odd length hex literals (#3747)
Browse files Browse the repository at this point in the history
# Description

single digit (or generally, odd length) hex literals such as `0x4`
result in an `InvalidIntegerLiteral` error

## Problem\*

Resolves #3235

## Summary\*

i just prefixed all odd-length hex literals with another `0`, happy to
change course if there's a better/more efficient way here (i'm kinda
rust noob)

## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
sambarnes committed Dec 9, 2023
1 parent c9c72ae commit 4000fb2
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
24 changes: 23 additions & 1 deletion acvm-repo/acir_field/src/generic_ark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,10 @@ impl<F: PrimeField> FieldElement<F> {
}
pub fn from_hex(hex_str: &str) -> Option<FieldElement<F>> {
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))
}

Expand Down Expand Up @@ -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::<ark_bn254::Fr>::from(i as i128);
let odd_field_element =
crate::generic_ark::FieldElement::<ark_bn254::Fr>::from_hex(case.0).unwrap();
let even_field_element =
crate::generic_ark::FieldElement::<ark_bn254::Fr>::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::<ark_bn254::Fr>::max_num_bits();
Expand Down
4 changes: 4 additions & 0 deletions test_programs/execution_success/strings/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit 4000fb2

Please sign in to comment.