From ed61734caf2e4f5342948b3df79a70baecc01fea Mon Sep 17 00:00:00 2001 From: jowparks Date: Thu, 11 Jan 2024 12:57:33 -0800 Subject: [PATCH] pass only required keys to MerkleNote, output builder, and mint builder (#4534) --- benchmarks/benches/merkle_note.rs | 14 ++++++- ironfish-rust/src/merkle_note.rs | 38 ++++++++++++------ ironfish-rust/src/transaction/mints.rs | 31 +++++++++++---- ironfish-rust/src/transaction/mod.rs | 6 ++- ironfish-rust/src/transaction/outputs.rs | 49 ++++++++++++++++++------ 5 files changed, 104 insertions(+), 34 deletions(-) diff --git a/benchmarks/benches/merkle_note.rs b/benchmarks/benches/merkle_note.rs index ff02a74d66..4ea13d1a20 100644 --- a/benchmarks/benches/merkle_note.rs +++ b/benchmarks/benches/merkle_note.rs @@ -22,7 +22,12 @@ pub fn decrypt_note_for_spender(c: &mut Criterion) { let ekp = EphemeralKeyPair::new(); let value_commitment = ValueCommitment::new(note.value(), note.asset_generator()); - let merkle_note = MerkleNote::new(&spender_key, ¬e, &value_commitment, &ekp); + let merkle_note = MerkleNote::new( + spender_key.outgoing_view_key(), + ¬e, + &value_commitment, + &ekp, + ); return (spender_key.outgoing_view_key().clone(), merkle_note); }, @@ -53,7 +58,12 @@ pub fn decrypt_note_for_owner(c: &mut Criterion) { let ekp = EphemeralKeyPair::new(); let value_commitment = ValueCommitment::new(note.value(), note.asset_generator()); - let merkle_note = MerkleNote::new(&spender_key, ¬e, &value_commitment, &ekp); + let merkle_note = MerkleNote::new( + spender_key.outgoing_view_key(), + ¬e, + &value_commitment, + &ekp, + ); return (receiver_key.incoming_view_key().clone(), merkle_note); }, diff --git a/ironfish-rust/src/merkle_note.rs b/ironfish-rust/src/merkle_note.rs index 9b874d76a6..7607f75b92 100644 --- a/ironfish-rust/src/merkle_note.rs +++ b/ironfish-rust/src/merkle_note.rs @@ -7,7 +7,7 @@ use crate::{errors::IronfishError, keys::EphemeralKeyPair, serializing::read_poi /// Implement a merkle note to store all the values that need to go into a merkle tree. /// A tree containing these values can serve as a snapshot of the entire chain. use super::{ - keys::{shared_secret, IncomingViewKey, OutgoingViewKey, PublicAddress, SaplingKey}, + keys::{shared_secret, IncomingViewKey, OutgoingViewKey, PublicAddress}, note::{Note, ENCRYPTED_NOTE_SIZE}, serializing::{aead, read_scalar}, witness::{WitnessNode, WitnessTrait}, @@ -73,7 +73,7 @@ impl PartialEq for MerkleNote { impl MerkleNote { pub fn new( - spender_key: &SaplingKey, + outgoing_view_key: &OutgoingViewKey, note: &Note, value_commitment: &ValueCommitment, diffie_hellman_keys: &EphemeralKeyPair, @@ -86,7 +86,7 @@ impl MerkleNote { key_bytes[32..].clone_from_slice(secret_key.to_repr().as_ref()); let encryption_key = calculate_key_for_encryption_keys( - spender_key.outgoing_view_key(), + outgoing_view_key, &value_commitment.commitment().into(), ¬e.commitment_point(), public_key, @@ -298,8 +298,12 @@ mod test { let value_commitment = ValueCommitment::new(note.value, note.asset_generator()); - let merkle_note = - MerkleNote::new(&spender_key, ¬e, &value_commitment, &diffie_hellman_keys); + let merkle_note = MerkleNote::new( + spender_key.outgoing_view_key(), + ¬e, + &value_commitment, + &diffie_hellman_keys, + ); assert_ne!( &merkle_note.note_encryption_keys, @@ -348,8 +352,12 @@ mod test { let value_commitment = ValueCommitment::new(note.value, note.asset_generator()); - let merkle_note = - MerkleNote::new(&spender_key, ¬e, &value_commitment, &diffie_hellman_keys); + let merkle_note = MerkleNote::new( + spender_key.outgoing_view_key(), + ¬e, + &value_commitment, + &diffie_hellman_keys, + ); merkle_note .decrypt_note_for_owner(receiver_key.incoming_view_key()) .expect("should be able to decrypt note for owner"); @@ -381,8 +389,12 @@ mod test { let value_commitment = ValueCommitment::new(note.value, note.asset_generator()); - let merkle_note = - MerkleNote::new(&spender_key, ¬e, &value_commitment, &diffie_hellman_keys); + let merkle_note = MerkleNote::new( + spender_key.outgoing_view_key(), + ¬e, + &value_commitment, + &diffie_hellman_keys, + ); assert!(merkle_note .decrypt_note_for_owner(third_party_key.incoming_view_key()) @@ -406,8 +418,12 @@ mod test { let value_commitment = ValueCommitment::new(note.value, note.asset_generator()); - let mut merkle_note = - MerkleNote::new(&spender_key, ¬e, &value_commitment, &diffie_hellman_keys); + let mut merkle_note = MerkleNote::new( + spender_key.outgoing_view_key(), + ¬e, + &value_commitment, + &diffie_hellman_keys, + ); merkle_note .decrypt_note_for_owner(spender_key.incoming_view_key()) .expect("should be able to decrypt note for owner"); diff --git a/ironfish-rust/src/transaction/mints.rs b/ironfish-rust/src/transaction/mints.rs index e87f76545e..2ee55dc902 100644 --- a/ironfish-rust/src/transaction/mints.rs +++ b/ironfish-rust/src/transaction/mints.rs @@ -13,6 +13,7 @@ use ironfish_zkp::{ constants::SPENDING_KEY_GENERATOR, proofs::MintAsset, redjubjub::{self, Signature}, + ProofGenerationKey, }; use jubjub::ExtendedPoint; use rand::thread_rng; @@ -58,12 +59,13 @@ impl MintBuilder { pub fn build( &self, - spender_key: &SaplingKey, + proof_generation_key: &ProofGenerationKey, + public_address: &PublicAddress, public_key_randomness: &jubjub::Fr, randomized_public_key: &redjubjub::PublicKey, ) -> Result { let circuit = MintAsset { - proof_generation_key: Some(spender_key.sapling_proof_generation_key()), + proof_generation_key: Some(proof_generation_key.clone()), public_key_randomness: Some(*public_key_randomness), }; @@ -78,7 +80,7 @@ impl MintBuilder { proof, asset: self.asset, value: self.value, - owner: spender_key.public_address(), + owner: *public_address, transfer_ownership_to: self.transfer_ownership_to, authorizing_signature: blank_signature, }; @@ -386,7 +388,12 @@ mod test { let mint = MintBuilder::new(asset, value); let unsigned_mint = mint - .build(&key, &public_key_randomness, &randomized_public_key) + .build( + &key.sapling_proof_generation_key(), + &key.public_address(), + &public_key_randomness, + &randomized_public_key, + ) .expect("should build valid mint description"); // Signature comes from the transaction, normally @@ -443,7 +450,7 @@ mod test { let mint = MintBuilder::new(asset, value); assert!(matches!( - mint.build(&owner_key, &public_key_randomness, &randomized_public_key), + mint.build(&owner_key.sapling_proof_generation_key(), &owner_key.public_address(), &public_key_randomness, &randomized_public_key), Err(e) if matches!(e.kind, IronfishErrorKind::InvalidMintProof) )) } @@ -549,7 +556,12 @@ mod test { .randomize(public_key_randomness, *SPENDING_KEY_GENERATOR); let unsigned_mint = mint - .build(key, &public_key_randomness, &randomized_public_key) + .build( + &key.sapling_proof_generation_key(), + &key.public_address(), + &public_key_randomness, + &randomized_public_key, + ) .expect("should build valid mint description"); // Signature comes from the transaction, normally @@ -650,7 +662,12 @@ mod test { value, ); - let unsigned_mint = mint.build(&key, &public_key_randomness, &randomized_public_key); + let unsigned_mint = mint.build( + &key.sapling_proof_generation_key(), + &key.public_address(), + &public_key_randomness, + &randomized_public_key, + ); assert!(unsigned_mint.is_err()); } } diff --git a/ironfish-rust/src/transaction/mod.rs b/ironfish-rust/src/transaction/mod.rs index e8ed5f0ca1..e084e2e839 100644 --- a/ironfish-rust/src/transaction/mod.rs +++ b/ironfish-rust/src/transaction/mod.rs @@ -305,7 +305,8 @@ impl ProposedTransaction { let mut output_descriptions = Vec::with_capacity(self.outputs.len()); for output in &self.outputs { output_descriptions.push(output.build( - &self.spender_key, + &self.spender_key.sapling_proof_generation_key(), + self.spender_key.outgoing_view_key(), &self.public_key_randomness, &randomized_public_key, )?); @@ -314,7 +315,8 @@ impl ProposedTransaction { let mut unsigned_mints = Vec::with_capacity(self.mints.len()); for mint in &self.mints { unsigned_mints.push(mint.build( - &self.spender_key, + &self.spender_key.sapling_proof_generation_key(), + &self.spender_key.public_address(), &self.public_key_randomness, &randomized_public_key, )?); diff --git a/ironfish-rust/src/transaction/outputs.rs b/ironfish-rust/src/transaction/outputs.rs index b5c5fa5709..52d7e6aca1 100644 --- a/ironfish-rust/src/transaction/outputs.rs +++ b/ironfish-rust/src/transaction/outputs.rs @@ -4,17 +4,18 @@ use crate::{ errors::{IronfishError, IronfishErrorKind}, - keys::{EphemeralKeyPair, SaplingKey}, + keys::EphemeralKeyPair, merkle_note::MerkleNote, note::Note, sapling_bls12::SAPLING, + OutgoingViewKey, }; use bellperson::groth16; use blstrs::{Bls12, Scalar}; use ff::Field; use group::Curve; -use ironfish_zkp::{primitives::ValueCommitment, proofs::Output, redjubjub}; +use ironfish_zkp::{primitives::ValueCommitment, proofs::Output, redjubjub, ProofGenerationKey}; use jubjub::ExtendedPoint; use rand::thread_rng; @@ -76,7 +77,8 @@ impl OutputBuilder { /// transactions. pub(crate) fn build( &self, - spender_key: &SaplingKey, + proof_generation_key: &ProofGenerationKey, + outgoing_view_key: &OutgoingViewKey, public_key_randomness: &jubjub::Fr, randomized_public_key: &redjubjub::PublicKey, ) -> Result { @@ -88,7 +90,7 @@ impl OutputBuilder { commitment_randomness: Some(self.note.randomness), esk: Some(*diffie_hellman_keys.secret()), asset_id: *self.note.asset_id().as_bytes(), - proof_generation_key: Some(spender_key.sapling_proof_generation_key()), + proof_generation_key: Some(proof_generation_key.clone()), ar: Some(*public_key_randomness), }; @@ -98,7 +100,7 @@ impl OutputBuilder { MerkleNote::new_for_miners_fee(&self.note, &self.value_commitment, &diffie_hellman_keys) } else { MerkleNote::new( - spender_key, + outgoing_view_key, &self.note, &self.value_commitment, &diffie_hellman_keys, @@ -252,7 +254,12 @@ mod test { output.set_is_miners_fee(); let proof = output - .build(&spender_key, &public_key_randomness, &randomized_public_key) + .build( + &spender_key.sapling_proof_generation_key(), + spender_key.outgoing_view_key(), + &public_key_randomness, + &randomized_public_key, + ) .expect("should be able to build output proof"); assert_eq!( @@ -280,7 +287,12 @@ mod test { let output = OutputBuilder::new(note); let proof = output - .build(&spender_key, &public_key_randomness, &randomized_public_key) + .build( + &spender_key.sapling_proof_generation_key(), + spender_key.outgoing_view_key(), + &public_key_randomness, + &randomized_public_key, + ) .expect("should be able to build output proof"); assert_ne!( @@ -314,7 +326,12 @@ mod test { let output = OutputBuilder::new(note); let description = output - .build(&spender_key, &public_key_randomness, &randomized_public_key) + .build( + &spender_key.sapling_proof_generation_key(), + spender_key.outgoing_view_key(), + &public_key_randomness, + &randomized_public_key, + ) .expect("should be able to build output proof"); verify_output_proof( @@ -326,7 +343,8 @@ mod test { // Wrong spender key assert!(output .build( - &receiver_key, + &receiver_key.sapling_proof_generation_key(), + receiver_key.outgoing_view_key(), &public_key_randomness, &randomized_public_key ) @@ -335,7 +353,8 @@ mod test { // Wrong public key randomness assert!(output .build( - &spender_key, + &spender_key.sapling_proof_generation_key(), + spender_key.outgoing_view_key(), &other_public_key_randomness, &randomized_public_key ) @@ -344,7 +363,8 @@ mod test { // Wrong randomized public key assert!(output .build( - &spender_key, + &spender_key.sapling_proof_generation_key(), + spender_key.outgoing_view_key(), &public_key_randomness, &other_randomized_public_key ) @@ -376,7 +396,12 @@ mod test { let output = OutputBuilder::new(note); let proof = output - .build(&spender_key, &public_key_randomness, &randomized_public_key) + .build( + &spender_key.sapling_proof_generation_key(), + spender_key.outgoing_view_key(), + &public_key_randomness, + &randomized_public_key, + ) .expect("Should be able to build output proof"); verify_output_proof(&proof.proof, &proof.public_inputs(&randomized_public_key)) .expect("proof should check out");