diff --git a/taiga_halo2/benches/action_proof.rs b/taiga_halo2/benches/action_proof.rs index deba38ee..49b99e97 100644 --- a/taiga_halo2/benches/action_proof.rs +++ b/taiga_halo2/benches/action_proof.rs @@ -13,7 +13,7 @@ use taiga_halo2::{ ACTION_CIRCUIT_PARAMS_SIZE, ACTION_PROVING_KEY, ACTION_VERIFYING_KEY, SETUP_PARAMS_MAP, TAIGA_COMMITMENT_TREE_DEPTH, }, - merkle_tree::MerklePath, + merkle_tree::{Anchor, MerklePath}, note::{Note, NoteType, RandomSeed}, nullifier::{Nullifier, NullifierKeyContainer}, }; @@ -66,8 +66,9 @@ fn bench_action_proof(name: &str, c: &mut Criterion) { } }; let input_merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); + let anchor = Anchor::from(pallas::Base::random(&mut rng)); let rseed = RandomSeed::random(&mut rng); - ActionInfo::new(input_note, input_merkle_path, output_note, rseed) + ActionInfo::new(input_note, input_merkle_path, anchor, output_note, rseed) }; let (action, action_circuit) = action_info.build(); let params = SETUP_PARAMS_MAP.get(&ACTION_CIRCUIT_PARAMS_SIZE).unwrap(); diff --git a/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs b/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs index 887e6a8e..30063018 100644 --- a/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs +++ b/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs @@ -15,7 +15,7 @@ use taiga_halo2::{ }, }, constant::TAIGA_COMMITMENT_TREE_DEPTH, - merkle_tree::MerklePath, + merkle_tree::{Anchor, MerklePath}, note::{InputNoteProvingInfo, OutputNoteProvingInfo}, nullifier::{Nullifier, NullifierKeyContainer}, shielded_ptx::ShieldedPartialTransaction, @@ -68,6 +68,9 @@ pub fn create_transaction(mut rng: R) -> Transaction { let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); + // Fetch a valid anchor for dummy notes + let anchor = Anchor::from(pallas::Base::random(&mut rng)); + // The first partial transaction: // Alice consumes 1 "BTC" and 2 "ETH". // Alice creates a cascade intent note and 1 "BTC" to Bob. @@ -143,6 +146,7 @@ pub fn create_transaction(mut rng: R) -> Transaction { InputNoteProvingInfo::new( cascade_intent_note, merkle_path.clone(), + Some(anchor), Box::new(intent_vp), vec![], ) diff --git a/taiga_halo2/examples/tx_examples/partial_fulfillment_token_swap.rs b/taiga_halo2/examples/tx_examples/partial_fulfillment_token_swap.rs index 54a7b8ee..d34818c1 100644 --- a/taiga_halo2/examples/tx_examples/partial_fulfillment_token_swap.rs +++ b/taiga_halo2/examples/tx_examples/partial_fulfillment_token_swap.rs @@ -20,7 +20,7 @@ use taiga_halo2::{ }, }, constant::TAIGA_COMMITMENT_TREE_DEPTH, - merkle_tree::MerklePath, + merkle_tree::{Anchor, MerklePath}, note::{InputNoteProvingInfo, Note, OutputNoteProvingInfo}, nullifier::{Nullifier, NullifierKeyContainer}, shielded_ptx::ShieldedPartialTransaction, @@ -70,6 +70,9 @@ pub fn create_token_intent_ptx( let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); + // Fetch a valid anchor for dummy notes + let anchor = Anchor::from(pallas::Base::random(&mut rng)); + // Create the input note proving info let input_note_proving_info = generate_input_token_note_proving_info( &mut rng, @@ -101,6 +104,7 @@ pub fn create_token_intent_ptx( let padding_input_note_proving_info = InputNoteProvingInfo::create_padding_note_proving_info( padding_input_note, merkle_path, + anchor, input_notes, output_notes, ); @@ -182,6 +186,9 @@ pub fn consume_token_intent_ptx( let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); + // Fetch a valid anchor for dummy notes + let anchor = Anchor::from(pallas::Base::random(&mut rng)); + // Create the intent note proving info let intent_note_proving_info = { let intent_vp = PartialFulfillmentIntentValidityPredicateCircuit { @@ -197,6 +204,7 @@ pub fn consume_token_intent_ptx( InputNoteProvingInfo::new( intent_note, merkle_path.clone(), + Some(anchor), Box::new(intent_vp), vec![], ) @@ -216,6 +224,7 @@ pub fn consume_token_intent_ptx( let padding_input_note_proving_info = InputNoteProvingInfo::create_padding_note_proving_info( padding_input_note, merkle_path, + anchor, input_notes, output_notes, ); diff --git a/taiga_halo2/examples/tx_examples/token.rs b/taiga_halo2/examples/tx_examples/token.rs index 75fb3e44..44e6ba16 100644 --- a/taiga_halo2/examples/tx_examples/token.rs +++ b/taiga_halo2/examples/tx_examples/token.rs @@ -12,7 +12,7 @@ use taiga_halo2::{ }, }, constant::TAIGA_COMMITMENT_TREE_DEPTH, - merkle_tree::MerklePath, + merkle_tree::{Anchor, MerklePath}, note::{InputNoteProvingInfo, Note, OutputNoteProvingInfo, RandomSeed}, nullifier::{Nullifier, NullifierKeyContainer}, shielded_ptx::ShieldedPartialTransaction, @@ -89,6 +89,9 @@ pub fn create_token_swap_ptx( // Generate proving info let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); + // Fetch a valid anchor for padding input notes + let anchor = Anchor::from(pallas::Base::random(&mut rng)); + // Create the input note proving info let input_note_proving_info = generate_input_token_note_proving_info( &mut rng, @@ -115,6 +118,7 @@ pub fn create_token_swap_ptx( let padding_input_note_proving_info = InputNoteProvingInfo::create_padding_note_proving_info( padding_input_note, merkle_path, + anchor, input_notes, output_notes, ); diff --git a/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs b/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs index 53a3772f..d93e4843 100644 --- a/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs +++ b/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs @@ -20,7 +20,7 @@ use taiga_halo2::{ }, }, constant::TAIGA_COMMITMENT_TREE_DEPTH, - merkle_tree::MerklePath, + merkle_tree::{Anchor, MerklePath}, note::{InputNoteProvingInfo, Note, OutputNoteProvingInfo}, nullifier::{Nullifier, NullifierKeyContainer}, shielded_ptx::ShieldedPartialTransaction, @@ -72,6 +72,8 @@ pub fn create_token_intent_ptx( let padding_input_note = Note::random_padding_input_note(&mut rng); let padding_input_note_nf = padding_input_note.get_nf().unwrap(); let padding_output_note = Note::random_padding_output_note(&mut rng, padding_input_note_nf); + // Fetch a valid anchor for padding input notes + let anchor = Anchor::from(pallas::Base::random(&mut rng)); let input_notes = [input_note, padding_input_note]; let output_notes = [intent_note, padding_output_note]; @@ -109,6 +111,7 @@ pub fn create_token_intent_ptx( let padding_input_note_proving_info = InputNoteProvingInfo::create_padding_note_proving_info( padding_input_note, merkle_path, + anchor, input_notes, output_notes, ); @@ -182,6 +185,9 @@ pub fn consume_token_intent_ptx( let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); + // Fetch a valid anchor for dummy notes + let anchor = Anchor::from(pallas::Base::random(&mut rng)); + // Create the intent note proving info let intent_note_proving_info = { let intent_vp = OrRelationIntentValidityPredicateCircuit { @@ -197,6 +203,7 @@ pub fn consume_token_intent_ptx( InputNoteProvingInfo::new( intent_note, merkle_path.clone(), + Some(anchor), Box::new(intent_vp), vec![], ) @@ -216,6 +223,7 @@ pub fn consume_token_intent_ptx( let padding_input_note_proving_info = InputNoteProvingInfo::create_padding_note_proving_info( padding_input_note, merkle_path, + anchor, input_notes, output_notes, ); diff --git a/taiga_halo2/src/action.rs b/taiga_halo2/src/action.rs index 7317efc1..b7f266b3 100644 --- a/taiga_halo2/src/action.rs +++ b/taiga_halo2/src/action.rs @@ -1,7 +1,7 @@ use crate::{ circuit::action_circuit::ActionCircuit, constant::{PRF_EXPAND_INPUT_VP_CM_R, PRF_EXPAND_OUTPUT_VP_CM_R}, - merkle_tree::{Anchor, MerklePath, Node}, + merkle_tree::{Anchor, MerklePath}, note::{InputNoteProvingInfo, Note, NoteCommitment, OutputNoteProvingInfo, RandomSeed}, nullifier::Nullifier, value_commitment::ValueCommitment, @@ -44,6 +44,7 @@ pub struct ActionPublicInputs { pub struct ActionInfo { input_note: Note, input_merkle_path: MerklePath, + input_anchor: Anchor, output_note: Note, // rseed is to generate the randomness of the value commitment and vp commitments rseed: RandomSeed, @@ -118,12 +119,14 @@ impl ActionInfo { pub fn new( input_note: Note, input_merkle_path: MerklePath, + input_anchor: Anchor, output_note: Note, rseed: RandomSeed, ) -> Self { Self { input_note, input_merkle_path, + input_anchor, output_note, rseed, } @@ -138,6 +141,7 @@ impl ActionInfo { Self { input_note: input.note, input_merkle_path: input.merkle_path, + input_anchor: input.anchor, output_note: output.note, rseed, } @@ -166,10 +170,6 @@ impl ActionInfo { ); let cm = self.output_note.commitment(); - let anchor = { - let cm_node = Node::from(&self.input_note); - self.input_merkle_path.root(cm_node) - }; let rcv = self.get_rcv(); let cv_net = ValueCommitment::new(&self.input_note, &self.output_note, &rcv); @@ -185,7 +185,7 @@ impl ActionInfo { let action = ActionPublicInputs { nf, cm, - anchor, + anchor: self.input_anchor, cv_net, input_vp_commitment, output_vp_commitment, @@ -208,7 +208,7 @@ impl ActionInfo { pub mod tests { use super::ActionInfo; use crate::constant::TAIGA_COMMITMENT_TREE_DEPTH; - use crate::merkle_tree::MerklePath; + use crate::merkle_tree::{MerklePath, Node}; use crate::note::tests::{random_input_note, random_output_note}; use crate::note::RandomSeed; use rand::RngCore; @@ -217,7 +217,17 @@ pub mod tests { let input_note = random_input_note(&mut rng); let output_note = random_output_note(&mut rng, input_note.get_nf().unwrap()); let input_merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); + let input_anchor = { + let cm_note = Node::from(&input_note); + input_merkle_path.root(cm_note) + }; let rseed = RandomSeed::random(&mut rng); - ActionInfo::new(input_note, input_merkle_path, output_note, rseed) + ActionInfo::new( + input_note, + input_merkle_path, + input_anchor, + output_note, + rseed, + ) } } diff --git a/taiga_halo2/src/circuit/vp_examples/token.rs b/taiga_halo2/src/circuit/vp_examples/token.rs index 43a72352..514ab1d9 100644 --- a/taiga_halo2/src/circuit/vp_examples/token.rs +++ b/taiga_halo2/src/circuit/vp_examples/token.rs @@ -381,6 +381,7 @@ pub fn generate_input_token_note_proving_info( InputNoteProvingInfo::new( input_note, merkle_path, + None, Box::new(token_vp), vec![Box::new(token_auth_vp)], ) diff --git a/taiga_halo2/src/note.rs b/taiga_halo2/src/note.rs index 83caf9d9..d7a2da51 100644 --- a/taiga_halo2/src/note.rs +++ b/taiga_halo2/src/note.rs @@ -7,7 +7,7 @@ use crate::{ NUM_NOTE, POSEIDON_TO_CURVE_INPUT_LEN, PRF_EXPAND_PERSONALIZATION, PRF_EXPAND_PSI, PRF_EXPAND_PUBLIC_INPUT_PADDING, PRF_EXPAND_RCM, PRF_EXPAND_VCM_R, }, - merkle_tree::MerklePath, + merkle_tree::{Anchor, MerklePath, Node}, nullifier::{Nullifier, NullifierKeyContainer}, utils::{poseidon_hash_n, poseidon_to_curve}, }; @@ -126,6 +126,7 @@ pub struct RandomSeed([u8; 32]); pub struct InputNoteProvingInfo { pub note: Note, pub merkle_path: MerklePath, + pub anchor: Anchor, application_vp: Box, dynamic_vps: Vec>, } @@ -488,12 +489,22 @@ impl InputNoteProvingInfo { pub fn new( note: Note, merkle_path: MerklePath, + // If no custom anchor is provided then the standard one is calculated from the note and path. + custom_anchor: Option, application_vp: Box, dynamic_vps: Vec>, ) -> Self { + let anchor = match custom_anchor { + Some(anchor) => anchor, + None => { + let cm_note = Node::from(¬e); + merkle_path.root(cm_note) + } + }; Self { note, merkle_path, + anchor, application_vp, dynamic_vps, } @@ -510,6 +521,7 @@ impl InputNoteProvingInfo { pub fn create_padding_note_proving_info( padding_note: Note, merkle_path: MerklePath, + anchor: Anchor, input_notes: [Note; NUM_NOTE], output_notes: [Note; NUM_NOTE], ) -> Self { @@ -518,7 +530,7 @@ impl InputNoteProvingInfo { input_notes, output_notes, }); - InputNoteProvingInfo::new(padding_note, merkle_path, trivail_vp, vec![]) + InputNoteProvingInfo::new(padding_note, merkle_path, Some(anchor), trivail_vp, vec![]) } } @@ -613,7 +625,7 @@ pub mod tests { let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); let application_vp = Box::new(random_trivial_vp_circuit(&mut rng)); let dynamic_vps = vec![]; - InputNoteProvingInfo::new(note, merkle_path, application_vp, dynamic_vps) + InputNoteProvingInfo::new(note, merkle_path, None, application_vp, dynamic_vps) } pub fn random_output_proving_info( diff --git a/taiga_halo2/src/shielded_ptx.rs b/taiga_halo2/src/shielded_ptx.rs index 9aac17b6..8e0d53a3 100644 --- a/taiga_halo2/src/shielded_ptx.rs +++ b/taiga_halo2/src/shielded_ptx.rs @@ -542,6 +542,7 @@ pub mod testing { let input_note_proving_info_1 = InputNoteProvingInfo::new( input_note_1, merkle_path.clone(), + None, input_application_vp_1, trivial_dynamic_vps.clone(), ); @@ -552,6 +553,7 @@ pub mod testing { let input_note_proving_info_2 = InputNoteProvingInfo::new( input_note_2, merkle_path, + None, input_application_vp_2, dynamic_vps.clone(), );