diff --git a/ff/ff_derive/src/lib.rs b/ff/ff_derive/src/lib.rs index ad25c5b..9fcf5a7 100644 --- a/ff/ff_derive/src/lib.rs +++ b/ff/ff_derive/src/lib.rs @@ -38,6 +38,23 @@ impl ReprEndianness { } } + fn modulus_repr(&self, modulus: &BigUint, bytes: usize) -> Vec { + match self { + ReprEndianness::Big => { + let buf = modulus.to_bytes_be(); + iter::repeat(0) + .take(bytes - buf.len()) + .chain(buf.into_iter()) + .collect() + } + ReprEndianness::Little => { + let mut buf = modulus.to_bytes_le(); + buf.extend(iter::repeat(0).take(bytes - buf.len())); + buf + } + } + } + fn from_repr(&self, name: &syn::Ident, limbs: usize) -> proc_macro2::TokenStream { let read_repr = match self { ReprEndianness::Big => quote! { @@ -159,8 +176,14 @@ pub fn prime_field(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let mut gen = proc_macro2::TokenStream::new(); - let (constants_impl, sqrt_impl) = - prime_field_constants_and_sqrt(&ast.ident, &repr_ident, &modulus, limbs, generator); + let (constants_impl, sqrt_impl) = prime_field_constants_and_sqrt( + &ast.ident, + &repr_ident, + &modulus, + &endianness, + limbs, + generator, + ); gen.extend(constants_impl); gen.extend(prime_field_repr_impl(&repr_ident, &endianness, limbs * 8)); @@ -466,6 +489,7 @@ fn prime_field_constants_and_sqrt( name: &syn::Ident, repr: &syn::Ident, modulus: &BigUint, + endianness: &ReprEndianness, limbs: usize, generator: BigUint, ) -> (proc_macro2::TokenStream, proc_macro2::TokenStream) { @@ -576,11 +600,7 @@ fn prime_field_constants_and_sqrt( let r2 = biguint_to_u64_vec((&r * &r) % modulus, limbs); let r = biguint_to_u64_vec(r, limbs); - let modulus_repr = { - let mut buf = modulus.to_bytes_le(); - buf.extend(iter::repeat(0).take((limbs * 8) - buf.len())); - buf - }; + let modulus_repr = endianness.modulus_repr(modulus, limbs * 8); let modulus = biguint_to_real_u64_vec(modulus.clone(), limbs); // Compute -m^-1 mod 2**64 by exponentiating by totient(2**64) - 1 diff --git a/pairing/src/bls12_381/fq.rs b/pairing/src/bls12_381/fq.rs index 4daf4bd..a840467 100644 --- a/pairing/src/bls12_381/fq.rs +++ b/pairing/src/bls12_381/fq.rs @@ -1644,7 +1644,8 @@ fn test_fq_pow() { use byteorder::ByteOrder; let mut char_limbs = [0; 6]; - byteorder::LittleEndian::read_u64_into(Fq::char().as_ref(), &mut char_limbs); + byteorder::BigEndian::read_u64_into(Fq::char().as_ref(), &mut char_limbs); + char_limbs.reverse(); for _ in 0..1000 { // Exponentiating by the modulus should have no effect in a prime field. diff --git a/pairing/src/bls12_381/tests/mod.rs b/pairing/src/bls12_381/tests/mod.rs index 6d9252e..6d8cc92 100644 --- a/pairing/src/bls12_381/tests/mod.rs +++ b/pairing/src/bls12_381/tests/mod.rs @@ -147,13 +147,11 @@ fn test_g1_uncompressed_invalid_vectors() { } } - // PrimeField::char() returns the modulus in its little-endian byte representation, - // but Fq field elements use big-endian encoding, so flip the endianness. - let m: Vec<_> = Fq::char().as_ref().iter().cloned().rev().collect(); + let m = Fq::char(); { let mut o = o; - o.as_mut()[..48].copy_from_slice(&m[..]); + o.as_mut()[..48].copy_from_slice(m.as_ref()); if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() { assert_eq!(coordinate, "x coordinate"); @@ -164,7 +162,7 @@ fn test_g1_uncompressed_invalid_vectors() { { let mut o = o; - o.as_mut()[48..].copy_from_slice(&m[..]); + o.as_mut()[48..].copy_from_slice(m.as_ref()); if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() { assert_eq!(coordinate, "y coordinate"); @@ -265,13 +263,11 @@ fn test_g2_uncompressed_invalid_vectors() { } } - // PrimeField::char() returns the modulus in its little-endian byte representation, - // but Fq field elements use big-endian encoding, so flip the endianness. - let m: Vec<_> = Fq::char().as_ref().iter().cloned().rev().collect(); + let m = Fq::char(); { let mut o = o; - o.as_mut()[..48].copy_from_slice(&m[..]); + o.as_mut()[..48].copy_from_slice(m.as_ref()); if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() { assert_eq!(coordinate, "x coordinate (c1)"); @@ -282,7 +278,7 @@ fn test_g2_uncompressed_invalid_vectors() { { let mut o = o; - o.as_mut()[48..96].copy_from_slice(&m[..]); + o.as_mut()[48..96].copy_from_slice(m.as_ref()); if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() { assert_eq!(coordinate, "x coordinate (c0)"); @@ -293,7 +289,7 @@ fn test_g2_uncompressed_invalid_vectors() { { let mut o = o; - o.as_mut()[96..144].copy_from_slice(&m[..]); + o.as_mut()[96..144].copy_from_slice(m.as_ref()); if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() { assert_eq!(coordinate, "y coordinate (c1)"); @@ -304,7 +300,7 @@ fn test_g2_uncompressed_invalid_vectors() { { let mut o = o; - o.as_mut()[144..].copy_from_slice(&m[..]); + o.as_mut()[144..].copy_from_slice(m.as_ref()); if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() { assert_eq!(coordinate, "y coordinate (c0)"); @@ -411,13 +407,11 @@ fn test_g1_compressed_invalid_vectors() { } } - // PrimeField::char() returns the modulus in its little-endian byte representation, - // but Fq field elements use big-endian encoding, so flip the endianness. - let m: Vec<_> = Fq::char().as_ref().iter().cloned().rev().collect(); + let m = Fq::char(); { let mut o = o; - o.as_mut()[..48].copy_from_slice(&m[..]); + o.as_mut()[..48].copy_from_slice(m.as_ref()); o.as_mut()[0] |= 0b1000_0000; if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() { @@ -527,13 +521,11 @@ fn test_g2_compressed_invalid_vectors() { } } - // PrimeField::char() returns the modulus in its little-endian byte representation, - // but Fq field elements use big-endian encoding, so flip the endianness. - let m: Vec<_> = Fq::char().as_ref().iter().cloned().rev().collect(); + let m = Fq::char(); { let mut o = o; - o.as_mut()[..48].copy_from_slice(&m[..]); + o.as_mut()[..48].copy_from_slice(m.as_ref()); o.as_mut()[0] |= 0b1000_0000; if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() { @@ -545,7 +537,7 @@ fn test_g2_compressed_invalid_vectors() { { let mut o = o; - o.as_mut()[48..96].copy_from_slice(&m[..]); + o.as_mut()[48..96].copy_from_slice(m.as_ref()); o.as_mut()[0] |= 0b1000_0000; if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {