Skip to content

Commit

Permalink
improve: add some macros to generate big testing suite of fields (#131)
Browse files Browse the repository at this point in the history
* feat: add the basic "field_testing_suite" macro

* feat: add the macro branches for common field tests

* fix: add more tests to some fields

* chore: remove useless clippy rule

* feat: add the macro of testing "bits"(PrimeFieldBits)

* feat: add the macro branch for "serialization_check" testing

* feat: add the macro branch for testing constants

* feat: add the macro branch to test the sqrt

* feat: add the macro branch to test the "ZETA" constant

* chore: rename the test into "field_arithmetic"

* feat: add the macro branch to test the "frobenius"

* feat: add the macro for some extension field(Fp2, Fq2) tests

* feat: add the macro for some extension field(Fp6, Fq6) tests

* feat: add the macro for some extension field(Fp12, Fq12) tests

* feat: add the macro for testing the "from_uniform_bytes"

* chore: remove the unnecessary ark_std timer

* chore: fmt

* refactor: roll back some macros to functions

* refactor: move the tests into "test" module

* chore: add comment about frobenius testing param

* chore: get rid of leftover

* fix: reduce the testing counts for extension field in "test_field"

* chore: add the comment for reducing number of tests in "test_field"
  • Loading branch information
duguorong009 authored Feb 5, 2024
1 parent d56a0d9 commit f96f7f9
Show file tree
Hide file tree
Showing 17 changed files with 1,141 additions and 1,924 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ bincode = "1.3.3"
serde_json = "1.0.105"
hex = "0.4"
rand_chacha = "0.3.1"
impls = "1"

# Added to make sure we are able to build the lib in the CI.
# Notice this will never be loaded for someone using this lib as dep.
Expand Down
155 changes: 73 additions & 82 deletions src/bn256/fq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,88 +285,79 @@ impl WithSmallOrderMulGroup<3> for Fq {
#[cfg(test)]
mod test {
use super::*;
use crate::ff_ext::Legendre;
use ff::Field;
use rand_core::OsRng;

#[test]
fn test_sqrt_fq() {
let v = (Fq::TWO_INV).square().sqrt().unwrap();
assert!(v == Fq::TWO_INV || (-v) == Fq::TWO_INV);

for _ in 0..10000 {
let a = Fq::random(OsRng);
let mut b = a;
b = b.square();
assert_eq!(b.legendre(), 1);

let b = b.sqrt().unwrap();
let mut negb = b;
negb = negb.neg();

assert!(a == b || a == negb);
}

let mut c = Fq::one();
for _ in 0..10000 {
let mut b = c;
b = b.square();
assert_eq!(b.legendre(), 1);

b = b.sqrt().unwrap();

if b != c {
b = b.neg();
}

assert_eq!(b, c);

c += &Fq::one();
}
}

#[test]
fn test_from_u512() {
assert_eq!(
crate::field_testing_suite!(Fq, "field_arithmetic");
crate::field_testing_suite!(Fq, "conversion");
crate::field_testing_suite!(Fq, "serialization");
crate::field_testing_suite!(Fq, "quadratic_residue");
crate::field_testing_suite!(Fq, "bits");
crate::field_testing_suite!(Fq, "serialization_check");
crate::field_testing_suite!(Fq, "constants", MODULUS_STR);
crate::field_testing_suite!(Fq, "sqrt");
crate::field_testing_suite!(Fq, "zeta");
crate::field_testing_suite!(
Fq,
"from_uniform_bytes",
[
Fq::from_raw([
0x1f8905a172affa8a,
0xde45ad177dcf3306,
0xaaa7987907d73ae2,
0x24d349431d468e30,
0xd1f334151139642a,
0xb0f28bcaa90fdb88,
0x9a13255d88eca613,
0x02afef300dd32d9a,
]),
Fq::from_u512([
0xaaaaaaaaaaaaaaaa,
0xaaaaaaaaaaaaaaaa,
0xaaaaaaaaaaaaaaaa,
0xaaaaaaaaaaaaaaaa,
0xaaaaaaaaaaaaaaaa,
0xaaaaaaaaaaaaaaaa,
0xaaaaaaaaaaaaaaaa,
0xaaaaaaaaaaaaaaaa
])
);
}

#[test]
fn test_field() {
crate::tests::field::random_field_tests::<Fq>("fq".to_string());
}

#[test]
fn test_conversion() {
crate::tests::field::random_conversion_tests::<Fq>("fq".to_string());
}

#[test]
#[cfg(feature = "bits")]
fn test_bits() {
crate::tests::field::random_bits_tests::<Fq>("fq".to_string());
}

#[test]
fn test_serialization() {
crate::tests::field::random_serialization_test::<Fq>("fq".to_string());
#[cfg(feature = "derive_serde")]
crate::tests::field::random_serde_test::<Fq>("fq".to_string());
}
Fq::from_raw([
0x03cd906680808fbe,
0xc28902db5aef5254,
0x3dbdb406ae292ddf,
0x276ec249e6b9e195
]),
Fq::from_raw([
0xb0e07ded189e91f7,
0x9e3b0caae2b98899,
0x49e511f19341fdcf,
0x1ea71260f64b72da
]),
Fq::from_raw([
0x61132be14bb978d4,
0xe27e09a20808067b,
0x3842cc8fd1d8406f,
0x13163c8a13fd550b
]),
Fq::from_raw([
0x04a6495a33d39ac5,
0xc918e75bb383fae0,
0x80068784d577b035,
0x1dd962b86e44e1be
]),
Fq::from_raw([
0x107ffeecf4cb3348,
0x53a0adb5491a4944,
0x50028f636ffcb780,
0x0af7f3aa38015c1d
]),
Fq::from_raw([
0x22513787342eba07,
0x4fac22ed88770319,
0x0b7c31082cc92b13,
0x250e22a8cac6e790
]),
Fq::from_raw([
0x5954fd7dda014940,
0x9df859b2124e66fa,
0xaab48d94eadd9d14,
0x2a9a75013e3da632
]),
Fq::from_raw([
0xedd59c88fee718de,
0x2b034dcfe6de3844,
0x76b0e2e360488694,
0x068998ef20d62df1
]),
Fq::from_raw([
0xac161667911634a4,
0x296c2f453152552f,
0x2653625dfaa1cf74,
0x171abf201a2587d7
]),
]
);
}
133 changes: 19 additions & 114 deletions src/bn256/fq12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,118 +490,23 @@ pub const FROBENIUS_COEFF_FQ12_C1: [Fq2; 12] = [
];

#[cfg(test)]
use rand::SeedableRng;
#[cfg(test)]
use rand_xorshift::XorShiftRng;

#[test]
fn test_fq12_mul_by_014() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
]);

