mirror of https://github.com/zcash/halo2.git
Test every row in test_lagrange_coeffs() instead of using random scalar
This commit is contained in:
parent
ce6e59bdb8
commit
e26b6c6123
|
@ -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]
|
||||||
|
|
|
@ -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())
|
{
|
||||||
{
|
// Interpolate the x-coordinate using this window's coefficients
|
||||||
let interpolated_x = util::evaluate::<C>(*bits, coeffs);
|
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;
|
||||||
|
|
||||||
assert_eq!(x, interpolated_x);
|
// Check that the interpolated x-coordinate matches the actual one.
|
||||||
points.push(point);
|
assert_eq!(x, interpolated_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
|
|
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue