Test every row in test_lagrange_coeffs() instead of using random scalar

This commit is contained in:
therealyingtong 2021-04-13 22:26:18 +08:00
parent ce6e59bdb8
commit e26b6c6123
7 changed files with 47 additions and 92 deletions

View File

@ -27,7 +27,6 @@ fpe = "0.4"
group = "0.9" group = "0.9"
rand = "0.8" rand = "0.8"
nonempty = "0.6" nonempty = "0.6"
rand = "0.8"
subtle = "2.3" subtle = "2.3"
[dependencies.halo2] [dependencies.halo2]

View File

@ -261,61 +261,60 @@ impl<C: CurveAffine> FixedBase<C> for OrchardFixedBase<C> {
} }
pub trait TestFixedBase<C: CurveAffine> { pub trait TestFixedBase<C: CurveAffine> {
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); fn test_z(&self, z: &[u64], u: &[[[u8; 32]; H]], num_windows: usize);
} }
impl<C: CurveAffine> TestFixedBase<C> for OrchardFixedBase<C> { impl<C: CurveAffine> TestFixedBase<C> for OrchardFixedBase<C> {
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 lagrange_coeffs = self.compute_lagrange_coeffs(num_windows);
let mut points = Vec::<C::CurveExt>::with_capacity(num_windows);
let bits =
util::decompose_scalar_fixed::<C>(scalar, scalar_num_bits, FIXED_BASE_WINDOW_SIZE);
// Check first 84 windows, i.e. `k_0, k_1, ..., k_83` // Check first 84 windows, i.e. `k_0, k_1, ..., k_83`
for ((idx, bits), coeffs) in bits[0..(num_windows - 1)] for (idx, coeffs) in lagrange_coeffs[0..(num_windows - 1)].iter().enumerate() {
.iter() // Test each three-bit chunk in this window.
.enumerate() for bits in 0..(1 << FIXED_BASE_WINDOW_SIZE) {
.zip(lagrange_coeffs[0..(num_windows - 1)].iter())
{ {
let interpolated_x = util::evaluate::<C>(*bits, coeffs); // Interpolate the x-coordinate using this window's coefficients
let interpolated_x = util::evaluate::<C>(bits, coeffs);
// [(k+1)*(8^w)]B // Compute the actual x-coordinate of the multiple [(k+1)*(8^w)]B.
let point = self.0 let point = self.0
* C::Scalar::from_u64(*bits as u64 + 1) * C::Scalar::from_u64(bits as u64 + 1)
* C::Scalar::from_u64(H as u64).pow(&[idx as u64, 0, 0, 0]); * C::Scalar::from_u64(H as u64).pow(&[idx as u64, 0, 0, 0]);
let x = point.to_affine().get_xy().unwrap().0; let x = point.to_affine().get_xy().unwrap().0;
// Check that the interpolated x-coordinate matches the actual one.
assert_eq!(x, interpolated_x); assert_eq!(x, interpolated_x);
points.push(point); }
}
} }
// Check last window // Check last window.
{ for bits in 0..(1 << FIXED_BASE_WINDOW_SIZE) {
let last_bits = bits[num_windows - 1]; // Interpolate the x-coordinate using the last window's coefficients
let interpolated_x = util::evaluate::<C>(last_bits, &lagrange_coeffs[num_windows - 1]); let interpolated_x = util::evaluate::<C>(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| { 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]) 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]) * C::Scalar::from_u64(H as u64).pow(&[(num_windows - 1) as u64, 0, 0, 0])
- offset; - offset;
let point = self.0 * scalar; let point = self.0 * scalar;
let x = point.to_affine().get_xy().unwrap().0; let x = point.to_affine().get_xy().unwrap().0;
// Check that the interpolated x-coordinate matches the actual one.
assert_eq!(x, interpolated_x); 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) { fn test_z(&self, z: &[u64], u: &[[[u8; 32]; H]], num_windows: usize) {

View File

@ -3690,10 +3690,9 @@ pub fn generator<C: CurveAffine>() -> OrchardFixedBases<C> {
#[cfg(test)] #[cfg(test)]
mod tests { 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 super::*;
use crate::primitives::sinsemilla::CommitDomain; use crate::primitives::sinsemilla::CommitDomain;
use ff::PrimeField;
use group::Curve; use group::Curve;
use halo2::{ use halo2::{
arithmetic::{CurveAffine, FieldExt}, arithmetic::{CurveAffine, FieldExt},
@ -3714,11 +3713,7 @@ mod tests {
fn lagrange_coeffs() { fn lagrange_coeffs() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::CommitIvkR(inner) => inner.test_lagrange_coeffs( OrchardFixedBases::CommitIvkR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS),
pallas::Scalar::rand(),
pallas::Scalar::NUM_BITS as usize,
NUM_WINDOWS,
),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -3727,10 +3722,7 @@ mod tests {
fn lagrange_coeffs_short() { fn lagrange_coeffs_short() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::CommitIvkR(inner) => { OrchardFixedBases::CommitIvkR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT),
let scalar = pallas::Scalar::from_u64(rand::random::<u64>());
inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT)
}
_ => unreachable!(), _ => unreachable!(),
} }
} }

View File

@ -3690,10 +3690,9 @@ pub fn generator<C: CurveAffine>() -> OrchardFixedBases<C> {
#[cfg(test)] #[cfg(test)]
mod tests { 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 super::*;
use crate::primitives::sinsemilla::CommitDomain; use crate::primitives::sinsemilla::CommitDomain;
use ff::PrimeField;
use group::Curve; use group::Curve;
use halo2::{ use halo2::{
arithmetic::{CurveAffine, FieldExt}, arithmetic::{CurveAffine, FieldExt},
@ -3714,11 +3713,7 @@ mod tests {
fn lagrange_coeffs() { fn lagrange_coeffs() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::NoteCommitR(inner) => inner.test_lagrange_coeffs( OrchardFixedBases::NoteCommitR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS),
pallas::Scalar::rand(),
pallas::Scalar::NUM_BITS as usize,
NUM_WINDOWS,
),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -3727,10 +3722,7 @@ mod tests {
fn lagrange_coeffs_short() { fn lagrange_coeffs_short() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::NoteCommitR(inner) => { OrchardFixedBases::NoteCommitR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT),
let scalar = pallas::Scalar::from_u64(rand::random::<u64>());
inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT)
}
_ => unreachable!(), _ => unreachable!(),
} }
} }

View File

@ -3689,9 +3689,8 @@ pub fn generator<C: CurveAffine>() -> OrchardFixedBases<C> {
#[cfg(test)] #[cfg(test)]
mod tests { 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 super::*;
use ff::PrimeField;
use group::Curve; use group::Curve;
use halo2::{ use halo2::{
arithmetic::{CurveAffine, CurveExt, FieldExt}, arithmetic::{CurveAffine, CurveExt, FieldExt},
@ -3712,11 +3711,7 @@ mod tests {
fn lagrange_coeffs() { fn lagrange_coeffs() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::NullifierK(inner) => inner.test_lagrange_coeffs( OrchardFixedBases::NullifierK(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS),
pallas::Scalar::rand(),
pallas::Scalar::NUM_BITS as usize,
NUM_WINDOWS,
),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -3725,10 +3720,7 @@ mod tests {
fn lagrange_coeffs_short() { fn lagrange_coeffs_short() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::NullifierK(inner) => { OrchardFixedBases::NullifierK(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT),
let scalar = pallas::Scalar::from_u64(rand::random::<u64>());
inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT)
}
_ => unreachable!(), _ => unreachable!(),
} }
} }

View File

@ -3691,9 +3691,8 @@ pub fn generator<C: CurveAffine>() -> OrchardFixedBases<C> {
#[cfg(test)] #[cfg(test)]
mod tests { 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 super::*;
use ff::PrimeField;
use group::Curve; use group::Curve;
use halo2::{ use halo2::{
arithmetic::{CurveAffine, CurveExt, FieldExt}, arithmetic::{CurveAffine, CurveExt, FieldExt},
@ -3714,11 +3713,7 @@ mod tests {
fn lagrange_coeffs() { fn lagrange_coeffs() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::ValueCommitR(inner) => inner.test_lagrange_coeffs( OrchardFixedBases::ValueCommitR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS),
pallas::Scalar::rand(),
pallas::Scalar::NUM_BITS as usize,
NUM_WINDOWS,
),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -3727,10 +3722,7 @@ mod tests {
fn lagrange_coeffs_short() { fn lagrange_coeffs_short() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::ValueCommitR(inner) => { OrchardFixedBases::ValueCommitR(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT),
let scalar = pallas::Scalar::from_u64(rand::random::<u64>());
inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT)
}
_ => unreachable!(), _ => unreachable!(),
} }
} }

View File

@ -3691,9 +3691,8 @@ pub fn generator<C: CurveAffine>() -> OrchardFixedBases<C> {
#[cfg(test)] #[cfg(test)]
mod tests { 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 super::*;
use ff::PrimeField;
use group::Curve; use group::Curve;
use halo2::{ use halo2::{
arithmetic::{CurveAffine, CurveExt, FieldExt}, arithmetic::{CurveAffine, CurveExt, FieldExt},
@ -3706,9 +3705,6 @@ mod tests {
let point = hasher(b"-v"); let point = hasher(b"-v");
let (x, y) = point.to_affine().get_xy().unwrap(); 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!(x, pallas::Base::from_bytes(&GENERATOR.0).unwrap());
assert_eq!(y, pallas::Base::from_bytes(&GENERATOR.1).unwrap()); assert_eq!(y, pallas::Base::from_bytes(&GENERATOR.1).unwrap());
} }
@ -3717,11 +3713,7 @@ mod tests {
fn lagrange_coeffs() { fn lagrange_coeffs() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::ValueCommitV(inner) => inner.test_lagrange_coeffs( OrchardFixedBases::ValueCommitV(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS),
pallas::Scalar::rand(),
pallas::Scalar::NUM_BITS as usize,
NUM_WINDOWS,
),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -3730,10 +3722,7 @@ mod tests {
fn lagrange_coeffs_short() { fn lagrange_coeffs_short() {
let base = super::generator::<pallas::Affine>(); let base = super::generator::<pallas::Affine>();
match base { match base {
OrchardFixedBases::ValueCommitV(inner) => { OrchardFixedBases::ValueCommitV(inner) => inner.test_lagrange_coeffs(NUM_WINDOWS_SHORT),
let scalar = pallas::Scalar::from_u64(rand::random::<u64>());
inner.test_lagrange_coeffs(scalar, L_VALUE, NUM_WINDOWS_SHORT)
}
_ => unreachable!(), _ => unreachable!(),
} }
} }