Skip to content

Commit

Permalink
test: check field representations in used libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
huitseeker committed Feb 28, 2024
1 parent 442f3b7 commit fd3ae7a
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion src/gadgets/nonnative/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ fn write_be<F: PrimeField, W: Write>(f: &F, mut writer: W) -> io::Result<()> {
/// Convert a field element to a natural number
pub fn f_to_nat<Scalar: PrimeField>(f: &Scalar) -> BigInt {
let mut s = Vec::new();
write_be(f, &mut s).unwrap(); // f.to_repr().write_be(&mut s).unwrap();
write_be(f, &mut s).unwrap();
BigInt::from_bytes_le(Sign::Plus, f.to_repr().as_ref())
}

Expand All @@ -254,3 +254,41 @@ pub fn f_to_nat<Scalar: PrimeField>(f: &Scalar) -> BigInt {
pub fn nat_to_f<Scalar: PrimeField>(n: &BigInt) -> Option<Scalar> {
Scalar::from_str_vartime(&format!("{n}"))
}

#[cfg(test)]
mod tests {
use bitvec::field::BitField as _;
use ff::PrimeFieldBits;
use rand::SeedableRng;
use rand_chacha::ChaCha20Rng;

// the write_be function above assumes Field::to_repr() outputs a representation that's an instance
// of `AsRef<[u8]>` in lower endian. We test that here, as this is not what the I2OSP standard recommends
// and may change in some implementations.
fn test_repr_is_le_with<F: PrimeFieldBits>() {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
for _i in 0..50 {
let f = F::random(&mut rng);
// This is guaranteed to be in LE
let le_bits = f.to_le_bits();
let leftmost_u64 = le_bits[..64].load_le::<u64>();

// This is not
let f_repr = f.to_repr();
let bytes: [u8; 8] = f_repr.as_ref()[..8].try_into().unwrap();
let u64_from_repr = u64::from_le_bytes(bytes);

assert_eq!(leftmost_u64, u64_from_repr);
}
}

#[test]
fn test_repr_is_le() {
test_repr_is_le_with::<pasta_curves::pallas::Scalar>();
test_repr_is_le_with::<pasta_curves::pallas::Base>();
test_repr_is_le_with::<crate::provider::bn256_grumpkin::bn256::Scalar>();
test_repr_is_le_with::<crate::provider::bn256_grumpkin::bn256::Base>();
test_repr_is_le_with::<crate::provider::secp_secq::secp256k1::Scalar>();
test_repr_is_le_with::<crate::provider::secp_secq::secp256k1::Base>();
}
}

0 comments on commit fd3ae7a

Please sign in to comment.