From c3c302309ae6f98416a5984ffdfd6930cc71833a Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 16 Aug 2021 16:16:25 -0300 Subject: [PATCH] Add orchard binding_verification_key (#2441) * add orchard binding_verification_key * Merge branch 'main' into issue2102 * Merge branch 'main' into issue2102 * fix the build * Merge branch 'main' into issue2102 * Merge branch 'main' into issue2102 * Fix docs Co-authored-by: Deirdre Connolly * Merge branch 'main' into issue2102 * rustfmt * readd binding validation * remove #2103 from the TODO list * Merge branch 'main' into issue2102 --- zebra-chain/src/orchard/shielded_data.rs | 38 ++++++++++++++++++++++-- zebra-consensus/src/transaction.rs | 9 +++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/zebra-chain/src/orchard/shielded_data.rs b/zebra-chain/src/orchard/shielded_data.rs index 0fd447e0ebc..0263625937a 100644 --- a/zebra-chain/src/orchard/shielded_data.rs +++ b/zebra-chain/src/orchard/shielded_data.rs @@ -12,9 +12,9 @@ use halo2::pasta::pallas; use crate::{ amount::{Amount, NegativeAllowed}, block::MAX_BLOCK_BYTES, - orchard::{tree, Action, Nullifier}, + orchard::{tree, Action, Nullifier, ValueCommitment}, primitives::{ - redpallas::{Binding, Signature, SpendAuth}, + redpallas::{self, Binding, Signature, SpendAuth}, Halo2Proof, }, serialization::{ @@ -51,6 +51,40 @@ impl ShieldedData { self.actions().map(|action| &action.nullifier) } + /// Calculate the Action binding verification key. + /// + /// Getting the binding signature validating key from the Action description + /// value commitments and the balancing value implicitly checks that the + /// balancing value is consistent with the value transferred in the + /// Action descriptions, but also proves that the signer knew the + /// randomness used for the Action value commitments, which + /// prevents replays of Action descriptions that perform an output. + /// In Orchard, all Action descriptions have a spend authorization signature, + /// therefore the proof of knowledge of the value commitment randomness + /// is less important, but stills provides defense in depth, and reduces the + /// differences between Orchard and Sapling. + /// + /// The net value of Orchard spends minus outputs in a transaction + /// is called the balancing value, measured in zatoshi as a signed integer + /// cv_balance. + /// + /// Consistency of cv_balance with the value commitments in Action + /// descriptions is enforced by the binding signature. + /// + /// Instead of generating a key pair at random, we generate it as a function + /// of the value commitments in the Action descriptions of the transaction, and + /// the balancing value. + /// + /// https://zips.z.cash/protocol/protocol.pdf#orchardbalance + pub fn binding_verification_key(&self) -> redpallas::VerificationKeyBytes { + let cv: ValueCommitment = self.actions().map(|action| action.cv).sum(); + let cv_balance: ValueCommitment = + ValueCommitment::new(pallas::Scalar::zero(), self.value_balance); + + let key_bytes: [u8; 32] = (cv - cv_balance).into(); + key_bytes.into() + } + /// Provide access to the `value_balance` field of the shielded data. /// /// Needed to calculate the sapling value balance. diff --git a/zebra-consensus/src/transaction.rs b/zebra-consensus/src/transaction.rs index f4d772210b5..791436884bf 100644 --- a/zebra-consensus/src/transaction.rs +++ b/zebra-consensus/src/transaction.rs @@ -326,7 +326,6 @@ where // - verify orchard shielded pool (ZIP-224) (#2105) // - ZIP-216 (#1798) // - ZIP-244 (#1874) - // - validate bindingSigOrchard (#2103) // - remaining consensus rules (#2379) // - remove `should_panic` from tests @@ -543,6 +542,14 @@ where .oneshot((action.rk, spend_auth_sig, &shielded_sighash).into()), ); } + + let bvk = orchard_shielded_data.binding_verification_key(); + + async_checks.push( + primitives::redpallas::VERIFIER + .clone() + .oneshot((bvk, orchard_shielded_data.binding_sig, &shielded_sighash).into()), + ); } Ok(async_checks)