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]
### 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
a notification channel on which transaction build progress updates will be
sent.

View File

@ -5,7 +5,7 @@
use ff::{Field, PrimeField};
use group::GroupEncoding;
use jubjub::{ExtendedPoint, SubgroupPoint};
use jubjub::{AffinePoint, ExtendedPoint, SubgroupPoint};
use rand_core::RngCore;
use std::io::{self, Read, Write};
use std::ops::{AddAssign, MulAssign, Neg};
@ -123,13 +123,27 @@ impl PublicKey {
}
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)
let c = h_star(&sig.rbar[..], msg);
// Signature checks:
// R != invalid
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() {
return false;
}

View File

@ -8,11 +8,17 @@ and this library adheres to Rust's notion of
## [Unreleased]
### Changed
- 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
abbreviations (matching Rust naming conventions):
- `JSInput` to `JsInput`
- `JSOutput` to `JsOutput`
### Removed
- `zcash_proofs::sapling::SaplingVerificationContext: Default`
## [0.5.0] - 2021-03-26
### Added
- `zcash_proofs::ZcashParameters`

View File

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