for _ in 0..1000 {
let c0 = Fq2::random(&mut rng);
let c1 = Fq2::random(&mut rng);
let c5 = Fq2::random(&mut rng);
let mut a = Fq12::random(&mut rng);
let mut b = a;

a.mul_by_014(&c0, &c1, &c5);
b.mul_assign(&Fq12 {
c0: Fq6 {
c0,
c1,
c2: Fq2::zero(),
},
c1: Fq6 {
c0: Fq2::zero(),
c1: c5,
c2: Fq2::zero(),
},
});

assert_eq!(a, b);
}
}

#[test]
fn test_fq12_mul_by_034() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
]);

for _ in 0..1000 {
let c0 = Fq2::random(&mut rng);
let c3 = Fq2::random(&mut rng);
let c4 = Fq2::random(&mut rng);
let mut a = Fq12::random(&mut rng);
let mut b = a;

a.mul_by_034(&c0, &c3, &c4);
b.mul_assign(&Fq12 {
c0: Fq6 {
c0,
c1: Fq2::zero(),
c2: Fq2::zero(),
},
c1: Fq6 {
c0: c3,
c1: c4,
c2: Fq2::zero(),
},
});

assert_eq!(a, b);
}
}

#[test]
fn test_squaring() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
]);

for _ in 0..1000 {
let mut a = Fq12::random(&mut rng);
let mut b = a;
b.mul_assign(&a);
a.square_assign();
assert_eq!(a, b);
}
}

#[test]
fn test_frobenius() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
]);

for _ in 0..100 {
for i in 0..14 {
let mut a = Fq12::random(&mut rng);
let mut b = a;

for _ in 0..i {
a = a.pow_vartime([
0x3c208c16d87cfd47,
0x97816a916871ca8d,
0xb85045b68181585d,
0x30644e72e131a029,
]);
}
b.frobenius_map(i);

assert_eq!(a, b);
}
}
}

#[test]
fn test_field() {
crate::tests::field::random_field_tests::<Fq12>("fq12".to_string());
mod test {
use super::*;
crate::field_testing_suite!(Fq12, "field_arithmetic");
// extension field-specific
crate::field_testing_suite!(Fq12, "f12_tests", Fq6, Fq2);
crate::field_testing_suite!(
Fq12,
"frobenius",
// Frobenius endomorphism power parameter for extension field
// ϕ: E → E
// (x, y) ↦ (x^p, y^p)
// p: modulus of base field (Here, Fq::MODULUS)
[
0x3c208c16d87cfd47,
0x97816a916871ca8d,
0xb85045b68181585d,
0x30644e72e131a029,
]
);
}
Loading

0 comments on commit f96f7f9

Please sign in to comment.