diff --git a/Cargo.toml b/Cargo.toml index 6eac15f6..48a32ccd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,6 @@ fpe = "0.4" group = "0.9" rand = "0.8" nonempty = "0.6" -rand = "0.8" subtle = "2.3" [dependencies.halo2] diff --git a/src/constants.rs b/src/constants.rs index 955d3564..04f6c74b 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -261,61 +261,60 @@ impl FixedBase for OrchardFixedBase { } pub trait TestFixedBase { - fn test_lagrange_coeffs(&self, scalar: C::Scalar, scalar_num_bits: usize, num_windows: usize); + // Test that Lagrange interpolation coefficients reproduce the correct x-coordinate + // for each fixed-base multiple in each window. + fn test_lagrange_coeffs(&self, num_windows: usize); + + // Test that the z-values and u-values satisfy the conditions: + // 1. y + z = u^2, + // 2. y - z is not a square + // for the y-coordinate of each fixed-base multiple in each window. fn test_z(&self, z: &[u64], u: &[[[u8; 32]; H]], num_windows: usize); } impl TestFixedBase for OrchardFixedBase { - fn test_lagrange_coeffs(&self, scalar: C::Scalar, scalar_num_bits: usize, num_windows: usize) { + fn test_lagrange_coeffs(&self, num_windows: usize) { let lagrange_coeffs = self.compute_lagrange_coeffs(num_windows); - let mut points = Vec::::with_capacity(num_windows); - - let bits = - util::decompose_scalar_fixed::(scalar, scalar_num_bits, FIXED_BASE_WINDOW_SIZE); // Check first 84 windows, i.e. `k_0, k_1, ..., k_83` - for ((idx, bits), coeffs) in bits[0..(num_windows - 1)] - .iter() - .enumerate() - .zip(lagrange_coeffs[0..(num_windows - 1)].iter()) - { - let interpolated_x = util::evaluate::(*bits, coeffs); + for (idx, coeffs) in lagrange_coeffs[0..(num_windows - 1)].iter().enumerate() { + // Test each three-bit chunk in this window. + for bits in 0..(1 << FIXED_BASE_WINDOW_SIZE) { + { + // Interpolate the x-coordinate using this window's coefficients + let interpolated_x = util::evaluate::(bits, coeffs); - // [(k+1)*(8^w)]B - let point = self.0 - * C::Scalar::from_u64(*bits as u64 + 1) - * C::Scalar::from_u64(H as u64).pow(&[idx as u64, 0, 0, 0]); - let x = point.to_affine().get_xy().unwrap().0; + // Compute the actual x-coordinate of the multiple [(k+1)*(8^w)]B. + let point = self.0 + * C::Scalar::from_u64(bits as u64 + 1) + * C::Scalar::from_u64(H as u64).pow(&[idx as u64, 0, 0, 0]); + let x = point.to_affine().get_xy().unwrap().0; - assert_eq!(x, interpolated_x); - points.push(point); + // Check that the interpolated x-coordinate matches the actual one. + assert_eq!(x, interpolated_x); + } + } } - // Check last window - { - let last_bits = bits[num_windows - 1]; - let interpolated_x = util::evaluate::(last_bits, &lagrange_coeffs[num_windows - 1]); + // Check last window. + for bits in 0..(1 << FIXED_BASE_WINDOW_SIZE) { + // Interpolate the x-coordinate using the last window's coefficients + let interpolated_x = util::evaluate::(bits, &lagrange_coeffs[num_windows - 1]); - // [k * (8^w) - offset]B, where offset = \sum_{j = 0}^{83} 8^j + // Compute the actual x-coordinate of the multiple [k * (8^84) - offset]B, + // where offset = \sum_{j = 0}^{83} 8^j let offset = (0..(num_windows - 1)).fold(C::Scalar::zero(), |acc, w| { acc + C::Scalar::from_u64(H as u64).pow(&[w as u64, 0, 0, 0]) }); - let scalar = C::Scalar::from_u64(last_bits as u64) + let scalar = C::Scalar::from_u64(bits as u64) * C::Scalar::from_u64(H as u64).pow(&[(num_windows - 1) as u64, 0, 0, 0]) - offset; let point = self.0 * scalar; let x = point.to_affine().get_xy().unwrap().0; + // Check that the interpolated x-coordinate matches the actual one. assert_eq!(x, interpolated_x); - points.push(point); } - - // Check the sum of all the window points - let window_sum = points - .iter() - .fold(C::CurveExt::default(), |acc, point| acc + point); - let multiple = self.0 * scalar; - assert_eq!(window_sum, multiple); } fn test_z(&self, z: &[u64], u: &[[[u8; 32]; H]], num_windows: usize) { diff --git a/src/constants/commit_ivk_r.rs b/src/constants/commit_ivk_r.rs index e2ea3cc5..f0ad2ca5 100644 --- a/src/constants/commit_ivk_r.rs +++ b/src/constants/commit_ivk_r.rs @@ -3690,10 +3690,9 @@ pub fn generator() -> OrchardFixedBases { #[cfg(test)] mod tests { - use super::super::{TestFixedBase, L_VALUE, NUM_WINDOWS, NUM_WINDOWS_SHORT}; + use super::super::{TestFixedBase, NUM_WINDOWS, NUM_WINDOWS_SHORT}; use super::*; use crate::primitives::sinsemilla::CommitDomain; - use ff::PrimeField; use group::Curve; use halo2::{ arithmetic::{CurveAffine, FieldExt}, @@ -3714,11 +3713,7 @@ mod tests { fn lagrange_coeffs() { let base = super::generator::(); match base { - OrchardFixedBases::CommitIvkR(inner) => inner.test_lagrange_coeffs( - pallas::Scalar::rand(), - pallas::Scalar::NUM_BITS as usize, - NUM_WINDOWS, - ), + OrchardFixedBases::CommitIvkR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS), _ => unreachable!(), } } @@ -3727,10 +3722,7 @@ mod tests { fn lagrange_coeffs_short() { let base = super::generator::(); match base { - OrchardFixedBases::CommitIvkR(inner) => { - let scalar = pallas::Scalar::from_u64(rand::random::()); - inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT) - } + OrchardFixedBases::CommitIvkR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT), _ => unreachable!(), } } diff --git a/src/constants/note_commit_r.rs b/src/constants/note_commit_r.rs index 23029516..90abd4b3 100644 --- a/src/constants/note_commit_r.rs +++ b/src/constants/note_commit_r.rs @@ -3690,10 +3690,9 @@ pub fn generator() -> OrchardFixedBases { #[cfg(test)] mod tests { - use super::super::{TestFixedBase, L_VALUE, NUM_WINDOWS, NUM_WINDOWS_SHORT}; + use super::super::{TestFixedBase, NUM_WINDOWS, NUM_WINDOWS_SHORT}; use super::*; use crate::primitives::sinsemilla::CommitDomain; - use ff::PrimeField; use group::Curve; use halo2::{ arithmetic::{CurveAffine, FieldExt}, @@ -3714,11 +3713,7 @@ mod tests { fn lagrange_coeffs() { let base = super::generator::(); match base { - OrchardFixedBases::NoteCommitR(inner) => inner.test_lagrange_coeffs( - pallas::Scalar::rand(), - pallas::Scalar::NUM_BITS as usize, - NUM_WINDOWS, - ), + OrchardFixedBases::NoteCommitR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS), _ => unreachable!(), } } @@ -3727,10 +3722,7 @@ mod tests { fn lagrange_coeffs_short() { let base = super::generator::(); match base { - OrchardFixedBases::NoteCommitR(inner) => { - let scalar = pallas::Scalar::from_u64(rand::random::()); - inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT) - } + OrchardFixedBases::NoteCommitR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT), _ => unreachable!(), } } diff --git a/src/constants/nullifier_k.rs b/src/constants/nullifier_k.rs index 3a4ead14..08e50e95 100644 --- a/src/constants/nullifier_k.rs +++ b/src/constants/nullifier_k.rs @@ -3689,9 +3689,8 @@ pub fn generator() -> OrchardFixedBases { #[cfg(test)] mod tests { - use super::super::{TestFixedBase, L_VALUE, NUM_WINDOWS, NUM_WINDOWS_SHORT}; + use super::super::{TestFixedBase, NUM_WINDOWS, NUM_WINDOWS_SHORT}; use super::*; - use ff::PrimeField; use group::Curve; use halo2::{ arithmetic::{CurveAffine, CurveExt, FieldExt}, @@ -3712,11 +3711,7 @@ mod tests { fn lagrange_coeffs() { let base = super::generator::(); match base { - OrchardFixedBases::NullifierK(inner) => inner.test_lagrange_coeffs( - pallas::Scalar::rand(), - pallas::Scalar::NUM_BITS as usize, - NUM_WINDOWS, - ), + OrchardFixedBases::NullifierK(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS), _ => unreachable!(), } } @@ -3725,10 +3720,7 @@ mod tests { fn lagrange_coeffs_short() { let base = super::generator::(); match base { - OrchardFixedBases::NullifierK(inner) => { - let scalar = pallas::Scalar::from_u64(rand::random::()); - inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT) - } + OrchardFixedBases::NullifierK(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT), _ => unreachable!(), } } diff --git a/src/constants/value_commit_r.rs b/src/constants/value_commit_r.rs index 6b0ca830..38fad852 100644 --- a/src/constants/value_commit_r.rs +++ b/src/constants/value_commit_r.rs @@ -3691,9 +3691,8 @@ pub fn generator() -> OrchardFixedBases { #[cfg(test)] mod tests { - use super::super::{TestFixedBase, L_VALUE, NUM_WINDOWS, NUM_WINDOWS_SHORT}; + use super::super::{TestFixedBase, NUM_WINDOWS, NUM_WINDOWS_SHORT}; use super::*; - use ff::PrimeField; use group::Curve; use halo2::{ arithmetic::{CurveAffine, CurveExt, FieldExt}, @@ -3714,11 +3713,7 @@ mod tests { fn lagrange_coeffs() { let base = super::generator::(); match base { - OrchardFixedBases::ValueCommitR(inner) => inner.test_lagrange_coeffs( - pallas::Scalar::rand(), - pallas::Scalar::NUM_BITS as usize, - NUM_WINDOWS, - ), + OrchardFixedBases::ValueCommitR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS), _ => unreachable!(), } } @@ -3727,10 +3722,7 @@ mod tests { fn lagrange_coeffs_short() { let base = super::generator::(); match base { - OrchardFixedBases::ValueCommitR(inner) => { - let scalar = pallas::Scalar::from_u64(rand::random::()); - inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT) - } + OrchardFixedBases::ValueCommitR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT), _ => unreachable!(), } } diff --git a/src/constants/value_commit_v.rs b/src/constants/value_commit_v.rs index d4966d04..a72bb374 100644 --- a/src/constants/value_commit_v.rs +++ b/src/constants/value_commit_v.rs @@ -3691,9 +3691,8 @@ pub fn generator() -> OrchardFixedBases { #[cfg(test)] mod tests { - use super::super::{TestFixedBase, L_VALUE, NUM_WINDOWS, NUM_WINDOWS_SHORT}; + use super::super::{TestFixedBase, NUM_WINDOWS, NUM_WINDOWS_SHORT}; use super::*; - use ff::PrimeField; use group::Curve; use halo2::{ arithmetic::{CurveAffine, CurveExt, FieldExt}, @@ -3706,9 +3705,6 @@ mod tests { let point = hasher(b"-v"); let (x, y) = point.to_affine().get_xy().unwrap(); - println!("{:?}", x.to_bytes()); - println!("{:?}", y.to_bytes()); - assert_eq!(x, pallas::Base::from_bytes(&GENERATOR.0).unwrap()); assert_eq!(y, pallas::Base::from_bytes(&GENERATOR.1).unwrap()); } @@ -3717,11 +3713,7 @@ mod tests { fn lagrange_coeffs() { let base = super::generator::(); match base { - OrchardFixedBases::ValueCommitV(inner) => inner.test_lagrange_coeffs( - pallas::Scalar::rand(), - pallas::Scalar::NUM_BITS as usize, - NUM_WINDOWS, - ), + OrchardFixedBases::ValueCommitV(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS), _ => unreachable!(), } } @@ -3730,10 +3722,7 @@ mod tests { fn lagrange_coeffs_short() { let base = super::generator::(); match base { - OrchardFixedBases::ValueCommitV(inner) => { - let scalar = pallas::Scalar::from_u64(rand::random::()); - inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT) - } + OrchardFixedBases::ValueCommitV(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT), _ => unreachable!(), } }