From 0636a6f2ec475c270f82d56e3fd2c41f2abd6ea8 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Mon, 24 May 2021 23:02:02 +0800 Subject: [PATCH] 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). --- src/constants.rs | 38 +++++++++++++++++++++------------ src/constants/commit_ivk_r.rs | 2 +- src/constants/note_commit_r.rs | 2 +- src/constants/nullifier_k.rs | 2 +- src/constants/value_commit_r.rs | 2 +- src/constants/value_commit_v.rs | 2 +- 6 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index 0f92e0ea..22a55670 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -107,14 +107,14 @@ impl FixedBase for OrchardFixedBase { 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 FixedBase for OrchardFixedBase { } // 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 { // 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 TestFixedBase for OrchardFixedBase { @@ -233,9 +238,9 @@ impl TestFixedBase for OrchardFixedBase { // Interpolate the x-coordinate using this window's coefficients let interpolated_x = util::evaluate::(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 TestFixedBase for OrchardFixedBase { let interpolated_x = util::evaluate::(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 TestFixedBase for OrchardFixedBase { } } - 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) { diff --git a/src/constants/commit_ivk_r.rs b/src/constants/commit_ivk_r.rs index bcab4196..e975867e 100644 --- a/src/constants/commit_ivk_r.rs +++ b/src/constants/commit_ivk_r.rs @@ -2958,6 +2958,6 @@ mod tests { #[test] fn z() { let base = super::generator::(); - base.0.test_z(&Z, &U, NUM_WINDOWS); + base.0.test_zs_and_us(&Z, &U, NUM_WINDOWS); } } diff --git a/src/constants/note_commit_r.rs b/src/constants/note_commit_r.rs index 72b6d6eb..fc69a9b2 100644 --- a/src/constants/note_commit_r.rs +++ b/src/constants/note_commit_r.rs @@ -2958,6 +2958,6 @@ mod tests { #[test] fn z() { let base = super::generator::(); - base.0.test_z(&Z, &U, NUM_WINDOWS); + base.0.test_zs_and_us(&Z, &U, NUM_WINDOWS); } } diff --git a/src/constants/nullifier_k.rs b/src/constants/nullifier_k.rs index 8d80f2cd..b844cd7e 100644 --- a/src/constants/nullifier_k.rs +++ b/src/constants/nullifier_k.rs @@ -2956,6 +2956,6 @@ mod tests { #[test] fn z() { let base = super::generator::(); - base.0.test_z(&Z, &U, NUM_WINDOWS); + base.0.test_zs_and_us(&Z, &U, NUM_WINDOWS); } } diff --git a/src/constants/value_commit_r.rs b/src/constants/value_commit_r.rs index f93e5202..646ab733 100644 --- a/src/constants/value_commit_r.rs +++ b/src/constants/value_commit_r.rs @@ -2958,6 +2958,6 @@ mod tests { #[test] fn z() { let base = super::generator::(); - base.0.test_z(&Z, &U, NUM_WINDOWS); + base.0.test_zs_and_us(&Z, &U, NUM_WINDOWS); } } diff --git a/src/constants/value_commit_v.rs b/src/constants/value_commit_v.rs index c6eb9993..17a6d59c 100644 --- a/src/constants/value_commit_v.rs +++ b/src/constants/value_commit_v.rs @@ -811,6 +811,6 @@ mod tests { #[test] fn z_short() { let base = super::generator::(); - base.0.test_z(&Z_SHORT, &U_SHORT, NUM_WINDOWS_SHORT); + base.0.test_zs_and_us(&Z_SHORT, &U_SHORT, NUM_WINDOWS_SHORT); } }