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

feat(acir_field): Add little-endian byte serialization for FieldElement #7258

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
28 changes: 25 additions & 3 deletions acvm-repo/acir_field/src/field_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,15 +274,19 @@ impl<F: PrimeField> AcirField for FieldElement<F> {
}

fn to_be_bytes(self) -> Vec<u8> {
// to_be_bytes! uses little endian which is why we reverse the output
// TODO: Add a little endian equivalent, so the caller can use whichever one
// TODO they desire
let mut bytes = Vec::new();
self.0.serialize_uncompressed(&mut bytes).unwrap();
bytes.reverse();
bytes
}

/// Converts the field element to a vector of bytes in little-endian order
fn to_le_bytes(self) -> Vec<u8> {
let mut bytes = Vec::new();
self.0.serialize_uncompressed(&mut bytes).unwrap();
bytes
}

/// Converts bytes into a FieldElement and applies a
/// reduction if needed.
fn from_be_bytes_reduce(bytes: &[u8]) -> FieldElement<F> {
Expand Down Expand Up @@ -405,6 +409,24 @@ mod tests {
assert_eq!(max_num_bits_bn254, 254);
}

#[test]
fn test_endianness() {
let field = FieldElement::<ark_bn254::Fr>::from(0x1234_5678_u32);
let le_bytes = field.to_le_bytes();
let be_bytes = field.to_be_bytes();

// Check that the bytes are reversed between BE and LE
let mut reversed_le = le_bytes.clone();
reversed_le.reverse();
assert_eq!(be_bytes, reversed_le);

// Verify we can reconstruct the same field element from either byte order
let from_le = FieldElement::from_be_bytes_reduce(&reversed_le);
let from_be = FieldElement::from_be_bytes_reduce(&be_bytes);
assert_eq!(from_le, from_be);
assert_eq!(from_le, field);
}

proptest! {
// This currently panics due to the fact that we allow inputs which are greater than the field modulus,
// automatically reducing them to fit within the canonical range.
Expand Down