Skip to content

Commit

Permalink
Make proof reading during transaction validation safe.
Browse files Browse the repository at this point in the history
  • Loading branch information
Murisi Tarusenga committed Apr 14, 2023
1 parent 6bfb0bc commit 39faf81
Showing 1 changed file with 51 additions and 27 deletions.
78 changes: 51 additions & 27 deletions shared/src/ledger/masp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ pub fn check_spend(
parameters: &PreparedVerifyingKey<Bls12>,
) -> bool {
let zkproof =
masp_proofs::bellman::groth16::Proof::read(spend.zkproof.as_slice()).unwrap();
masp_proofs::bellman::groth16::Proof::read(spend.zkproof.as_slice());
let zkproof = match zkproof {
Ok(zkproof) => zkproof,
_ => return false,
};
ctx.check_spend(
spend.cv,
spend.anchor,
Expand All @@ -130,8 +134,13 @@ pub fn check_output(
parameters: &PreparedVerifyingKey<Bls12>,
) -> bool {
let zkproof =
masp_proofs::bellman::groth16::Proof::read(output.zkproof.as_slice()).unwrap();
let epk = match masp_proofs::jubjub::ExtendedPoint::from_bytes(&output.ephemeral_key.0).into() {
masp_proofs::bellman::groth16::Proof::read(output.zkproof.as_slice());
let zkproof = match zkproof {
Ok(zkproof) => zkproof,
_ => return false,
};
let epk = masp_proofs::jubjub::ExtendedPoint::from_bytes(&output.ephemeral_key.0);
let epk = match epk.into() {
Some(p) => p,
None => return false,
};
Expand All @@ -151,35 +160,27 @@ pub fn check_convert(
parameters: &PreparedVerifyingKey<Bls12>,
) -> bool {
let zkproof =
masp_proofs::bellman::groth16::Proof::read(convert.zkproof.as_slice()).unwrap();
masp_proofs::bellman::groth16::Proof::read(convert.zkproof.as_slice());
let zkproof = match zkproof {
Ok(zkproof) => zkproof,
_ => return false,
};
ctx.check_convert(convert.cv, convert.anchor, zkproof, parameters)
}

pub struct Nauthorized;
/// Represents an authorization where the Sapling bundle is authorized and the
/// transparent bundle is unauthorized.
pub struct PartialAuthorized;

impl Authorization for Nauthorized {
impl Authorization for PartialAuthorized {
type TransparentAuth = <Unauthorized as Authorization>::TransparentAuth;
type SaplingAuth = <Authorized as Authorization>::SaplingAuth;
}

/// Verify a shielded transaction.
pub fn verify_shielded_tx(transaction: &Transaction) -> bool {
tracing::info!("entered verify_shielded_tx()");

let sapling_bundle = if let Some(bundle) = transaction.sapling_bundle() {
bundle
} else {
return false;
};

let mut ctx = SaplingVerificationContext::new(true);
let tx_data = transaction.deref();

let (_, spend_pvk) = load_spend_params();
let (_, convert_pvk) = load_convert_params();
let (_, output_pvk) = load_output_params();

// Deauthorize the transparent bundle
/// Partially deauthorize the transparent bundle
fn partial_deauthorize(
tx_data: &TransactionData<Authorized>
) -> Option<TransactionData<PartialAuthorized>> {
let transp = tx_data.transparent_bundle().and_then(|x| {
let mut tb = TransparentBuilder::empty();
for vin in &x.vin {
Expand All @@ -195,16 +196,34 @@ pub fn verify_shielded_tx(transaction: &Transaction) -> bool {
tb.build()
});
if tx_data.transparent_bundle().is_some() != transp.is_some() {
return false;
return None;
}
let unauth_tx_data: TransactionData<Nauthorized> = TransactionData::from_parts(
Some(TransactionData::from_parts(
tx_data.version(),
tx_data.consensus_branch_id(),
tx_data.lock_time(),
tx_data.expiry_height(),
transp,
tx_data.sapling_bundle().cloned(),
);
))
}

/// Verify a shielded transaction.
pub fn verify_shielded_tx(transaction: &Transaction) -> bool {
tracing::info!("entered verify_shielded_tx()");

let sapling_bundle = if let Some(bundle) = transaction.sapling_bundle() {
bundle
} else {
return false;
};
let tx_data = transaction.deref();

// Partially deauthorize the transparent bundle
let unauth_tx_data = match partial_deauthorize(tx_data) {
Some(tx_data) => tx_data,
None => return false,
};

let txid_parts = unauth_tx_data.digest(TxIdDigester);
// the commitment being signed is shared across all Sapling inputs; once
Expand All @@ -215,6 +234,11 @@ pub fn verify_shielded_tx(transaction: &Transaction) -> bool {

tracing::info!("sighash computed");

let (_, spend_pvk) = load_spend_params();
let (_, convert_pvk) = load_convert_params();
let (_, output_pvk) = load_output_params();

let mut ctx = SaplingVerificationContext::new(true);
let spends_valid = sapling_bundle
.shielded_spends
.iter()
Expand Down

0 comments on commit 39faf81

Please sign in to comment.