Files
ff-Goldilocks/src/tests.rs
2023-11-28 19:08:10 -05:00

242 lines
6.5 KiB
Rust

mod fp;
mod fp2;
mod fp3;
use ark_std::{end_timer, start_timer};
use ff::Field;
use ff::PrimeField;
use rand_core::RngCore;
use rand_core::SeedableRng;
use rand_xorshift::XorShiftRng;
pub fn random_field_tests<F: Field>(type_name: String) {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
]);
random_multiplication_tests::<F, _>(&mut rng, type_name.clone());
random_addition_tests::<F, _>(&mut rng, type_name.clone());
random_subtraction_tests::<F, _>(&mut rng, type_name.clone());
random_negation_tests::<F, _>(&mut rng, type_name.clone());
random_doubling_tests::<F, _>(&mut rng, type_name.clone());
random_squaring_tests::<F, _>(&mut rng, type_name.clone());
// random_inversion_tests::<F, _>(&mut rng, type_name.clone());
random_expansion_tests::<F, _>(&mut rng, type_name);
assert_eq!(F::ZERO.is_zero().unwrap_u8(), 1);
{
let mut z = F::ZERO;
z = z.neg();
assert_eq!(z.is_zero().unwrap_u8(), 1);
}
// assert!(bool::from(F::ZERO.invert().is_none()));
// Multiplication by zero
{
let mut a = F::random(&mut rng);
a.mul_assign(&F::ZERO);
assert_eq!(a.is_zero().unwrap_u8(), 1);
}
// Addition by zero
{
let mut a = F::random(&mut rng);
let copy = a;
a.add_assign(&F::ZERO);
assert_eq!(a, copy);
}
}
fn random_multiplication_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
let message = format!("multiplication {}", type_name);
let start = start_timer!(|| message);
for _ in 0..1000000 {
let a = F::random(&mut rng);
let b = F::random(&mut rng);
let c = F::random(&mut rng);
let mut t0 = a; // (a * b) * c
t0.mul_assign(&b);
t0.mul_assign(&c);
let mut t1 = a; // (a * c) * b
t1.mul_assign(&c);
t1.mul_assign(&b);
let mut t2 = b; // (b * c) * a
t2.mul_assign(&c);
t2.mul_assign(&a);
assert_eq!(t0, t1);
assert_eq!(t1, t2);
}
end_timer!(start);
}
fn random_addition_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
let message = format!("addition {}", type_name);
let start = start_timer!(|| message);
for _ in 0..1000000 {
let a = F::random(&mut rng);
let b = F::random(&mut rng);
let c = F::random(&mut rng);
let mut t0 = a; // (a + b) + c
t0.add_assign(&b);
t0.add_assign(&c);
let mut t1 = a; // (a + c) + b
t1.add_assign(&c);
t1.add_assign(&b);
let mut t2 = b; // (b + c) + a
t2.add_assign(&c);
t2.add_assign(&a);
assert_eq!(t0, t1);
assert_eq!(t1, t2);
}
end_timer!(start);
}
fn random_subtraction_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
let message = format!("subtraction {}", type_name);
let start = start_timer!(|| message);
for _ in 0..1000000 {
let a = F::random(&mut rng);
let b = F::random(&mut rng);
let mut t0 = a; // (a - b)
t0.sub_assign(&b);
let mut t1 = b; // (b - a)
t1.sub_assign(&a);
let mut t2 = t0; // (a - b) + (b - a) = 0
t2.add_assign(&t1);
assert_eq!(t2.is_zero().unwrap_u8(), 1);
}
end_timer!(start);
}
fn random_negation_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
let message = format!("negation {}", type_name);
let start = start_timer!(|| message);
for _ in 0..1000000 {
let a = F::random(&mut rng);
let mut b = a;
b = b.neg();
b.add_assign(&a);
assert_eq!(b.is_zero().unwrap_u8(), 1);
}
end_timer!(start);
}
fn random_doubling_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
let message = format!("doubling {}", type_name);
let start = start_timer!(|| message);
for _ in 0..1000000 {
let mut a = F::random(&mut rng);
let mut b = a;
a.add_assign(&b);
b = b.double();
assert_eq!(a, b);
}
end_timer!(start);
}
fn random_squaring_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
let message = format!("squaring {}", type_name);
let start = start_timer!(|| message);
for _ in 0..1000000 {
let mut a = F::random(&mut rng);
let mut b = a;
a.mul_assign(&b);
b = b.square();
assert_eq!(a, b);
}
end_timer!(start);
}
#[allow(dead_code)]
fn random_inversion_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
assert!(bool::from(F::ZERO.invert().is_none()));
let message = format!("inversion {}", type_name);
let start = start_timer!(|| message);
for _ in 0..1000000 {
let mut a = F::random(&mut rng);
let b = a.invert().unwrap(); // probabilistically nonzero
a.mul_assign(&b);
assert_eq!(a, F::ONE);
}
end_timer!(start);
}
fn random_expansion_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
let message = format!("expansion {}", type_name);
let start = start_timer!(|| message);
for _ in 0..1000000 {
// Compare (a + b)(c + d) and (a*c + b*c + a*d + b*d)
let a = F::random(&mut rng);
let b = F::random(&mut rng);
let c = F::random(&mut rng);
let d = F::random(&mut rng);
let mut t0 = a;
t0.add_assign(&b);
let mut t1 = c;
t1.add_assign(&d);
t0.mul_assign(&t1);
let mut t2 = a;
t2.mul_assign(&c);
let mut t3 = b;
t3.mul_assign(&c);
let mut t4 = a;
t4.mul_assign(&d);
let mut t5 = b;
t5.mul_assign(&d);
t2.add_assign(&t3);
t2.add_assign(&t4);
t2.add_assign(&t5);
assert_eq!(t0, t2);
}
end_timer!(start);
}
pub fn random_prime_field_tests<F: PrimeField>(type_name: String) {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
]);
random_serdes_tests::<F, _>(&mut rng, type_name);
}
fn random_serdes_tests<F: PrimeField, R: RngCore>(mut rng: R, type_name: String) {
let message = format!("expansion {}", type_name);
let start = start_timer!(|| message);
for _ in 0..1000000 {
// convert a into and from repr
let a = F::random(&mut rng);
let b = a.to_repr();
let c = F::from_repr(b).unwrap();
let d = c.to_repr();
assert_eq!(a, c);
assert_eq!(b.as_ref(), d.as_ref());
}
end_timer!(start);
}