Impl ZIP 216 on SaplingVerificationContext and redjubjub::PublicKey

`PublicKey::verify` now always uses post-ZIP 216 validation rules, which
is fine in non-consensus contexts.

`SaplingVerificationContext` is used by `zcashd`'s consensus rules.
This commit is contained in:
Jack Grigg 2021-06-06 23:45:15 +01:00
parent 2ba8073971
commit e2fb5e6402
4 changed files with 36 additions and 11 deletions

View File

@ -7,6 +7,9 @@ and this library adheres to Rust's notion of
## [Unreleased] ## [Unreleased]
### Added ### Added
- `zcash_primitives::sapling::redjubjub::PublicKey::verify_with_zip216`, for
controlling how RedJubjub signatures are validated. `PublicKey::verify` has
been altered to always use post-ZIP 216 validation rules.
- `zcash_primitives::transaction::Builder::with_progress_notifier`, for setting - `zcash_primitives::transaction::Builder::with_progress_notifier`, for setting
a notification channel on which transaction build progress updates will be a notification channel on which transaction build progress updates will be
sent. sent.

View File

@ -5,7 +5,7 @@
use ff::{Field, PrimeField}; use ff::{Field, PrimeField};
use group::GroupEncoding; use group::GroupEncoding;
use jubjub::{ExtendedPoint, SubgroupPoint}; use jubjub::{AffinePoint, ExtendedPoint, SubgroupPoint};
use rand_core::RngCore; use rand_core::RngCore;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::ops::{AddAssign, MulAssign, Neg}; use std::ops::{AddAssign, MulAssign, Neg};
@ -123,13 +123,27 @@ impl PublicKey {
} }
pub fn verify(&self, msg: &[u8], sig: &Signature, p_g: SubgroupPoint) -> bool { pub fn verify(&self, msg: &[u8], sig: &Signature, p_g: SubgroupPoint) -> bool {
self.verify_with_zip216(msg, sig, p_g, true)
}
pub fn verify_with_zip216(
&self,
msg: &[u8],
sig: &Signature,
p_g: SubgroupPoint,
zip216_enabled: bool,
) -> bool {
// c = H*(Rbar || M) // c = H*(Rbar || M)
let c = h_star(&sig.rbar[..], msg); let c = h_star(&sig.rbar[..], msg);
// Signature checks: // Signature checks:
// R != invalid // R != invalid
let r = { let r = {
let r = ExtendedPoint::from_bytes(&sig.rbar); let r = if zip216_enabled {
ExtendedPoint::from_bytes(&sig.rbar)
} else {
AffinePoint::from_bytes_pre_zip216_compatibility(sig.rbar).map(|p| p.to_extended())
};
if r.is_none().into() { if r.is_none().into() {
return false; return false;
} }

View File

@ -8,11 +8,17 @@ and this library adheres to Rust's notion of
## [Unreleased] ## [Unreleased]
### Changed ### Changed
- MSRV is now 1.51.0. - MSRV is now 1.51.0.
- `zcash_proofs::sapling::SaplingVerificationContext::new` now takes a
`zip216_enabled` boolean; this is used to control how RedJubjub signatures are
validated.
- Renamed the following in `zcash_proofs::circuit::sprout` to use lower-case - Renamed the following in `zcash_proofs::circuit::sprout` to use lower-case
abbreviations (matching Rust naming conventions): abbreviations (matching Rust naming conventions):
- `JSInput` to `JsInput` - `JSInput` to `JsInput`
- `JSOutput` to `JsOutput` - `JSOutput` to `JsOutput`
### Removed
- `zcash_proofs::sapling::SaplingVerificationContext: Default`
## [0.5.0] - 2021-03-26 ## [0.5.0] - 2021-03-26
### Added ### Added
- `zcash_proofs::ZcashParameters` - `zcash_proofs::ZcashParameters`

View File

@ -16,19 +16,15 @@ use super::compute_value_balance;
pub struct SaplingVerificationContext { pub struct SaplingVerificationContext {
// (sum of the Spend value commitments) - (sum of the Output value commitments) // (sum of the Spend value commitments) - (sum of the Output value commitments)
cv_sum: jubjub::ExtendedPoint, cv_sum: jubjub::ExtendedPoint,
} zip216_enabled: bool,
impl Default for SaplingVerificationContext {
fn default() -> Self {
SaplingVerificationContext::new()
}
} }
impl SaplingVerificationContext { impl SaplingVerificationContext {
/// Construct a new context to be used with a single transaction. /// Construct a new context to be used with a single transaction.
pub fn new() -> Self { pub fn new(zip216_enabled: bool) -> Self {
SaplingVerificationContext { SaplingVerificationContext {
cv_sum: jubjub::ExtendedPoint::identity(), cv_sum: jubjub::ExtendedPoint::identity(),
zip216_enabled,
} }
} }
@ -62,7 +58,12 @@ impl SaplingVerificationContext {
(&mut data_to_be_signed[32..64]).copy_from_slice(&sighash_value[..]); (&mut data_to_be_signed[32..64]).copy_from_slice(&sighash_value[..]);
// Verify the spend_auth_sig // Verify the spend_auth_sig
if !rk.verify(&data_to_be_signed, &spend_auth_sig, SPENDING_KEY_GENERATOR) { if !rk.verify_with_zip216(
&data_to_be_signed,
&spend_auth_sig,
SPENDING_KEY_GENERATOR,
self.zip216_enabled,
) {
return false; return false;
} }
@ -161,10 +162,11 @@ impl SaplingVerificationContext {
(&mut data_to_be_signed[32..64]).copy_from_slice(&sighash_value[..]); (&mut data_to_be_signed[32..64]).copy_from_slice(&sighash_value[..]);
// Verify the binding_sig // Verify the binding_sig
bvk.verify( bvk.verify_with_zip216(
&data_to_be_signed, &data_to_be_signed,
&binding_sig, &binding_sig,
VALUE_COMMITMENT_RANDOMNESS_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR,
self.zip216_enabled,
) )
} }
} }