mirror of https://github.com/zcash/halo2.git
Update window table formula.
Previously, the window table M for fixed-base scalar multiplication computed M[w][k] = [(k+1)*(2^3)^w]B for each window w, where k is a 3-bit chunk in the scalar decomposition in the range [0..8). However, in the case k_0 = 7, k_1= 0, the window table entries would evaluate to: * M[0][k_0] = [(7+1)*(2^3)^0]B = [8]B, * M[1][k_1] = [(0+1)*(2^3)^1]B = [8]B, which means the first addition would require complete addition. To avoid this, we alter the formula to M[w][k] = [(k+2)*(2^3)^w]B. We make a corresponding change to the formula for the last window W. Previously, we had: M[W][k] = [k * (2^3)^W - \sum((2^3)^j)]B, for j in [0..W-1). Now, we have: M[W][k] = [k * (2^3)^W - \sum(2^(3j+1))]B, for j in [0..W-1).
This commit is contained in:
parent
5d57bee562
commit
0636a6f2ec
|
@ -107,14 +107,14 @@ impl<C: CurveAffine> FixedBase<C> for OrchardFixedBase<C> {
|
|||
let mut window_table: Vec<[C; H]> = Vec::with_capacity(num_windows);
|
||||
|
||||
// Generate window table entries for all windows but the last.
|
||||
// For these first `num_windows - 1` windows, we compute the multiple [(k+1)*(8^w)]B.
|
||||
// For these first `num_windows - 1` windows, we compute the multiple [(k+2)*(2^3)^w]B.
|
||||
// Here, w ranges from [0..`num_windows - 1`)
|
||||
for w in 0..(num_windows - 1) {
|
||||
window_table.push(
|
||||
(0..H)
|
||||
.map(|k| {
|
||||
// scalar = (k+1)*(8^w)
|
||||
let scalar = C::ScalarExt::from_u64(k as u64 + 1)
|
||||
// scalar = (k+2)*(8^w)
|
||||
let scalar = C::ScalarExt::from_u64(k as u64 + 2)
|
||||
* C::ScalarExt::from_u64(H as u64).pow(&[w as u64, 0, 0, 0]);
|
||||
(self.0 * scalar).to_affine()
|
||||
})
|
||||
|
@ -125,15 +125,20 @@ impl<C: CurveAffine> FixedBase<C> for OrchardFixedBase<C> {
|
|||
}
|
||||
|
||||
// Generate window table entries for the last window, w = `num_windows - 1`.
|
||||
// For the last window, we compute [k * (8^w) - sum]B, where sum is defined
|
||||
// as sum = \sum_{j = 0}^{`num_windows - 2`} 8^j
|
||||
let sum = (0..(num_windows - 1)).fold(C::ScalarExt::zero(), |acc, w| {
|
||||
acc + C::ScalarExt::from_u64(H as u64).pow(&[w as u64, 0, 0, 0])
|
||||
// For the last window, we compute [k * (2^3)^w - sum]B, where sum is defined
|
||||
// as sum = \sum_{j = 0}^{`num_windows - 2`} 2^{3j+1}
|
||||
let sum = (0..(num_windows - 1)).fold(C::ScalarExt::zero(), |acc, j| {
|
||||
acc + C::ScalarExt::from_u64(2).pow(&[
|
||||
FIXED_BASE_WINDOW_SIZE as u64 * j as u64 + 1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
])
|
||||
});
|
||||
window_table.push(
|
||||
(0..H)
|
||||
.map(|k| {
|
||||
// scalar = k * (8^w) - sum, where w = `num_windows - 1`
|
||||
// scalar = k * (2^3)^w - sum, where w = `num_windows - 1`
|
||||
let scalar = C::ScalarExt::from_u64(k as u64)
|
||||
* C::ScalarExt::from_u64(H as u64).pow(&[
|
||||
(num_windows - 1) as u64,
|
||||
|
@ -218,7 +223,7 @@ trait TestFixedBase<C: CurveAffine> {
|
|||
// 1. z + y = u^2,
|
||||
// 2. z - y 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_zs_and_us(&self, z: &[u64], u: &[[[u8; 32]; H]], num_windows: usize);
|
||||
}
|
||||
|
||||
impl<C: CurveAffine> TestFixedBase<C> for OrchardFixedBase<C> {
|
||||
|
@ -233,9 +238,9 @@ impl<C: CurveAffine> TestFixedBase<C> for OrchardFixedBase<C> {
|
|||
// Interpolate the x-coordinate using this window's coefficients
|
||||
let interpolated_x = util::evaluate::<C>(bits, coeffs);
|
||||
|
||||
// Compute the actual x-coordinate of the multiple [(k+1)*(8^w)]B.
|
||||
// Compute the actual x-coordinate of the multiple [(k+2)*(8^w)]B.
|
||||
let point = self.0
|
||||
* C::Scalar::from_u64(bits as u64 + 1)
|
||||
* C::Scalar::from_u64(bits as u64 + 2)
|
||||
* C::Scalar::from_u64(H as u64).pow(&[idx as u64, 0, 0, 0]);
|
||||
let x = *point.to_affine().coordinates().unwrap().x();
|
||||
|
||||
|
@ -251,9 +256,14 @@ impl<C: CurveAffine> TestFixedBase<C> for OrchardFixedBase<C> {
|
|||
let interpolated_x = util::evaluate::<C>(bits, &lagrange_coeffs[num_windows - 1]);
|
||||
|
||||
// Compute the actual x-coordinate of the multiple [k * (8^84) - offset]B,
|
||||
// where offset = \sum_{j = 0}^{83} 8^j
|
||||
// where offset = \sum_{j = 0}^{83} 2^{3j+1}
|
||||
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(2).pow(&[
|
||||
FIXED_BASE_WINDOW_SIZE as u64 * w as u64 + 1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
])
|
||||
});
|
||||
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])
|
||||
|
@ -266,7 +276,7 @@ impl<C: CurveAffine> TestFixedBase<C> for OrchardFixedBase<C> {
|
|||
}
|
||||
}
|
||||
|
||||
fn test_z(&self, z: &[u64], u: &[[[u8; 32]; H]], num_windows: usize) {
|
||||
fn test_zs_and_us(&self, z: &[u64], u: &[[[u8; 32]; H]], num_windows: usize) {
|
||||
let window_table = self.compute_window_table(num_windows);
|
||||
|
||||
for ((u, z), window_points) in u.iter().zip(z.iter()).zip(window_table) {
|
||||
|
|
|
@ -2958,6 +2958,6 @@ mod tests {
|
|||
#[test]
|
||||
fn z() {
|
||||
let base = super::generator::<pallas::Affine>();
|
||||
base.0.test_z(&Z, &U, NUM_WINDOWS);
|
||||
base.0.test_zs_and_us(&Z, &U, NUM_WINDOWS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2958,6 +2958,6 @@ mod tests {
|
|||
#[test]
|
||||
fn z() {
|
||||
let base = super::generator::<pallas::Affine>();
|
||||
base.0.test_z(&Z, &U, NUM_WINDOWS);
|
||||
base.0.test_zs_and_us(&Z, &U, NUM_WINDOWS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2956,6 +2956,6 @@ mod tests {
|
|||
#[test]
|
||||
fn z() {
|
||||
let base = super::generator::<pallas::Affine>();
|
||||
base.0.test_z(&Z, &U, NUM_WINDOWS);
|
||||
base.0.test_zs_and_us(&Z, &U, NUM_WINDOWS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2958,6 +2958,6 @@ mod tests {
|
|||
#[test]
|
||||
fn z() {
|
||||
let base = super::generator::<pallas::Affine>();
|
||||
base.0.test_z(&Z, &U, NUM_WINDOWS);
|
||||
base.0.test_zs_and_us(&Z, &U, NUM_WINDOWS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -811,6 +811,6 @@ mod tests {
|
|||
#[test]
|
||||
fn z_short() {
|
||||
let base = super::generator::<pallas::Affine>();
|
||||
base.0.test_z(&Z_SHORT, &U_SHORT, NUM_WINDOWS_SHORT);
|
||||
base.0.test_zs_and_us(&Z_SHORT, &U_SHORT, NUM_WINDOWS_SHORT);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue