Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add orchard binding_verification_key #2441

Merged
merged 12 commits into from
Aug 16, 2021
38 changes: 36 additions & 2 deletions zebra-chain/src/orchard/shielded_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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<Binding> {
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.
Expand Down
9 changes: 8 additions & 1 deletion zebra-consensus/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down