Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: deserialize odd length hex literals #3747

Merged
merged 2 commits into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -19,7 +19,7 @@
// Check if the negative version is smaller to represent
//
let minus_number = BigUint::from_bytes_be(&(self.neg()).to_be_bytes());
let (smaller_repr, is_negative) =

Check warning on line 22 in acvm-repo/acir_field/src/generic_ark.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (repr)
if minus_number.to_string().len() < number.to_string().len() {
(minus_number, true)
} else {
Expand All @@ -30,13 +30,13 @@
}

// Number of bits needed to represent the smaller representation
let num_bits = smaller_repr.bits();

Check warning on line 33 in acvm-repo/acir_field/src/generic_ark.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (repr)

// Check if the number represents a power of 2
if smaller_repr.count_ones() == 1 {

Check warning on line 36 in acvm-repo/acir_field/src/generic_ark.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (repr)
let mut bit_index = 0;
for i in 0..num_bits {
if smaller_repr.bit(i) {

Check warning on line 39 in acvm-repo/acir_field/src/generic_ark.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (repr)
bit_index = i;
break;
}
Expand All @@ -59,7 +59,7 @@
let mul_sign = "×";
for power in [64, 32, 16, 8, 4] {
let power_of_two = BigUint::from(2_u128).pow(power);
if &smaller_repr % &power_of_two == BigUint::zero() {

Check warning on line 62 in acvm-repo/acir_field/src/generic_ark.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (repr)
return write!(
f,
"2{}{}{}",
Expand Down Expand Up @@ -272,7 +272,10 @@
}
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))
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
}

Expand Down Expand Up @@ -446,6 +449,25 @@
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);
}
}
kevaundray marked this conversation as resolved.
Show resolved Hide resolved

#[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
Loading