A few more tests, ported (with some adaptations) from plonky1

This commit is contained in:
Daniel Lubarov 2021-04-22 21:12:34 -07:00
parent 4491d5ad9f
commit 84a71c9ca5
4 changed files with 102 additions and 30 deletions

View File

@ -110,6 +110,21 @@ pub trait Field:
subgroup
}
fn cyclic_subgroup_unknown_order(generator: Self) -> Vec<Self> {
let mut subgroup = Vec::new();
for power in generator.powers() {
if power.is_one() && !subgroup.is_empty() {
break;
}
subgroup.push(power);
}
subgroup
}
fn generator_order(generator: Self) -> usize {
Self::cyclic_subgroup_unknown_order(generator).len()
}
/// Computes a coset of a multiplicative subgroup whose order is known in advance.
fn cyclic_subgroup_coset_known_order(generator: Self, shift: Self, order: usize) -> Vec<Self> {
let subgroup = Self::cyclic_subgroup_known_order(generator, order);

View File

@ -225,35 +225,61 @@ macro_rules! test_arithmetic {
)
}
// #[test]
// #[ignore]
// fn arithmetic_division() {
// // This test takes ages to finish so is #[ignore]d by default.
// // TODO: Re-enable and reimplement when
// // https://github.com/rust-num/num-bigint/issues/60 is finally resolved.
// let modulus = <$field>::ORDER;
// crate::field::field_testing::run_binaryop_test_cases(
// modulus,
// WORD_BITS,
// // Need to help the compiler infer the type of y here
// |x: $field, y: $field| {
// // TODO: Work out how to check that div() panics
// // appropriately when given a zero divisor.
// if !y.is_zero() {
// <$field>::div(x, y)
// } else {
// <$field>::ZERO
// }
// },
// |x, y| {
// // yinv = y^-1 (mod modulus)
// let exp = modulus - 2u64;
// let yinv = y.modpow(exp, modulus);
// // returns 0 if y was 0
// x * yinv % modulus
// },
// )
// }
#[test]
fn inversion() {
let zero = <$field>::ZERO;
let one = <$field>::ONE;
let order = <$field>::ORDER;
assert_eq!(zero.try_inverse(), None);
for &x in &[1, 2, 3, order - 3, order - 2, order - 1] {
let x = <$field>::from_canonical_u64(x);
let inv = x.inverse();
assert_eq!(x * inv, one);
}
}
#[test]
fn batch_inversion() {
let xs = (1..=3)
.map(|i| <$field>::from_canonical_u64(i))
.collect::<Vec<_>>();
let invs = <$field>::batch_multiplicative_inverse(&xs);
for (x, inv) in xs.into_iter().zip(invs) {
assert_eq!(x * inv, <$field>::ONE);
}
}
#[test]
fn primitive_root_order() {
for n_power in 0..8 {
let root = <$field>::primitive_root_of_unity(n_power);
let order = <$field>::generator_order(root);
assert_eq!(order, 1 << n_power, "2^{}'th primitive root", n_power);
}
}
#[test]
fn negation() {
let zero = <$field>::ZERO;
let order = <$field>::ORDER;
for &i in &[0, 1, 2, order - 2, order - 1] {
let i_f = <$field>::from_canonical_u64(i);
assert_eq!(i_f + -i_f, zero);
}
}
#[test]
fn bits() {
assert_eq!(<$field>::ZERO.bits(), 0);
assert_eq!(<$field>::ONE.bits(), 1);
assert_eq!(<$field>::TWO.bits(), 2);
assert_eq!(<$field>::from_canonical_u64(3).bits(), 2);
assert_eq!(<$field>::from_canonical_u64(4).bits(), 3);
assert_eq!(<$field>::from_canonical_u64(5).bits(), 3);
}
}
};
}

View File

@ -60,8 +60,38 @@ pub(crate) fn divide_by_z_h<F: Field>(mut a: PolynomialCoeffs<F>, n: usize) -> P
#[cfg(test)]
mod tests {
use crate::field::crandall_field::CrandallField;
use crate::field::field::Field;
use crate::polynomial::division::divide_by_z_h;
use crate::polynomial::polynomial::PolynomialCoeffs;
#[test]
fn zero_div_z_h() {
type F = CrandallField;
let zero = PolynomialCoeffs::<F>::zero(16);
let quotient = divide_by_z_h(zero.clone(), 4);
assert_eq!(quotient, zero);
}
#[test]
fn division_by_z_h() {
// TODO
type F = CrandallField;
let zero = F::ZERO;
let one = F::ONE;
let two = F::TWO;
let three = F::from_canonical_u64(3);
let four = F::from_canonical_u64(4);
let five = F::from_canonical_u64(5);
let six = F::from_canonical_u64(6);
// a(x) = Z_4(x) q(x), where
// a(x) = 3 x^7 + 4 x^6 + 5 x^5 + 6 x^4 - 3 x^3 - 4 x^2 - 5 x - 6
// Z_4(x) = x^4 - 1
// q(x) = 3 x^3 + 4 x^2 + 5 x + 6
let a = PolynomialCoeffs::new(vec![-six, -five, -four, -three, six, five, four, three]);
let q = PolynomialCoeffs::new(vec![six, five, four, three, zero, zero, zero, zero]);
let computed_q = divide_by_z_h(a, 4);
assert_eq!(computed_q, q);
}
}

View File

@ -502,6 +502,7 @@ fn sbox_layer_b<F: Field>(x: [F; W]) -> [F; W] {
#[unroll_for_loops]
fn sbox_a<F: Field>(x: F) -> F {
// x^{-5}, via Fermat's little theorem
// TODO: This only works for our current field.
const EXP: u64 = 7378697628517453005;
let mut product = F::ONE;