diff --git a/taiga_halo2/benches/action_proof.rs b/taiga_halo2/benches/action_proof.rs index fa1dfc88..1613177c 100644 --- a/taiga_halo2/benches/action_proof.rs +++ b/taiga_halo2/benches/action_proof.rs @@ -14,63 +14,63 @@ use taiga_halo2::{ TAIGA_COMMITMENT_TREE_DEPTH, }, merkle_tree::MerklePath, - note::{Note, NoteType, RandomSeed}, nullifier::{Nullifier, NullifierKeyContainer}, + resource::{RandomSeed, Resource, ResourceKind}, }; fn bench_action_proof(name: &str, c: &mut Criterion) { let mut rng = OsRng; let action_info = { - let input_note = { - let rho = Nullifier::from(pallas::Base::random(&mut rng)); + let input_resource = { + let nonce = Nullifier::from(pallas::Base::random(&mut rng)); let nk = NullifierKeyContainer::from_key(pallas::Base::random(&mut rng)); - let note_type = { - let app_vk = pallas::Base::random(&mut rng); - let app_data_static = pallas::Base::random(&mut rng); - NoteType::new(app_vk, app_data_static) + let kind = { + let logic = pallas::Base::random(&mut rng); + let label = pallas::Base::random(&mut rng); + ResourceKind::new(logic, label) }; - let app_data_dynamic = pallas::Base::random(&mut rng); - let value: u64 = rng.gen(); + let value = pallas::Base::random(&mut rng); + let quantity: u64 = rng.gen(); let rseed = RandomSeed::random(&mut rng); - Note { - note_type, - app_data_dynamic, + Resource { + kind, value, + quantity, nk_container: nk, is_merkle_checked: true, - psi: rseed.get_psi(&rho), - rcm: rseed.get_rcm(&rho), - rho, + psi: rseed.get_psi(&nonce), + rcm: rseed.get_rcm(&nonce), + nonce, } }; - let mut output_note = { - let rho = input_note.get_nf().unwrap(); - let nk_com = NullifierKeyContainer::from_commitment(pallas::Base::random(&mut rng)); - let note_type = { - let app_vk = pallas::Base::random(&mut rng); - let app_data_static = pallas::Base::random(&mut rng); - NoteType::new(app_vk, app_data_static) + let mut output_resource = { + let nonce = input_resource.get_nf().unwrap(); + let npk = NullifierKeyContainer::from_npk(pallas::Base::random(&mut rng)); + let kind = { + let logic = pallas::Base::random(&mut rng); + let label = pallas::Base::random(&mut rng); + ResourceKind::new(logic, label) }; - let app_data_dynamic = pallas::Base::random(&mut rng); - let value: u64 = rng.gen(); + let value = pallas::Base::random(&mut rng); + let quantity: u64 = rng.gen(); let rseed = RandomSeed::random(&mut rng); - Note { - note_type, - app_data_dynamic, + Resource { + kind, value, - nk_container: nk_com, + quantity, + nk_container: npk, is_merkle_checked: true, - psi: rseed.get_psi(&rho), - rcm: rseed.get_rcm(&rho), - rho, + psi: rseed.get_psi(&nonce), + rcm: rseed.get_rcm(&nonce), + nonce, } }; let input_merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); ActionInfo::new( - input_note, + input_resource, input_merkle_path, None, - &mut output_note, + &mut output_resource, &mut rng, ) }; diff --git a/taiga_halo2/benches/vp_proof.rs b/taiga_halo2/benches/vp_proof.rs index 4916634a..09bc51c6 100644 --- a/taiga_halo2/benches/vp_proof.rs +++ b/taiga_halo2/benches/vp_proof.rs @@ -7,68 +7,68 @@ use rand::rngs::OsRng; use rand::Rng; use taiga_halo2::{ circuit::{vp_circuit::ValidityPredicateCircuit, vp_examples::TrivialValidityPredicateCircuit}, - constant::{NUM_NOTE, SETUP_PARAMS_MAP, VP_CIRCUIT_PARAMS_SIZE}, - note::{Note, NoteType, RandomSeed}, + constant::{NUM_RESOURCE, SETUP_PARAMS_MAP, VP_CIRCUIT_PARAMS_SIZE}, nullifier::{Nullifier, NullifierKeyContainer}, proof::Proof, + resource::{RandomSeed, Resource, ResourceKind}, }; fn bench_vp_proof(name: &str, c: &mut Criterion) { let mut rng = OsRng; let vp_circuit = { - let input_notes = [(); NUM_NOTE].map(|_| { - let rho = Nullifier::from(pallas::Base::random(&mut rng)); + let input_resources = [(); NUM_RESOURCE].map(|_| { + let nonce = Nullifier::from(pallas::Base::random(&mut rng)); let nk = NullifierKeyContainer::from_key(pallas::Base::random(&mut rng)); - let note_type = { - let app_vk = pallas::Base::random(&mut rng); - let app_data_static = pallas::Base::random(&mut rng); - NoteType::new(app_vk, app_data_static) + let kind = { + let logic = pallas::Base::random(&mut rng); + let label = pallas::Base::random(&mut rng); + ResourceKind::new(logic, label) }; - let app_data_dynamic = pallas::Base::random(&mut rng); - let value: u64 = rng.gen(); + let value = pallas::Base::random(&mut rng); + let quantity: u64 = rng.gen(); let rseed = RandomSeed::random(&mut rng); - Note { - note_type, - app_data_dynamic, + Resource { + kind, value, + quantity, nk_container: nk, is_merkle_checked: true, - psi: rseed.get_psi(&rho), - rcm: rseed.get_rcm(&rho), - rho, + psi: rseed.get_psi(&nonce), + rcm: rseed.get_rcm(&nonce), + nonce, } }); - let output_notes = input_notes + let output_resources = input_resources .iter() .map(|input| { - let rho = input.get_nf().unwrap(); - let nk_com = NullifierKeyContainer::from_commitment(pallas::Base::random(&mut rng)); - let note_type = { - let app_vk = pallas::Base::random(&mut rng); - let app_data_static = pallas::Base::random(&mut rng); - NoteType::new(app_vk, app_data_static) + let nonce = input.get_nf().unwrap(); + let npk = NullifierKeyContainer::from_npk(pallas::Base::random(&mut rng)); + let kind = { + let logic = pallas::Base::random(&mut rng); + let label = pallas::Base::random(&mut rng); + ResourceKind::new(logic, label) }; - let app_data_dynamic = pallas::Base::random(&mut rng); - let value: u64 = rng.gen(); + let value = pallas::Base::random(&mut rng); + let quantity: u64 = rng.gen(); let rseed = RandomSeed::random(&mut rng); - Note { - note_type, - app_data_dynamic, + Resource { + kind, value, - nk_container: nk_com, + quantity, + nk_container: npk, is_merkle_checked: true, - psi: rseed.get_psi(&rho), - rcm: rseed.get_rcm(&rho), - rho, + psi: rseed.get_psi(&nonce), + rcm: rseed.get_rcm(&nonce), + nonce, } }) .collect::>(); - let owned_note_pub_id = input_notes[0].get_nf().unwrap().inner(); + let owned_resource_id = input_resources[0].get_nf().unwrap().inner(); TrivialValidityPredicateCircuit::new( - owned_note_pub_id, - input_notes, - output_notes.try_into().unwrap(), + owned_resource_id, + input_resources, + output_resources.try_into().unwrap(), ) }; let params = SETUP_PARAMS_MAP.get(&VP_CIRCUIT_PARAMS_SIZE).unwrap(); diff --git a/taiga_halo2/deprecated/simple_sudoku/vp.rs b/taiga_halo2/deprecated/simple_sudoku/vp.rs index 2140a8ca..76afc3d2 100644 --- a/taiga_halo2/deprecated/simple_sudoku/vp.rs +++ b/taiga_halo2/deprecated/simple_sudoku/vp.rs @@ -7,15 +7,15 @@ use pasta_curves::pallas; extern crate taiga_halo2; use taiga_halo2::{ circuit::{ - note_circuit::NoteConfig, + resource_circuit::ResourceConfig, vp_circuit::{ BasicValidityPredicateVariables, VPVerifyingInfo, ValidityPredicateCircuit, ValidityPredicateConfig, ValidityPredicateInfo, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo, }, }, - constant::{NUM_NOTE, SETUP_PARAMS_MAP}, - note::{Note, RandomSeed}, + constant::{NUM_RESOURCE, SETUP_PARAMS_MAP}, + resource::{Resource, RandomSeed}, proof::Proof, vp_circuit_impl, vp_vk::ValidityPredicateVerifyingKey, @@ -26,15 +26,15 @@ use rand::{rngs::OsRng, RngCore}; #[derive(Clone, Debug)] pub struct SudokuVPConfig { - note_config: NoteConfig, + resource_config: ResourceConfig, sudoku_config: SudokuConfig, } #[derive(Clone, Debug, Default)] pub struct SudokuVP { pub sudoku: SudokuCircuit, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], } impl ValidityPredicateCircuit for SudokuVP { @@ -49,12 +49,12 @@ impl ValidityPredicateCircuit for SudokuVP { } impl ValidityPredicateInfo for SudokuVP { - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -67,7 +67,7 @@ impl ValidityPredicateInfo for SudokuVP { public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { + fn get_owned_resource_id(&self) -> pallas::Base { pallas::Base::zero() } } @@ -75,13 +75,13 @@ impl ValidityPredicateInfo for SudokuVP { impl SudokuVP { pub fn new( sudoku: SudokuCircuit, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], ) -> Self { Self { sudoku, - input_notes, - output_notes, + input_resources, + output_resources, } } } @@ -91,8 +91,8 @@ vp_circuit_impl!(SudokuVP); #[cfg(test)] mod tests { use taiga_halo2::{ - constant::NUM_NOTE, - note::{Note, RandomSeed}, + constant::NUM_RESOURCE, + resource::{Resource, RandomSeed}, nullifier::{Nullifier, NullifierKeyContainer}, vp_vk::ValidityPredicateVerifyingKey, }; @@ -108,8 +108,8 @@ mod tests { #[test] fn test_vp() { let mut rng = OsRng; - let input_notes = [(); NUM_NOTE].map(|_| Note::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::dummy(&mut rng)); + let input_resources = [(); NUM_RESOURCE].map(|_| Resource::dummy(&mut rng)); + let output_resources = [(); NUM_RESOURCE].map(|_| Resource::dummy(&mut rng)); const K: u32 = 13; let sudoku = SudokuCircuit { @@ -129,22 +129,22 @@ mod tests { let vk = plonk::keygen_vk(¶ms, &sudoku).unwrap(); - let mut _vp = SudokuVP::new(sudoku, input_notes, output_notes); + let mut _vp = SudokuVP::new(sudoku, input_resources, output_resources); let vp_vk = ValidityPredicateVerifyingKey::from_vk(vk); let app_data_static = pallas::Base::zero(); let app_data_dynamic = pallas::Base::zero(); - let value: u64 = 0; + let quantity: u64 = 0; let nk = NullifierKeyContainer::random_key(&mut rng); let rseed = RandomSeed::random(&mut rng); let rho = Nullifier::from(pallas::Base::random(&mut rng)); - Note::new( + Resource::new( vp_vk, app_data_static, app_data_dynamic, - value, + quantity, nk, rho, true, diff --git a/taiga_halo2/deprecated/taiga_sudoku/app_vp.rs b/taiga_halo2/deprecated/taiga_sudoku/app_vp.rs index e8d12fb4..bc1aaee7 100644 --- a/taiga_halo2/deprecated/taiga_sudoku/app_vp.rs +++ b/taiga_halo2/deprecated/taiga_sudoku/app_vp.rs @@ -13,18 +13,18 @@ use taiga_halo2::{ mul::{MulChip, MulConfig, MulInstructions}, poseidon_hash::poseidon_hash_gadget, sub::{SubChip, SubConfig, SubInstructions}, - target_note_variable::{get_is_input_note_flag, GetIsInputNoteFlagConfig}, + target_resource_variable::{get_is_input_resource_flag, GetIsInputResourceFlagConfig}, triple_mul::TripleMulConfig, }, - note_circuit::NoteConfig, + resource_circuit::ResourceConfig, vp_circuit::{ - BasicValidityPredicateVariables, InputNoteVariables, OutputNoteVariables, + BasicValidityPredicateVariables, InputResourceVariables, OutputResourceVariables, VPVerifyingInfo, ValidityPredicateCircuit, ValidityPredicateConfig, ValidityPredicateInfo, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo, }, }, - constant::{NUM_NOTE, SETUP_PARAMS_MAP}, - note::{Note, RandomSeed}, + constant::{NUM_RESOURCE, SETUP_PARAMS_MAP}, + resource::{Resource, RandomSeed}, proof::Proof, utils::poseidon_hash, vp_circuit_impl, @@ -42,7 +42,7 @@ pub struct SudokuState { impl SudokuState { pub fn encode(&self) -> pallas::Base { - // TODO: add the rho of note to make the app_data_static unique. + // TODO: add the rho of resource to make the app_data_static unique. let sudoku = self.state.concat(); let s1 = &sudoku[..sudoku.len() / 2]; // s1 contains 40 elements @@ -107,9 +107,9 @@ impl Default for SudokuState { #[derive(Clone, Debug, Default)] struct SudokuAppValidityPredicateCircuit { - owned_note_pub_id: pallas::Base, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + owned_resource_id: pallas::Base, + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], // Initial puzzle encoded in a single field encoded_init_state: pallas::Base, // If it is a init state, previous_state is equal to current_state @@ -119,9 +119,9 @@ struct SudokuAppValidityPredicateCircuit { #[derive(Clone, Debug)] struct SudokuAppValidityPredicateConfig { - note_config: NoteConfig, + resource_config: ResourceConfig, advices: [Column; 10], - get_is_input_note_flag_config: GetIsInputNoteFlagConfig, + get_is_input_resource_flag_config: GetIsInputResourceFlagConfig, sudoku_state_check_config: SudokuStateCheckConfig, state_update_config: StateUpdateConfig, triple_mul_config: TripleMulConfig, @@ -141,14 +141,14 @@ impl SudokuAppValidityPredicateConfig { } impl ValidityPredicateConfig for SudokuAppValidityPredicateConfig { - fn get_note_config(&self) -> NoteConfig { - self.note_config.clone() + fn get_resource_config(&self) -> ResourceConfig { + self.resource_config.clone() } fn configure(meta: &mut ConstraintSystem) -> Self { - let note_config = Self::configure_note(meta); + let resource_config = Self::configure_resource(meta); - let advices = note_config.advices; + let advices = resource_config.advices; let sudoku_state_check_config = SudokuStateCheckConfig::configure( meta, advices[0], advices[1], advices[2], advices[3], advices[4], advices[5], advices[6], advices[7], @@ -160,12 +160,12 @@ impl ValidityPredicateConfig for SudokuAppValidityPredicateConfig { ValueCheckConfig::configure(meta, advices[0], advices[1], advices[2]); let sub_config = SubChip::configure(meta, [advices[0], advices[1]]); let mul_config = MulChip::configure(meta, [advices[0], advices[1]]); - let get_is_input_note_flag_config = - GetIsInputNoteFlagConfig::configure(meta, advices[0], advices[1], advices[2]); + let get_is_input_resource_flag_config = + GetIsInputResourceFlagConfig::configure(meta, advices[0], advices[1], advices[2]); Self { - note_config, + resource_config, advices, - get_is_input_note_flag_config, + get_is_input_resource_flag_config, sudoku_state_check_config, state_update_config, triple_mul_config, @@ -290,26 +290,26 @@ impl SudokuAppValidityPredicateCircuit { fn check_state( config: &SudokuStateCheckConfig, mut layouter: impl Layouter, - is_input_note: &AssignedCell, + is_input_resource: &AssignedCell, init_state: &AssignedCell, - input_note_pre_state: &AssignedCell, - output_note_cur_state: &AssignedCell, - input_note_app_data_static_encode: &AssignedCell, - input_note: &InputNoteVariables, - output_note: &OutputNoteVariables, + input_resource_pre_state: &AssignedCell, + output_resource_cur_state: &AssignedCell, + input_resource_app_data_static_encode: &AssignedCell, + input_resource: &InputResourceVariables, + output_resource: &OutputResourceVariables, ) -> Result<(), Error> { layouter.assign_region( || "dealer intent check", |mut region| { config.assign_region( - is_input_note, + is_input_resource, init_state, - &input_note.note_variables.app_data_static, - input_note_app_data_static_encode, - &input_note.note_variables.app_vk, - &output_note.note_variables.app_vk, - input_note_pre_state, - output_note_cur_state, + &input_resource.resource_variables.app_data_static, + input_resource_app_data_static_encode, + &input_resource.resource_variables.app_vk, + &output_resource.resource_variables.app_vk, + input_resource_pre_state, + output_resource_cur_state, 0, &mut region, ) @@ -323,11 +323,11 @@ impl SudokuAppValidityPredicateCircuit { state_update_config: &StateUpdateConfig, triple_mul_config: &TripleMulConfig, value_check_config: &ValueCheckConfig, - is_input_note: &AssignedCell, + is_input_resource: &AssignedCell, pre_state: &[AssignedCell], cur_state: &[AssignedCell], - input_note: &InputNoteVariables, - output_note: &OutputNoteVariables, + input_resource: &InputResourceVariables, + output_resource: &OutputResourceVariables, ) -> Result<(), Error> { // check state update: the cur_state is updated from pre_state pre_state @@ -339,7 +339,7 @@ impl SudokuAppValidityPredicateCircuit { || "state update check", |mut region| { state_update_config.assign_region( - is_input_note, + is_input_resource, pre_state_cell, cur_state_cell, 0, @@ -350,7 +350,7 @@ impl SudokuAppValidityPredicateCircuit { .unwrap(); }); - // if cur_state is the final solution, check the output.value is zero else check the output.value is one + // if cur_state is the final solution, check the output.quantity is zero else check the output.quantity is one // ret has 27 elements let ret: Vec> = cur_state .chunks(3) @@ -417,13 +417,13 @@ impl SudokuAppValidityPredicateCircuit { )?; layouter.assign_region( - || "check value", + || "check quantity", |mut region| { value_check_config.assign_region( - is_input_note, + is_input_resource, &product, - &input_note.note_variables.value, - &output_note.note_variables.value, + &input_resource.resource_variables.quantity, + &output_resource.resource_variables.quantity, 0, &mut region, ) @@ -435,12 +435,12 @@ impl SudokuAppValidityPredicateCircuit { } impl ValidityPredicateInfo for SudokuAppValidityPredicateCircuit { - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -453,8 +453,8 @@ impl ValidityPredicateInfo for SudokuAppValidityPredicateCircuit { public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } @@ -467,13 +467,13 @@ impl ValidityPredicateCircuit for SudokuAppValidityPredicateCircuit { mut layouter: impl Layouter, basic_variables: BasicValidityPredicateVariables, ) -> Result<(), Error> { - let owned_note_pub_id = basic_variables.get_owned_note_pub_id(); - let is_input_note = get_is_input_note_flag( - config.get_is_input_note_flag_config, - layouter.namespace(|| "get is_input_note_flag"), - &owned_note_pub_id, - &basic_variables.get_input_note_nfs(), - &basic_variables.get_output_note_cms(), + let owned_resource_id = basic_variables.get_owned_resource_id(); + let is_input_resource = get_is_input_resource_flag( + config.get_is_input_resource_flag_config, + layouter.namespace(|| "get is_input_resource_flag"), + &owned_resource_id, + &basic_variables.get_input_resource_nfs(), + &basic_variables.get_output_resource_cms(), )?; // witness the sudoku previous state @@ -527,25 +527,25 @@ impl ValidityPredicateCircuit for SudokuAppValidityPredicateCircuit { config.advices[0], Value::known(self.encoded_init_state), )?; - let input_note_app_data_static_encode = poseidon_hash_gadget( - config.get_note_config().poseidon_config, - layouter.namespace(|| "input note app_data_static encoding"), + let input_resource_app_data_static_encode = poseidon_hash_gadget( + config.get_resource_config().poseidon_config, + layouter.namespace(|| "input resource app_data_static encoding"), [encoded_init_state.clone(), encoded_previous_state.clone()], )?; - let output_note_app_data_static_encode = poseidon_hash_gadget( - config.get_note_config().poseidon_config, - layouter.namespace(|| "output note app_data_static encoding"), + let output_resource_app_data_static_encode = poseidon_hash_gadget( + config.get_resource_config().poseidon_config, + layouter.namespace(|| "output resource app_data_static encoding"), [encoded_init_state.clone(), encoded_current_state.clone()], )?; layouter.assign_region( - || "check output note app_data_static encoding", + || "check output resource app_data_static encoding", |mut region| { region.constrain_equal( - output_note_app_data_static_encode.cell(), - basic_variables.output_note_variables[0] - .note_variables + output_resource_app_data_static_encode.cell(), + basic_variables.output_resource_variables[0] + .resource_variables .app_data_static .cell(), ) @@ -562,27 +562,27 @@ impl ValidityPredicateCircuit for SudokuAppValidityPredicateCircuit { Self::check_state( &config.sudoku_state_check_config, layouter.namespace(|| "check state"), - &is_input_note, + &is_input_resource, &encoded_init_state, &encoded_previous_state, &encoded_current_state, - &input_note_app_data_static_encode, - &basic_variables.input_note_variables[0], - &basic_variables.output_note_variables[0], + &input_resource_app_data_static_encode, + &basic_variables.input_resource_variables[0], + &basic_variables.output_resource_variables[0], )?; - // if it is an input note, check that the cur_state is updated from pre_state - // if encoded_current_state is the final solution, check the output.value is zero else check the output.value is one + // if it is an input resource, check that the cur_state is updated from pre_state + // if encoded_current_state is the final solution, check the output.quantity is zero else check the output.quantity is one Self::check_solution( layouter.namespace(|| "check solution"), &config.state_update_config, &config.triple_mul_config, &config.value_check_config, - &is_input_note, + &is_input_resource, &previous_sudoku_cells, ¤t_sudoku_cells, - &basic_variables.input_note_variables[0], - &basic_variables.output_note_variables[0], + &basic_variables.input_resource_variables[0], + &basic_variables.output_resource_variables[0], )?; Ok(()) @@ -597,25 +597,25 @@ pub mod tests { use pasta_curves::pallas; use rand::{Rng, RngCore}; use taiga_halo2::{ - note::{Note, NoteType, RandomSeed}, + resource::{Resource, ResourceKind, RandomSeed}, nullifier::{Nullifier, NullifierKeyContainer}, }; - pub fn random_input_note(mut rng: R) -> Note { + pub fn random_input_resource(mut rng: R) -> Resource { let rho = Nullifier::from(pallas::Base::random(&mut rng)); let nk = NullifierKeyContainer::from_key(pallas::Base::random(&mut rng)); - let note_type = { + let kind = { let app_vk = pallas::Base::random(&mut rng); let app_data_static = pallas::Base::random(&mut rng); - NoteType::new(app_vk, app_data_static) + ResourceKind::new(app_vk, app_data_static) }; let app_data_dynamic = pallas::Base::random(&mut rng); - let value: u64 = rng.gen(); + let quantity: u64 = rng.gen(); let rseed = RandomSeed::random(&mut rng); - Note { - note_type, + Resource { + kind, app_data_dynamic, - value, + quantity, nk_container: nk, is_merkle_checked: true, psi: rseed.get_psi(&rho), @@ -624,20 +624,20 @@ pub mod tests { } } - pub fn random_output_note(mut rng: R, rho: Nullifier) -> Note { + pub fn random_output_resource(mut rng: R, rho: Nullifier) -> Resource { let nk_com = NullifierKeyContainer::from_commitment(pallas::Base::random(&mut rng)); - let note_type = { + let kind = { let app_vk = pallas::Base::random(&mut rng); let app_data_static = pallas::Base::random(&mut rng); - NoteType::new(app_vk, app_data_static) + ResourceKind::new(app_vk, app_data_static) }; let app_data_dynamic = pallas::Base::random(&mut rng); - let value: u64 = rng.gen(); + let quantity: u64 = rng.gen(); let rseed = RandomSeed::random(&mut rng); - Note { - note_type, + Resource { + kind, app_data_dynamic, - value, + quantity, nk_container: nk_com, is_merkle_checked: true, psi: rseed.get_psi(&rho), @@ -649,28 +649,28 @@ pub mod tests { #[test] fn test_halo2_sudoku_app_vp_circuit_init() { - use crate::app_vp::tests::{random_input_note, random_output_note}; + use crate::app_vp::tests::{random_input_resource, random_output_resource}; use halo2_proofs::dev::MockProver; use rand::rngs::OsRng; let mut rng = OsRng; let circuit = { - let input_notes = [(); NUM_NOTE].map(|_| random_input_note(&mut rng)); - let mut output_notes = input_notes + let input_resources = [(); NUM_RESOURCE].map(|_| random_input_resource(&mut rng)); + let mut output_resources = input_resources .iter() - .map(|input| random_output_note(&mut rng, input.get_nf().unwrap())) + .map(|input| random_output_resource(&mut rng, input.get_nf().unwrap())) .collect::>(); let encoded_init_state = SudokuState::default().encode(); let previous_state = SudokuState::default(); let current_state = SudokuState::default(); - output_notes[0].note_type.app_data_static = + output_resources[0].kind.app_data_static = poseidon_hash(encoded_init_state, current_state.encode()); - output_notes[0].value = 1u64; - let owned_note_pub_id = output_notes[0].commitment().inner(); + output_resources[0].quantity = 1u64; + let owned_resource_id = output_resources[0].commitment().inner(); SudokuAppValidityPredicateCircuit { - owned_note_pub_id, - input_notes, - output_notes: output_notes.try_into().unwrap(), + owned_resource_id, + input_resources, + output_resources: output_resources.try_into().unwrap(), encoded_init_state, previous_state, current_state, @@ -685,17 +685,17 @@ fn test_halo2_sudoku_app_vp_circuit_init() { #[test] fn test_halo2_sudoku_app_vp_circuit_update() { - use crate::app_vp::tests::{random_input_note, random_output_note}; + use crate::app_vp::tests::{random_input_resource, random_output_resource}; use halo2_proofs::dev::MockProver; use rand::rngs::OsRng; let mut rng = OsRng; // Construct circuit let circuit = { - let mut input_notes = [(); NUM_NOTE].map(|_| random_input_note(&mut rng)); - let mut output_notes = input_notes + let mut input_resources = [(); NUM_RESOURCE].map(|_| random_input_resource(&mut rng)); + let mut output_resources = input_resources .iter() - .map(|input| random_output_note(&mut rng, input.get_nf().unwrap())) + .map(|input| random_output_resource(&mut rng, input.get_nf().unwrap())) .collect::>(); let init_state = SudokuState { state: [ @@ -737,17 +737,17 @@ fn test_halo2_sudoku_app_vp_circuit_update() { [6, 0, 7, 4, 3, 5, 1, 9, 8], ], }; - input_notes[0].note_type.app_data_static = + input_resources[0].kind.app_data_static = poseidon_hash(encoded_init_state, previous_state.encode()); - input_notes[0].value = 1u64; - output_notes[0].note_type.app_data_static = + input_resources[0].quantity = 1u64; + output_resources[0].kind.app_data_static = poseidon_hash(encoded_init_state, current_state.encode()); - output_notes[0].value = 1u64; - output_notes[0].note_type.app_vk = input_notes[0].note_type.app_vk; + output_resources[0].quantity = 1u64; + output_resources[0].kind.app_vk = input_resources[0].kind.app_vk; SudokuAppValidityPredicateCircuit { - owned_note_pub_id: input_notes[0].get_nf().unwrap().inner(), - input_notes, - output_notes: output_notes.try_into().unwrap(), + owned_resource_id: input_resources[0].get_nf().unwrap().inner(), + input_resources, + output_resources: output_resources.try_into().unwrap(), encoded_init_state, previous_state, current_state, @@ -762,16 +762,16 @@ fn test_halo2_sudoku_app_vp_circuit_update() { #[test] fn halo2_sudoku_app_vp_circuit_final() { - use crate::app_vp::tests::{random_input_note, random_output_note}; + use crate::app_vp::tests::{random_input_resource, random_output_resource}; use halo2_proofs::dev::MockProver; let mut rng = OsRng; // Construct circuit let circuit = { - let mut input_notes = [(); NUM_NOTE].map(|_| random_input_note(&mut rng)); - let mut output_notes = input_notes + let mut input_resources = [(); NUM_RESOURCE].map(|_| random_input_resource(&mut rng)); + let mut output_resources = input_resources .iter() - .map(|input| random_output_note(&mut rng, input.get_nf().unwrap())) + .map(|input| random_output_resource(&mut rng, input.get_nf().unwrap())) .collect::>(); let init_state = SudokuState { state: [ @@ -813,17 +813,17 @@ fn halo2_sudoku_app_vp_circuit_final() { [6, 2, 7, 4, 3, 5, 1, 9, 8], ], }; - input_notes[0].note_type.app_data_static = + input_resources[0].kind.app_data_static = poseidon_hash(encoded_init_state, previous_state.encode()); - input_notes[0].value = 1u64; - output_notes[0].note_type.app_data_static = + input_resources[0].quantity = 1u64; + output_resources[0].kind.app_data_static = poseidon_hash(encoded_init_state, current_state.encode()); - output_notes[0].value = 0u64; - output_notes[0].note_type.app_vk = input_notes[0].note_type.app_vk; + output_resources[0].quantity = 0u64; + output_resources[0].kind.app_vk = input_resources[0].kind.app_vk; SudokuAppValidityPredicateCircuit { - owned_note_pub_id: input_notes[0].get_nf().unwrap().inner(), - input_notes, - output_notes: output_notes.try_into().unwrap(), + owned_resource_id: input_resources[0].get_nf().unwrap().inner(), + input_resources, + output_resources: output_resources.try_into().unwrap(), encoded_init_state, previous_state, current_state, diff --git a/taiga_halo2/deprecated/taiga_sudoku/dealer_intent_app_vp.rs b/taiga_halo2/deprecated/taiga_sudoku/dealer_intent_app_vp.rs index 2a1d13d5..cd9df917 100644 --- a/taiga_halo2/deprecated/taiga_sudoku/dealer_intent_app_vp.rs +++ b/taiga_halo2/deprecated/taiga_sudoku/dealer_intent_app_vp.rs @@ -15,20 +15,20 @@ use taiga_halo2::{ gadgets::{ assign_free_advice, poseidon_hash::poseidon_hash_gadget, - target_note_variable::{ - get_is_input_note_flag, get_owned_note_variable, GetIsInputNoteFlagConfig, - GetOwnedNoteVariableConfig, + target_resource_variable::{ + get_is_input_resource_flag, get_owned_resource_variable, GetIsInputResourceFlagConfig, + GetOwnedResourceVariableConfig, }, }, - note_circuit::NoteConfig, + resource_circuit::ResourceConfig, vp_circuit::{ - BasicValidityPredicateVariables, OutputNoteVariables, VPVerifyingInfo, + BasicValidityPredicateVariables, OutputResourceVariables, VPVerifyingInfo, ValidityPredicateCircuit, ValidityPredicateConfig, ValidityPredicateInfo, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo, }, }, - constant::{NUM_NOTE, SETUP_PARAMS_MAP}, - note::{Note, RandomSeed}, + constant::{NUM_RESOURCE, SETUP_PARAMS_MAP}, + resource::{Resource, RandomSeed}, proof::Proof, utils::poseidon_hash, vp_circuit_impl, @@ -37,34 +37,34 @@ use taiga_halo2::{ #[derive(Clone, Debug, Default)] struct DealerIntentValidityPredicateCircuit { - owned_note_pub_id: pallas::Base, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + owned_resource_id: pallas::Base, + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], encoded_puzzle: pallas::Base, sudoku_app_vk: pallas::Base, - // When it's an output note, we don't need a valid solution. + // When it's an output resource, we don't need a valid solution. encoded_solution: pallas::Base, } #[derive(Clone, Debug)] struct IntentAppValidityPredicateConfig { - note_conifg: NoteConfig, + resource_config: ResourceConfig, advices: [Column; 10], - get_owned_note_variable_config: GetOwnedNoteVariableConfig, - get_is_input_note_flag_config: GetIsInputNoteFlagConfig, + get_owned_resource_variable_config: GetOwnedResourceVariableConfig, + get_is_input_resource_flag_config: GetIsInputResourceFlagConfig, dealer_intent_check_config: DealerIntentCheckConfig, } impl ValidityPredicateConfig for IntentAppValidityPredicateConfig { - fn get_note_config(&self) -> NoteConfig { - self.note_conifg.clone() + fn get_resource_config(&self) -> ResourceConfig { + self.resource_config.clone() } fn configure(meta: &mut ConstraintSystem) -> Self { - let note_conifg = Self::configure_note(meta); + let resource_config = Self::configure_resource(meta); - let advices = note_conifg.advices; - let get_owned_note_variable_config = GetOwnedNoteVariableConfig::configure( + let advices = resource_config.advices; + let get_owned_resource_variable_config = GetOwnedResourceVariableConfig::configure( meta, advices[0], [advices[1], advices[2], advices[3], advices[4]], @@ -72,14 +72,14 @@ impl ValidityPredicateConfig for IntentAppValidityPredicateConfig { let dealer_intent_check_config = DealerIntentCheckConfig::configure( meta, advices[0], advices[1], advices[2], advices[3], advices[4], advices[5], ); - let get_is_input_note_flag_config = - GetIsInputNoteFlagConfig::configure(meta, advices[0], advices[1], advices[2]); + let get_is_input_resource_flag_config = + GetIsInputResourceFlagConfig::configure(meta, advices[0], advices[1], advices[2]); Self { - note_conifg, + resource_config, advices, - get_owned_note_variable_config, - get_is_input_note_flag_config, + get_owned_resource_variable_config, + get_is_input_resource_flag_config, dealer_intent_check_config, } } @@ -98,19 +98,19 @@ impl DealerIntentValidityPredicateCircuit { &self, config: &IntentAppValidityPredicateConfig, mut layouter: impl Layouter, - is_input_note: &AssignedCell, + is_input_resource: &AssignedCell, encoded_puzzle: &AssignedCell, - sudoku_app_vk_in_dealer_intent_note: &AssignedCell, - puzzle_note: &OutputNoteVariables, + sudoku_app_vk_in_dealer_intent_resource: &AssignedCell, + puzzle_resource: &OutputResourceVariables, ) -> Result<(), Error> { - // puzzle_note_app_data_static = poseidon_hash(encoded_puzzle || encoded_solution) + // puzzle_resource_app_data_static = poseidon_hash(encoded_puzzle || encoded_solution) let encoded_solution = assign_free_advice( layouter.namespace(|| "witness encoded_solution"), config.advices[0], Value::known(self.encoded_solution), )?; - let encoded_puzzle_note_app_data_static = poseidon_hash_gadget( - config.get_note_config().poseidon_config, + let puzzle_resource_app_data_static = poseidon_hash_gadget( + config.get_resource_config().poseidon_config, layouter.namespace(|| "app_data_static encoding"), [encoded_puzzle.clone(), encoded_solution], )?; @@ -119,12 +119,12 @@ impl DealerIntentValidityPredicateCircuit { || "dealer intent check", |mut region| { config.dealer_intent_check_config.assign_region( - is_input_note, - &puzzle_note.note_variables.value, - &puzzle_note.note_variables.app_vk, - sudoku_app_vk_in_dealer_intent_note, - &puzzle_note.note_variables.app_data_static, - &encoded_puzzle_note_app_data_static, + is_input_resource, + &puzzle_resource.resource_variables.quantity, + &puzzle_resource.resource_variables.app_vk, + sudoku_app_vk_in_dealer_intent_resource, + &puzzle_resource.resource_variables.app_data_static, + &puzzle_resource_app_data_static, 0, &mut region, ) @@ -135,12 +135,12 @@ impl DealerIntentValidityPredicateCircuit { } impl ValidityPredicateInfo for DealerIntentValidityPredicateCircuit { - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -153,8 +153,8 @@ impl ValidityPredicateInfo for DealerIntentValidityPredicateCircuit { public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } @@ -167,20 +167,20 @@ impl ValidityPredicateCircuit for DealerIntentValidityPredicateCircuit { mut layouter: impl Layouter, basic_variables: BasicValidityPredicateVariables, ) -> Result<(), Error> { - let owned_note_pub_id = basic_variables.get_owned_note_pub_id(); - let is_input_note = get_is_input_note_flag( - config.get_is_input_note_flag_config, - layouter.namespace(|| "get is_input_note_flag"), - &owned_note_pub_id, - &basic_variables.get_input_note_nfs(), - &basic_variables.get_output_note_cms(), + let owned_resource_id = basic_variables.get_owned_resource_id(); + let is_input_resource = get_is_input_resource_flag( + config.get_is_input_resource_flag_config, + layouter.namespace(|| "get is_input_resource_flag"), + &owned_resource_id, + &basic_variables.get_input_resource_nfs(), + &basic_variables.get_output_resource_cms(), )?; - // search target note and output the app_static_data - let app_data_static = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_static_data"), - &owned_note_pub_id, + // search target resource and output the app_static_data + let app_data_static = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource app_static_data"), + &owned_resource_id, &basic_variables.get_app_data_static_searchable_pairs(), )?; @@ -196,7 +196,7 @@ impl ValidityPredicateCircuit for DealerIntentValidityPredicateCircuit { Value::known(self.sudoku_app_vk), )?; let app_data_static_encode = poseidon_hash_gadget( - config.get_note_config().poseidon_config, + config.get_resource_config().poseidon_config, layouter.namespace(|| "app_data_static encoding"), [encoded_puzzle.clone(), sudoku_app_vk.clone()], )?; @@ -208,15 +208,15 @@ impl ValidityPredicateCircuit for DealerIntentValidityPredicateCircuit { }, )?; - // if it is an output note, do nothing - // if it is an input note, 1. check the zero value of puzzle_note; 2. check the puzzle equality. + // if it is an output resource, do nothing + // if it is an input resource, 1. check the zero quantity of puzzle_resource; 2. check the puzzle equality. self.dealer_intent_check( &config, layouter.namespace(|| "dealer intent check"), - &is_input_note, + &is_input_resource, &encoded_puzzle, &sudoku_app_vk, - &basic_variables.output_note_variables[0], + &basic_variables.output_resource_variables[0], ) } } @@ -226,40 +226,40 @@ vp_circuit_impl!(DealerIntentValidityPredicateCircuit); #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct DealerIntentCheckConfig { q_dealer_intent_check: Selector, - is_input_note: Column, - puzzle_note_value: Column, + is_input_resource: Column, + puzzle_resource_value: Column, sudoku_app_vk: Column, - sudoku_app_vk_in_dealer_intent_note: Column, - puzzle_note_app_data_static: Column, - encoded_puzzle_note_app_data_static: Column, + sudoku_app_vk_in_dealer_intent_resource: Column, + puzzle_resource_app_data_static: Column, + puzzle_resource_app_data_static: Column, } impl DealerIntentCheckConfig { #[allow(clippy::too_many_arguments)] pub fn configure( meta: &mut ConstraintSystem, - is_input_note: Column, - puzzle_note_value: Column, + is_input_resource: Column, + puzzle_resource_value: Column, sudoku_app_vk: Column, - sudoku_app_vk_in_dealer_intent_note: Column, - puzzle_note_app_data_static: Column, - encoded_puzzle_note_app_data_static: Column, + sudoku_app_vk_in_dealer_intent_resource: Column, + puzzle_resource_app_data_static: Column, + puzzle_resource_app_data_static: Column, ) -> Self { - meta.enable_equality(is_input_note); - meta.enable_equality(puzzle_note_value); + meta.enable_equality(is_input_resource); + meta.enable_equality(puzzle_resource_value); meta.enable_equality(sudoku_app_vk); - meta.enable_equality(sudoku_app_vk_in_dealer_intent_note); - meta.enable_equality(puzzle_note_app_data_static); - meta.enable_equality(encoded_puzzle_note_app_data_static); + meta.enable_equality(sudoku_app_vk_in_dealer_intent_resource); + meta.enable_equality(puzzle_resource_app_data_static); + meta.enable_equality(puzzle_resource_app_data_static); let config = Self { q_dealer_intent_check: meta.selector(), - is_input_note, - puzzle_note_value, + is_input_resource, + puzzle_resource_value, sudoku_app_vk, - sudoku_app_vk_in_dealer_intent_note, - puzzle_note_app_data_static, - encoded_puzzle_note_app_data_static, + sudoku_app_vk_in_dealer_intent_resource, + puzzle_resource_app_data_static, + puzzle_resource_app_data_static, }; config.create_gate(meta); @@ -270,35 +270,35 @@ impl DealerIntentCheckConfig { fn create_gate(&self, meta: &mut ConstraintSystem) { meta.create_gate("check dealer intent", |meta| { let q_dealer_intent_check = meta.query_selector(self.q_dealer_intent_check); - let is_input_note = meta.query_advice(self.is_input_note, Rotation::cur()); - let puzzle_note_value = meta.query_advice(self.puzzle_note_value, Rotation::cur()); + let is_input_resource = meta.query_advice(self.is_input_resource, Rotation::cur()); + let puzzle_resource_value = meta.query_advice(self.puzzle_resource_value, Rotation::cur()); let sudoku_app_vk = meta.query_advice(self.sudoku_app_vk, Rotation::cur()); - let sudoku_app_vk_in_dealer_intent_note = - meta.query_advice(self.sudoku_app_vk_in_dealer_intent_note, Rotation::cur()); - let puzzle_note_app_data_static = - meta.query_advice(self.puzzle_note_app_data_static, Rotation::cur()); - let encoded_puzzle_note_app_data_static = - meta.query_advice(self.encoded_puzzle_note_app_data_static, Rotation::cur()); + let sudoku_app_vk_in_dealer_intent_resource = + meta.query_advice(self.sudoku_app_vk_in_dealer_intent_resource, Rotation::cur()); + let puzzle_resource_app_data_static = + meta.query_advice(self.puzzle_resource_app_data_static, Rotation::cur()); + let puzzle_resource_app_data_static = + meta.query_advice(self.puzzle_resource_app_data_static, Rotation::cur()); - let bool_check_is_input = bool_check(is_input_note.clone()); + let bool_check_is_input = bool_check(is_input_resource.clone()); Constraints::with_selector( q_dealer_intent_check, [ ("bool_check_is_input", bool_check_is_input), ( - "check zero value of puzzle note", - is_input_note.clone() * puzzle_note_value, + "check zero quantity of puzzle resource", + is_input_resource.clone() * puzzle_resource_value, ), ( "check sudoku_app_vk", - is_input_note.clone() - * (sudoku_app_vk - sudoku_app_vk_in_dealer_intent_note), + is_input_resource.clone() + * (sudoku_app_vk - sudoku_app_vk_in_dealer_intent_resource), ), ( - "check puzzle note app_data_static encoding", - is_input_note - * (puzzle_note_app_data_static - encoded_puzzle_note_app_data_static), + "check puzzle resource app_data_static encoding", + is_input_resource + * (puzzle_resource_app_data_static - puzzle_resource_app_data_static), ), ], ) @@ -308,42 +308,42 @@ impl DealerIntentCheckConfig { #[allow(clippy::too_many_arguments)] pub fn assign_region( &self, - is_input_note: &AssignedCell, - puzzle_note_value: &AssignedCell, + is_input_resource: &AssignedCell, + puzzle_resource_value: &AssignedCell, sudoku_app_vk: &AssignedCell, - sudoku_app_vk_in_dealer_intent_note: &AssignedCell, - puzzle_note_app_data_static: &AssignedCell, - encoded_puzzle_note_app_data_static: &AssignedCell, + sudoku_app_vk_in_dealer_intent_resource: &AssignedCell, + puzzle_resource_app_data_static: &AssignedCell, + puzzle_resource_app_data_static: &AssignedCell, offset: usize, region: &mut Region<'_, pallas::Base>, ) -> Result<(), Error> { // Enable `q_dealer_intent_check` selector self.q_dealer_intent_check.enable(region, offset)?; - is_input_note.copy_advice(|| "is_input_note", region, self.is_input_note, offset)?; - puzzle_note_value.copy_advice( - || "puzzle_note_value", + is_input_resource.copy_advice(|| "is_input_resource", region, self.is_input_resource, offset)?; + puzzle_resource_value.copy_advice( + || "puzzle_resource_value", region, - self.puzzle_note_value, + self.puzzle_resource_value, offset, )?; sudoku_app_vk.copy_advice(|| "sudoku_app_vk", region, self.sudoku_app_vk, offset)?; - sudoku_app_vk_in_dealer_intent_note.copy_advice( - || "sudoku_app_vk_in_dealer_intent_note", + sudoku_app_vk_in_dealer_intent_resource.copy_advice( + || "sudoku_app_vk_in_dealer_intent_resource", region, - self.sudoku_app_vk_in_dealer_intent_note, + self.sudoku_app_vk_in_dealer_intent_resource, offset, )?; - puzzle_note_app_data_static.copy_advice( - || "puzzle_note_app_data_static", + puzzle_resource_app_data_static.copy_advice( + || "puzzle_resource_app_data_static", region, - self.puzzle_note_app_data_static, + self.puzzle_resource_app_data_static, offset, )?; - encoded_puzzle_note_app_data_static.copy_advice( - || "encoded_puzzle_note_app_data_static", + puzzle_resource_app_data_static.copy_advice( + || "puzzle_resource_app_data_static", region, - self.encoded_puzzle_note_app_data_static, + self.puzzle_resource_app_data_static, offset, )?; @@ -353,30 +353,30 @@ impl DealerIntentCheckConfig { #[test] fn test_halo2_dealer_intent_vp_circuit() { - use crate::app_vp::tests::{random_input_note, random_output_note}; + use crate::app_vp::tests::{random_input_resource, random_output_resource}; use halo2_proofs::dev::MockProver; use rand::rngs::OsRng; let mut rng = OsRng; let circuit = { - let input_notes = [(); NUM_NOTE].map(|_| random_input_note(&mut rng)); - let mut output_notes = input_notes + let input_resources = [(); NUM_RESOURCE].map(|_| random_input_resource(&mut rng)); + let mut output_resources = input_resources .iter() - .map(|input| random_output_note(&mut rng, input.get_nf().unwrap())) + .map(|input| random_output_resource(&mut rng, input.get_nf().unwrap())) .collect::>(); let encoded_puzzle = pallas::Base::random(&mut rng); let sudoku_app_vk = pallas::Base::random(&mut rng); - output_notes[0].note_type.app_data_static = + output_resources[0].kind.app_data_static = DealerIntentValidityPredicateCircuit::compute_app_data_static( encoded_puzzle, sudoku_app_vk, ); let encoded_solution = pallas::Base::random(&mut rng); - let owned_note_pub_id = output_notes[0].commitment().inner(); + let owned_resource_id = output_resources[0].commitment().inner(); DealerIntentValidityPredicateCircuit { - owned_note_pub_id, - input_notes, - output_notes: output_notes.try_into().unwrap(), + owned_resource_id, + input_resources, + output_resources: output_resources.try_into().unwrap(), encoded_puzzle, sudoku_app_vk, encoded_solution, diff --git a/taiga_halo2/deprecated/taiga_sudoku/gadgets/state_check.rs b/taiga_halo2/deprecated/taiga_sudoku/gadgets/state_check.rs index 562ce6d9..0a1f116e 100644 --- a/taiga_halo2/deprecated/taiga_sudoku/gadgets/state_check.rs +++ b/taiga_halo2/deprecated/taiga_sudoku/gadgets/state_check.rs @@ -10,48 +10,48 @@ use pasta_curves::pallas; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct SudokuStateCheckConfig { q_state_check: Selector, - is_input_note: Column, + is_input_resource: Column, init_state: Column, - input_note_app_data_static: Column, - input_note_app_data_static_encoding: Column, - input_note_vk: Column, - output_note_vk: Column, - input_note_pre_state: Column, - output_note_cur_state: Column, + input_resource_app_data_static: Column, + input_resource_app_data_static_encoding: Column, + input_resource_vk: Column, + output_resource_vk: Column, + input_resource_pre_state: Column, + output_resource_cur_state: Column, } impl SudokuStateCheckConfig { #[allow(clippy::too_many_arguments)] pub fn configure( meta: &mut ConstraintSystem, - is_input_note: Column, + is_input_resource: Column, init_state: Column, - input_note_app_data_static: Column, - input_note_app_data_static_encoding: Column, - input_note_vk: Column, - output_note_vk: Column, - input_note_pre_state: Column, - output_note_cur_state: Column, + input_resource_app_data_static: Column, + input_resource_app_data_static_encoding: Column, + input_resource_vk: Column, + output_resource_vk: Column, + input_resource_pre_state: Column, + output_resource_cur_state: Column, ) -> Self { - meta.enable_equality(is_input_note); + meta.enable_equality(is_input_resource); meta.enable_equality(init_state); - meta.enable_equality(input_note_app_data_static); - meta.enable_equality(input_note_app_data_static_encoding); - meta.enable_equality(input_note_vk); - meta.enable_equality(output_note_vk); - meta.enable_equality(input_note_pre_state); - meta.enable_equality(output_note_cur_state); + meta.enable_equality(input_resource_app_data_static); + meta.enable_equality(input_resource_app_data_static_encoding); + meta.enable_equality(input_resource_vk); + meta.enable_equality(output_resource_vk); + meta.enable_equality(input_resource_pre_state); + meta.enable_equality(output_resource_cur_state); let config = Self { q_state_check: meta.selector(), - is_input_note, + is_input_resource, init_state, - input_note_app_data_static, - input_note_app_data_static_encoding, - input_note_vk, - output_note_vk, - input_note_pre_state, - output_note_cur_state, + input_resource_app_data_static, + input_resource_app_data_static_encoding, + input_resource_vk, + output_resource_vk, + input_resource_pre_state, + output_resource_cur_state, }; config.create_gate(meta); @@ -62,28 +62,28 @@ impl SudokuStateCheckConfig { fn create_gate(&self, meta: &mut ConstraintSystem) { meta.create_gate("check state", |meta| { let q_state_check = meta.query_selector(self.q_state_check); - let is_input_note = meta.query_advice(self.is_input_note, Rotation::cur()); + let is_input_resource = meta.query_advice(self.is_input_resource, Rotation::cur()); let init_state = meta.query_advice(self.init_state, Rotation::cur()); - let input_note_app_data_static = - meta.query_advice(self.input_note_app_data_static, Rotation::cur()); - let input_note_app_data_static_encoding = - meta.query_advice(self.input_note_app_data_static_encoding, Rotation::cur()); - let input_note_vk = meta.query_advice(self.input_note_vk, Rotation::cur()); - let output_note_vk = meta.query_advice(self.output_note_vk, Rotation::cur()); + let input_resource_app_data_static = + meta.query_advice(self.input_resource_app_data_static, Rotation::cur()); + let input_resource_app_data_static_encoding = + meta.query_advice(self.input_resource_app_data_static_encoding, Rotation::cur()); + let input_resource_vk = meta.query_advice(self.input_resource_vk, Rotation::cur()); + let output_resource_vk = meta.query_advice(self.output_resource_vk, Rotation::cur()); - let input_note_pre_state = - meta.query_advice(self.input_note_pre_state, Rotation::cur()); - let output_note_cur_state = - meta.query_advice(self.output_note_cur_state, Rotation::cur()); - let pre_state_minus_cur_state = input_note_pre_state - output_note_cur_state.clone(); + let input_resource_pre_state = + meta.query_advice(self.input_resource_pre_state, Rotation::cur()); + let output_resource_cur_state = + meta.query_advice(self.output_resource_cur_state, Rotation::cur()); + let pre_state_minus_cur_state = input_resource_pre_state - output_resource_cur_state.clone(); let pre_state_minus_cur_state_inv = - meta.query_advice(self.input_note_pre_state, Rotation::next()); + meta.query_advice(self.input_resource_pre_state, Rotation::next()); let one = Expression::Constant(pallas::Base::one()); let pre_state_minus_cur_state_is_zero = one - pre_state_minus_cur_state.clone() * pre_state_minus_cur_state_inv; let poly = pre_state_minus_cur_state_is_zero.clone() * pre_state_minus_cur_state; - let bool_check_is_input = bool_check(is_input_note.clone()); + let bool_check_is_input = bool_check(is_input_resource.clone()); Constraints::with_selector( q_state_check, @@ -91,21 +91,21 @@ impl SudokuStateCheckConfig { ("bool_check_is_input", bool_check_is_input), ( "check vk", - is_input_note.clone() * (input_note_vk.clone() - output_note_vk.clone()), + is_input_resource.clone() * (input_resource_vk.clone() - output_resource_vk.clone()), ), ( - "check input_note_app_data_static_encoding", - is_input_note.clone() - * (input_note_app_data_static_encoding - input_note_app_data_static), + "check input_resource_app_data_static_encoding", + is_input_resource.clone() + * (input_resource_app_data_static_encoding - input_resource_app_data_static), ), ( "check puzzle init", - (init_state - output_note_cur_state) * (output_note_vk - input_note_vk), + (init_state - output_resource_cur_state) * (output_resource_vk - input_resource_vk), ), ("is_zero check", poly), ( "pre_state != cur_state", - is_input_note * pre_state_minus_cur_state_is_zero, + is_input_resource * pre_state_minus_cur_state_is_zero, ), ], ) @@ -115,55 +115,55 @@ impl SudokuStateCheckConfig { #[allow(clippy::too_many_arguments)] pub fn assign_region( &self, - is_input_note: &AssignedCell, + is_input_resource: &AssignedCell, init_state: &AssignedCell, - input_note_app_data_static: &AssignedCell, - input_note_app_data_static_encoding: &AssignedCell, - input_note_vk: &AssignedCell, - output_note_vk: &AssignedCell, - input_note_pre_state: &AssignedCell, - output_note_cur_state: &AssignedCell, + input_resource_app_data_static: &AssignedCell, + input_resource_app_data_static_encoding: &AssignedCell, + input_resource_vk: &AssignedCell, + output_resource_vk: &AssignedCell, + input_resource_pre_state: &AssignedCell, + output_resource_cur_state: &AssignedCell, offset: usize, region: &mut Region<'_, pallas::Base>, ) -> Result<(), Error> { // Enable `q_state_check` selector self.q_state_check.enable(region, offset)?; - is_input_note.copy_advice(|| "is_input_notex", region, self.is_input_note, offset)?; + is_input_resource.copy_advice(|| "is_input_resourcex", region, self.is_input_resource, offset)?; init_state.copy_advice(|| "init_state", region, self.init_state, offset)?; - input_note_app_data_static.copy_advice( - || "input_note_app_data_static", + input_resource_app_data_static.copy_advice( + || "input_resource_app_data_static", region, - self.input_note_app_data_static, + self.input_resource_app_data_static, offset, )?; - input_note_app_data_static_encoding.copy_advice( - || "input_note_app_data_static_encoding", + input_resource_app_data_static_encoding.copy_advice( + || "input_resource_app_data_static_encoding", region, - self.input_note_app_data_static_encoding, + self.input_resource_app_data_static_encoding, offset, )?; - input_note_vk.copy_advice(|| "input_note_vk", region, self.input_note_vk, offset)?; - output_note_vk.copy_advice(|| "output_note_vk", region, self.output_note_vk, offset)?; - input_note_pre_state.copy_advice( - || "input_note_pre_state", + input_resource_vk.copy_advice(|| "input_resource_vk", region, self.input_resource_vk, offset)?; + output_resource_vk.copy_advice(|| "output_resource_vk", region, self.output_resource_vk, offset)?; + input_resource_pre_state.copy_advice( + || "input_resource_pre_state", region, - self.input_note_pre_state, + self.input_resource_pre_state, offset, )?; - output_note_cur_state.copy_advice( - || "output_note_cur_state", + output_resource_cur_state.copy_advice( + || "output_resource_cur_state", region, - self.output_note_cur_state, + self.output_resource_cur_state, offset, )?; - let pre_state_minus_cur_state_inv = input_note_pre_state + let pre_state_minus_cur_state_inv = input_resource_pre_state .value() - .zip(output_note_cur_state.value()) + .zip(output_resource_cur_state.value()) .map(|(pre, cur)| (pre - cur).invert().unwrap_or(pallas::Base::zero())); region.assign_advice( || "pre_state_minus_cur_state_inv", - self.input_note_pre_state, + self.input_resource_pre_state, offset + 1, || pre_state_minus_cur_state_inv, )?; diff --git a/taiga_halo2/deprecated/taiga_sudoku/gadgets/state_update.rs b/taiga_halo2/deprecated/taiga_sudoku/gadgets/state_update.rs index 45ddff76..2200ae46 100644 --- a/taiga_halo2/deprecated/taiga_sudoku/gadgets/state_update.rs +++ b/taiga_halo2/deprecated/taiga_sudoku/gadgets/state_update.rs @@ -9,7 +9,7 @@ use pasta_curves::pallas; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct StateUpdateConfig { q_state_update: Selector, - is_input_note: Column, + is_input_resource: Column, pre_state_cell: Column, cur_state_cell: Column, } @@ -18,17 +18,17 @@ impl StateUpdateConfig { #[allow(clippy::too_many_arguments)] pub fn configure( meta: &mut ConstraintSystem, - is_input_note: Column, + is_input_resource: Column, pre_state_cell: Column, cur_state_cell: Column, ) -> Self { - meta.enable_equality(is_input_note); + meta.enable_equality(is_input_resource); meta.enable_equality(pre_state_cell); meta.enable_equality(cur_state_cell); let config = Self { q_state_update: meta.selector(), - is_input_note, + is_input_resource, pre_state_cell, cur_state_cell, }; @@ -41,11 +41,11 @@ impl StateUpdateConfig { fn create_gate(&self, meta: &mut ConstraintSystem) { meta.create_gate("check state update", |meta| { let q_state_update = meta.query_selector(self.q_state_update); - let is_input_note = meta.query_advice(self.is_input_note, Rotation::cur()); + let is_input_resource = meta.query_advice(self.is_input_resource, Rotation::cur()); let pre_state_cell = meta.query_advice(self.pre_state_cell, Rotation::cur()); let cur_state_cell = meta.query_advice(self.cur_state_cell, Rotation::cur()); - let bool_check_is_input = bool_check(is_input_note.clone()); + let bool_check_is_input = bool_check(is_input_resource.clone()); Constraints::with_selector( q_state_update, @@ -53,7 +53,7 @@ impl StateUpdateConfig { ("bool_check_is_input", bool_check_is_input), ( "check state update", - is_input_note * pre_state_cell.clone() * (pre_state_cell - cur_state_cell), + is_input_resource * pre_state_cell.clone() * (pre_state_cell - cur_state_cell), ), ], ) @@ -62,7 +62,7 @@ impl StateUpdateConfig { pub fn assign_region( &self, - is_input_note: &AssignedCell, + is_input_resource: &AssignedCell, pre_state_cell: &AssignedCell, cur_state_cell: &AssignedCell, offset: usize, @@ -71,7 +71,7 @@ impl StateUpdateConfig { // Enable `q_state_update` selector self.q_state_update.enable(region, offset)?; - is_input_note.copy_advice(|| "is_input_note", region, self.is_input_note, offset)?; + is_input_resource.copy_advice(|| "is_input_resource", region, self.is_input_resource, offset)?; pre_state_cell.copy_advice(|| "pre_state_cell", region, self.pre_state_cell, offset)?; cur_state_cell.copy_advice(|| "cur_state_cell", region, self.cur_state_cell, offset)?; Ok(()) diff --git a/taiga_halo2/deprecated/taiga_sudoku/gadgets/value_check.rs b/taiga_halo2/deprecated/taiga_sudoku/gadgets/value_check.rs index 9f3b1b41..77ef7a0a 100644 --- a/taiga_halo2/deprecated/taiga_sudoku/gadgets/value_check.rs +++ b/taiga_halo2/deprecated/taiga_sudoku/gadgets/value_check.rs @@ -11,24 +11,24 @@ use pasta_curves::pallas; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct ValueCheckConfig { q_value_check: Selector, - is_input_note: Column, + is_input_resource: Column, state_product: Column, - value: Column, + quantity: Column, } impl ValueCheckConfig { #[allow(clippy::too_many_arguments)] pub fn configure( meta: &mut ConstraintSystem, - is_input_note: Column, + is_input_resource: Column, state_product: Column, - value: Column, + quantity: Column, ) -> Self { let config = Self { q_value_check: meta.selector(), - is_input_note, + is_input_resource, state_product, - value, + quantity, }; config.create_gate(meta); @@ -39,10 +39,10 @@ impl ValueCheckConfig { fn create_gate(&self, meta: &mut ConstraintSystem) { meta.create_gate("check state update", |meta| { let q_value_check = meta.query_selector(self.q_value_check); - let is_input_note = meta.query_advice(self.is_input_note, Rotation::cur()); + let is_input_resource = meta.query_advice(self.is_input_resource, Rotation::cur()); let state_product = meta.query_advice(self.state_product, Rotation::cur()); - let input_value = meta.query_advice(self.value, Rotation::cur()); - let output_value = meta.query_advice(self.value, Rotation::next()); + let input_value = meta.query_advice(self.quantity, Rotation::cur()); + let output_value = meta.query_advice(self.quantity, Rotation::next()); let state_product_inv = meta.query_advice(self.state_product, Rotation::next()); let one = Expression::Constant(pallas::Base::one()); let state_product_is_zero = one - state_product.clone() * state_product_inv; @@ -56,8 +56,8 @@ impl ValueCheckConfig { [ ("bool_check_value", bool_check_value), ("is_zero check", poly), - ("output value check", (state_product_is_zero - output_value)), - ("input value check", is_input_note * (input_value - one)), + ("output quantity check", (state_product_is_zero - output_value)), + ("input quantity check", is_input_resource * (input_value - one)), ], ) }); @@ -65,7 +65,7 @@ impl ValueCheckConfig { pub fn assign_region( &self, - is_input_note: &AssignedCell, + is_input_resource: &AssignedCell, state_product: &AssignedCell, input_value: &AssignedCell, output_value: &AssignedCell, @@ -74,10 +74,10 @@ impl ValueCheckConfig { ) -> Result<(), Error> { // Enable `q_value_check` selector self.q_value_check.enable(region, offset)?; - is_input_note.copy_advice(|| "is_input_note", region, self.is_input_note, offset)?; + is_input_resource.copy_advice(|| "is_input_resource", region, self.is_input_resource, offset)?; state_product.copy_advice(|| "state_product", region, self.state_product, offset)?; - input_value.copy_advice(|| "input value", region, self.value, offset)?; - output_value.copy_advice(|| "output value", region, self.value, offset + 1)?; + input_value.copy_advice(|| "input quantity", region, self.quantity, offset)?; + output_value.copy_advice(|| "output quantity", region, self.quantity, offset + 1)?; let state_product_inv = state_product .value() .map(|state_product| state_product.invert().unwrap_or(pallas::Base::zero())); diff --git a/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs b/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs index d9b4b4d7..37140218 100644 --- a/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs +++ b/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs @@ -7,13 +7,13 @@ use rand::{CryptoRng, RngCore}; use taiga_halo2::{ action::ActionInfo, circuit::vp_examples::{ - cascade_intent::{create_intent_note, CascadeIntentValidityPredicateCircuit}, + cascade_intent::{create_intent_resource, CascadeIntentValidityPredicateCircuit}, signature_verification::COMPRESSED_TOKEN_AUTH_VK, token::{Token, TokenAuthorization}, }, constant::TAIGA_COMMITMENT_TREE_DEPTH, merkle_tree::{Anchor, MerklePath}, - note::NoteValidityPredicates, + resource::ResourceValidityPredicates, shielded_ptx::ShieldedPartialTransaction, transaction::{ShieldedPartialTxBundle, Transaction, TransparentPartialTxBundle}, }; @@ -24,51 +24,54 @@ pub fn create_transaction(mut rng: R) -> Transaction { let alice_nk = pallas::Base::random(&mut rng); let bob_auth = TokenAuthorization::random(&mut rng); - let bob_nk_com = pallas::Base::random(&mut rng); + let bob_npk = pallas::Base::random(&mut rng); let input_token_1 = Token::new("btc".to_string(), 1u64); - let input_note_1 = - input_token_1.create_random_input_token_note(&mut rng, alice_nk, &alice_auth); + let input_resource_1 = + input_token_1.create_random_input_token_resource(&mut rng, alice_nk, &alice_auth); let output_token_1 = Token::new("btc".to_string(), 1u64); - let mut output_note_1 = output_token_1.create_random_output_token_note(bob_nk_com, &bob_auth); + let mut output_resource_1 = + output_token_1.create_random_output_token_resource(bob_npk, &bob_auth); let input_token_2 = Token::new("eth".to_string(), 2u64); - let input_note_2 = - input_token_2.create_random_input_token_note(&mut rng, alice_nk, &alice_auth); + let input_resource_2 = + input_token_2.create_random_input_token_resource(&mut rng, alice_nk, &alice_auth); let input_token_3 = Token::new("xan".to_string(), 3u64); - let input_note_3 = - input_token_3.create_random_input_token_note(&mut rng, alice_nk, &alice_auth); - let mut cascade_intent_note = - create_intent_note(&mut rng, input_note_3.commitment().inner(), alice_nk); + let input_resource_3 = + input_token_3.create_random_input_token_resource(&mut rng, alice_nk, &alice_auth); + let mut cascade_intent_resource = + create_intent_resource(&mut rng, input_resource_3.commitment().inner(), alice_nk); let output_token_2 = Token::new("eth".to_string(), 2u64); - let mut output_note_2 = output_token_2.create_random_output_token_note(bob_nk_com, &bob_auth); + let mut output_resource_2 = + output_token_2.create_random_output_token_resource(bob_npk, &bob_auth); let output_token_3 = Token::new("xan".to_string(), 3u64); - let mut output_note_3 = output_token_3.create_random_output_token_note(bob_nk_com, &bob_auth); + let mut output_resource_3 = + output_token_3.create_random_output_token_resource(bob_npk, &bob_auth); let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); - // Fetch a valid anchor for dummy notes + // Fetch a valid anchor for dummy resources 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. + // Alice creates a cascade intent resource and 1 "BTC" to Bob. let ptx_1 = { // Create action pairs let actions = { let action_1 = ActionInfo::new( - *input_note_1.note(), + *input_resource_1.resource(), merkle_path.clone(), None, - &mut output_note_1.note, + &mut output_resource_1.resource, &mut rng, ); let action_2 = ActionInfo::new( - *input_note_2.note(), + *input_resource_2.resource(), merkle_path.clone(), None, - &mut cascade_intent_note, + &mut cascade_intent_resource, &mut rng, ); vec![action_1, action_2] @@ -76,50 +79,50 @@ pub fn create_transaction(mut rng: R) -> Transaction { // Create VPs let (input_vps, output_vps) = { - let input_notes = [*input_note_1.note(), *input_note_2.note()]; - let output_notes = [*output_note_1.note(), cascade_intent_note]; + let input_resources = [*input_resource_1.resource(), *input_resource_2.resource()]; + let output_resources = [*output_resource_1.resource(), cascade_intent_resource]; - // Create the input note_1 vps - let input_note_1_vps = input_note_1.generate_input_token_vps( + // Create the input resource_1 vps + let input_resource_1_vps = input_resource_1.generate_input_token_vps( &mut rng, alice_auth, alice_auth_sk, - input_notes, - output_notes, + input_resources, + output_resources, ); - // Create the input note_2 vps - let input_note_2_vps = input_note_2.generate_input_token_vps( + // Create the input resource_2 vps + let input_resource_2_vps = input_resource_2.generate_input_token_vps( &mut rng, alice_auth, alice_auth_sk, - input_notes, - output_notes, + input_resources, + output_resources, ); - // Create the output note_1 vps - let output_note_1_vps = output_note_1.generate_output_token_vps( + // Create the output resource_1 vps + let output_resource_1_vps = output_resource_1.generate_output_token_vps( &mut rng, bob_auth, - input_notes, - output_notes, + input_resources, + output_resources, ); // Create intent vps let intent_vps = { let intent_vp = CascadeIntentValidityPredicateCircuit { - owned_note_pub_id: cascade_intent_note.commitment().inner(), - input_notes, - output_notes, - cascade_note_cm: cascade_intent_note.get_app_data_static(), + owned_resource_id: cascade_intent_resource.commitment().inner(), + input_resources, + output_resources, + cascade_resource_cm: cascade_intent_resource.get_label(), }; - NoteValidityPredicates::new(Box::new(intent_vp), vec![]) + ResourceValidityPredicates::new(Box::new(intent_vp), vec![]) }; ( - vec![input_note_1_vps, input_note_2_vps], - vec![output_note_1_vps, intent_vps], + vec![input_resource_1_vps, input_resource_2_vps], + vec![output_resource_1_vps, intent_vps], ) }; @@ -128,24 +131,24 @@ pub fn create_transaction(mut rng: R) -> Transaction { }; // The second partial transaction: - // Alice consumes the intent note and 3 "XAN"; + // Alice consumes the intent resource and 3 "XAN"; // Alice creates 2 "ETH" and 3 "XAN" to Bob let ptx_2 = { // Create action pairs let actions = { let action_1 = ActionInfo::new( - cascade_intent_note, + cascade_intent_resource, merkle_path.clone(), Some(anchor), - &mut output_note_2.note, + &mut output_resource_2.resource, &mut rng, ); let action_2 = ActionInfo::new( - *input_note_3.note(), + *input_resource_3.resource(), merkle_path, None, - &mut output_note_3.note, + &mut output_resource_3.resource, &mut rng, ); vec![action_1, action_2] @@ -153,49 +156,49 @@ pub fn create_transaction(mut rng: R) -> Transaction { // Create VPs let (input_vps, output_vps) = { - let input_notes = [cascade_intent_note, *input_note_3.note()]; - let output_notes = [*output_note_2.note(), *output_note_3.note()]; + let input_resources = [cascade_intent_resource, *input_resource_3.resource()]; + let output_resources = [*output_resource_2.resource(), *output_resource_3.resource()]; // Create intent vps let intent_vps = { let intent_vp = CascadeIntentValidityPredicateCircuit { - owned_note_pub_id: cascade_intent_note.get_nf().unwrap().inner(), - input_notes, - output_notes, - cascade_note_cm: cascade_intent_note.get_app_data_static(), + owned_resource_id: cascade_intent_resource.get_nf().unwrap().inner(), + input_resources, + output_resources, + cascade_resource_cm: cascade_intent_resource.get_label(), }; - NoteValidityPredicates::new(Box::new(intent_vp), vec![]) + ResourceValidityPredicates::new(Box::new(intent_vp), vec![]) }; - // Create input note_3 vps - let input_note_3_vps = input_note_3.generate_input_token_vps( + // Create input resource_3 vps + let input_resource_3_vps = input_resource_3.generate_input_token_vps( &mut rng, alice_auth, alice_auth_sk, - input_notes, - output_notes, + input_resources, + output_resources, ); - // Create output note_2 vps - let output_note_2_vps = output_note_2.generate_output_token_vps( + // Create output resource_2 vps + let output_resource_2_vps = output_resource_2.generate_output_token_vps( &mut rng, bob_auth, - input_notes, - output_notes, + input_resources, + output_resources, ); - // Create output note_3 vps - let output_note_3_vps = output_note_3.generate_output_token_vps( + // Create output resource_3 vps + let output_resource_3_vps = output_resource_3.generate_output_token_vps( &mut rng, bob_auth, - input_notes, - output_notes, + input_resources, + output_resources, ); ( - vec![intent_vps, input_note_3_vps], - vec![output_note_2_vps, output_note_3_vps], + vec![intent_vps, input_resource_3_vps], + vec![output_resource_2_vps, output_resource_3_vps], ) }; 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 95efd62f..91a89408 100644 --- a/taiga_halo2/examples/tx_examples/partial_fulfillment_token_swap.rs +++ b/taiga_halo2/examples/tx_examples/partial_fulfillment_token_swap.rs @@ -13,12 +13,12 @@ use taiga_halo2::{ circuit::vp_examples::{ partial_fulfillment_intent::{PartialFulfillmentIntentValidityPredicateCircuit, Swap}, signature_verification::COMPRESSED_TOKEN_AUTH_VK, - token::{Token, TokenAuthorization, TokenNote}, + token::{Token, TokenAuthorization, TokenResource}, }, constant::TAIGA_COMMITMENT_TREE_DEPTH, merkle_tree::{Anchor, MerklePath}, - note::{Note, NoteValidityPredicates}, nullifier::NullifierKeyContainer, + resource::{Resource, ResourceValidityPredicates}, shielded_ptx::ShieldedPartialTransaction, transaction::{ShieldedPartialTxBundle, Transaction, TransparentPartialTxBundle}, }; @@ -28,33 +28,33 @@ pub fn create_token_intent_ptx( sell: Token, buy: Token, input_auth_sk: pallas::Scalar, -) -> (ShieldedPartialTransaction, Swap, Note) { +) -> (ShieldedPartialTransaction, Swap, Resource) { let input_auth = TokenAuthorization::from_sk_vk(&input_auth_sk, &COMPRESSED_TOKEN_AUTH_VK); let swap = Swap::random(&mut rng, sell, buy, input_auth); - let mut intent_note = swap.create_intent_note(&mut rng); + let mut intent_resource = swap.create_intent_resource(&mut rng); - // padding the zero notes - let padding_input_note = Note::random_padding_note(&mut rng); - let mut padding_output_note = Note::random_padding_note(&mut rng); + // padding the zero resources + let padding_input_resource = Resource::random_padding_resource(&mut rng); + let mut padding_output_resource = Resource::random_padding_resource(&mut rng); let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); // Create action pairs let actions = { let action_1 = ActionInfo::new( - *swap.sell.note(), + *swap.sell.resource(), merkle_path.clone(), None, - &mut intent_note, + &mut intent_resource, &mut rng, ); - // Fetch a valid anchor for dummy notes + // Fetch a valid anchor for dummy resources let anchor = Anchor::from(pallas::Base::random(&mut rng)); let action_2 = ActionInfo::new( - padding_input_note, + padding_input_resource, merkle_path, Some(anchor), - &mut padding_output_note, + &mut padding_output_resource, &mut rng, ); vec![action_1, action_2] @@ -62,41 +62,41 @@ pub fn create_token_intent_ptx( // Create VPs let (input_vps, output_vps) = { - let input_notes = [*swap.sell.note(), padding_input_note]; - let output_notes = [intent_note, padding_output_note]; + let input_resources = [*swap.sell.resource(), padding_input_resource]; + let output_resources = [intent_resource, padding_output_resource]; // Create the input token vps let input_token_vps = swap.sell.generate_input_token_vps( &mut rng, input_auth, input_auth_sk, - input_notes, - output_notes, + input_resources, + output_resources, ); // Create the intent vps let intent_vps = { let intent_vp = PartialFulfillmentIntentValidityPredicateCircuit { - owned_note_pub_id: intent_note.commitment().inner(), - input_notes, - output_notes, + owned_resource_id: intent_resource.commitment().inner(), + input_resources, + output_resources, swap: swap.clone(), }; - NoteValidityPredicates::new(Box::new(intent_vp), vec![]) + ResourceValidityPredicates::new(Box::new(intent_vp), vec![]) }; // Create the padding input vps - let padding_input_vps = NoteValidityPredicates::create_input_padding_note_vps( - &padding_input_note, - input_notes, - output_notes, + let padding_input_vps = ResourceValidityPredicates::create_input_padding_resource_vps( + &padding_input_resource, + input_resources, + output_resources, ); // Create the padding output vps - let padding_output_vps = NoteValidityPredicates::create_output_padding_note_vps( - &padding_output_note, - input_notes, - output_notes, + let padding_output_vps = ResourceValidityPredicates::create_output_padding_resource_vps( + &padding_output_resource, + input_resources, + output_resources, ); ( @@ -109,43 +109,43 @@ pub fn create_token_intent_ptx( let ptx = ShieldedPartialTransaction::build(actions, input_vps, output_vps, vec![], &mut rng) .unwrap(); - (ptx, swap, intent_note) + (ptx, swap, intent_resource) } #[allow(clippy::too_many_arguments)] pub fn consume_token_intent_ptx( mut rng: R, swap: Swap, - intent_note: Note, + intent_resource: Resource, offer: Token, output_auth_pk: pallas::Point, ) -> ShieldedPartialTransaction { - let (input_notes, [mut bought_note, mut returned_note]) = - swap.fill(&mut rng, intent_note, offer); - let [intent_note, padding_input_note] = input_notes; + let (input_resources, [mut bought_resource, mut returned_resource]) = + swap.fill(&mut rng, intent_resource, offer); + let [intent_resource, padding_input_resource] = input_resources; - // output notes + // output resources let output_auth = TokenAuthorization::new(output_auth_pk, *COMPRESSED_TOKEN_AUTH_VK); let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); - // Fetch a valid anchor for dummy notes + // Fetch a valid anchor for dummy resources let anchor = Anchor::from(pallas::Base::random(&mut rng)); // Create action pairs let actions = { let action_1 = ActionInfo::new( - intent_note, + intent_resource, merkle_path.clone(), Some(anchor), - &mut bought_note, + &mut bought_resource, &mut rng, ); let action_2 = ActionInfo::new( - padding_input_note, + padding_input_resource, merkle_path, Some(anchor), - &mut returned_note, + &mut returned_resource, &mut rng, ); vec![action_1, action_2] @@ -153,43 +153,53 @@ pub fn consume_token_intent_ptx( // Create VPs let (input_vps, output_vps) = { - let output_notes = [bought_note, returned_note]; + let output_resources = [bought_resource, returned_resource]; // Create intent vps let intent_vps = { let intent_vp = PartialFulfillmentIntentValidityPredicateCircuit { - owned_note_pub_id: intent_note.get_nf().unwrap().inner(), - input_notes, - output_notes, + owned_resource_id: intent_resource.get_nf().unwrap().inner(), + input_resources, + output_resources, swap: swap.clone(), }; - NoteValidityPredicates::new(Box::new(intent_vp), vec![]) + ResourceValidityPredicates::new(Box::new(intent_vp), vec![]) }; - // Create bought_note_vps - let bought_note_vps = TokenNote { + // Create bought_resource_vps + let bought_resource_vps = TokenResource { token_name: swap.buy.name().clone(), - note: bought_note, + resource: bought_resource, } - .generate_output_token_vps(&mut rng, output_auth, input_notes, output_notes); + .generate_output_token_vps( + &mut rng, + output_auth, + input_resources, + output_resources, + ); // Create the padding input vps - let padding_input_vps = NoteValidityPredicates::create_input_padding_note_vps( - &padding_input_note, - input_notes, - output_notes, + let padding_input_vps = ResourceValidityPredicates::create_input_padding_resource_vps( + &padding_input_resource, + input_resources, + output_resources, ); - // Create returned_note_vps - let returned_note_vps = TokenNote { + // Create returned_resource_vps + let returned_resource_vps = TokenResource { token_name: swap.sell.token_name().clone(), - note: returned_note, + resource: returned_resource, } - .generate_output_token_vps(&mut rng, output_auth, input_notes, output_notes); + .generate_output_token_vps( + &mut rng, + output_auth, + input_resources, + output_resources, + ); ( vec![intent_vps, padding_input_vps], - vec![bought_note_vps, returned_note_vps], + vec![bought_resource_vps, returned_resource_vps], ) }; @@ -207,7 +217,7 @@ pub fn create_token_swap_transaction(mut rng: R) -> Tran let alice_auth_pk = generator * alice_auth_sk; let sell = Token::new("btc".to_string(), 2u64); let buy = Token::new("eth".to_string(), 10u64); - let (alice_ptx, swap, intent_note) = + let (alice_ptx, swap, intent_resource) = create_token_intent_ptx(&mut rng, sell.clone(), buy.clone(), alice_auth_sk); // Bob creates the partial transaction with 1 DOLPHIN input and 5 BTC output @@ -224,12 +234,13 @@ pub fn create_token_swap_transaction(mut rng: R) -> Tran bob_nk.get_nk().unwrap(), returned, bob_auth_pk, - bob_nk.get_commitment(), + bob_nk.get_npk(), ); - // Solver/Bob creates the partial transaction to consume the intent note + // Solver/Bob creates the partial transaction to consume the intent resource // The bob_ptx and solver_ptx can be merged to one ptx. - let solver_ptx = consume_token_intent_ptx(&mut rng, swap, intent_note, offer, alice_auth_pk); + let solver_ptx = + consume_token_intent_ptx(&mut rng, swap, intent_resource, offer, alice_auth_pk); // Solver creates the final transaction let shielded_tx_bundle = ShieldedPartialTxBundle::new(vec![alice_ptx, bob_ptx, solver_ptx]); diff --git a/taiga_halo2/examples/tx_examples/token.rs b/taiga_halo2/examples/tx_examples/token.rs index 5a0cdba3..9d9aec9a 100644 --- a/taiga_halo2/examples/tx_examples/token.rs +++ b/taiga_halo2/examples/tx_examples/token.rs @@ -11,7 +11,7 @@ use taiga_halo2::{ }, constant::TAIGA_COMMITMENT_TREE_DEPTH, merkle_tree::{Anchor, MerklePath}, - note::{Note, NoteValidityPredicates}, + resource::{Resource, ResourceValidityPredicates}, shielded_ptx::ShieldedPartialTransaction, }; @@ -23,20 +23,22 @@ pub fn create_token_swap_ptx( input_nk: pallas::Base, output_token: Token, output_auth_pk: pallas::Point, - output_nk_com: pallas::Base, + output_npk: pallas::Base, ) -> ShieldedPartialTransaction { let input_auth = TokenAuthorization::from_sk_vk(&input_auth_sk, &COMPRESSED_TOKEN_AUTH_VK); - // input note - let input_note = input_token.create_random_input_token_note(&mut rng, input_nk, &input_auth); + // input resource + let input_resource = + input_token.create_random_input_token_resource(&mut rng, input_nk, &input_auth); - // output note + // output resource let output_auth = TokenAuthorization::new(output_auth_pk, *COMPRESSED_TOKEN_AUTH_VK); - let mut output_note = output_token.create_random_output_token_note(output_nk_com, &output_auth); + let mut output_resource = + output_token.create_random_output_token_resource(output_npk, &output_auth); - // padding the zero notes - let padding_input_note = Note::random_padding_note(&mut rng); - let mut padding_output_note = Note::random_padding_note(&mut rng); + // padding the zero resources + let padding_input_resource = Resource::random_padding_resource(&mut rng); + let mut padding_output_resource = Resource::random_padding_resource(&mut rng); // Generate proving info let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); @@ -44,20 +46,20 @@ pub fn create_token_swap_ptx( // Create action pairs let actions = { let action_1 = ActionInfo::new( - *input_note.note(), + *input_resource.resource(), merkle_path.clone(), None, - &mut output_note.note, + &mut output_resource.resource, &mut rng, ); - // Fetch a valid anchor for padding input notes + // Fetch a valid anchor for padding input resources let anchor = Anchor::from(pallas::Base::random(&mut rng)); let action_2 = ActionInfo::new( - padding_input_note, + padding_input_resource, merkle_path, Some(anchor), - &mut padding_output_note, + &mut padding_output_resource, &mut rng, ); vec![action_1, action_2] @@ -65,33 +67,37 @@ pub fn create_token_swap_ptx( // Create VPs let (input_vps, output_vps) = { - let input_notes = [*input_note.note(), padding_input_note]; - let output_notes = [*output_note.note(), padding_output_note]; + let input_resources = [*input_resource.resource(), padding_input_resource]; + let output_resources = [*output_resource.resource(), padding_output_resource]; // Create the input token vps - let input_token_vps = input_note.generate_input_token_vps( + let input_token_vps = input_resource.generate_input_token_vps( &mut rng, input_auth, input_auth_sk, - input_notes, - output_notes, + input_resources, + output_resources, ); // Create the output token vps - let output_token_vps = - output_note.generate_output_token_vps(&mut rng, output_auth, input_notes, output_notes); + let output_token_vps = output_resource.generate_output_token_vps( + &mut rng, + output_auth, + input_resources, + output_resources, + ); // Create the padding input vps - let padding_input_vps = NoteValidityPredicates::create_input_padding_note_vps( - &padding_input_note, - input_notes, - output_notes, + let padding_input_vps = ResourceValidityPredicates::create_input_padding_resource_vps( + &padding_input_resource, + input_resources, + output_resources, ); // Create the padding output vps - let padding_output_vps = NoteValidityPredicates::create_output_padding_note_vps( - &padding_output_note, - input_notes, - output_notes, + let padding_output_vps = ResourceValidityPredicates::create_output_padding_resource_vps( + &padding_output_resource, + input_resources, + output_resources, ); ( 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 89d80343..3a6928ab 100644 --- a/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs +++ b/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs @@ -1,4 +1,4 @@ -/// Token swap example with intent note +/// Token swap example with intent resource /// Alice has 5 "BTC" and wants 1 "DOLPHIN" or 2 "Monkeys". Then Alice creates an intent for it. /// Bob has 1 "DOLPHIN" and wants 5 "BTC". /// The Solver/Bob matches Alice's intent and creates the final tx. @@ -11,14 +11,14 @@ use rand::{CryptoRng, RngCore}; use taiga_halo2::{ action::ActionInfo, circuit::vp_examples::{ - or_relation_intent::{create_intent_note, OrRelationIntentValidityPredicateCircuit}, + or_relation_intent::{create_intent_resource, OrRelationIntentValidityPredicateCircuit}, signature_verification::COMPRESSED_TOKEN_AUTH_VK, token::{Token, TokenAuthorization}, }, constant::TAIGA_COMMITMENT_TREE_DEPTH, merkle_tree::{Anchor, MerklePath}, - note::{Note, NoteValidityPredicates}, nullifier::NullifierKeyContainer, + resource::{Resource, ResourceValidityPredicates}, shielded_ptx::ShieldedPartialTransaction, transaction::{ShieldedPartialTxBundle, Transaction, TransparentPartialTxBundle}, }; @@ -38,43 +38,44 @@ pub fn create_token_intent_ptx( ) { let input_auth = TokenAuthorization::from_sk_vk(&input_auth_sk, &COMPRESSED_TOKEN_AUTH_VK); - // input note - let input_note = input_token.create_random_input_token_note(&mut rng, input_nk, &input_auth); + // input resource + let input_resource = + input_token.create_random_input_token_resource(&mut rng, input_nk, &input_auth); - // output intent note - let input_note_nk_com = input_note.get_nk_commitment(); - let mut intent_note = create_intent_note( + // output intent resource + let input_resource_npk = input_resource.get_npk(); + let mut intent_resource = create_intent_resource( &mut rng, &token_1, &token_2, - input_note_nk_com, - input_note.app_data_dynamic, + input_resource_npk, + input_resource.value, input_nk, ); - // padding the zero notes - let padding_input_note = Note::random_padding_note(&mut rng); - let mut padding_output_note = Note::random_padding_note(&mut rng); + // padding the zero resources + let padding_input_resource = Resource::random_padding_resource(&mut rng); + let mut padding_output_resource = Resource::random_padding_resource(&mut rng); let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); // Create action pairs let actions = { let action_1 = ActionInfo::new( - *input_note.note(), + *input_resource.resource(), merkle_path.clone(), None, - &mut intent_note, + &mut intent_resource, &mut rng, ); - // Fetch a valid anchor for padding input notes + // Fetch a valid anchor for padding input resources let anchor = Anchor::from(pallas::Base::random(&mut rng)); let action_2 = ActionInfo::new( - padding_input_note, + padding_input_resource, merkle_path, Some(anchor), - &mut padding_output_note, + &mut padding_output_resource, &mut rng, ); vec![action_1, action_2] @@ -82,49 +83,49 @@ pub fn create_token_intent_ptx( // Create VPs let (input_vps, output_vps) = { - let input_notes = [*input_note.note(), padding_input_note]; - let output_notes = [intent_note, padding_output_note]; - // Create the input note vps - let input_note_vps = input_note.generate_input_token_vps( + let input_resources = [*input_resource.resource(), padding_input_resource]; + let output_resources = [intent_resource, padding_output_resource]; + // Create the input resource vps + let input_resource_vps = input_resource.generate_input_token_vps( &mut rng, input_auth, input_auth_sk, - input_notes, - output_notes, + input_resources, + output_resources, ); - // Create the intent note proving info - let intent_note_vps = { + // Create the intent resource proving info + let intent_resource_vps = { let intent_vp = OrRelationIntentValidityPredicateCircuit { - owned_note_pub_id: intent_note.commitment().inner(), - input_notes, - output_notes, + owned_resource_id: intent_resource.commitment().inner(), + input_resources, + output_resources, token_1, token_2, - receiver_nk_com: input_note_nk_com, - receiver_app_data_dynamic: input_note.app_data_dynamic, + receiver_npk: input_resource_npk, + receiver_value: input_resource.value, }; - NoteValidityPredicates::new(Box::new(intent_vp), vec![]) + ResourceValidityPredicates::new(Box::new(intent_vp), vec![]) }; // Create the padding input vps - let padding_input_vps = NoteValidityPredicates::create_input_padding_note_vps( - &padding_input_note, - input_notes, - output_notes, + let padding_input_vps = ResourceValidityPredicates::create_input_padding_resource_vps( + &padding_input_resource, + input_resources, + output_resources, ); // Create the padding output vps - let padding_output_vps = NoteValidityPredicates::create_output_padding_note_vps( - &padding_output_note, - input_notes, - output_notes, + let padding_output_vps = ResourceValidityPredicates::create_output_padding_resource_vps( + &padding_output_resource, + input_resources, + output_resources, ); ( - vec![input_note_vps, padding_input_vps], - vec![intent_note_vps, padding_output_vps], + vec![input_resource_vps, padding_input_vps], + vec![intent_resource_vps, padding_output_vps], ) }; @@ -132,12 +133,7 @@ pub fn create_token_intent_ptx( let ptx = ShieldedPartialTransaction::build(actions, input_vps, output_vps, vec![], &mut rng) .unwrap(); - ( - ptx, - input_nk, - input_note_nk_com, - input_note.app_data_dynamic, - ) + (ptx, input_nk, input_resource_npk, input_resource.value) } #[allow(clippy::too_many_arguments)] @@ -146,51 +142,52 @@ pub fn consume_token_intent_ptx( token_1: Token, token_2: Token, input_nk: pallas::Base, - receiver_nk_com: pallas::Base, - receiver_app_data_dynamic: pallas::Base, + receiver_npk: pallas::Base, + receiver_value: pallas::Base, output_token: Token, output_auth_pk: pallas::Point, ) -> ShieldedPartialTransaction { - // input intent note - let intent_note = create_intent_note( + // input intent resource + let intent_resource = create_intent_resource( &mut rng, &token_1, &token_2, - receiver_nk_com, - receiver_app_data_dynamic, + receiver_npk, + receiver_value, input_nk, ); - // output note - let input_note_nf = intent_note.get_nf().unwrap(); + // output resource + let input_resource_nf = intent_resource.get_nf().unwrap(); let output_auth = TokenAuthorization::new(output_auth_pk, *COMPRESSED_TOKEN_AUTH_VK); - let output_nk_com = NullifierKeyContainer::from_key(input_nk).get_commitment(); - let mut output_note = output_token.create_random_output_token_note(output_nk_com, &output_auth); + let output_npk = NullifierKeyContainer::from_key(input_nk).get_npk(); + let mut output_resource = + output_token.create_random_output_token_resource(output_npk, &output_auth); - // padding the zero notes - let padding_input_note = Note::random_padding_note(&mut rng); - let mut padding_output_note = Note::random_padding_note(&mut rng); + // padding the zero resources + let padding_input_resource = Resource::random_padding_resource(&mut rng); + let mut padding_output_resource = Resource::random_padding_resource(&mut rng); let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); - // Fetch a valid anchor for dummy notes + // Fetch a valid anchor for dummy resources let anchor = Anchor::from(pallas::Base::random(&mut rng)); // Create action pairs let actions = { let action_1 = ActionInfo::new( - intent_note, + intent_resource, merkle_path.clone(), Some(anchor), - &mut output_note.note, + &mut output_resource.resource, &mut rng, ); let action_2 = ActionInfo::new( - padding_input_note, + padding_input_resource, merkle_path, Some(anchor), - &mut padding_output_note, + &mut padding_output_resource, &mut rng, ); vec![action_1, action_2] @@ -198,39 +195,43 @@ pub fn consume_token_intent_ptx( // Create VPs let (input_vps, output_vps) = { - let input_notes = [intent_note, padding_input_note]; - let output_notes = [*output_note.note(), padding_output_note]; + let input_resources = [intent_resource, padding_input_resource]; + let output_resources = [*output_resource.resource(), padding_output_resource]; // Create intent vps let intent_vps = { let intent_vp = OrRelationIntentValidityPredicateCircuit { - owned_note_pub_id: input_note_nf.inner(), - input_notes, - output_notes, + owned_resource_id: input_resource_nf.inner(), + input_resources, + output_resources, token_1, token_2, - receiver_nk_com, - receiver_app_data_dynamic, + receiver_npk, + receiver_value, }; - NoteValidityPredicates::new(Box::new(intent_vp), vec![]) + ResourceValidityPredicates::new(Box::new(intent_vp), vec![]) }; // Create the output token vps - let output_token_vps = - output_note.generate_output_token_vps(&mut rng, output_auth, input_notes, output_notes); + let output_token_vps = output_resource.generate_output_token_vps( + &mut rng, + output_auth, + input_resources, + output_resources, + ); // Create the padding input vps - let padding_input_vps = NoteValidityPredicates::create_input_padding_note_vps( - &padding_input_note, - input_notes, - output_notes, + let padding_input_vps = ResourceValidityPredicates::create_input_padding_resource_vps( + &padding_input_resource, + input_resources, + output_resources, ); // Create the padding output vps - let padding_output_vps = NoteValidityPredicates::create_output_padding_note_vps( - &padding_output_note, - input_notes, - output_notes, + let padding_output_vps = ResourceValidityPredicates::create_output_padding_resource_vps( + &padding_output_resource, + input_resources, + output_resources, ); ( @@ -253,15 +254,14 @@ pub fn create_token_swap_intent_transaction(mut rng: R) let token_1 = Token::new("dolphin".to_string(), 1u64); let token_2 = Token::new("monkey".to_string(), 2u64); let btc_token = Token::new("btc".to_string(), 5u64); - let (alice_ptx, intent_nk, receiver_nk_com, receiver_app_data_dynamic) = - create_token_intent_ptx( - &mut rng, - token_1.clone(), - token_2.clone(), - btc_token.clone(), - alice_auth_sk, - alice_nk, - ); + let (alice_ptx, intent_nk, receiver_npk, receiver_value) = create_token_intent_ptx( + &mut rng, + token_1.clone(), + token_2.clone(), + btc_token.clone(), + alice_auth_sk, + alice_nk, + ); // Bob creates the partial transaction with 1 DOLPHIN input and 5 BTC output let bob_auth_sk = pallas::Scalar::random(&mut rng); @@ -275,18 +275,18 @@ pub fn create_token_swap_intent_transaction(mut rng: R) bob_nk.get_nk().unwrap(), btc_token, bob_auth_pk, - bob_nk.get_commitment(), + bob_nk.get_npk(), ); - // Solver/Bob creates the partial transaction to consume the intent note + // Solver/Bob creates the partial transaction to consume the intent resource // The bob_ptx and solver_ptx can be merged to one ptx. let solver_ptx = consume_token_intent_ptx( &mut rng, token_1.clone(), token_2, intent_nk, - receiver_nk_com, - receiver_app_data_dynamic, + receiver_npk, + receiver_value, token_1, alice_auth_pk, ); diff --git a/taiga_halo2/examples/tx_examples/token_swap_without_intent.rs b/taiga_halo2/examples/tx_examples/token_swap_without_intent.rs index 0712132d..39d0a8be 100644 --- a/taiga_halo2/examples/tx_examples/token_swap_without_intent.rs +++ b/taiga_halo2/examples/tx_examples/token_swap_without_intent.rs @@ -1,4 +1,4 @@ -/// Multi-party token swap without intent notes +/// Multi-party token swap without intent resources /// Alice has 5 "BTC" and wants 10 "ETH" /// Bob has 10 "ETH" and wants 15 "XAN" /// Carol has 15 "XAN" and wants 5 BTC"" @@ -33,7 +33,7 @@ pub fn create_token_swap_transaction(mut rng: R) -> Tran alice_nk.get_nk().unwrap(), eth_token.clone(), alice_auth_pk, - alice_nk.get_commitment(), + alice_nk.get_npk(), ); // Bob creates the partial transaction @@ -48,7 +48,7 @@ pub fn create_token_swap_transaction(mut rng: R) -> Tran bob_nk.get_nk().unwrap(), xan_token.clone(), bob_auth_pk, - bob_nk.get_commitment(), + bob_nk.get_npk(), ); // Carol creates the partial transaction @@ -63,7 +63,7 @@ pub fn create_token_swap_transaction(mut rng: R) -> Tran carol_nk.get_nk().unwrap(), btc_token, carol_auth_pk, - carol_nk.get_commitment(), + carol_nk.get_npk(), ); // Solver creates the final transaction diff --git a/taiga_halo2/src/action.rs b/taiga_halo2/src/action.rs index 8305a8d2..0fc771e3 100644 --- a/taiga_halo2/src/action.rs +++ b/taiga_halo2/src/action.rs @@ -1,10 +1,10 @@ use crate::{ circuit::action_circuit::ActionCircuit, constant::{PRF_EXPAND_INPUT_VP_CM_R, PRF_EXPAND_OUTPUT_VP_CM_R}, + delta_commitment::DeltaCommitment, merkle_tree::{Anchor, MerklePath}, - note::{Note, NoteCommitment, RandomSeed}, nullifier::Nullifier, - value_commitment::ValueCommitment, + resource::{RandomSeed, Resource, ResourceCommitment}, vp_commitment::ValidityPredicateCommitment, }; use pasta_curves::pallas; @@ -25,17 +25,17 @@ use borsh::{BorshDeserialize, BorshSerialize}; #[cfg_attr(feature = "nif", module = "Taiga.Action.PublicInputs")] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ActionPublicInputs { - /// The root of the note commitment Merkle tree. + /// The root of the resource commitment Merkle tree. pub anchor: Anchor, - /// The nullifier of input note. + /// The nullifier of input resource. pub nf: Nullifier, - /// The commitment to the output note. - pub cm: NoteCommitment, - /// net value commitment - pub cv_net: ValueCommitment, - /// The commitment to input note application(static) vp + /// The commitment to the output resource. + pub cm: ResourceCommitment, + /// Resource delta is used to reason about total quantities of different kinds of resources. + pub delta: DeltaCommitment, + /// The commitment to input resource application(static) vp pub input_vp_commitment: ValidityPredicateCommitment, - /// The commitment to output note application(static) vp + /// The commitment to output resource application(static) vp pub output_vp_commitment: ValidityPredicateCommitment, } @@ -44,11 +44,11 @@ pub struct ActionPublicInputs { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))] pub struct ActionInfo { - input_note: Note, + input_resource: Resource, input_merkle_path: MerklePath, input_anchor: Anchor, - output_note: Note, - // rseed is to generate the randomness of the value commitment and vp commitments + output_resource: Resource, + // rseed is to generate the randomness of the delta commitment and vp commitments rseed: RandomSeed, } @@ -60,8 +60,8 @@ impl ActionPublicInputs { self.nf.inner(), self.anchor.inner(), self.cm.inner(), - self.cv_net.get_x(), - self.cv_net.get_y(), + self.delta.get_x(), + self.delta.get_y(), input_vp_commitment[0], input_vp_commitment[1], output_vp_commitment[0], @@ -76,7 +76,7 @@ impl BorshSerialize for ActionPublicInputs { writer.write_all(&self.anchor.to_bytes())?; writer.write_all(&self.nf.to_bytes())?; writer.write_all(&self.cm.to_bytes())?; - writer.write_all(&self.cv_net.to_bytes())?; + writer.write_all(&self.delta.to_bytes())?; writer.write_all(&self.input_vp_commitment.to_bytes())?; writer.write_all(&self.output_vp_commitment.to_bytes())?; Ok(()) @@ -94,11 +94,11 @@ impl BorshDeserialize for ActionPublicInputs { let nf = Option::from(Nullifier::from_bytes(nf_bytes)) .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "nf not in field"))?; let cm_bytes = <[u8; 32]>::deserialize_reader(reader)?; - let cm = Option::from(NoteCommitment::from_bytes(cm_bytes)) + let cm = Option::from(ResourceCommitment::from_bytes(cm_bytes)) .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "cm not in field"))?; - let cv_net_bytes = <[u8; 32]>::deserialize_reader(reader)?; - let cv_net = Option::from(ValueCommitment::from_bytes(cv_net_bytes)) - .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "cv_net not in field"))?; + let detla_bytes = <[u8; 32]>::deserialize_reader(reader)?; + let delta = Option::from(DeltaCommitment::from_bytes(detla_bytes)) + .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "delta not in field"))?; let input_vp_commitment_bytes = <[u8; 32]>::deserialize_reader(reader)?; let input_vp_commitment = ValidityPredicateCommitment::from_bytes(input_vp_commitment_bytes); @@ -110,7 +110,7 @@ impl BorshDeserialize for ActionPublicInputs { anchor, nf, cm, - cv_net, + delta, input_vp_commitment, output_vp_commitment, }) @@ -118,98 +118,98 @@ impl BorshDeserialize for ActionPublicInputs { } impl ActionInfo { - // The dummy input note must provide a valid custom_anchor, but a random merkle path - // The normal input note only needs to provide a valid merkle path. The anchor will be calculated from the note and path. - // The rho of output_note will be reset to the nullifier of input_note + // The dummy input resource must provide a valid custom_anchor, but a random merkle path + // The normal input resource only needs to provide a valid merkle path. The anchor will be calculated from the resource and path. + // The nonce of output_resource will be set to the nullifier of input_resource pub fn new( - input_note: Note, + input_resource: Resource, input_merkle_path: MerklePath, custom_anchor: Option, - output_note: &mut Note, + output_resource: &mut Resource, mut rng: R, ) -> Self { let input_anchor = match custom_anchor { Some(anchor) => anchor, - None => input_note.calculate_root(&input_merkle_path), + None => input_resource.calculate_root(&input_merkle_path), }; - output_note.set_rho(&input_note, &mut rng); + output_resource.set_nonce(&input_resource, &mut rng); Self { - input_note, + input_resource, input_merkle_path, input_anchor, - output_note: *output_note, + output_resource: *output_resource, rseed: RandomSeed::random(&mut rng), } } - // Get the randomness of value commitment + // Get the randomness of delta commitment pub fn get_rcv(&self) -> pallas::Scalar { self.rseed.get_rcv() } - // Get the randomness of input note application vp commitment + // Get the randomness of input resource application vp commitment pub fn get_input_vp_com_r(&self) -> pallas::Base { self.rseed.get_vp_cm_r(PRF_EXPAND_INPUT_VP_CM_R) } - // Get the randomness of output note application vp commitment + // Get the randomness of output resource application vp commitment pub fn get_output_vp_com_r(&self) -> pallas::Base { self.rseed.get_vp_cm_r(PRF_EXPAND_OUTPUT_VP_CM_R) } // Only used in transparent scenario: the achor is untrusted, recalculate root when executing it transparently. pub fn calculate_root(&self) -> Anchor { - self.input_note.calculate_root(&self.input_merkle_path) + self.input_resource.calculate_root(&self.input_merkle_path) } - // Get value commitment - pub fn get_value_commitment(&self, blind_r: &pallas::Scalar) -> ValueCommitment { - ValueCommitment::commit(&self.input_note, &self.output_note, blind_r) + // Get delta commitment + pub fn get_delta_commitment(&self, blind_r: &pallas::Scalar) -> DeltaCommitment { + DeltaCommitment::commit(&self.input_resource, &self.output_resource, blind_r) } - pub fn get_input_note_nullifer(&self) -> Nullifier { - self.input_note.get_nf().unwrap() + pub fn get_input_resource_nullifer(&self) -> Nullifier { + self.input_resource.get_nf().unwrap() } - pub fn get_output_note_cm(&self) -> NoteCommitment { - self.output_note.commitment() + pub fn get_output_resource_cm(&self) -> ResourceCommitment { + self.output_resource.commitment() } pub fn build(&self) -> (ActionPublicInputs, ActionCircuit) { - let nf = self.get_input_note_nullifer(); + let nf = self.get_input_resource_nullifer(); assert_eq!( - nf, self.output_note.rho, - "The nf of input note should be equal to the rho of output note" + nf, self.output_resource.nonce, + "The nf of input resource must be equal to the nonce of output resource" ); - let cm = self.get_output_note_cm(); + let cm = self.get_output_resource_cm(); let rcv = self.get_rcv(); - let cv_net = self.get_value_commitment(&rcv); + let delta = self.get_delta_commitment(&rcv); let input_vp_cm_r = self.get_input_vp_com_r(); let input_vp_commitment = - ValidityPredicateCommitment::commit(&self.input_note.get_app_vk(), &input_vp_cm_r); + ValidityPredicateCommitment::commit(&self.input_resource.get_logic(), &input_vp_cm_r); let output_vp_cm_r = self.get_output_vp_com_r(); let output_vp_commitment = - ValidityPredicateCommitment::commit(&self.output_note.get_app_vk(), &output_vp_cm_r); + ValidityPredicateCommitment::commit(&self.output_resource.get_logic(), &output_vp_cm_r); let action = ActionPublicInputs { nf, cm, anchor: self.input_anchor, - cv_net, + delta, input_vp_commitment, output_vp_commitment, }; let action_circuit = ActionCircuit { - input_note: self.input_note, + input_resource: self.input_resource, merkle_path: self.input_merkle_path.get_path().try_into().unwrap(), - output_note: self.output_note, + output_resource: self.output_resource, rcv, input_vp_cm_r, output_vp_cm_r, @@ -224,18 +224,18 @@ pub mod tests { use super::ActionInfo; use crate::constant::TAIGA_COMMITMENT_TREE_DEPTH; use crate::merkle_tree::MerklePath; - use crate::note::tests::random_note; + use crate::resource::tests::random_resource; use rand::RngCore; pub fn random_action_info(mut rng: R) -> ActionInfo { - let input_note = random_note(&mut rng); - let mut output_note = random_note(&mut rng); + let input_resource = random_resource(&mut rng); + let mut output_resource = random_resource(&mut rng); let input_merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); ActionInfo::new( - input_note, + input_resource, input_merkle_path, None, - &mut output_note, + &mut output_resource, &mut rng, ) } diff --git a/taiga_halo2/src/binding_signature.rs b/taiga_halo2/src/binding_signature.rs index 3266c18b..d73fa16d 100644 --- a/taiga_halo2/src/binding_signature.rs +++ b/taiga_halo2/src/binding_signature.rs @@ -1,4 +1,4 @@ -use crate::constant::NOTE_COMMITMENT_R_GENERATOR; +use crate::constant::RESOURCE_COMMITMENT_R_GENERATOR; use pasta_curves::group::cofactor::CofactorCurveAffine; use pasta_curves::group::{ff::PrimeField, GroupEncoding}; use pasta_curves::pallas; @@ -26,7 +26,7 @@ impl private::Sealed for TaigaBinding { type Scalar = pallas::Scalar; fn basepoint() -> pallas::Point { - NOTE_COMMITMENT_R_GENERATOR.to_curve() + RESOURCE_COMMITMENT_R_GENERATOR.to_curve() } } diff --git a/taiga_halo2/src/circuit/action_circuit.rs b/taiga_halo2/src/circuit/action_circuit.rs index 5b777a4e..6830c187 100644 --- a/taiga_halo2/src/circuit/action_circuit.rs +++ b/taiga_halo2/src/circuit/action_circuit.rs @@ -1,19 +1,21 @@ use crate::circuit::blake2s::{vp_commitment_gadget, Blake2sChip, Blake2sConfig}; use crate::circuit::gadgets::assign_free_advice; use crate::circuit::hash_to_curve::HashToCurveConfig; -use crate::circuit::integrity::{check_input_note, check_output_note, compute_value_commitment}; +use crate::circuit::integrity::{ + check_input_resource, check_output_resource, compute_delta_commitment, +}; use crate::circuit::merkle_circuit::{ merkle_poseidon_gadget, MerklePoseidonChip, MerklePoseidonConfig, }; use crate::constant::{ - TaigaFixedBases, ACTION_ANCHOR_PUBLIC_INPUT_ROW_IDX, ACTION_INPUT_VP_CM_1_ROW_IDX, - ACTION_INPUT_VP_CM_2_ROW_IDX, ACTION_NET_VALUE_CM_X_PUBLIC_INPUT_ROW_IDX, - ACTION_NET_VALUE_CM_Y_PUBLIC_INPUT_ROW_IDX, ACTION_NF_PUBLIC_INPUT_ROW_IDX, + TaigaFixedBases, ACTION_ANCHOR_PUBLIC_INPUT_ROW_IDX, ACTION_DELTA_CM_X_PUBLIC_INPUT_ROW_IDX, + ACTION_DELTA_CM_Y_PUBLIC_INPUT_ROW_IDX, ACTION_INPUT_VP_CM_1_ROW_IDX, + ACTION_INPUT_VP_CM_2_ROW_IDX, ACTION_NF_PUBLIC_INPUT_ROW_IDX, ACTION_OUTPUT_CM_PUBLIC_INPUT_ROW_IDX, ACTION_OUTPUT_VP_CM_1_ROW_IDX, ACTION_OUTPUT_VP_CM_2_ROW_IDX, TAIGA_COMMITMENT_TREE_DEPTH, }; use crate::merkle_tree::LR; -use crate::note::Note; +use crate::resource::Resource; use halo2_gadgets::{ ecc::chip::{EccChip, EccConfig}, @@ -30,7 +32,7 @@ use halo2_proofs::{ }; use pasta_curves::pallas; -use crate::circuit::note_commitment::{NoteCommitChip, NoteCommitConfig}; +use crate::circuit::resource_commitment::{ResourceCommitChip, ResourceCommitConfig}; #[derive(Clone, Debug)] pub struct ActionConfig { @@ -43,23 +45,23 @@ pub struct ActionConfig { merkle_path_selector: Selector, hash_to_curve_config: HashToCurveConfig, blake2s_config: Blake2sConfig, - note_commit_config: NoteCommitConfig, + resource_commit_config: ResourceCommitConfig, } /// The Action circuit. #[derive(Clone, Debug, Default)] pub struct ActionCircuit { - /// Input note - pub input_note: Note, - /// The authorization path of input note + /// Input resource + pub input_resource: Resource, + /// The authorization path of input resource pub merkle_path: [(pallas::Base, LR); TAIGA_COMMITMENT_TREE_DEPTH], - /// Output note - pub output_note: Note, - /// random scalar for net value commitment + /// Output resource + pub output_resource: Resource, + /// random scalar for delta commitment pub rcv: pallas::Scalar, - /// The randomness for input note application vp commitment + /// The randomness for input resource application vp commitment pub input_vp_cm_r: pallas::Base, - /// The randomness for output note application vp commitment + /// The randomness for output resource application vp commitment pub output_vp_cm_r: pallas::Base, } @@ -146,7 +148,7 @@ impl Circuit for ActionCircuit { let blake2s_config = Blake2sConfig::configure(meta, advices); - let note_commit_config = NoteCommitChip::configure( + let resource_commit_config = ResourceCommitChip::configure( meta, advices[0..3].try_into().unwrap(), poseidon_config.clone(), @@ -163,7 +165,7 @@ impl Circuit for ActionCircuit { merkle_path_selector, hash_to_curve_config, blake2s_config, - note_commit_config, + resource_commit_config, } } @@ -196,17 +198,17 @@ impl Circuit for ActionCircuit { // Construct a blake2s chip let blake2s_chip = Blake2sChip::construct(config.blake2s_config); - // Construct a note_commit chip - let note_commit_chip = NoteCommitChip::construct(config.note_commit_config); + // Construct a resource_commit chip + let resource_commit_chip = ResourceCommitChip::construct(config.resource_commit_config); - // Input note - // Check the input note commitment - let input_note_variables = check_input_note( - layouter.namespace(|| "check input note"), + // Input resource + // Check the input resource commitment + let input_resource_variables = check_input_resource( + layouter.namespace(|| "check input resource"), config.advices, config.instances, - note_commit_chip.clone(), - self.input_note, + resource_commit_chip.clone(), + self.input_resource, ACTION_NF_PUBLIC_INPUT_ROW_IDX, )?; @@ -214,51 +216,51 @@ impl Circuit for ActionCircuit { let root = merkle_poseidon_gadget( layouter.namespace(|| "poseidon merkle"), merkle_chip, - input_note_variables.cm, + input_resource_variables.cm, &self.merkle_path, )?; - // Output note - let output_note_vars = check_output_note( - layouter.namespace(|| "check output note"), + // Output resource + let output_resource_vars = check_output_resource( + layouter.namespace(|| "check output resource"), config.advices, config.instances, - note_commit_chip, - self.output_note, - input_note_variables.nf, + resource_commit_chip, + self.output_resource, + input_resource_variables.nf, ACTION_OUTPUT_CM_PUBLIC_INPUT_ROW_IDX, )?; - // compute and public net value commitment(input_value_commitment - output_value_commitment) - let cv_net = compute_value_commitment( - layouter.namespace(|| "net value commitment"), + // compute and public delta commitment(input_value_commitment - output_value_commitment) + let delta = compute_delta_commitment( + layouter.namespace(|| "delta commitment"), ecc_chip, config.hash_to_curve_config.clone(), - input_note_variables.note_variables.app_vk.clone(), - input_note_variables.note_variables.app_data_static.clone(), - input_note_variables.note_variables.value.clone(), - output_note_vars.note_variables.app_vk.clone(), - output_note_vars.note_variables.app_data_static.clone(), - output_note_vars.note_variables.value, + input_resource_variables.resource_variables.logic.clone(), + input_resource_variables.resource_variables.label.clone(), + input_resource_variables.resource_variables.quantity.clone(), + output_resource_vars.resource_variables.logic.clone(), + output_resource_vars.resource_variables.label.clone(), + output_resource_vars.resource_variables.quantity, self.rcv, )?; layouter.constrain_instance( - cv_net.inner().x().cell(), + delta.inner().x().cell(), config.instances, - ACTION_NET_VALUE_CM_X_PUBLIC_INPUT_ROW_IDX, + ACTION_DELTA_CM_X_PUBLIC_INPUT_ROW_IDX, )?; layouter.constrain_instance( - cv_net.inner().y().cell(), + delta.inner().y().cell(), config.instances, - ACTION_NET_VALUE_CM_Y_PUBLIC_INPUT_ROW_IDX, + ACTION_DELTA_CM_Y_PUBLIC_INPUT_ROW_IDX, )?; // merkle path check layouter.assign_region( || "merkle path check", |mut region| { - input_note_variables - .note_variables + input_resource_variables + .resource_variables .is_merkle_checked .copy_advice( || "is_merkle_checked_input", @@ -278,7 +280,7 @@ impl Circuit for ActionCircuit { }, )?; - // Input note application VP commitment + // Input resource application VP commitment let input_vp_cm_r = assign_free_advice( layouter.namespace(|| "witness input_vp_cm_r"), config.advices[0], @@ -287,7 +289,7 @@ impl Circuit for ActionCircuit { let input_vp_commitment = vp_commitment_gadget( &mut layouter, &blake2s_chip, - input_note_variables.note_variables.app_vk.clone(), + input_resource_variables.resource_variables.logic.clone(), input_vp_cm_r, )?; layouter.constrain_instance( @@ -301,7 +303,7 @@ impl Circuit for ActionCircuit { ACTION_INPUT_VP_CM_2_ROW_IDX, )?; - // Output note application VP commitment + // Output resource application VP commitment let output_vp_cm_r = assign_free_advice( layouter.namespace(|| "witness output_vp_cm_r"), config.advices[0], @@ -310,7 +312,7 @@ impl Circuit for ActionCircuit { let output_vp_commitment = vp_commitment_gadget( &mut layouter, &blake2s_chip, - output_note_vars.note_variables.app_vk.clone(), + output_resource_vars.resource_variables.logic.clone(), output_vp_cm_r, )?; layouter.constrain_instance( diff --git a/taiga_halo2/src/circuit/gadgets.rs b/taiga_halo2/src/circuit/gadgets.rs index fd798a60..d386314c 100644 --- a/taiga_halo2/src/circuit/gadgets.rs +++ b/taiga_halo2/src/circuit/gadgets.rs @@ -11,7 +11,7 @@ pub mod extended_or_relation; pub mod mul; pub mod poseidon_hash; pub mod sub; -pub mod target_note_variable; +pub mod target_resource_variable; pub mod triple_mul; pub fn assign_free_advice( diff --git a/taiga_halo2/src/circuit/gadgets/extended_or_relation.rs b/taiga_halo2/src/circuit/gadgets/extended_or_relation.rs index bbbabbec..af37a967 100644 --- a/taiga_halo2/src/circuit/gadgets/extended_or_relation.rs +++ b/taiga_halo2/src/circuit/gadgets/extended_or_relation.rs @@ -35,19 +35,21 @@ impl ExtendedOrRelationConfig { meta.create_gate("extended or relation", |meta| { let q_extended_or_relation = meta.query_selector(self.q_extended_or_relation); - let is_input_note_flag = meta.query_advice(self.advice[2], Rotation::cur()); + let is_input_resource_flag = meta.query_advice(self.advice[2], Rotation::cur()); let a1 = meta.query_advice(self.advice[0], Rotation::prev()); let a2 = meta.query_advice(self.advice[1], Rotation::prev()); let b1 = meta.query_advice(self.advice[0], Rotation::cur()); let b2 = meta.query_advice(self.advice[1], Rotation::cur()); let c1 = meta.query_advice(self.advice[0], Rotation::next()); let c2 = meta.query_advice(self.advice[1], Rotation::next()); - let poly1 = - is_input_note_flag.clone() * (c1.clone() - a1.clone()) * (c1.clone() - b1.clone()); - let poly2 = - is_input_note_flag.clone() * (c2.clone() - a2.clone()) * (c2.clone() - b2.clone()); - let poly3 = is_input_note_flag.clone() * (c1.clone() - a1) * (c2.clone() - b2); - let poly4 = is_input_note_flag * (c1 - b1) * (c2 - a2); + let poly1 = is_input_resource_flag.clone() + * (c1.clone() - a1.clone()) + * (c1.clone() - b1.clone()); + let poly2 = is_input_resource_flag.clone() + * (c2.clone() - a2.clone()) + * (c2.clone() - b2.clone()); + let poly3 = is_input_resource_flag.clone() * (c1.clone() - a1) * (c2.clone() - b2); + let poly4 = is_input_resource_flag * (c1 - b1) * (c2 - a2); Constraints::with_selector( q_extended_or_relation, @@ -63,7 +65,7 @@ impl ExtendedOrRelationConfig { pub fn assign_region( &self, - is_input_note_flag: &AssignedCell, + is_input_resource_flag: &AssignedCell, a: ( &AssignedCell, &AssignedCell, @@ -82,8 +84,8 @@ impl ExtendedOrRelationConfig { // Enable `q_extended_or_relation` selector self.q_extended_or_relation.enable(region, offset + 1)?; - is_input_note_flag.copy_advice( - || "is_input_note_flag", + is_input_resource_flag.copy_advice( + || "is_input_resource_flag", region, self.advice[2], offset + 1, diff --git a/taiga_halo2/src/circuit/gadgets/target_note_variable.rs b/taiga_halo2/src/circuit/gadgets/target_note_variable.rs deleted file mode 100644 index 0453fae1..00000000 --- a/taiga_halo2/src/circuit/gadgets/target_note_variable.rs +++ /dev/null @@ -1,336 +0,0 @@ -use crate::circuit::vp_circuit::NoteSearchableVariablePair; -use crate::constant::NUM_NOTE; -use halo2_gadgets::utilities::bool_check; -use halo2_proofs::{ - arithmetic::Field, - circuit::{AssignedCell, Layouter, Region, Value}, - plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Expression, Selector}, - poly::Rotation, -}; -use pasta_curves::pallas; - -// Search and get owned note variable -pub fn get_owned_note_variable( - config: GetOwnedNoteVariableConfig, - mut layouter: impl Layouter, - // The owned_note_pub_id is the input_note_nf or the output_note_cm_x - owned_note_pub_id: &AssignedCell, - // NUM_NOTE pairs are from input notes, the other NUM_NOTE are from output notes - note_variable_pairs: &[NoteSearchableVariablePair; NUM_NOTE * 2], -) -> Result, Error> { - layouter.assign_region( - || "get owned_note_variable", - |mut region| config.assign_region(owned_note_pub_id, note_variable_pairs, 0, &mut region), - ) -} - -// Search and get is_input_note_flag variable -pub fn get_is_input_note_flag( - config: GetIsInputNoteFlagConfig, - mut layouter: impl Layouter, - // The owned_note_pub_id is the input_note_nf or the output_note_cm_x - owned_note_pub_id: &AssignedCell, - input_note_nfs: &[AssignedCell; NUM_NOTE], - output_note_cms: &[AssignedCell; NUM_NOTE], -) -> Result, Error> { - layouter.assign_region( - || "get is_input_note_flag", - |mut region| { - config.assign_region( - owned_note_pub_id, - input_note_nfs, - output_note_cms, - 0, - &mut region, - ) - }, - ) -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct GetOwnedNoteVariableConfig { - q_get_owned_note_variable: Selector, - owned_note_pub_id: Column, - note_variable_pairs: [Column; NUM_NOTE * 2], -} - -impl GetOwnedNoteVariableConfig { - #[allow(clippy::too_many_arguments)] - pub fn configure( - meta: &mut ConstraintSystem, - owned_note_pub_id: Column, - note_variable_pairs: [Column; NUM_NOTE * 2], - ) -> Self { - let config = Self { - q_get_owned_note_variable: meta.selector(), - owned_note_pub_id, - note_variable_pairs, - }; - - config.create_gate(meta); - - config - } - - fn create_gate(&self, meta: &mut ConstraintSystem) { - meta.create_gate("get owned note variable", |meta| { - let q_get_owned_note_variable = meta.query_selector(self.q_get_owned_note_variable); - let owned_note_pub_id = meta.query_advice(self.owned_note_pub_id, Rotation::cur()); - let owned_note_variable = meta.query_advice(self.owned_note_pub_id, Rotation::next()); - let nf_or_cm_vec: Vec> = self - .note_variable_pairs - .into_iter() - .map(|column| meta.query_advice(column, Rotation::cur())) - .collect(); - let target_variable_vec: Vec> = self - .note_variable_pairs - .into_iter() - .map(|column| meta.query_advice(column, Rotation::next())) - .collect(); - let inv_vec: Vec> = self - .note_variable_pairs - .into_iter() - .map(|column| meta.query_advice(column, Rotation::prev())) - .collect(); - let nf_or_cm_minus_owned_note_pub_id_vec: Vec> = - nf_or_cm_vec - .into_iter() - .map(|nf_or_cm| nf_or_cm - owned_note_pub_id.clone()) - .collect(); - let one = Expression::Constant(pallas::Base::one()); - let nf_or_cm_minus_owned_note_pub_id_is_zero_vec: Vec> = - nf_or_cm_minus_owned_note_pub_id_vec - .clone() - .into_iter() - .zip(inv_vec) - .map(|(nf_or_cm_minus_owned_note_pub_id, inv)| { - one.clone() - nf_or_cm_minus_owned_note_pub_id * inv - }) - .collect(); - let poly_vec: Vec> = nf_or_cm_minus_owned_note_pub_id_vec - .into_iter() - .zip(nf_or_cm_minus_owned_note_pub_id_is_zero_vec.clone()) - .map(|(nf_or_cm_minus_owned_note_pub_id, is_zero)| { - nf_or_cm_minus_owned_note_pub_id * is_zero - }) - .collect(); - - Constraints::with_selector( - q_get_owned_note_variable, - [ - ( - "nf_or_cm_minus_owned_note_pub_id_is_zero check0", - poly_vec[0].clone(), - ), - ( - "nf_or_cm_minus_owned_note_pub_id_is_zero check1", - poly_vec[1].clone(), - ), - ( - "nf_or_cm_minus_owned_note_pub_id_is_zero check2", - poly_vec[2].clone(), - ), - ( - "nf_or_cm_minus_owned_note_pub_id_is_zero check3", - poly_vec[3].clone(), - ), - ( - "owned_note_variable check0", - nf_or_cm_minus_owned_note_pub_id_is_zero_vec[0].clone() - * (owned_note_variable.clone() - target_variable_vec[0].clone()), - ), - ( - "owned_note_variable check1", - nf_or_cm_minus_owned_note_pub_id_is_zero_vec[1].clone() - * (owned_note_variable.clone() - target_variable_vec[1].clone()), - ), - ( - "owned_note_variable check2", - nf_or_cm_minus_owned_note_pub_id_is_zero_vec[2].clone() - * (owned_note_variable.clone() - target_variable_vec[2].clone()), - ), - ( - "owned_note_variable check3", - nf_or_cm_minus_owned_note_pub_id_is_zero_vec[3].clone() - * (owned_note_variable - target_variable_vec[3].clone()), - ), - ( - "owned_note_pub_id exists in the notes", - nf_or_cm_minus_owned_note_pub_id_is_zero_vec[0].clone() - * nf_or_cm_minus_owned_note_pub_id_is_zero_vec[1].clone() - * nf_or_cm_minus_owned_note_pub_id_is_zero_vec[2].clone() - * nf_or_cm_minus_owned_note_pub_id_is_zero_vec[3].clone(), - ), - ], - ) - }); - } - - pub fn assign_region( - &self, - owned_note_pub_id: &AssignedCell, - note_variable_pairs: &[NoteSearchableVariablePair; NUM_NOTE * 2], - offset: usize, - region: &mut Region<'_, pallas::Base>, - ) -> Result, Error> { - // Enable `q_get_owned_note_variable` selector - self.q_get_owned_note_variable.enable(region, offset + 1)?; - - // copy owned_note_pub_id, note_variable_pairs into the advice columns - owned_note_pub_id.copy_advice( - || "owned_note_pub_id", - region, - self.owned_note_pub_id, - offset + 1, - )?; - - let mut ret = Value::known(pallas::Base::zero()); - for (pair, column) in note_variable_pairs.iter().zip(self.note_variable_pairs) { - pair.src_variable - .copy_advice(|| "nf or cm", region, column, offset + 1)?; - pair.target_variable - .copy_advice(|| "target_variable", region, column, offset + 2)?; - let inv = pair - .src_variable - .value() - .zip(owned_note_pub_id.value()) - .map(|(nf_or_cm, owned_note_pub_id)| { - let inv = (nf_or_cm - owned_note_pub_id) - .invert() - .unwrap_or(pallas::Base::zero()); - - // Find the target variable - if inv == pallas::Base::zero() { - ret = pair.target_variable.value().copied(); - } - inv - }); - region.assign_advice(|| "inv", column, offset, || inv)?; - } - region.assign_advice(|| "ret", self.owned_note_pub_id, offset + 2, || ret) - } -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct GetIsInputNoteFlagConfig { - q_get_is_input_note_flag: Selector, - owned_note_pub_id: Column, - input_note_nf: Column, - output_note_cm: Column, -} - -impl GetIsInputNoteFlagConfig { - #[allow(clippy::too_many_arguments)] - pub fn configure( - meta: &mut ConstraintSystem, - owned_note_pub_id: Column, - input_note_nf: Column, - output_note_cm: Column, - ) -> Self { - meta.enable_equality(owned_note_pub_id); - meta.enable_equality(input_note_nf); - meta.enable_equality(output_note_cm); - - let config = Self { - q_get_is_input_note_flag: meta.selector(), - owned_note_pub_id, - input_note_nf, - output_note_cm, - }; - - config.create_gate(meta); - - config - } - - fn create_gate(&self, meta: &mut ConstraintSystem) { - meta.create_gate("get is_input_note_flag", |meta| { - let q_get_is_input_note_flag = meta.query_selector(self.q_get_is_input_note_flag); - let owned_note_pub_id = meta.query_advice(self.owned_note_pub_id, Rotation::cur()); - let is_input_note_flag = meta.query_advice(self.owned_note_pub_id, Rotation::next()); - let input_note_nf_1 = meta.query_advice(self.input_note_nf, Rotation::cur()); - let input_note_nf_2 = meta.query_advice(self.input_note_nf, Rotation::next()); - let output_note_cm_1 = - meta.query_advice(self.output_note_cm, Rotation::cur()); - let output_note_cm_2 = - meta.query_advice(self.output_note_cm, Rotation::next()); - let one = Expression::Constant(pallas::Base::one()); - - Constraints::with_selector( - q_get_is_input_note_flag, - [ - ("bool_check is_input_note_flag", bool_check(is_input_note_flag.clone())), - ( - "if is_input_note_flag, then owned_note_pub_id == input_note_nf_1 or owned_note_pub_id == input_note_nf_2", - is_input_note_flag.clone() * (owned_note_pub_id.clone() - input_note_nf_1) * (owned_note_pub_id.clone() - input_note_nf_2), - ), - ( - "if not is_input_note_flag, then owned_note_pub_id == output_note_cm_1 or owned_note_pub_id == output_note_cm_2", - (is_input_note_flag - one) * (owned_note_pub_id.clone() - output_note_cm_1) * (owned_note_pub_id - output_note_cm_2), - ), - ], - ) - }); - } - - pub fn assign_region( - &self, - owned_note_pub_id: &AssignedCell, - input_note_nfs: &[AssignedCell; NUM_NOTE], - output_note_cms: &[AssignedCell; NUM_NOTE], - offset: usize, - region: &mut Region<'_, pallas::Base>, - ) -> Result, Error> { - // Enable `q_get_is_input_note_flag` selector - self.q_get_is_input_note_flag.enable(region, offset)?; - - // copy owned_note_pub_id, input_note_nfs and output_note_cms into the advice columns - owned_note_pub_id.copy_advice( - || "owned_note_pub_id", - region, - self.owned_note_pub_id, - offset, - )?; - input_note_nfs[0].copy_advice(|| "input_note_nf 1", region, self.input_note_nf, offset)?; - input_note_nfs[1].copy_advice( - || "input_note_nf 2", - region, - self.input_note_nf, - offset + 1, - )?; - output_note_cms[0].copy_advice( - || "output_note_cm 1", - region, - self.output_note_cm, - offset, - )?; - output_note_cms[1].copy_advice( - || "output_note_cm 2", - region, - self.output_note_cm, - offset + 1, - )?; - - // compute the is_input_note_flag - let is_input_note_flag = owned_note_pub_id - .value() - .zip(input_note_nfs[0].value()) - .zip(input_note_nfs[1].value()) - .map( - |((&owned_note_pub_id, &input_note_nf_1), &input_note_nf_2)| { - if owned_note_pub_id == input_note_nf_1 || owned_note_pub_id == input_note_nf_2 - { - pallas::Base::one() - } else { - pallas::Base::zero() - } - }, - ); - region.assign_advice( - || "is_input_note_flag", - self.owned_note_pub_id, - offset + 1, - || is_input_note_flag, - ) - } -} diff --git a/taiga_halo2/src/circuit/gadgets/target_resource_variable.rs b/taiga_halo2/src/circuit/gadgets/target_resource_variable.rs new file mode 100644 index 00000000..9aa68636 --- /dev/null +++ b/taiga_halo2/src/circuit/gadgets/target_resource_variable.rs @@ -0,0 +1,350 @@ +use crate::circuit::vp_circuit::ResourceSearchableVariablePair; +use crate::constant::NUM_RESOURCE; +use halo2_gadgets::utilities::bool_check; +use halo2_proofs::{ + arithmetic::Field, + circuit::{AssignedCell, Layouter, Region, Value}, + plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Expression, Selector}, + poly::Rotation, +}; +use pasta_curves::pallas; + +// Search and get owned resource variable +pub fn get_owned_resource_variable( + config: GetOwnedResourceVariableConfig, + mut layouter: impl Layouter, + // The owned_resource_id is the input_resource_nf or the output_resource_cm_x + owned_resource_id: &AssignedCell, + // NUM_RESOURCE pairs are from input resources, the other NUM_RESOURCE are from output resources + resource_variable_pairs: &[ResourceSearchableVariablePair; NUM_RESOURCE * 2], +) -> Result, Error> { + layouter.assign_region( + || "get owned_resource_variable", + |mut region| { + config.assign_region(owned_resource_id, resource_variable_pairs, 0, &mut region) + }, + ) +} + +// Search and get is_input_resource_flag variable +pub fn get_is_input_resource_flag( + config: GetIsInputResourceFlagConfig, + mut layouter: impl Layouter, + // The owned_resource_id is the input_resource_nf or the output_resource_cm_x + owned_resource_id: &AssignedCell, + input_resource_nfs: &[AssignedCell; NUM_RESOURCE], + output_resource_cms: &[AssignedCell; NUM_RESOURCE], +) -> Result, Error> { + layouter.assign_region( + || "get is_input_resource_flag", + |mut region| { + config.assign_region( + owned_resource_id, + input_resource_nfs, + output_resource_cms, + 0, + &mut region, + ) + }, + ) +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct GetOwnedResourceVariableConfig { + q_get_owned_resource_variable: Selector, + owned_resource_id: Column, + resource_variable_pairs: [Column; NUM_RESOURCE * 2], +} + +impl GetOwnedResourceVariableConfig { + #[allow(clippy::too_many_arguments)] + pub fn configure( + meta: &mut ConstraintSystem, + owned_resource_id: Column, + resource_variable_pairs: [Column; NUM_RESOURCE * 2], + ) -> Self { + let config = Self { + q_get_owned_resource_variable: meta.selector(), + owned_resource_id, + resource_variable_pairs, + }; + + config.create_gate(meta); + + config + } + + fn create_gate(&self, meta: &mut ConstraintSystem) { + meta.create_gate("get owned resource variable", |meta| { + let q_get_owned_resource_variable = + meta.query_selector(self.q_get_owned_resource_variable); + let owned_resource_id = meta.query_advice(self.owned_resource_id, Rotation::cur()); + let owned_resource_variable = + meta.query_advice(self.owned_resource_id, Rotation::next()); + let nf_or_cm_vec: Vec> = self + .resource_variable_pairs + .into_iter() + .map(|column| meta.query_advice(column, Rotation::cur())) + .collect(); + let target_variable_vec: Vec> = self + .resource_variable_pairs + .into_iter() + .map(|column| meta.query_advice(column, Rotation::next())) + .collect(); + let inv_vec: Vec> = self + .resource_variable_pairs + .into_iter() + .map(|column| meta.query_advice(column, Rotation::prev())) + .collect(); + let nf_or_cm_minus_owned_resource_id_vec: Vec> = + nf_or_cm_vec + .into_iter() + .map(|nf_or_cm| nf_or_cm - owned_resource_id.clone()) + .collect(); + let one = Expression::Constant(pallas::Base::one()); + let nf_or_cm_minus_owned_resource_id_is_zero_vec: Vec> = + nf_or_cm_minus_owned_resource_id_vec + .clone() + .into_iter() + .zip(inv_vec) + .map(|(nf_or_cm_minus_owned_resource_id, inv)| { + one.clone() - nf_or_cm_minus_owned_resource_id * inv + }) + .collect(); + let poly_vec: Vec> = nf_or_cm_minus_owned_resource_id_vec + .into_iter() + .zip(nf_or_cm_minus_owned_resource_id_is_zero_vec.clone()) + .map(|(nf_or_cm_minus_owned_resource_id, is_zero)| { + nf_or_cm_minus_owned_resource_id * is_zero + }) + .collect(); + + Constraints::with_selector( + q_get_owned_resource_variable, + [ + ( + "nf_or_cm_minus_owned_resource_id_is_zero check0", + poly_vec[0].clone(), + ), + ( + "nf_or_cm_minus_owned_resource_id_is_zero check1", + poly_vec[1].clone(), + ), + ( + "nf_or_cm_minus_owned_resource_id_is_zero check2", + poly_vec[2].clone(), + ), + ( + "nf_or_cm_minus_owned_resource_id_is_zero check3", + poly_vec[3].clone(), + ), + ( + "owned_resource_variable check0", + nf_or_cm_minus_owned_resource_id_is_zero_vec[0].clone() + * (owned_resource_variable.clone() - target_variable_vec[0].clone()), + ), + ( + "owned_resource_variable check1", + nf_or_cm_minus_owned_resource_id_is_zero_vec[1].clone() + * (owned_resource_variable.clone() - target_variable_vec[1].clone()), + ), + ( + "owned_resource_variable check2", + nf_or_cm_minus_owned_resource_id_is_zero_vec[2].clone() + * (owned_resource_variable.clone() - target_variable_vec[2].clone()), + ), + ( + "owned_resource_variable check3", + nf_or_cm_minus_owned_resource_id_is_zero_vec[3].clone() + * (owned_resource_variable - target_variable_vec[3].clone()), + ), + ( + "owned_resource_id exists in the resources", + nf_or_cm_minus_owned_resource_id_is_zero_vec[0].clone() + * nf_or_cm_minus_owned_resource_id_is_zero_vec[1].clone() + * nf_or_cm_minus_owned_resource_id_is_zero_vec[2].clone() + * nf_or_cm_minus_owned_resource_id_is_zero_vec[3].clone(), + ), + ], + ) + }); + } + + pub fn assign_region( + &self, + owned_resource_id: &AssignedCell, + resource_variable_pairs: &[ResourceSearchableVariablePair; NUM_RESOURCE * 2], + offset: usize, + region: &mut Region<'_, pallas::Base>, + ) -> Result, Error> { + // Enable `q_get_owned_resource_variable` selector + self.q_get_owned_resource_variable + .enable(region, offset + 1)?; + + // copy owned_resource_id, resource_variable_pairs into the advice columns + owned_resource_id.copy_advice( + || "owned_resource_id", + region, + self.owned_resource_id, + offset + 1, + )?; + + let mut ret = Value::known(pallas::Base::zero()); + for (pair, column) in resource_variable_pairs + .iter() + .zip(self.resource_variable_pairs) + { + pair.src_variable + .copy_advice(|| "nf or cm", region, column, offset + 1)?; + pair.target_variable + .copy_advice(|| "target_variable", region, column, offset + 2)?; + let inv = pair + .src_variable + .value() + .zip(owned_resource_id.value()) + .map(|(nf_or_cm, owned_resource_id)| { + let inv = (nf_or_cm - owned_resource_id) + .invert() + .unwrap_or(pallas::Base::zero()); + + // Find the target variable + if inv == pallas::Base::zero() { + ret = pair.target_variable.value().copied(); + } + inv + }); + region.assign_advice(|| "inv", column, offset, || inv)?; + } + region.assign_advice(|| "ret", self.owned_resource_id, offset + 2, || ret) + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct GetIsInputResourceFlagConfig { + q_get_is_input_resource_flag: Selector, + owned_resource_id: Column, + input_resource_nf: Column, + output_resource_cm: Column, +} + +impl GetIsInputResourceFlagConfig { + #[allow(clippy::too_many_arguments)] + pub fn configure( + meta: &mut ConstraintSystem, + owned_resource_id: Column, + input_resource_nf: Column, + output_resource_cm: Column, + ) -> Self { + meta.enable_equality(owned_resource_id); + meta.enable_equality(input_resource_nf); + meta.enable_equality(output_resource_cm); + + let config = Self { + q_get_is_input_resource_flag: meta.selector(), + owned_resource_id, + input_resource_nf, + output_resource_cm, + }; + + config.create_gate(meta); + + config + } + + fn create_gate(&self, meta: &mut ConstraintSystem) { + meta.create_gate("get is_input_resource_flag", |meta| { + let q_get_is_input_resource_flag = meta.query_selector(self.q_get_is_input_resource_flag); + let owned_resource_id = meta.query_advice(self.owned_resource_id, Rotation::cur()); + let is_input_resource_flag = meta.query_advice(self.owned_resource_id, Rotation::next()); + let input_resource_nf_1 = meta.query_advice(self.input_resource_nf, Rotation::cur()); + let input_resource_nf_2 = meta.query_advice(self.input_resource_nf, Rotation::next()); + let output_resource_cm_1 = + meta.query_advice(self.output_resource_cm, Rotation::cur()); + let output_resource_cm_2 = + meta.query_advice(self.output_resource_cm, Rotation::next()); + let one = Expression::Constant(pallas::Base::one()); + + Constraints::with_selector( + q_get_is_input_resource_flag, + [ + ("bool_check is_input_resource_flag", bool_check(is_input_resource_flag.clone())), + ( + "if is_input_resource_flag, then owned_resource_id == input_resource_nf_1 or owned_resource_id == input_resource_nf_2", + is_input_resource_flag.clone() * (owned_resource_id.clone() - input_resource_nf_1) * (owned_resource_id.clone() - input_resource_nf_2), + ), + ( + "if not is_input_resource_flag, then owned_resource_id == output_resource_cm_1 or owned_resource_id == output_resource_cm_2", + (is_input_resource_flag - one) * (owned_resource_id.clone() - output_resource_cm_1) * (owned_resource_id - output_resource_cm_2), + ), + ], + ) + }); + } + + pub fn assign_region( + &self, + owned_resource_id: &AssignedCell, + input_resource_nfs: &[AssignedCell; NUM_RESOURCE], + output_resource_cms: &[AssignedCell; NUM_RESOURCE], + offset: usize, + region: &mut Region<'_, pallas::Base>, + ) -> Result, Error> { + // Enable `q_get_is_input_resource_flag` selector + self.q_get_is_input_resource_flag.enable(region, offset)?; + + // copy owned_resource_id, input_resource_nfs and output_resource_cms into the advice columns + owned_resource_id.copy_advice( + || "owned_resource_id", + region, + self.owned_resource_id, + offset, + )?; + input_resource_nfs[0].copy_advice( + || "input_resource_nf 1", + region, + self.input_resource_nf, + offset, + )?; + input_resource_nfs[1].copy_advice( + || "input_resource_nf 2", + region, + self.input_resource_nf, + offset + 1, + )?; + output_resource_cms[0].copy_advice( + || "output_resource_cm 1", + region, + self.output_resource_cm, + offset, + )?; + output_resource_cms[1].copy_advice( + || "output_resource_cm 2", + region, + self.output_resource_cm, + offset + 1, + )?; + + // compute the is_input_resource_flag + let is_input_resource_flag = owned_resource_id + .value() + .zip(input_resource_nfs[0].value()) + .zip(input_resource_nfs[1].value()) + .map( + |((&owned_resource_id, &input_resource_nf_1), &input_resource_nf_2)| { + if owned_resource_id == input_resource_nf_1 + || owned_resource_id == input_resource_nf_2 + { + pallas::Base::one() + } else { + pallas::Base::zero() + } + }, + ); + region.assign_advice( + || "is_input_resource_flag", + self.owned_resource_id, + offset + 1, + || is_input_resource_flag, + ) + } +} diff --git a/taiga_halo2/src/circuit/integrity.rs b/taiga_halo2/src/circuit/integrity.rs index 7151705f..27ea9b5c 100644 --- a/taiga_halo2/src/circuit/integrity.rs +++ b/taiga_halo2/src/circuit/integrity.rs @@ -1,11 +1,11 @@ use crate::circuit::{ gadgets::{assign_free_advice, assign_free_constant, poseidon_hash::poseidon_hash_gadget}, hash_to_curve::{hash_to_curve_circuit, HashToCurveConfig}, - note_commitment::{note_commit, NoteCommitChip}, - vp_circuit::{InputNoteVariables, NoteVariables, OutputNoteVariables}, + resource_commitment::{resource_commit, ResourceCommitChip}, + vp_circuit::{InputResourceVariables, OutputResourceVariables, ResourceVariables}, }; use crate::constant::{TaigaFixedBases, TaigaFixedBasesFull, POSEIDON_TO_CURVE_INPUT_LEN}; -use crate::note::Note; +use crate::resource::Resource; use crate::utils::poseidon_to_curve; use halo2_gadgets::{ ecc::{chip::EccChip, FixedPoint, NonIdentityPoint, Point, ScalarFixed, ScalarVar}, @@ -26,11 +26,11 @@ pub fn nullifier_circuit( mut layouter: impl Layouter, poseidon_config: PoseidonConfig, nk: AssignedCell, - rho: AssignedCell, + nonce: AssignedCell, psi: AssignedCell, cm: AssignedCell, ) -> Result, Error> { - let poseidon_message = [nk, rho, psi, cm]; + let poseidon_message = [nk, nonce, psi, cm]; poseidon_hash_gadget( poseidon_config, layouter.namespace(|| "derive nullifier"), @@ -38,18 +38,18 @@ pub fn nullifier_circuit( ) } -// Check input note integrity and return the input note variables and the nullifier +// Check input resource integrity and return the input resource variables and the nullifier #[allow(clippy::too_many_arguments)] -pub fn check_input_note( +pub fn check_input_resource( mut layouter: impl Layouter, advices: [Column; 10], instances: Column, - note_commit_chip: NoteCommitChip, - input_note: Note, + resource_commit_chip: ResourceCommitChip, + input_resource: Resource, nf_row_idx: usize, -) -> Result { +) -> Result { // Witness nk - let nk = input_note.get_nk().unwrap(); + let nk = input_resource.get_nk().unwrap(); let nk_var = assign_free_advice( layouter.namespace(|| "witness nk"), advices[0], @@ -62,81 +62,81 @@ pub fn check_input_note( pallas::Base::zero(), )?; - // nk_com = Com_r(nk, zero) - let nk_com = poseidon_hash_gadget( - note_commit_chip.get_poseidon_config(), - layouter.namespace(|| "nk_com encoding"), + // npk = Com_r(nk, zero) + let npk = poseidon_hash_gadget( + resource_commit_chip.get_poseidon_config(), + layouter.namespace(|| "npk encoding"), [nk_var.clone(), zero_constant], )?; - // Witness app_data_dynamic - let app_data_dynamic = assign_free_advice( - layouter.namespace(|| "witness app_data_dynamic"), + // Witness value + let value = assign_free_advice( + layouter.namespace(|| "witness value"), advices[0], - Value::known(input_note.app_data_dynamic), + Value::known(input_resource.value), )?; - // Witness app_vk - let app_vk = assign_free_advice( - layouter.namespace(|| "witness app_vk"), + // Witness logic + let logic = assign_free_advice( + layouter.namespace(|| "witness logic"), advices[0], - Value::known(input_note.get_app_vk()), + Value::known(input_resource.get_logic()), )?; - // Witness app_data_static - let app_data_static = assign_free_advice( - layouter.namespace(|| "witness app_data_static"), + // Witness label + let label = assign_free_advice( + layouter.namespace(|| "witness label"), advices[0], - Value::known(input_note.get_app_data_static()), + Value::known(input_resource.get_label()), )?; - // Witness and range check the value(u64) - let value = value_range_check( - layouter.namespace(|| "value range check"), - note_commit_chip.get_lookup_config(), - input_note.value, + // Witness and range check the quantity(u64) + let quantity = quantity_range_check( + layouter.namespace(|| "quantity range check"), + resource_commit_chip.get_lookup_config(), + input_resource.quantity, )?; - // Witness rho - let rho = assign_free_advice( - layouter.namespace(|| "witness rho"), + // Witness nonce + let nonce = assign_free_advice( + layouter.namespace(|| "witness nonce"), advices[0], - Value::known(input_note.rho.inner()), + Value::known(input_resource.nonce.inner()), )?; // Witness psi let psi = assign_free_advice( layouter.namespace(|| "witness psi_input"), advices[0], - Value::known(input_note.get_psi()), + Value::known(input_resource.get_psi()), )?; // Witness rcm let rcm = assign_free_advice( layouter.namespace(|| "witness rcm"), advices[0], - Value::known(input_note.get_rcm()), + Value::known(input_resource.get_rcm()), )?; // Witness is_merkle_checked - // is_merkle_checked will be boolean-constrained in the note_commit. + // is_merkle_checked will be boolean-constrained in the resource_commit. let is_merkle_checked = assign_free_advice( layouter.namespace(|| "witness is_merkle_checked"), advices[0], - Value::known(pallas::Base::from(input_note.is_merkle_checked)), - )?; - - // Check note commitment - let cm = note_commit( - layouter.namespace(|| "note commitment"), - note_commit_chip.clone(), - app_vk.clone(), - app_data_static.clone(), - app_data_dynamic.clone(), - nk_com.clone(), - rho.clone(), - psi.clone(), + Value::known(pallas::Base::from(input_resource.is_merkle_checked)), + )?; + + // Check resource commitment + let cm = resource_commit( + layouter.namespace(|| "resource commitment"), + resource_commit_chip.clone(), + logic.clone(), + label.clone(), value.clone(), + npk.clone(), + nonce.clone(), + psi.clone(), + quantity.clone(), is_merkle_checked.clone(), rcm.clone(), )?; @@ -144,9 +144,9 @@ pub fn check_input_note( // Generate nullifier let nf = nullifier_circuit( layouter.namespace(|| "Generate nullifier"), - note_commit_chip.get_poseidon_config(), + resource_commit_chip.get_poseidon_config(), nk_var, - rho.clone(), + nonce.clone(), psi.clone(), cm.clone(), )?; @@ -154,103 +154,103 @@ pub fn check_input_note( // Public nullifier layouter.constrain_instance(nf.cell(), instances, nf_row_idx)?; - let note_variables = NoteVariables { - app_vk, - value, - app_data_static, + let resource_variables = ResourceVariables { + logic, + quantity, + label, is_merkle_checked, - app_data_dynamic, - rho, - nk_com, + value, + nonce, + npk, psi, rcm, }; - Ok(InputNoteVariables { - note_variables, + Ok(InputResourceVariables { + resource_variables, nf, cm, }) } #[allow(clippy::too_many_arguments)] -pub fn check_output_note( +pub fn check_output_resource( mut layouter: impl Layouter, advices: [Column; 10], instances: Column, - note_commit_chip: NoteCommitChip, - output_note: Note, + resource_commit_chip: ResourceCommitChip, + output_resource: Resource, old_nf: AssignedCell, cm_row_idx: usize, -) -> Result { - // Witness nk_com - let nk_com = assign_free_advice( - layouter.namespace(|| "witness nk_com"), +) -> Result { + // Witness npk + let npk = assign_free_advice( + layouter.namespace(|| "witness npk"), advices[0], - Value::known(output_note.get_nk_commitment()), + Value::known(output_resource.get_npk()), )?; - // Witness app_data_dynamic - let app_data_dynamic = assign_free_advice( - layouter.namespace(|| "witness app_data_dynamic"), + // Witness value + let value = assign_free_advice( + layouter.namespace(|| "witness value"), advices[0], - Value::known(output_note.app_data_dynamic), + Value::known(output_resource.value), )?; - // Witness app_vk - let app_vk = assign_free_advice( - layouter.namespace(|| "witness app_vk"), + // Witness logic + let logic = assign_free_advice( + layouter.namespace(|| "witness logic"), advices[0], - Value::known(output_note.get_app_vk()), + Value::known(output_resource.get_logic()), )?; - // Witness app_data_static - let app_data_static = assign_free_advice( - layouter.namespace(|| "witness app_data_static"), + // Witness label + let label = assign_free_advice( + layouter.namespace(|| "witness label"), advices[0], - Value::known(output_note.get_app_data_static()), + Value::known(output_resource.get_label()), )?; - // Witness and range check the value(u64) - let value = value_range_check( - layouter.namespace(|| "value range check"), - note_commit_chip.get_lookup_config(), - output_note.value, + // Witness and range check the quantity(u64) + let quantity = quantity_range_check( + layouter.namespace(|| "quantity range check"), + resource_commit_chip.get_lookup_config(), + output_resource.quantity, )?; // Witness rcm let rcm = assign_free_advice( layouter.namespace(|| "witness rcm"), advices[0], - Value::known(output_note.get_rcm()), + Value::known(output_resource.get_rcm()), )?; // Witness psi let psi = assign_free_advice( layouter.namespace(|| "witness psi_output"), advices[0], - Value::known(output_note.get_psi()), + Value::known(output_resource.get_psi()), )?; // Witness is_merkle_checked - // is_merkle_checked will be boolean-constrained in the note_commit. + // is_merkle_checked will be boolean-constrained in the resource_commit. let is_merkle_checked = assign_free_advice( layouter.namespace(|| "witness is_merkle_checked"), advices[0], - Value::known(pallas::Base::from(output_note.is_merkle_checked)), + Value::known(pallas::Base::from(output_resource.is_merkle_checked)), )?; - // Check note commitment - let cm = note_commit( - layouter.namespace(|| "note commitment"), - note_commit_chip, - app_vk.clone(), - app_data_static.clone(), - app_data_dynamic.clone(), - nk_com.clone(), + // Check resource commitment + let cm = resource_commit( + layouter.namespace(|| "resource commitment"), + resource_commit_chip, + logic.clone(), + label.clone(), + value.clone(), + npk.clone(), old_nf.clone(), psi.clone(), - value.clone(), + quantity.clone(), is_merkle_checked.clone(), rcm.clone(), )?; @@ -258,99 +258,99 @@ pub fn check_output_note( // Public cm layouter.constrain_instance(cm.cell(), instances, cm_row_idx)?; - let note_variables = NoteVariables { - app_vk, - app_data_static, - value, + let resource_variables = ResourceVariables { + logic, + label, + quantity, is_merkle_checked, - app_data_dynamic, - rho: old_nf, - nk_com, + value, + nonce: old_nf, + npk, psi, rcm, }; - Ok(OutputNoteVariables { note_variables, cm }) + Ok(OutputResourceVariables { + resource_variables, + cm, + }) } -pub fn derive_note_type( +pub fn derive_kind( mut layouter: impl Layouter, hash_to_curve_config: HashToCurveConfig, ecc_chip: EccChip, - app_vk: AssignedCell, - app_data_static: AssignedCell, + logic: AssignedCell, + label: AssignedCell, ) -> Result>, Error> { let point = hash_to_curve_circuit( layouter.namespace(|| "hash to curve"), hash_to_curve_config, ecc_chip.clone(), - &[app_vk.clone(), app_data_static.clone()], + &[logic.clone(), label.clone()], )?; // Assign a new `NonIdentityPoint` and constran equal to hash_to_curve point since `Point` doesn't have mul operation - // IndentityPoint is an invalid note type and it returns an error. - let non_identity_point = app_vk - .value() - .zip(app_data_static.value()) - .map(|(&vk, &data)| { - poseidon_to_curve::(&[vk, data]).to_affine() - }); + // IndentityPoint is an invalid resource kind and it returns an error. + let non_identity_point = logic.value().zip(label.value()).map(|(&vk, &data)| { + poseidon_to_curve::(&[vk, data]).to_affine() + }); let non_identity_point_var = NonIdentityPoint::new( ecc_chip, - layouter.namespace(|| "non-identity note type"), + layouter.namespace(|| "non-identity resource kind"), non_identity_point, )?; point.constrain_equal( - layouter.namespace(|| "non-identity note type"), + layouter.namespace(|| "non-identity resource kind"), &non_identity_point_var, )?; Ok(non_identity_point_var) } #[allow(clippy::too_many_arguments)] -pub fn compute_value_commitment( +pub fn compute_delta_commitment( mut layouter: impl Layouter, ecc_chip: EccChip, hash_to_curve_config: HashToCurveConfig, - app_address_input: AssignedCell, - data_input: AssignedCell, - v_input: AssignedCell, - app_address_output: AssignedCell, - data_output: AssignedCell, - v_output: AssignedCell, + input_logic: AssignedCell, + input_label: AssignedCell, + input_quantity: AssignedCell, + output_logic: AssignedCell, + output_label: AssignedCell, + output_quantity: AssignedCell, rcv: pallas::Scalar, ) -> Result>, Error> { - // input value point - let note_type_input = derive_note_type( - layouter.namespace(|| "derive input note type"), + // input value base point + let input_kind = derive_kind( + layouter.namespace(|| "derive input resource kind"), hash_to_curve_config.clone(), ecc_chip.clone(), - app_address_input, - data_input, + input_logic, + input_label, )?; let v_input_scalar = ScalarVar::from_base( ecc_chip.clone(), layouter.namespace(|| "ScalarVar from_base"), - &v_input, + &input_quantity, )?; let (value_point_input, _) = - note_type_input.mul(layouter.namespace(|| "input value point"), v_input_scalar)?; + input_kind.mul(layouter.namespace(|| "input value point"), v_input_scalar)?; - // output value point - let note_type_output = derive_note_type( - layouter.namespace(|| "derive output note type"), + // output value base point + let output_kind = derive_kind( + layouter.namespace(|| "derive output resource kind"), hash_to_curve_config, ecc_chip.clone(), - app_address_output, - data_output, + output_logic, + output_label, )?; let v_output_scalar = ScalarVar::from_base( ecc_chip.clone(), layouter.namespace(|| "ScalarVar from_base"), - &v_output, + &output_quantity, )?; let (value_point_output, _) = - note_type_output.mul(layouter.namespace(|| "output value point"), v_output_scalar)?; + output_kind.mul(layouter.namespace(|| "output value point"), v_output_scalar)?; // Get and constrain the negative output value point let neg_v_point_output = Point::new( @@ -385,23 +385,23 @@ pub fn compute_value_commitment( Value::known(rcv), )?; - let blind_base = FixedPoint::from_inner(ecc_chip, TaigaFixedBasesFull::NoteCommitmentR); + let blind_base = FixedPoint::from_inner(ecc_chip, TaigaFixedBasesFull::ResourceCommitmentR); let (blind, _) = blind_base.mul( layouter.namespace(|| "blind_scalar * blind_base"), &blind_scalar, )?; - commitment_v.add(layouter.namespace(|| "net value commitment"), &blind) + commitment_v.add(layouter.namespace(|| "delta commitment"), &blind) } -fn value_range_check( +fn quantity_range_check( mut layouter: impl Layouter, lookup_config: &LookupRangeCheckConfig, - value: u64, + quantity: u64, ) -> Result, Error> { let zs = lookup_config.witness_check( layouter.namespace(|| "6 * K(10) bits range check"), - Value::known(pallas::Base::from(value)), + Value::known(pallas::Base::from(quantity)), 6, false, )?; @@ -418,8 +418,8 @@ fn value_range_check( #[test] fn test_halo2_nullifier_circuit() { use crate::circuit::gadgets::assign_free_advice; - use crate::note::NoteCommitment; use crate::nullifier::{Nullifier, NullifierKeyContainer}; + use crate::resource::ResourceCommitment; use halo2_gadgets::poseidon::{ primitives as poseidon, Pow5Chip as PoseidonChip, Pow5Config as PoseidonConfig, }; @@ -434,9 +434,9 @@ fn test_halo2_nullifier_circuit() { #[derive(Default)] struct MyCircuit { nk: NullifierKeyContainer, - rho: pallas::Base, + nonce: pallas::Base, psi: pallas::Base, - cm: NoteCommitment, + cm: ResourceCommitment, } impl Circuit for MyCircuit { @@ -503,11 +503,11 @@ fn test_halo2_nullifier_circuit() { Value::known(self.nk.get_nk().unwrap()), )?; - // Witness rho - let rho = assign_free_advice( - layouter.namespace(|| "witness rho"), + // Witness nonce + let nonce = assign_free_advice( + layouter.namespace(|| "witness nonce"), advices[0], - Value::known(self.rho), + Value::known(self.nonce), )?; // Witness psi @@ -528,13 +528,13 @@ fn test_halo2_nullifier_circuit() { layouter.namespace(|| "nullifier"), poseidon_config, nk, - rho, + nonce, psi, cm, )?; let expect_nf = { - let nf = Nullifier::derive(&self.nk, &self.rho, &self.psi, &self.cm) + let nf = Nullifier::derive(&self.nk, &self.nonce, &self.psi, &self.cm) .unwrap() .inner(); assign_free_advice( @@ -554,9 +554,9 @@ fn test_halo2_nullifier_circuit() { let mut rng = OsRng; let circuit = MyCircuit { nk: NullifierKeyContainer::random_key(&mut rng), - rho: pallas::Base::random(&mut rng), + nonce: pallas::Base::random(&mut rng), psi: pallas::Base::random(&mut rng), - cm: NoteCommitment::default(), + cm: ResourceCommitment::default(), }; let prover = MockProver::run(11, &circuit, vec![]).unwrap(); diff --git a/taiga_halo2/src/circuit/merkle_circuit.rs b/taiga_halo2/src/circuit/merkle_circuit.rs index 037d45b0..8c4e7428 100644 --- a/taiga_halo2/src/circuit/merkle_circuit.rs +++ b/taiga_halo2/src/circuit/merkle_circuit.rs @@ -60,7 +60,7 @@ impl MerklePoseidonChip { pub fn merkle_poseidon_gadget( mut layouter: impl Layouter, chip: MerklePoseidonChip, - note_x: AssignedCell, + resource: AssignedCell, merkle_path: &[(pallas::Base, LR)], ) -> Result, Error> { fn swap( @@ -83,7 +83,7 @@ pub fn merkle_poseidon_gadget( chip.swap(layouter, pair, swap) } - let mut cur = note_x; + let mut cur = resource; for e in merkle_path.iter() { let pair = { let pair = (cur, Value::known(e.0)); diff --git a/taiga_halo2/src/circuit/mod.rs b/taiga_halo2/src/circuit/mod.rs index 59c5446d..8ebef428 100644 --- a/taiga_halo2/src/circuit/mod.rs +++ b/taiga_halo2/src/circuit/mod.rs @@ -2,14 +2,14 @@ pub mod action_circuit; pub mod gadgets; pub mod integrity; pub mod merkle_circuit; -// pub mod note_circuit; +// pub mod resource_circuit; #[macro_use] pub mod vp_circuit; pub mod blake2s; pub mod curve; pub mod hash_to_curve; -pub mod note_commitment; -pub mod note_encryption_circuit; +pub mod resource_commitment; +pub mod resource_encryption_circuit; mod vamp_ir_utils; pub mod vp_bytecode; pub mod vp_examples; diff --git a/taiga_halo2/src/circuit/note_commitment.rs b/taiga_halo2/src/circuit/resource_commitment.rs similarity index 64% rename from taiga_halo2/src/circuit/note_commitment.rs rename to taiga_halo2/src/circuit/resource_commitment.rs index cc92de4b..439a7251 100644 --- a/taiga_halo2/src/circuit/note_commitment.rs +++ b/taiga_halo2/src/circuit/resource_commitment.rs @@ -11,16 +11,16 @@ use halo2_proofs::{ }; use pasta_curves::pallas; -/// compose = is_merkle_checked(bool) * 2^128 + value(64 bits) +/// compose = is_merkle_checked(bool) * 2^128 + quantity(64 bits) #[derive(Clone, Debug)] -struct ComposeMerkleCheckValue { +struct ComposeMerkleCheckQuantity { q_compose: Selector, col_l: Column, col_m: Column, col_r: Column, } -impl ComposeMerkleCheckValue { +impl ComposeMerkleCheckQuantity { fn configure( meta: &mut ConstraintSystem, col_l: Column, @@ -30,16 +30,16 @@ impl ComposeMerkleCheckValue { ) -> Self { let q_compose = meta.selector(); - meta.create_gate("Compose is_merkle_checked and value", |meta| { + meta.create_gate("Compose is_merkle_checked and quantity", |meta| { let q_compose = meta.query_selector(q_compose); - let compose_is_merkle_checked_and_value = meta.query_advice(col_l, Rotation::cur()); + let compose_is_merkle_checked_and_quantity = meta.query_advice(col_l, Rotation::cur()); let is_merkle_checked = meta.query_advice(col_m, Rotation::cur()); - let value = meta.query_advice(col_r, Rotation::cur()); + let quantity = meta.query_advice(col_r, Rotation::cur()); - // e = value + (2^128) * is_merkle_checked - let composition_check = compose_is_merkle_checked_and_value - - (value + is_merkle_checked.clone() * two_pow_128); + // e = quantity + (2^128) * is_merkle_checked + let composition_check = compose_is_merkle_checked_and_quantity + - (quantity + is_merkle_checked.clone() * two_pow_128); Constraints::with_selector( q_compose, @@ -65,16 +65,16 @@ impl ComposeMerkleCheckValue { &self, layouter: &mut impl Layouter, is_merkle_checked: &AssignedCell, - value: &AssignedCell, + quantity: &AssignedCell, ) -> Result, Error> { layouter.assign_region( - || "NoteCommit MessagePiece e", + || "Compose is_merkle_checked and quantity", |mut region| { self.q_compose.enable(&mut region, 0)?; - let compose = is_merkle_checked.value().zip(value.value()).map( - |(is_merkle_checked, value)| { - value + is_merkle_checked * pallas::Base::from_u128(1 << 64).square() + let compose = is_merkle_checked.value().zip(quantity.value()).map( + |(is_merkle_checked, quantity)| { + quantity + is_merkle_checked * pallas::Base::from_u128(1 << 64).square() }, ); is_merkle_checked.copy_advice( @@ -83,7 +83,7 @@ impl ComposeMerkleCheckValue { self.col_m, 0, )?; - value.copy_advice(|| "value", &mut region, self.col_r, 0)?; + quantity.copy_advice(|| "quantity", &mut region, self.col_r, 0)?; region.assign_advice(|| "compose", self.col_l, 0, || compose) }, @@ -92,26 +92,26 @@ impl ComposeMerkleCheckValue { } #[derive(Clone, Debug)] -pub struct NoteCommitConfig { - compose_config: ComposeMerkleCheckValue, +pub struct ResourceCommitConfig { + compose_config: ComposeMerkleCheckQuantity, poseidon_config: PoseidonConfig, lookup_config: LookupRangeCheckConfig, } #[derive(Clone, Debug)] -pub struct NoteCommitChip { - config: NoteCommitConfig, +pub struct ResourceCommitChip { + config: ResourceCommitConfig, } -impl NoteCommitChip { +impl ResourceCommitChip { pub fn configure( meta: &mut ConstraintSystem, advices: [Column; 3], poseidon_config: PoseidonConfig, lookup_config: LookupRangeCheckConfig, - ) -> NoteCommitConfig { + ) -> ResourceCommitConfig { let two_pow_128 = pallas::Base::from_u128(1 << 64).square(); - let compose_config = ComposeMerkleCheckValue::configure( + let compose_config = ComposeMerkleCheckQuantity::configure( meta, advices[0], advices[1], @@ -119,15 +119,15 @@ impl NoteCommitChip { two_pow_128, ); - NoteCommitConfig { + ResourceCommitConfig { compose_config, poseidon_config, lookup_config, } } - pub fn construct(config: NoteCommitConfig) -> Self { - NoteCommitChip { config } + pub fn construct(config: ResourceCommitConfig) -> Self { + ResourceCommitChip { config } } pub fn get_poseidon_config(&self) -> PoseidonConfig { @@ -140,39 +140,39 @@ impl NoteCommitChip { } #[allow(clippy::too_many_arguments)] -pub fn note_commit( +pub fn resource_commit( mut layouter: impl Layouter, - chip: NoteCommitChip, + chip: ResourceCommitChip, app_vp: AssignedCell, - app_data_static: AssignedCell, - app_data_dynamic: AssignedCell, - nk_com: AssignedCell, - rho: AssignedCell, - psi: AssignedCell, + label: AssignedCell, value: AssignedCell, + npk: AssignedCell, + nonce: AssignedCell, + psi: AssignedCell, + quantity: AssignedCell, is_merkle_checked: AssignedCell, rcm: AssignedCell, ) -> Result, Error> { - // Compose the value and is_merkle_checked to one field in order to save one poseidon absorb - let compose_is_merkle_checked_and_value = + // Compose the quantity and is_merkle_checked to one field in order to save one poseidon absorb + let compose_is_merkle_checked_and_quantity = chip.config .compose_config - .assign(&mut layouter, &is_merkle_checked, &value)?; + .assign(&mut layouter, &is_merkle_checked, &quantity)?; - // note commitment + // resource commitment let poseidon_message = [ app_vp, - app_data_static, - app_data_dynamic, - nk_com, - rho, + label, + value, + npk, + nonce, psi, - compose_is_merkle_checked_and_value, + compose_is_merkle_checked_and_quantity, rcm, ]; poseidon_hash_gadget( chip.config.poseidon_config, - layouter.namespace(|| "note commitment"), + layouter.namespace(|| "resource commitment"), poseidon_message, ) } diff --git a/taiga_halo2/src/circuit/note_encryption_circuit.rs b/taiga_halo2/src/circuit/resource_encryption_circuit.rs similarity index 87% rename from taiga_halo2/src/circuit/note_encryption_circuit.rs rename to taiga_halo2/src/circuit/resource_encryption_circuit.rs index 797c833b..c7e06a65 100644 --- a/taiga_halo2/src/circuit/note_encryption_circuit.rs +++ b/taiga_halo2/src/circuit/resource_encryption_circuit.rs @@ -3,8 +3,8 @@ use crate::circuit::gadgets::{ assign_free_advice, assign_free_constant, }; use crate::constant::{ - BaseFieldGenerators, TaigaFixedBases, NOTE_ENCRYPTION_PLAINTEXT_NUM, POSEIDON_RATE, - POSEIDON_WIDTH, VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX, + BaseFieldGenerators, TaigaFixedBases, POSEIDON_RATE, POSEIDON_WIDTH, + RESOURCE_ENCRYPTION_PLAINTEXT_NUM, VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX, }; use ff::PrimeField; use halo2_gadgets::{ @@ -23,14 +23,14 @@ use halo2_proofs::{ use pasta_curves::pallas; #[allow(clippy::too_many_arguments)] -pub fn note_encryption_gadget( +pub fn resource_encryption_gadget( mut layouter: impl Layouter, advice: Column, instances: Column, poseidon_config: PoseidonConfig, add_chip: AddChip, ecc_chip: EccChip, - nonce: AssignedCell, + encrypt_nonce: AssignedCell, sender_sk: AssignedCell, rcv_pk: NonIdentityPoint>, message: &mut Vec>, @@ -42,7 +42,7 @@ pub fn note_encryption_gadget( Value::known(pallas::Base::zero()), )?; let paddings = - std::iter::repeat(padding_zero).take(NOTE_ENCRYPTION_PLAINTEXT_NUM - message.len()); + std::iter::repeat(padding_zero).take(RESOURCE_ENCRYPTION_PLAINTEXT_NUM - message.len()); message.extend(paddings); // Compute symmetric secret key @@ -55,16 +55,16 @@ pub fn note_encryption_gadget( let sender_pk = generator.mul(layouter.namespace(|| "sender_sk * generator"), sender_sk)?; let (secret_key, _) = rcv_pk.mul(layouter.namespace(|| "sender_sk * rcv_pk"), sk)?; - // length_nonce = length * 2^128 + nonce + // length_nonce = length * 2^128 + encrypt_nonce let length_var = assign_free_constant( layouter.namespace(|| "constant zero"), advice, pallas::Base::from(message.len() as u64) * pallas::Base::from_u128(1 << 64).square(), )?; let length_nonce = add_chip.add( - layouter.namespace(|| "length_nonce = length || nonce"), + layouter.namespace(|| "length_nonce = length || encrypt_nonce"), &length_var, - &nonce, + &encrypt_nonce, )?; // Init poseidon sponge state @@ -109,8 +109,8 @@ pub fn note_encryption_gadget( .for_each(|s| cipher.push(s.clone().into())); } - // Add nonce - cipher.push(nonce); + // Add encrypt_nonce + cipher.push(encrypt_nonce); // Compute MAC state = as PoseidonInstructions< @@ -130,7 +130,7 @@ pub fn note_encryption_gadget( layouter.constrain_instance( ele.cell(), instances, - VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX + i, + VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX + i, )?; } diff --git a/taiga_halo2/src/circuit/vp_bytecode.rs b/taiga_halo2/src/circuit/vp_bytecode.rs index 9753792b..b202d762 100644 --- a/taiga_halo2/src/circuit/vp_bytecode.rs +++ b/taiga_halo2/src/circuit/vp_bytecode.rs @@ -1,7 +1,7 @@ #[cfg(feature = "borsh")] use crate::circuit::vp_examples::TrivialValidityPredicateCircuit; use crate::error::TransactionError; -use crate::shielded_ptx::NoteVPVerifyingInfoSet; +use crate::shielded_ptx::ResourceVPVerifyingInfoSet; use crate::{ circuit::vp_circuit::{ VPVerifyingInfo, ValidityPredicateVerifyingInfo, VampIRValidityPredicateCircuit, @@ -9,10 +9,10 @@ use crate::{ constant::{ VP_CIRCUIT_NULLIFIER_ONE_PUBLIC_INPUT_IDX, VP_CIRCUIT_NULLIFIER_TWO_PUBLIC_INPUT_IDX, VP_CIRCUIT_OUTPUT_CM_ONE_PUBLIC_INPUT_IDX, VP_CIRCUIT_OUTPUT_CM_TWO_PUBLIC_INPUT_IDX, - VP_CIRCUIT_OWNED_NOTE_PUB_ID_PUBLIC_INPUT_IDX, + VP_CIRCUIT_OWNED_RESOURCE_ID_PUBLIC_INPUT_IDX, }, - note::NoteCommitment, nullifier::Nullifier, + resource::ResourceCommitment, }; #[cfg(feature = "borsh")] @@ -79,11 +79,11 @@ impl ValidityPredicateByteCode { } } - // Verify vp circuit transparently and return owned note PubID for further checking + // Verify vp circuit transparently and return owned resource PubID for further checking pub fn verify_transparently( &self, action_nfs: &[Nullifier], - action_cms: &[NoteCommitment], + action_cms: &[ResourceCommitment], ) -> Result { // check VP transparently let public_inputs = match &self.circuit { @@ -109,7 +109,7 @@ impl ValidityPredicateByteCode { }; // check nullifiers - // Check the vp actually uses the input notes from action circuits. + // Check the vp actually uses the input resources from action circuits. let vp_nfs = [ public_inputs.get_from_index(VP_CIRCUIT_NULLIFIER_ONE_PUBLIC_INPUT_IDX), public_inputs.get_from_index(VP_CIRCUIT_NULLIFIER_TWO_PUBLIC_INPUT_IDX), @@ -121,8 +121,8 @@ impl ValidityPredicateByteCode { return Err(TransactionError::InconsistentNullifier); } - // check note_commitments - // Check the vp actually uses the output notes from action circuits. + // check resource_commitments + // Check the vp actually uses the output resources from action circuits. let vp_cms = [ public_inputs.get_from_index(VP_CIRCUIT_OUTPUT_CM_ONE_PUBLIC_INPUT_IDX), public_inputs.get_from_index(VP_CIRCUIT_OUTPUT_CM_TWO_PUBLIC_INPUT_IDX), @@ -130,10 +130,10 @@ impl ValidityPredicateByteCode { if !((action_cms[0].inner() == vp_cms[0] && action_cms[1].inner() == vp_cms[1]) || (action_cms[0].inner() == vp_cms[1] && action_cms[1].inner() == vp_cms[0])) { - return Err(TransactionError::InconsistentOutputNoteCommitment); + return Err(TransactionError::InconsistentOutputResourceCommitment); } - Ok(public_inputs.get_from_index(VP_CIRCUIT_OWNED_NOTE_PUB_ID_PUBLIC_INPUT_IDX)) + Ok(public_inputs.get_from_index(VP_CIRCUIT_OWNED_RESOURCE_ID_PUBLIC_INPUT_IDX)) } } @@ -148,7 +148,7 @@ impl ApplicationByteCode { } } - pub fn generate_proofs(self) -> Result { + pub fn generate_proofs(self) -> Result { let app_vp_verifying_info = self.app_vp_bytecode.generate_proof()?; let app_dynamic_vp_verifying_info: Result, _> = self @@ -156,28 +156,28 @@ impl ApplicationByteCode { .into_iter() .map(|bytecode| bytecode.generate_proof()) .collect(); - Ok(NoteVPVerifyingInfoSet::new( + Ok(ResourceVPVerifyingInfoSet::new( app_vp_verifying_info, app_dynamic_vp_verifying_info?, )) } - // Verify vp circuits transparently and return owned note PubID for further checking + // Verify vp circuits transparently and return owned resource PubID for further checking pub fn verify_transparently( &self, action_nfs: &[Nullifier], - action_cms: &[NoteCommitment], + action_cms: &[ResourceCommitment], ) -> Result { - let owned_note_id = self + let owned_resource_id = self .app_vp_bytecode .verify_transparently(action_nfs, action_cms)?; for dynamic_vp in self.dynamic_vp_bytecode.iter() { let id = dynamic_vp.verify_transparently(action_nfs, action_cms)?; - // check: the app_vp and dynamic_vps belong to the note - if id != owned_note_id { - return Err(TransactionError::InconsistentOwnedNotePubID); + // check: the app_vp and dynamic_vps belong to the resource + if id != owned_resource_id { + return Err(TransactionError::InconsistentOwneResourceID); } } - Ok(owned_note_id) + Ok(owned_resource_id) } } diff --git a/taiga_halo2/src/circuit/vp_circuit.rs b/taiga_halo2/src/circuit/vp_circuit.rs index 932f162a..566e2019 100644 --- a/taiga_halo2/src/circuit/vp_circuit.rs +++ b/taiga_halo2/src/circuit/vp_circuit.rs @@ -10,25 +10,27 @@ use crate::{ extended_or_relation::ExtendedOrRelationConfig, mul::{MulChip, MulConfig}, sub::{SubChip, SubConfig}, - target_note_variable::{GetIsInputNoteFlagConfig, GetOwnedNoteVariableConfig}, + target_resource_variable::{ + GetIsInputResourceFlagConfig, GetOwnedResourceVariableConfig, + }, }, - integrity::{check_input_note, check_output_note}, - note_commitment::{NoteCommitChip, NoteCommitConfig}, + integrity::{check_input_resource, check_output_resource}, + resource_commitment::{ResourceCommitChip, ResourceCommitConfig}, vamp_ir_utils::{get_circuit_assignments, parse, VariableAssignmentError}, }, constant::{ - TaigaFixedBases, NOTE_ENCRYPTION_CIPHERTEXT_NUM, NUM_NOTE, SETUP_PARAMS_MAP, - VP_CIRCUIT_NOTE_ENCRYPTION_PK_X_IDX, VP_CIRCUIT_NOTE_ENCRYPTION_PK_Y_IDX, - VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX, + TaigaFixedBases, NUM_RESOURCE, RESOURCE_ENCRYPTION_CIPHERTEXT_NUM, SETUP_PARAMS_MAP, VP_CIRCUIT_NULLIFIER_ONE_PUBLIC_INPUT_IDX, VP_CIRCUIT_NULLIFIER_TWO_PUBLIC_INPUT_IDX, VP_CIRCUIT_OUTPUT_CM_ONE_PUBLIC_INPUT_IDX, VP_CIRCUIT_OUTPUT_CM_TWO_PUBLIC_INPUT_IDX, - VP_CIRCUIT_OWNED_NOTE_PUB_ID_PUBLIC_INPUT_IDX, VP_CIRCUIT_PARAMS_SIZE, - VP_CIRCUIT_PUBLIC_INPUT_NUM, + VP_CIRCUIT_OWNED_RESOURCE_ID_PUBLIC_INPUT_IDX, VP_CIRCUIT_PARAMS_SIZE, + VP_CIRCUIT_PUBLIC_INPUT_NUM, VP_CIRCUIT_RESOURCE_ENCRYPTION_PK_X_IDX, + VP_CIRCUIT_RESOURCE_ENCRYPTION_PK_Y_IDX, + VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX, }, error::TransactionError, - note::{Note, NoteCommitment, RandomSeed}, - note_encryption::{NoteCiphertext, SecretKey}, proof::Proof, + resource::{RandomSeed, Resource, ResourceCommitment}, + resource_encryption::{ResourceCiphertext, SecretKey}, utils::mod_r_p, vp_vk::ValidityPredicateVerifyingKey, }; @@ -157,7 +159,7 @@ impl VPVerifyingInfo { .verify(&self.vk, params, &[self.public_inputs.inner()]) } - pub fn get_nullifiers(&self) -> [pallas::Base; NUM_NOTE] { + pub fn get_nullifiers(&self) -> [pallas::Base; NUM_RESOURCE] { [ self.public_inputs .get_from_index(VP_CIRCUIT_NULLIFIER_ONE_PUBLIC_INPUT_IDX), @@ -166,7 +168,7 @@ impl VPVerifyingInfo { ] } - pub fn get_note_commitments(&self) -> [NoteCommitment; NUM_NOTE] { + pub fn get_resource_commitments(&self) -> [ResourceCommitment; NUM_RESOURCE] { [ self.public_inputs .get_from_index(VP_CIRCUIT_OUTPUT_CM_ONE_PUBLIC_INPUT_IDX) @@ -177,9 +179,9 @@ impl VPVerifyingInfo { ] } - pub fn get_owned_note_pub_id(&self) -> pallas::Base { + pub fn get_owned_resource_id(&self) -> pallas::Base { self.public_inputs - .get_from_index(VP_CIRCUIT_OWNED_NOTE_PUB_ID_PUBLIC_INPUT_IDX) + .get_from_index(VP_CIRCUIT_OWNED_RESOURCE_ID_PUBLIC_INPUT_IDX) } } @@ -270,13 +272,13 @@ impl ValidityPredicatePublicInputs { rseed.get_random_padding(VP_CIRCUIT_PUBLIC_INPUT_NUM - input_len) } - // Only pad the custom public inputs, then we can add the actual note encryption public inputs. + // Only pad the custom public inputs, then we can add the actual resource encryption public inputs. pub fn get_custom_public_input_padding( input_len: usize, rseed: &RandomSeed, ) -> Vec { - assert!(input_len < VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX); - rseed.get_random_padding(VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX - input_len) + assert!(input_len < VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX); + rseed.get_random_padding(VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX - input_len) } pub fn to_vec(&self) -> Vec { @@ -284,13 +286,15 @@ impl ValidityPredicatePublicInputs { } pub fn decrypt(&self, sk: pallas::Base) -> Option> { - let cipher: NoteCiphertext = self.0[VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX - ..VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX + NOTE_ENCRYPTION_CIPHERTEXT_NUM] + let cipher: ResourceCiphertext = self.0 + [VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX + ..VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX + + RESOURCE_ENCRYPTION_CIPHERTEXT_NUM] .to_vec() .into(); let sender_pk = pallas::Affine::from_xy( - self.get_from_index(VP_CIRCUIT_NOTE_ENCRYPTION_PK_X_IDX), - self.get_from_index(VP_CIRCUIT_NOTE_ENCRYPTION_PK_Y_IDX), + self.get_from_index(VP_CIRCUIT_RESOURCE_ENCRYPTION_PK_X_IDX), + self.get_from_index(VP_CIRCUIT_RESOURCE_ENCRYPTION_PK_Y_IDX), ) .unwrap() .to_curve(); @@ -316,8 +320,8 @@ pub struct ValidityPredicateConfig { pub table_idx: TableColumn, pub ecc_config: EccConfig, pub poseidon_config: PoseidonConfig, - pub get_is_input_note_flag_config: GetIsInputNoteFlagConfig, - pub get_owned_note_variable_config: GetOwnedNoteVariableConfig, + pub get_is_input_resource_flag_config: GetIsInputResourceFlagConfig, + pub get_owned_resource_variable_config: GetOwnedResourceVariableConfig, pub conditional_equal_config: ConditionalEqualConfig, pub conditional_select_config: ConditionalSelectConfig, pub extended_or_relation_config: ExtendedOrRelationConfig, @@ -325,7 +329,7 @@ pub struct ValidityPredicateConfig { pub sub_config: SubConfig, pub mul_config: MulConfig, pub blake2s_config: Blake2sConfig, - pub note_commit_config: NoteCommitConfig, + pub resource_commit_config: ResourceCommitConfig, } impl ValidityPredicateConfig { @@ -377,14 +381,14 @@ impl ValidityPredicateConfig { lagrange_coeffs[5..8].try_into().unwrap(), ); - let get_owned_note_variable_config = GetOwnedNoteVariableConfig::configure( + let get_owned_resource_variable_config = GetOwnedResourceVariableConfig::configure( meta, advices[0], [advices[1], advices[2], advices[3], advices[4]], ); - let get_is_input_note_flag_config = - GetIsInputNoteFlagConfig::configure(meta, advices[0], advices[1], advices[2]); + let get_is_input_resource_flag_config = + GetIsInputResourceFlagConfig::configure(meta, advices[0], advices[1], advices[2]); let conditional_equal_config = ConditionalEqualConfig::configure(meta, [advices[0], advices[1], advices[2]]); @@ -398,7 +402,7 @@ impl ValidityPredicateConfig { let extended_or_relation_config = ExtendedOrRelationConfig::configure(meta, [advices[0], advices[1], advices[2]]); let blake2s_config = Blake2sConfig::configure(meta, advices); - let note_commit_config = NoteCommitChip::configure( + let resource_commit_config = ResourceCommitChip::configure( meta, advices[0..3].try_into().unwrap(), poseidon_config.clone(), @@ -410,8 +414,8 @@ impl ValidityPredicateConfig { table_idx, ecc_config, poseidon_config, - get_is_input_note_flag_config, - get_owned_note_variable_config, + get_is_input_resource_flag_config, + get_owned_resource_variable_config, conditional_equal_config, conditional_select_config, extended_or_relation_config, @@ -419,7 +423,7 @@ impl ValidityPredicateConfig { sub_config, mul_config, blake2s_config, - note_commit_config, + resource_commit_config, } } } @@ -433,7 +437,7 @@ pub trait ValidityPredicateVerifyingInfo: DynClone { clone_trait_object!(ValidityPredicateVerifyingInfo); pub trait ValidityPredicateCircuit: Circuit + ValidityPredicateVerifyingInfo { - // Default implementation, constrains the notes integrity. + // Default implementation, constrains the resources integrity. // TODO: how to enforce the constraints in vp circuit? fn basic_constraints( &self, @@ -455,63 +459,64 @@ pub trait ValidityPredicateCircuit: Circuit + ValidityPredicateVer }, )?; - // Construct a note_commit chip - let note_commit_chip = NoteCommitChip::construct(config.note_commit_config.clone()); - - let input_notes = self.get_input_notes(); - let output_notes = self.get_output_notes(); - let mut input_note_variables = vec![]; - let mut output_note_variables = vec![]; - for i in 0..NUM_NOTE { - input_note_variables.push(check_input_note( - layouter.namespace(|| "check input note"), + // Construct a resource_commit chip + let resource_commit_chip = + ResourceCommitChip::construct(config.resource_commit_config.clone()); + + let input_resources = self.get_input_resources(); + let output_resources = self.get_output_resources(); + let mut input_resource_variables = vec![]; + let mut output_resource_variables = vec![]; + for i in 0..NUM_RESOURCE { + input_resource_variables.push(check_input_resource( + layouter.namespace(|| "check input resource"), config.advices, config.instances, - note_commit_chip.clone(), - input_notes[i], + resource_commit_chip.clone(), + input_resources[i], i * 2, )?); - // The old_nf may not be from above input note + // The old_nf may not be from above input resource let old_nf = assign_free_advice( layouter.namespace(|| "old nf"), config.advices[0], - Value::known(output_notes[i].rho.inner()), + Value::known(output_resources[i].nonce.inner()), )?; - output_note_variables.push(check_output_note( - layouter.namespace(|| "check output note"), + output_resource_variables.push(check_output_resource( + layouter.namespace(|| "check output resource"), config.advices, config.instances, - note_commit_chip.clone(), - output_notes[i], + resource_commit_chip.clone(), + output_resources[i], old_nf, i * 2 + 1, )?); } - // Publicize the owned_note_pub_id - let owned_note_pub_id = assign_free_advice( - layouter.namespace(|| "owned_note_pub_id"), + // Publicize the owned_resource_id + let owned_resource_id = assign_free_advice( + layouter.namespace(|| "owned_resource_id"), config.advices[0], - Value::known(self.get_owned_note_pub_id()), + Value::known(self.get_owned_resource_id()), )?; layouter.constrain_instance( - owned_note_pub_id.cell(), + owned_resource_id.cell(), config.instances, - VP_CIRCUIT_OWNED_NOTE_PUB_ID_PUBLIC_INPUT_IDX, + VP_CIRCUIT_OWNED_RESOURCE_ID_PUBLIC_INPUT_IDX, )?; Ok(BasicValidityPredicateVariables { - owned_note_pub_id, - input_note_variables: input_note_variables.try_into().unwrap(), - output_note_variables: output_note_variables.try_into().unwrap(), + owned_resource_id, + input_resource_variables: input_resource_variables.try_into().unwrap(), + output_resource_variables: output_resource_variables.try_into().unwrap(), }) } // VP designer need to implement the following functions. - // `get_input_notes` and `get_output_notes` will be used in `basic_constraints` to get the basic note info. + // `get_input_resources` and `get_output_resources` will be used in `basic_constraints` to get the basic resource info. - // Add custom constraints on basic note variables and user-defined variables. + // Add custom constraints on basic resource variables and user-defined variables. // It should at least contain the default vp commitment fn custom_constraints( &self, @@ -531,89 +536,93 @@ pub trait ValidityPredicateCircuit: Circuit + ValidityPredicateVer fn get_mandatory_public_inputs(&self) -> Vec { let mut public_inputs = vec![]; - self.get_input_notes() + self.get_input_resources() .iter() - .zip(self.get_output_notes().iter()) - .for_each(|(input_note, output_note)| { - let nf = input_note.get_nf().unwrap().inner(); + .zip(self.get_output_resources().iter()) + .for_each(|(input_resource, output_resource)| { + let nf = input_resource.get_nf().unwrap().inner(); public_inputs.push(nf); - let cm = output_note.commitment(); + let cm = output_resource.commitment(); public_inputs.push(cm.inner()); }); - public_inputs.push(self.get_owned_note_pub_id()); + public_inputs.push(self.get_owned_resource_id()); public_inputs } - fn get_input_notes(&self) -> &[Note; NUM_NOTE]; - fn get_output_notes(&self) -> &[Note; NUM_NOTE]; + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE]; + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE]; fn get_public_inputs(&self, rng: impl RngCore) -> ValidityPredicatePublicInputs; - // The owned_note_pub_id is the input_note_nf or the output_note_cm_x - // The owned_note_pub_id is the key to look up the target variables and - // help determine whether the owned note is the input note or not in VP circuit. - fn get_owned_note_pub_id(&self) -> pallas::Base; + // The owned_resource_id is the input_resource_nf or the output_resource_cm_x + // The owned_resource_id is the key to look up the target variables and + // help determine whether the owned resource is the input resource or not in VP circuit. + fn get_owned_resource_id(&self) -> pallas::Base; } /// BasicValidityPredicateVariables are generally constrained in ValidityPredicateCircuit::basic_constraints /// and will be used in ValidityPredicateCircuit::custom_constraints #[derive(Debug, Clone)] pub struct BasicValidityPredicateVariables { - pub owned_note_pub_id: AssignedCell, - pub input_note_variables: [InputNoteVariables; NUM_NOTE], - pub output_note_variables: [OutputNoteVariables; NUM_NOTE], + pub owned_resource_id: AssignedCell, + pub input_resource_variables: [InputResourceVariables; NUM_RESOURCE], + pub output_resource_variables: [OutputResourceVariables; NUM_RESOURCE], } #[derive(Debug, Clone)] -pub struct NoteVariables { - pub app_vk: AssignedCell, - pub app_data_static: AssignedCell, - pub value: AssignedCell, +pub struct ResourceVariables { + pub logic: AssignedCell, + pub label: AssignedCell, + pub quantity: AssignedCell, pub is_merkle_checked: AssignedCell, - pub app_data_dynamic: AssignedCell, - pub rho: AssignedCell, - pub nk_com: AssignedCell, + pub value: AssignedCell, + pub nonce: AssignedCell, + pub npk: AssignedCell, pub psi: AssignedCell, pub rcm: AssignedCell, } -// Variables in the input note +// Variables in the input resource #[derive(Debug, Clone)] -pub struct InputNoteVariables { +pub struct InputResourceVariables { pub nf: AssignedCell, pub cm: AssignedCell, - pub note_variables: NoteVariables, + pub resource_variables: ResourceVariables, } -// Variables in the out note +// Variables in the out resource #[derive(Debug, Clone)] -pub struct OutputNoteVariables { +pub struct OutputResourceVariables { pub cm: AssignedCell, - pub note_variables: NoteVariables, + pub resource_variables: ResourceVariables, } #[derive(Debug, Clone)] -pub struct NoteSearchableVariablePair { - // src_variable is the input_note_nf or the output_note_cm_x +pub struct ResourceSearchableVariablePair { + // src_variable is the input_resource_nf or the output_resource_cm_x pub src_variable: AssignedCell, - // target_variable is one of the parameter in the NoteVariables + // target_variable is one of the parameter in the ResourceVariables pub target_variable: AssignedCell, } impl BasicValidityPredicateVariables { - pub fn get_owned_note_pub_id(&self) -> AssignedCell { - self.owned_note_pub_id.clone() + pub fn get_owned_resource_id(&self) -> AssignedCell { + self.owned_resource_id.clone() } - pub fn get_input_note_nfs(&self) -> [AssignedCell; NUM_NOTE] { + pub fn get_input_resource_nfs( + &self, + ) -> [AssignedCell; NUM_RESOURCE] { let ret: Vec<_> = self - .input_note_variables + .input_resource_variables .iter() .map(|variables| variables.nf.clone()) .collect(); ret.try_into().unwrap() } - pub fn get_output_note_cms(&self) -> [AssignedCell; NUM_NOTE] { + pub fn get_output_resource_cms( + &self, + ) -> [AssignedCell; NUM_RESOURCE] { let ret: Vec<_> = self - .output_note_variables + .output_resource_variables .iter() .map(|variables| variables.cm.clone()) .collect(); @@ -622,96 +631,94 @@ impl BasicValidityPredicateVariables { fn get_variable_searchable_pairs( &self, - input_target_variable: impl Fn(&InputNoteVariables) -> AssignedCell, + input_target_variable: impl Fn( + &InputResourceVariables, + ) -> AssignedCell, output_target_variable: impl Fn( - &OutputNoteVariables, + &OutputResourceVariables, ) -> AssignedCell, - ) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { - self.input_note_variables + ) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { + self.input_resource_variables .iter() - .map(|variables| NoteSearchableVariablePair { + .map(|variables| ResourceSearchableVariablePair { src_variable: variables.nf.clone(), target_variable: input_target_variable(variables), }) - .chain( - self.output_note_variables - .iter() - .map(|variables| NoteSearchableVariablePair { - src_variable: variables.cm.clone(), - target_variable: output_target_variable(variables), - }), - ) + .chain(self.output_resource_variables.iter().map(|variables| { + ResourceSearchableVariablePair { + src_variable: variables.cm.clone(), + target_variable: output_target_variable(variables), + } + })) .collect::>() .try_into() .unwrap() } - pub fn get_app_vk_searchable_pairs(&self) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { + pub fn get_logic_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.note_variables.app_vk.clone(), - |variables| variables.note_variables.app_vk.clone(), + |variables| variables.resource_variables.logic.clone(), + |variables| variables.resource_variables.logic.clone(), ) } - pub fn get_app_data_static_searchable_pairs( - &self, - ) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { + pub fn get_label_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.note_variables.app_data_static.clone(), - |variables| variables.note_variables.app_data_static.clone(), + |variables| variables.resource_variables.label.clone(), + |variables| variables.resource_variables.label.clone(), ) } - pub fn get_value_searchable_pairs(&self) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { + pub fn get_quantity_searchable_pairs( + &self, + ) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.note_variables.value.clone(), - |variables| variables.note_variables.value.clone(), + |variables| variables.resource_variables.quantity.clone(), + |variables| variables.resource_variables.quantity.clone(), ) } pub fn get_is_merkle_checked_searchable_pairs( &self, - ) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { + ) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.note_variables.is_merkle_checked.clone(), - |variables| variables.note_variables.is_merkle_checked.clone(), + |variables| variables.resource_variables.is_merkle_checked.clone(), + |variables| variables.resource_variables.is_merkle_checked.clone(), ) } - pub fn get_app_data_dynamic_searchable_pairs( - &self, - ) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { + pub fn get_value_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.note_variables.app_data_dynamic.clone(), - |variables| variables.note_variables.app_data_dynamic.clone(), + |variables| variables.resource_variables.value.clone(), + |variables| variables.resource_variables.value.clone(), ) } - pub fn get_rho_searchable_pairs(&self) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { + pub fn get_nonce_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.note_variables.rho.clone(), - |variables| variables.note_variables.rho.clone(), + |variables| variables.resource_variables.nonce.clone(), + |variables| variables.resource_variables.nonce.clone(), ) } - pub fn get_nk_com_searchable_pairs(&self) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { + pub fn get_npk_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.note_variables.nk_com.clone(), - |variables| variables.note_variables.nk_com.clone(), + |variables| variables.resource_variables.npk.clone(), + |variables| variables.resource_variables.npk.clone(), ) } - pub fn get_psi_searchable_pairs(&self) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { + pub fn get_psi_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.note_variables.psi.clone(), - |variables| variables.note_variables.psi.clone(), + |variables| variables.resource_variables.psi.clone(), + |variables| variables.resource_variables.psi.clone(), ) } - pub fn get_rcm_searchable_pairs(&self) -> [NoteSearchableVariablePair; NUM_NOTE * 2] { + pub fn get_rcm_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.note_variables.rcm.clone(), - |variables| variables.note_variables.rcm.clone(), + |variables| variables.resource_variables.rcm.clone(), + |variables| variables.resource_variables.rcm.clone(), ) } } diff --git a/taiga_halo2/src/circuit/vp_examples.rs b/taiga_halo2/src/circuit/vp_examples.rs index 2ed238e6..48bda659 100644 --- a/taiga_halo2/src/circuit/vp_examples.rs +++ b/taiga_halo2/src/circuit/vp_examples.rs @@ -5,10 +5,10 @@ use crate::{ VPVerifyingInfo, ValidityPredicateCircuit, ValidityPredicateConfig, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo, }, - constant::{NUM_NOTE, SETUP_PARAMS_MAP, VP_CIRCUIT_PARAMS_SIZE}, + constant::{NUM_RESOURCE, SETUP_PARAMS_MAP, VP_CIRCUIT_PARAMS_SIZE}, error::TransactionError, - note::{Note, RandomSeed}, proof::Proof, + resource::{RandomSeed, Resource}, vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, }; @@ -59,9 +59,9 @@ lazy_static! { // TrivialValidityPredicateCircuit with empty custom constraints. #[derive(Clone, Debug, Default)] pub struct TrivialValidityPredicateCircuit { - pub owned_note_pub_id: pallas::Base, - pub input_notes: [Note; NUM_NOTE], - pub output_notes: [Note; NUM_NOTE], + pub owned_resource_id: pallas::Base, + pub input_resources: [Resource; NUM_RESOURCE], + pub output_resources: [Resource; NUM_RESOURCE], } // I only exist to allow trivial derivation of the nifstruct @@ -69,21 +69,21 @@ pub struct TrivialValidityPredicateCircuit { #[cfg_attr(feature = "nif", derive(NifStruct))] #[cfg_attr(feature = "nif", module = "Taiga.VP.Trivial")] struct TrivialValidtyPredicateCircuitProxy { - owned_note_pub_id: pallas::Base, - input_notes: Vec, - output_notes: Vec, + owned_resource_id: pallas::Base, + input_resources: Vec, + output_resources: Vec, } impl TrivialValidityPredicateCircuit { pub fn new( - owned_note_pub_id: pallas::Base, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + owned_resource_id: pallas::Base, + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], ) -> Self { Self { - owned_note_pub_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, } } @@ -107,9 +107,9 @@ impl TrivialValidityPredicateCircuit { fn to_proxy(&self) -> TrivialValidtyPredicateCircuitProxy { TrivialValidtyPredicateCircuitProxy { - owned_note_pub_id: self.owned_note_pub_id, - input_notes: self.input_notes.to_vec(), - output_notes: self.output_notes.to_vec(), + owned_resource_id: self.owned_resource_id, + input_resources: self.input_resources.to_vec(), + output_resources: self.output_resources.to_vec(), } } } @@ -118,12 +118,12 @@ impl TrivialValidityPredicateCircuit { impl BorshSerialize for TrivialValidityPredicateCircuit { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { use ff::PrimeField; - writer.write_all(&self.owned_note_pub_id.to_repr())?; - for input in self.input_notes.iter() { + writer.write_all(&self.owned_resource_id.to_repr())?; + for input in self.input_resources.iter() { input.serialize(writer)?; } - for output in self.output_notes.iter() { + for output in self.output_resources.iter() { output.serialize(writer)?; } Ok(()) @@ -134,37 +134,37 @@ impl BorshSerialize for TrivialValidityPredicateCircuit { impl BorshDeserialize for TrivialValidityPredicateCircuit { fn deserialize_reader(reader: &mut R) -> std::io::Result { use ff::PrimeField; - let owned_note_pub_id_bytes = <[u8; 32]>::deserialize_reader(reader)?; - let owned_note_pub_id = Option::from(pallas::Base::from_repr(owned_note_pub_id_bytes)) + let owned_resource_id_bytes = <[u8; 32]>::deserialize_reader(reader)?; + let owned_resource_id = Option::from(pallas::Base::from_repr(owned_resource_id_bytes)) .ok_or_else(|| { std::io::Error::new( std::io::ErrorKind::InvalidData, - "owned_note_pub_id not in field", + "owned_resource_id not in field", ) })?; - let input_notes: Vec<_> = (0..NUM_NOTE) - .map(|_| Note::deserialize_reader(reader)) + let input_resources: Vec<_> = (0..NUM_RESOURCE) + .map(|_| Resource::deserialize_reader(reader)) .collect::>()?; - let output_notes: Vec<_> = (0..NUM_NOTE) - .map(|_| Note::deserialize_reader(reader)) + let output_resources: Vec<_> = (0..NUM_RESOURCE) + .map(|_| Resource::deserialize_reader(reader)) .collect::>()?; Ok(Self { - owned_note_pub_id, - input_notes: input_notes.try_into().unwrap(), - output_notes: output_notes.try_into().unwrap(), + owned_resource_id, + input_resources: input_resources.try_into().unwrap(), + output_resources: output_resources.try_into().unwrap(), }) } } impl TrivialValidtyPredicateCircuitProxy { fn to_concrete(&self) -> Option { - let input_notes = self.input_notes.clone().try_into().ok()?; - let output_notes = self.output_notes.clone().try_into().ok()?; - let owned_note_pub_id = self.owned_note_pub_id; + let input_resources = self.input_resources.clone().try_into().ok()?; + let output_resources = self.output_resources.clone().try_into().ok()?; + let owned_resource_id = self.owned_resource_id; Some(TrivialValidityPredicateCircuit { - owned_note_pub_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, }) } } @@ -184,12 +184,12 @@ impl<'a> Decoder<'a> for TrivialValidityPredicateCircuit { } impl ValidityPredicateCircuit for TrivialValidityPredicateCircuit { - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -206,8 +206,8 @@ impl ValidityPredicateCircuit for TrivialValidityPredicateCircuit { public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } @@ -251,15 +251,15 @@ impl ValidityPredicateVerifyingInfo for TrivialValidityPredicateCircuit { #[cfg(test)] pub mod tests { use super::TrivialValidityPredicateCircuit; - use crate::{constant::NUM_NOTE, note::tests::random_note}; + use crate::{constant::NUM_RESOURCE, resource::tests::random_resource}; use ff::Field; use pasta_curves::pallas; use rand::RngCore; pub fn random_trivial_vp_circuit(mut rng: R) -> TrivialValidityPredicateCircuit { - let owned_note_pub_id = pallas::Base::random(&mut rng); - let input_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); - TrivialValidityPredicateCircuit::new(owned_note_pub_id, input_notes, output_notes) + let owned_resource_id = pallas::Base::random(&mut rng); + let input_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); + let output_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); + TrivialValidityPredicateCircuit::new(owned_resource_id, input_resources, output_resources) } #[test] diff --git a/taiga_halo2/src/circuit/vp_examples/cascade_intent.rs b/taiga_halo2/src/circuit/vp_examples/cascade_intent.rs index 5779f0df..4b90d84e 100644 --- a/taiga_halo2/src/circuit/vp_examples/cascade_intent.rs +++ b/taiga_halo2/src/circuit/vp_examples/cascade_intent.rs @@ -1,26 +1,26 @@ /// The intent is to show how to cascade partial transactions so they can be executed atomically. -/// In this example, Alice wants to spend three(more than the fixed NUM_NOTE) different kinds of tokens/notes simultaneously. -/// She needs to distribute the notes to two partial transactions. She can use the intent to cascade the partial transactions. -/// In the first partial transaction, she spends two notes and creates a cascade intent note to encode and check the third note info. -/// In the sencond partial transaction, she spends the cascade note and the third note. +/// In this example, Alice wants to spend three(more than the fixed NUM_RESOURCE) different kinds of tokens/resources simultaneously. +/// She needs to distribute the resources to two partial transactions. She can use the intent to cascade the partial transactions. +/// In the first partial transaction, she spends two resources and creates a cascade intent resource to encode and check the third resource info. +/// In the sencond partial transaction, she spends the cascade resource and the third resource. /// use crate::{ circuit::{ blake2s::publicize_default_dynamic_vp_commitments, gadgets::{ assign_free_advice, - target_note_variable::{get_is_input_note_flag, get_owned_note_variable}, + target_resource_variable::{get_is_input_resource_flag, get_owned_resource_variable}, }, vp_circuit::{ BasicValidityPredicateVariables, VPVerifyingInfo, ValidityPredicateCircuit, ValidityPredicateConfig, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo, }, }, - constant::{NUM_NOTE, SETUP_PARAMS_MAP}, + constant::{NUM_RESOURCE, SETUP_PARAMS_MAP}, error::TransactionError, - note::{Note, RandomSeed}, nullifier::Nullifier, proof::Proof, + resource::{RandomSeed, Resource}, vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, }; @@ -42,17 +42,17 @@ lazy_static! { // CascadeIntentValidityPredicateCircuit #[derive(Clone, Debug, Default)] pub struct CascadeIntentValidityPredicateCircuit { - pub owned_note_pub_id: pallas::Base, - pub input_notes: [Note; NUM_NOTE], - pub output_notes: [Note; NUM_NOTE], - // use the note commitment to identify the note. - pub cascade_note_cm: pallas::Base, + pub owned_resource_id: pallas::Base, + pub input_resources: [Resource; NUM_RESOURCE], + pub output_resources: [Resource; NUM_RESOURCE], + // use the resource commitment to identify the resource. + pub cascade_resource_cm: pallas::Base, } impl CascadeIntentValidityPredicateCircuit { - // We can encode at most three notes to app_data_static if needed. - pub fn encode_app_data_static(cascade_note_cm: pallas::Base) -> pallas::Base { - cascade_note_cm + // We can encode at most three resources to label if needed. + pub fn encode_label(cascade_resource_cm: pallas::Base) -> pallas::Base { + cascade_resource_cm } } @@ -64,44 +64,44 @@ impl ValidityPredicateCircuit for CascadeIntentValidityPredicateCircuit { mut layouter: impl Layouter, basic_variables: BasicValidityPredicateVariables, ) -> Result<(), Error> { - let owned_note_pub_id = basic_variables.get_owned_note_pub_id(); - let is_input_note = get_is_input_note_flag( - config.get_is_input_note_flag_config, - layouter.namespace(|| "get is_input_note_flag"), - &owned_note_pub_id, - &basic_variables.get_input_note_nfs(), - &basic_variables.get_output_note_cms(), + let owned_resource_id = basic_variables.get_owned_resource_id(); + let is_input_resource = get_is_input_resource_flag( + config.get_is_input_resource_flag_config, + layouter.namespace(|| "get is_input_resource_flag"), + &owned_resource_id, + &basic_variables.get_input_resource_nfs(), + &basic_variables.get_output_resource_cms(), )?; - // If the number of cascade notes is more than one, encode them. - let cascade_note_cm = assign_free_advice( - layouter.namespace(|| "witness cascade_note_cm"), + // If the number of cascade resources is more than one, encode them. + let cascade_resource_cm = assign_free_advice( + layouter.namespace(|| "witness cascade_resource_cm"), config.advices[0], - Value::known(self.cascade_note_cm), + Value::known(self.cascade_resource_cm), )?; - // search target note and get the intent app_static_data - let app_data_static = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_data_static"), - &owned_note_pub_id, - &basic_variables.get_app_data_static_searchable_pairs(), + // search target resource and get the intent label + let label = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource label"), + &owned_resource_id, + &basic_variables.get_label_searchable_pairs(), )?; - // check the app_data_static of intent note + // check the label of intent resource layouter.assign_region( - || "check app_data_static", - |mut region| region.constrain_equal(cascade_note_cm.cell(), app_data_static.cell()), + || "check label", + |mut region| region.constrain_equal(cascade_resource_cm.cell(), label.cell()), )?; - // check the cascade note + // check the cascade resource layouter.assign_region( - || "conditional equal: check the cascade note", + || "conditional equal: check the cascade resource", |mut region| { config.conditional_equal_config.assign_region( - &is_input_note, - &app_data_static, - &basic_variables.input_note_variables[1].cm, + &is_input_resource, + &label, + &basic_variables.input_resource_variables[1].cm, 0, &mut region, ) @@ -118,12 +118,12 @@ impl ValidityPredicateCircuit for CascadeIntentValidityPredicateCircuit { Ok(()) } - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -140,30 +140,29 @@ impl ValidityPredicateCircuit for CascadeIntentValidityPredicateCircuit { public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } vp_circuit_impl!(CascadeIntentValidityPredicateCircuit); vp_verifying_info_impl!(CascadeIntentValidityPredicateCircuit); -pub fn create_intent_note( +pub fn create_intent_resource( mut rng: R, - cascade_note_cm: pallas::Base, + cascade_resource_cm: pallas::Base, nk: pallas::Base, -) -> Note { - let app_data_static = - CascadeIntentValidityPredicateCircuit::encode_app_data_static(cascade_note_cm); +) -> Resource { + let label = CascadeIntentValidityPredicateCircuit::encode_label(cascade_resource_cm); let rseed = RandomSeed::random(&mut rng); - let rho = Nullifier::random(&mut rng); - Note::new_input_note( + let nonce = Nullifier::random(&mut rng); + Resource::new_input_resource( *COMPRESSED_CASCADE_INTENT_VK, - app_data_static, + label, pallas::Base::zero(), 1u64, nk, - rho, + nonce, false, rseed, ) @@ -172,25 +171,25 @@ pub fn create_intent_note( #[test] fn test_halo2_cascade_intent_vp_circuit() { use crate::constant::VP_CIRCUIT_PARAMS_SIZE; - use crate::note::tests::random_note; + use crate::resource::tests::random_resource; use halo2_proofs::arithmetic::Field; use halo2_proofs::dev::MockProver; use rand::rngs::OsRng; let mut rng = OsRng; let circuit = { - let cascade_input_note = random_note(&mut rng); - let cascade_note_cm = cascade_input_note.commitment().inner(); + let cascade_input_resource = random_resource(&mut rng); + let cascade_resource_cm = cascade_input_resource.commitment().inner(); let nk = pallas::Base::random(&mut rng); - let intent_note = create_intent_note(&mut rng, cascade_note_cm, nk); - let input_notes = [intent_note, cascade_input_note]; - let output_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); + let intent_resource = create_intent_resource(&mut rng, cascade_resource_cm, nk); + let input_resources = [intent_resource, cascade_input_resource]; + let output_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); CascadeIntentValidityPredicateCircuit { - owned_note_pub_id: input_notes[0].get_nf().unwrap().inner(), - input_notes, - output_notes, - cascade_note_cm, + owned_resource_id: input_resources[0].get_nf().unwrap().inner(), + input_resources, + output_resources, + cascade_resource_cm, } }; let public_inputs = circuit.get_public_inputs(&mut rng); diff --git a/taiga_halo2/src/circuit/vp_examples/field_addition.rs b/taiga_halo2/src/circuit/vp_examples/field_addition.rs index 4e0d1662..96b739aa 100644 --- a/taiga_halo2/src/circuit/vp_examples/field_addition.rs +++ b/taiga_halo2/src/circuit/vp_examples/field_addition.rs @@ -10,10 +10,10 @@ use crate::{ ValidityPredicateConfig, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo, }, }, - constant::{NUM_NOTE, SETUP_PARAMS_MAP, VP_CIRCUIT_CUSTOM_PUBLIC_INPUT_BEGIN_IDX}, + constant::{NUM_RESOURCE, SETUP_PARAMS_MAP, VP_CIRCUIT_CUSTOM_PUBLIC_INPUT_BEGIN_IDX}, error::TransactionError, - note::{Note, RandomSeed}, proof::Proof, + resource::{RandomSeed, Resource}, vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, }; @@ -28,16 +28,16 @@ use rand::RngCore; // FieldAdditionValidityPredicateCircuit with a trivial constraint a + b = c. #[derive(Clone, Debug, Default)] struct FieldAdditionValidityPredicateCircuit { - owned_note_pub_id: pallas::Base, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + owned_resource_id: pallas::Base, + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], a: pallas::Base, b: pallas::Base, } impl ValidityPredicateCircuit for FieldAdditionValidityPredicateCircuit { // Add custom constraints - // Note: the trivial vp doesn't constrain on input_note_variables and output_note_variables + // Resource: the trivial vp doesn't constrain on input_resource_variables and output_resource_variables fn custom_constraints( &self, config: Self::Config, @@ -77,12 +77,12 @@ impl ValidityPredicateCircuit for FieldAdditionValidityPredicateCircuit { Ok(()) } - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -100,8 +100,8 @@ impl ValidityPredicateCircuit for FieldAdditionValidityPredicateCircuit { public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } @@ -111,22 +111,22 @@ vp_verifying_info_impl!(FieldAdditionValidityPredicateCircuit); #[test] fn test_halo2_addition_vp_circuit() { use crate::constant::VP_CIRCUIT_PARAMS_SIZE; - use crate::note::tests::random_note; + use crate::resource::tests::random_resource; use halo2_proofs::arithmetic::Field; use halo2_proofs::dev::MockProver; use rand::rngs::OsRng; let mut rng = OsRng; let circuit = { - let input_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); + let input_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); + let output_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); let a = pallas::Base::random(&mut rng); let b = pallas::Base::random(&mut rng); - let owned_note_pub_id = pallas::Base::random(&mut rng); + let owned_resource_id = pallas::Base::random(&mut rng); FieldAdditionValidityPredicateCircuit { - owned_note_pub_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, a, b, } diff --git a/taiga_halo2/src/circuit/vp_examples/or_relation_intent.rs b/taiga_halo2/src/circuit/vp_examples/or_relation_intent.rs index 521758a2..ec4ada54 100644 --- a/taiga_halo2/src/circuit/vp_examples/or_relation_intent.rs +++ b/taiga_halo2/src/circuit/vp_examples/or_relation_intent.rs @@ -8,7 +8,7 @@ use crate::{ gadgets::{ assign_free_advice, poseidon_hash::poseidon_hash_gadget, - target_note_variable::{get_is_input_note_flag, get_owned_note_variable}, + target_resource_variable::{get_is_input_resource_flag, get_owned_resource_variable}, }, vp_circuit::{ BasicValidityPredicateVariables, VPVerifyingInfo, ValidityPredicateCircuit, @@ -16,11 +16,11 @@ use crate::{ }, vp_examples::token::{Token, TOKEN_VK}, }, - constant::{NUM_NOTE, SETUP_PARAMS_MAP}, + constant::{NUM_RESOURCE, SETUP_PARAMS_MAP}, error::TransactionError, - note::{Note, RandomSeed}, nullifier::Nullifier, proof::Proof, + resource::{RandomSeed, Resource}, utils::poseidon_hash_n, vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, @@ -44,34 +44,34 @@ lazy_static! { // OrRelationIntentValidityPredicateCircuit #[derive(Clone, Debug, Default)] pub struct OrRelationIntentValidityPredicateCircuit { - pub owned_note_pub_id: pallas::Base, - pub input_notes: [Note; NUM_NOTE], - pub output_notes: [Note; NUM_NOTE], + pub owned_resource_id: pallas::Base, + pub input_resources: [Resource; NUM_RESOURCE], + pub output_resources: [Resource; NUM_RESOURCE], pub token_1: Token, pub token_2: Token, - pub receiver_nk_com: pallas::Base, - pub receiver_app_data_dynamic: pallas::Base, + pub receiver_npk: pallas::Base, + pub receiver_value: pallas::Base, } impl OrRelationIntentValidityPredicateCircuit { - pub fn encode_app_data_static( + pub fn encode_label( token_1: &Token, token_2: &Token, - receiver_nk_com: pallas::Base, - receiver_app_data_dynamic: pallas::Base, + receiver_npk: pallas::Base, + receiver_value: pallas::Base, ) -> pallas::Base { let token_property_1 = token_1.encode_name(); - let token_value_1 = token_1.encode_value(); + let token_quantity_1 = token_1.encode_quantity(); let token_property_2 = token_2.encode_name(); - let token_value_2 = token_2.encode_value(); + let token_quantity_2 = token_2.encode_quantity(); poseidon_hash_n([ token_property_1, - token_value_1, + token_quantity_1, token_property_2, - token_value_2, + token_quantity_2, TOKEN_VK.get_compressed(), - receiver_nk_com, - receiver_app_data_dynamic, + receiver_npk, + receiver_value, ]) } } @@ -84,13 +84,13 @@ impl ValidityPredicateCircuit for OrRelationIntentValidityPredicateCircuit { mut layouter: impl Layouter, basic_variables: BasicValidityPredicateVariables, ) -> Result<(), Error> { - let owned_note_pub_id = basic_variables.get_owned_note_pub_id(); - let is_input_note = get_is_input_note_flag( - config.get_is_input_note_flag_config, - layouter.namespace(|| "get is_input_note_flag"), - &owned_note_pub_id, - &basic_variables.get_input_note_nfs(), - &basic_variables.get_output_note_cms(), + let owned_resource_id = basic_variables.get_owned_resource_id(); + let is_input_resource = get_is_input_resource_flag( + config.get_is_input_resource_flag_config, + layouter.namespace(|| "get is_input_resource_flag"), + &owned_resource_id, + &basic_variables.get_input_resource_nfs(), + &basic_variables.get_output_resource_cms(), )?; let token_vp_vk = assign_free_advice( @@ -105,10 +105,10 @@ impl ValidityPredicateCircuit for OrRelationIntentValidityPredicateCircuit { Value::known(self.token_1.encode_name()), )?; - let token_value_1 = assign_free_advice( - layouter.namespace(|| "witness token value in token_1"), + let token_quantity_1 = assign_free_advice( + layouter.namespace(|| "witness token quantity in token_1"), config.advices[0], - Value::known(self.token_1.encode_value()), + Value::known(self.token_1.encode_quantity()), )?; let token_property_2 = assign_free_advice( @@ -117,118 +117,119 @@ impl ValidityPredicateCircuit for OrRelationIntentValidityPredicateCircuit { Value::known(self.token_2.encode_name()), )?; - let token_value_2 = assign_free_advice( - layouter.namespace(|| "witness token value in token_2"), + let token_quantity_2 = assign_free_advice( + layouter.namespace(|| "witness token quantity in token_2"), config.advices[0], - Value::known(self.token_2.encode_value()), + Value::known(self.token_2.encode_quantity()), )?; - let receiver_nk_com = assign_free_advice( - layouter.namespace(|| "witness receiver nk_com"), + let receiver_npk = assign_free_advice( + layouter.namespace(|| "witness receiver npk"), config.advices[0], - Value::known(self.receiver_nk_com), + Value::known(self.receiver_npk), )?; - let receiver_app_data_dynamic = assign_free_advice( - layouter.namespace(|| "witness receiver app_data_dynamic"), + let receiver_value = assign_free_advice( + layouter.namespace(|| "witness receiver value"), config.advices[0], - Value::known(self.receiver_app_data_dynamic), + Value::known(self.receiver_value), )?; - // Encode the app_data_static of intent note - let encoded_app_data_static = poseidon_hash_gadget( + // Encode the label of intent resource + let encoded_label = poseidon_hash_gadget( config.poseidon_config, - layouter.namespace(|| "encode app_data_static"), + layouter.namespace(|| "encode label"), [ token_property_1.clone(), - token_value_1.clone(), + token_quantity_1.clone(), token_property_2.clone(), - token_value_2.clone(), + token_quantity_2.clone(), token_vp_vk.clone(), - receiver_nk_com.clone(), - receiver_app_data_dynamic.clone(), + receiver_npk.clone(), + receiver_value.clone(), ], )?; - // search target note and get the intent app_static_data - let app_data_static = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_data_static"), - &owned_note_pub_id, - &basic_variables.get_app_data_static_searchable_pairs(), + // search target resource and get the intent label + let label = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource label"), + &owned_resource_id, + &basic_variables.get_label_searchable_pairs(), )?; - // check the app_data_static of intent note + // check the label of intent resource layouter.assign_region( - || "check app_data_static", - |mut region| { - region.constrain_equal(encoded_app_data_static.cell(), app_data_static.cell()) - }, + || "check label", + |mut region| region.constrain_equal(encoded_label.cell(), label.cell()), )?; - // check the vp vk of output note + // check the vp vk of output resource layouter.assign_region( || "conditional equal: check vp vk", |mut region| { config.conditional_equal_config.assign_region( - &is_input_note, + &is_input_resource, &token_vp_vk, - &basic_variables.output_note_variables[0] - .note_variables - .app_vk, + &basic_variables.output_resource_variables[0] + .resource_variables + .logic, 0, &mut region, ) }, )?; - // check nk_com + // check npk layouter.assign_region( - || "conditional equal: check nk_com", + || "conditional equal: check npk", |mut region| { config.conditional_equal_config.assign_region( - &is_input_note, - &receiver_nk_com, - &basic_variables.output_note_variables[0] - .note_variables - .nk_com, + &is_input_resource, + &receiver_npk, + &basic_variables.output_resource_variables[0] + .resource_variables + .npk, 0, &mut region, ) }, )?; - // check app_data_dynamic + // check value layouter.assign_region( - || "conditional equal: check app_data_dynamic", + || "conditional equal: check value", |mut region| { config.conditional_equal_config.assign_region( - &is_input_note, - &receiver_app_data_dynamic, - &basic_variables.output_note_variables[0] - .note_variables - .app_data_dynamic, + &is_input_resource, + &receiver_value, + &basic_variables.output_resource_variables[0] + .resource_variables + .value, 0, &mut region, ) }, )?; - // check the token_property and token_value in conditions - let output_note_token_property = &basic_variables.output_note_variables[0] - .note_variables - .app_data_static; - let output_note_token_value = &basic_variables.output_note_variables[0] - .note_variables - .value; + // check the token_property and token_quantity in conditions + let output_resource_token_property = &basic_variables.output_resource_variables[0] + .resource_variables + .label; + let output_resource_token_quantity = &basic_variables.output_resource_variables[0] + .resource_variables + .quantity; layouter.assign_region( || "extended or relatioin", |mut region| { config.extended_or_relation_config.assign_region( - &is_input_note, - (&token_property_1, &token_value_1), - (&token_property_2, &token_value_2), - (output_note_token_property, output_note_token_value), + &is_input_resource, + (&token_property_1, &token_quantity_1), + (&token_property_2, &token_quantity_2), + ( + output_resource_token_property, + output_resource_token_quantity, + ), 0, &mut region, ) @@ -245,12 +246,12 @@ impl ValidityPredicateCircuit for OrRelationIntentValidityPredicateCircuit { Ok(()) } - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -267,37 +268,37 @@ impl ValidityPredicateCircuit for OrRelationIntentValidityPredicateCircuit { public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } vp_circuit_impl!(OrRelationIntentValidityPredicateCircuit); vp_verifying_info_impl!(OrRelationIntentValidityPredicateCircuit); -pub fn create_intent_note( +pub fn create_intent_resource( mut rng: R, token_1: &Token, token_2: &Token, - receiver_nk_com: pallas::Base, - receiver_app_data_dynamic: pallas::Base, + receiver_npk: pallas::Base, + receiver_value: pallas::Base, nk: pallas::Base, -) -> Note { - let app_data_static = OrRelationIntentValidityPredicateCircuit::encode_app_data_static( +) -> Resource { + let label = OrRelationIntentValidityPredicateCircuit::encode_label( token_1, token_2, - receiver_nk_com, - receiver_app_data_dynamic, + receiver_npk, + receiver_value, ); let rseed = RandomSeed::random(&mut rng); - let rho = Nullifier::random(&mut rng); - Note::new_input_note( + let nonce = Nullifier::random(&mut rng); + Resource::new_input_resource( *COMPRESSED_OR_RELATION_INTENT_VK, - app_data_static, + label, pallas::Base::zero(), 1u64, nk, - rho, + nonce, false, rseed, ) @@ -306,40 +307,42 @@ pub fn create_intent_note( #[test] fn test_halo2_or_relation_intent_vp_circuit() { use crate::constant::VP_CIRCUIT_PARAMS_SIZE; - use crate::{circuit::vp_examples::token::COMPRESSED_TOKEN_VK, note::tests::random_note}; + use crate::{ + circuit::vp_examples::token::COMPRESSED_TOKEN_VK, resource::tests::random_resource, + }; use halo2_proofs::arithmetic::Field; use halo2_proofs::dev::MockProver; use rand::rngs::OsRng; let mut rng = OsRng; let circuit = { - let mut output_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); + let mut output_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); let token_1 = Token::new("token1".to_string(), 1u64); let token_2 = Token::new("token2".to_string(), 2u64); - output_notes[0].note_type.app_vk = *COMPRESSED_TOKEN_VK; - output_notes[0].note_type.app_data_static = token_1.encode_name(); - output_notes[0].value = token_1.value(); + output_resources[0].kind.logic = *COMPRESSED_TOKEN_VK; + output_resources[0].kind.label = token_1.encode_name(); + output_resources[0].quantity = token_1.quantity(); let nk = pallas::Base::random(&mut rng); - let nk_com = output_notes[0].get_nk_commitment(); - let intent_note = create_intent_note( + let npk = output_resources[0].get_npk(); + let intent_resource = create_intent_resource( &mut rng, &token_1, &token_2, - nk_com, - output_notes[0].app_data_dynamic, + npk, + output_resources[0].value, nk, ); - let padding_input_note = Note::random_padding_note(&mut rng); - let input_notes = [intent_note, padding_input_note]; + let padding_input_resource = Resource::random_padding_resource(&mut rng); + let input_resources = [intent_resource, padding_input_resource]; OrRelationIntentValidityPredicateCircuit { - owned_note_pub_id: input_notes[0].get_nf().unwrap().inner(), - input_notes, - output_notes, + owned_resource_id: input_resources[0].get_nf().unwrap().inner(), + input_resources, + output_resources, token_1, token_2, - receiver_nk_com: nk_com, - receiver_app_data_dynamic: output_notes[0].app_data_dynamic, + receiver_npk: npk, + receiver_value: output_resources[0].value, } }; let public_inputs = circuit.get_public_inputs(&mut rng); diff --git a/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent.rs b/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent.rs index 6f48c3ac..bff301f8 100644 --- a/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent.rs +++ b/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent.rs @@ -9,17 +9,17 @@ use crate::{ assign_free_constant, mul::MulChip, sub::{SubChip, SubInstructions}, - target_note_variable::{get_is_input_note_flag, get_owned_note_variable}, + target_resource_variable::{get_is_input_resource_flag, get_owned_resource_variable}, }, vp_circuit::{ BasicValidityPredicateVariables, VPVerifyingInfo, ValidityPredicateCircuit, ValidityPredicateConfig, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo, }, }, - constant::{NUM_NOTE, SETUP_PARAMS_MAP}, + constant::{NUM_RESOURCE, SETUP_PARAMS_MAP}, error::TransactionError, - note::{Note, RandomSeed}, proof::Proof, + resource::{RandomSeed, Resource}, vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, }; @@ -35,8 +35,8 @@ use rand::RngCore; pub mod swap; pub use swap::Swap; -mod data_static; -use data_static::PartialFulfillmentIntentDataStatic; +mod label; +use label::PartialFulfillmentIntentLabel; lazy_static! { pub static ref PARTIAL_FULFILLMENT_INTENT_VK: ValidityPredicateVerifyingKey = @@ -48,9 +48,9 @@ lazy_static! { // PartialFulfillmentIntentValidityPredicateCircuit #[derive(Clone, Debug, Default)] pub struct PartialFulfillmentIntentValidityPredicateCircuit { - pub owned_note_pub_id: pallas::Base, - pub input_notes: [Note; NUM_NOTE], - pub output_notes: [Note; NUM_NOTE], + pub owned_resource_id: pallas::Base, + pub input_resources: [Resource; NUM_RESOURCE], + pub output_resources: [Resource; NUM_RESOURCE], pub swap: Swap, } @@ -65,54 +65,48 @@ impl ValidityPredicateCircuit for PartialFulfillmentIntentValidityPredicateCircu let sub_chip = SubChip::construct(config.sub_config.clone(), ()); let mul_chip = MulChip::construct(config.mul_config.clone()); - let owned_note_pub_id = basic_variables.get_owned_note_pub_id(); + let owned_resource_id = basic_variables.get_owned_resource_id(); - let app_data_static = self.swap.assign_app_data_static( - config.advices[0], - layouter.namespace(|| "assign app_data_static"), - )?; - let encoded_app_data_static = app_data_static.encode( + let label = self + .swap + .assign_label(config.advices[0], layouter.namespace(|| "assign label"))?; + let encoded_label = label.encode( config.poseidon_config.clone(), - layouter.namespace(|| "encode app_data_static"), + layouter.namespace(|| "encode label"), )?; - // search target note and get the intent app_static_data - let owned_note_app_data_static = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_data_static"), - &owned_note_pub_id, - &basic_variables.get_app_data_static_searchable_pairs(), + // search target resource and get the intent label + let owned_resource_label = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource label"), + &owned_resource_id, + &basic_variables.get_label_searchable_pairs(), )?; - // Enforce consistency of app_data_static: + // Enforce consistency of label: // - as witnessed in the swap, and - // - as encoded in the intent note + // - as encoded in the intent resource layouter.assign_region( - || "check app_data_static", - |mut region| { - region.constrain_equal( - encoded_app_data_static.cell(), - owned_note_app_data_static.cell(), - ) - }, + || "check label", + |mut region| region.constrain_equal(encoded_label.cell(), owned_resource_label.cell()), )?; - let is_input_note = get_is_input_note_flag( - config.get_is_input_note_flag_config, - layouter.namespace(|| "get is_input_note_flag"), - &owned_note_pub_id, - &basic_variables.get_input_note_nfs(), - &basic_variables.get_output_note_cms(), + let is_input_resource = get_is_input_resource_flag( + config.get_is_input_resource_flag_config, + layouter.namespace(|| "get is_input_resource_flag"), + &owned_resource_id, + &basic_variables.get_input_resource_nfs(), + &basic_variables.get_output_resource_cms(), )?; - // Conditional checks if is_input_note == 1 - app_data_static.is_input_note_checks( - &is_input_note, + // Conditional checks if is_input_resource == 1 + label.is_input_resource_checks( + &is_input_resource, &basic_variables, &config.conditional_equal_config, - layouter.namespace(|| "is_input_note checks"), + layouter.namespace(|| "is_input_resource checks"), )?; - let is_output_note = { + let is_output_resource = { let constant_one = assign_free_constant( layouter.namespace(|| "one"), config.advices[0], @@ -121,22 +115,22 @@ impl ValidityPredicateCircuit for PartialFulfillmentIntentValidityPredicateCircu // TODO: use a nor gate to replace the sub gate. SubInstructions::sub( &sub_chip, - layouter.namespace(|| "expected_sold_value - returned_value"), - &is_input_note, + layouter.namespace(|| "expected_sold_quantity - returned_quantity"), + &is_input_resource, &constant_one, )? }; - // Conditional checks if is_output_note == 1 - app_data_static.is_output_note_checks( - &is_output_note, + // Conditional checks if is_output_resource == 1 + label.is_output_resource_checks( + &is_output_resource, &basic_variables, &config.conditional_equal_config, - layouter.namespace(|| "is_output_note checks"), + layouter.namespace(|| "is_output_resource checks"), )?; // Conditional checks if is_partial_fulfillment == 1 - app_data_static.is_partial_fulfillment_checks( - &is_input_note, + label.is_partial_fulfillment_checks( + &is_input_resource, &basic_variables, &config.conditional_equal_config, &sub_chip, @@ -154,12 +148,12 @@ impl ValidityPredicateCircuit for PartialFulfillmentIntentValidityPredicateCircu Ok(()) } - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -176,8 +170,8 @@ impl ValidityPredicateCircuit for PartialFulfillmentIntentValidityPredicateCircu public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } @@ -197,7 +191,7 @@ mod tests { use rand::rngs::OsRng; use rand::RngCore; - // Generate a swap, along with its corresponding intent note and authorisation + // Generate a swap, along with its corresponding intent resource and authorisation fn swap(mut rng: impl RngCore, sell: Token, buy: Token) -> Swap { let sk = pallas::Scalar::random(&mut rng); let auth = TokenAuthorization::from_sk_vk(&sk, &COMPRESSED_TOKEN_AUTH_VK); @@ -212,18 +206,18 @@ mod tests { let buy = Token::new("token2".to_string(), 4u64); let swap = swap(&mut rng, sell, buy); - let intent_note = swap.create_intent_note(&mut rng); + let intent_resource = swap.create_intent_resource(&mut rng); - let input_padding_note = Note::random_padding_note(&mut rng); - let output_padding_note = Note::random_padding_note(&mut rng); + let input_padding_resource = Resource::random_padding_resource(&mut rng); + let output_padding_resource = Resource::random_padding_resource(&mut rng); - let input_notes = [*swap.sell.note(), input_padding_note]; - let output_notes = [intent_note, output_padding_note]; + let input_resources = [*swap.sell.resource(), input_padding_resource]; + let output_resources = [intent_resource, output_padding_resource]; let circuit = PartialFulfillmentIntentValidityPredicateCircuit { - owned_note_pub_id: intent_note.commitment().inner(), - input_notes, - output_notes, + owned_resource_id: intent_resource.commitment().inner(), + input_resources, + output_resources, swap, }; let public_inputs = circuit.get_public_inputs(&mut rng); @@ -244,15 +238,15 @@ mod tests { let buy = Token::new("token2".to_string(), 4u64); let swap = swap(&mut rng, sell, buy); - let intent_note = swap.create_intent_note(&mut rng); + let intent_resource = swap.create_intent_resource(&mut rng); let bob_sell = swap.buy.clone(); - let (input_notes, output_notes) = swap.fill(&mut rng, intent_note, bob_sell); + let (input_resources, output_resources) = swap.fill(&mut rng, intent_resource, bob_sell); let circuit = PartialFulfillmentIntentValidityPredicateCircuit { - owned_note_pub_id: intent_note.get_nf().unwrap().inner(), - input_notes, - output_notes, + owned_resource_id: intent_resource.get_nf().unwrap().inner(), + input_resources, + output_resources, swap, }; let public_inputs = circuit.get_public_inputs(&mut rng); @@ -273,15 +267,15 @@ mod tests { let buy = Token::new("token2".to_string(), 4u64); let swap = swap(&mut rng, sell, buy); - let intent_note = swap.create_intent_note(&mut rng); + let intent_resource = swap.create_intent_resource(&mut rng); let bob_sell = Token::new(swap.buy.name().inner().to_string(), 2u64); - let (input_notes, output_notes) = swap.fill(&mut rng, intent_note, bob_sell); + let (input_resources, output_resources) = swap.fill(&mut rng, intent_resource, bob_sell); let circuit = PartialFulfillmentIntentValidityPredicateCircuit { - owned_note_pub_id: intent_note.get_nf().unwrap().inner(), - input_notes, - output_notes, + owned_resource_id: intent_resource.get_nf().unwrap().inner(), + input_resources, + output_resources, swap, }; let public_inputs = circuit.get_public_inputs(&mut rng); diff --git a/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/data_static.rs b/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/label.rs similarity index 52% rename from taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/data_static.rs rename to taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/label.rs index f3b7e2bc..785c4330 100644 --- a/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/data_static.rs +++ b/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/label.rs @@ -15,42 +15,42 @@ use halo2_proofs::{ use pasta_curves::pallas; #[derive(Clone, Debug)] -pub struct PartialFulfillmentIntentDataStatic { +pub struct PartialFulfillmentIntentLabel { pub token_vp_vk: AssignedCell, pub sold_token: AssignedCell, - pub sold_token_value: AssignedCell, + pub sold_token_quantity: AssignedCell, pub bought_token: AssignedCell, - pub bought_token_value: AssignedCell, - pub receiver_nk_com: AssignedCell, - pub receiver_app_data_dynamic: AssignedCell, + pub bought_token_quantity: AssignedCell, + pub receiver_npk: AssignedCell, + pub receiver_value: AssignedCell, } -impl PartialFulfillmentIntentDataStatic { +impl PartialFulfillmentIntentLabel { pub fn encode( &self, config: PoseidonConfig, mut layouter: impl Layouter, ) -> Result, Error> { - // Encode the app_data_static of intent note + // Encode the label of intent resource poseidon_hash_gadget( config.clone(), - layouter.namespace(|| "app_data_static encoding"), + layouter.namespace(|| "label encoding"), [ self.sold_token.clone(), - self.sold_token_value.clone(), + self.sold_token_quantity.clone(), self.bought_token.clone(), - self.bought_token_value.clone(), + self.bought_token_quantity.clone(), self.token_vp_vk.clone(), - self.receiver_nk_com.clone(), - self.receiver_app_data_dynamic.clone(), + self.receiver_npk.clone(), + self.receiver_value.clone(), ], ) } - /// Checks to be enforced if `is_input_note == 1` - pub fn is_input_note_checks( + /// Checks to be enforced if `is_input_resource == 1` + pub fn is_input_resource_checks( &self, - is_input_note: &AssignedCell, + is_input_resource: &AssignedCell, basic_variables: &BasicValidityPredicateVariables, config: &ConditionalEqualConfig, mut layouter: impl Layouter, @@ -59,11 +59,11 @@ impl PartialFulfillmentIntentDataStatic { || "conditional equal: check bought token vk", |mut region| { config.assign_region( - is_input_note, + is_input_resource, &self.token_vp_vk, - &basic_variables.output_note_variables[0] - .note_variables - .app_vk, + &basic_variables.output_resource_variables[0] + .resource_variables + .logic, 0, &mut region, ) @@ -74,43 +74,43 @@ impl PartialFulfillmentIntentDataStatic { || "conditional equal: check bought token vk", |mut region| { config.assign_region( - is_input_note, + is_input_resource, &self.bought_token, - &basic_variables.output_note_variables[0] - .note_variables - .app_data_static, + &basic_variables.output_resource_variables[0] + .resource_variables + .label, 0, &mut region, ) }, )?; - // check nk_com + // check npk layouter.assign_region( - || "conditional equal: check bought token nk_com", + || "conditional equal: check bought token npk", |mut region| { config.assign_region( - is_input_note, - &self.receiver_nk_com, - &basic_variables.output_note_variables[0] - .note_variables - .nk_com, + is_input_resource, + &self.receiver_npk, + &basic_variables.output_resource_variables[0] + .resource_variables + .npk, 0, &mut region, ) }, )?; - // check app_data_dynamic + // check value layouter.assign_region( - || "conditional equal: check bought token app_data_dynamic", + || "conditional equal: check bought token value", |mut region| { config.assign_region( - is_input_note, - &self.receiver_app_data_dynamic, - &basic_variables.output_note_variables[0] - .note_variables - .app_data_dynamic, + is_input_resource, + &self.receiver_value, + &basic_variables.output_resource_variables[0] + .resource_variables + .value, 0, &mut region, ) @@ -120,10 +120,10 @@ impl PartialFulfillmentIntentDataStatic { Ok(()) } - /// Checks to be enforced if `is_output_note == 1` - pub fn is_output_note_checks( + /// Checks to be enforced if `is_output_resource == 1` + pub fn is_output_resource_checks( &self, - is_output_note: &AssignedCell, + is_output_resource: &AssignedCell, basic_variables: &BasicValidityPredicateVariables, config: &ConditionalEqualConfig, mut layouter: impl Layouter, @@ -132,11 +132,11 @@ impl PartialFulfillmentIntentDataStatic { || "conditional equal: check sold token vp_vk", |mut region| { config.assign_region( - is_output_note, + is_output_resource, &self.token_vp_vk, - &basic_variables.input_note_variables[0] - .note_variables - .app_vk, + &basic_variables.input_resource_variables[0] + .resource_variables + .logic, 0, &mut region, ) @@ -144,14 +144,14 @@ impl PartialFulfillmentIntentDataStatic { )?; layouter.assign_region( - || "conditional equal: check sold token app_data_static", + || "conditional equal: check sold token label", |mut region| { config.assign_region( - is_output_note, + is_output_resource, &self.sold_token, - &basic_variables.input_note_variables[0] - .note_variables - .app_data_static, + &basic_variables.input_resource_variables[0] + .resource_variables + .label, 0, &mut region, ) @@ -159,12 +159,14 @@ impl PartialFulfillmentIntentDataStatic { )?; layouter.assign_region( - || "conditional equal: check sold token value", + || "conditional equal: check sold token quantity", |mut region| { config.assign_region( - is_output_note, - &self.sold_token_value, - &basic_variables.input_note_variables[0].note_variables.value, + is_output_resource, + &self.sold_token_quantity, + &basic_variables.input_resource_variables[0] + .resource_variables + .quantity, 0, &mut region, ) @@ -177,7 +179,7 @@ impl PartialFulfillmentIntentDataStatic { /// Checks to be enforced if `is_partial_fulfillment == 1` pub fn is_partial_fulfillment_checks( &self, - is_input_note: &AssignedCell, + is_input_resource: &AssignedCell, basic_variables: &BasicValidityPredicateVariables, config: &ConditionalEqualConfig, sub_chip: &SubChip, @@ -187,16 +189,17 @@ impl PartialFulfillmentIntentDataStatic { let is_partial_fulfillment = { let is_partial_fulfillment = SubInstructions::sub( sub_chip, - layouter.namespace(|| "expected_bought_token_value - actual_bought_token_value"), - &self.bought_token_value, - &basic_variables.output_note_variables[0] - .note_variables - .value, + layouter + .namespace(|| "expected_bought_token_quantity - actual_bought_token_quantity"), + &self.bought_token_quantity, + &basic_variables.output_resource_variables[0] + .resource_variables + .quantity, )?; MulInstructions::mul( mul_chip, layouter.namespace(|| "is_input * is_partial_fulfillment"), - is_input_note, + is_input_resource, &is_partial_fulfillment, )? }; @@ -208,25 +211,25 @@ impl PartialFulfillmentIntentDataStatic { config.assign_region( &is_partial_fulfillment, &self.token_vp_vk, - &basic_variables.output_note_variables[1] - .note_variables - .app_vk, + &basic_variables.output_resource_variables[1] + .resource_variables + .logic, 0, &mut region, ) }, )?; - // check return token app_data_static if it's partially fulfilled + // check return token label if it's partially fulfilled layouter.assign_region( - || "conditional equal: check returned token app_data_static", + || "conditional equal: check returned token label", |mut region| { config.assign_region( &is_partial_fulfillment, &self.sold_token, - &basic_variables.output_note_variables[1] - .note_variables - .app_data_static, + &basic_variables.output_resource_variables[1] + .resource_variables + .label, 0, &mut region, ) @@ -234,14 +237,14 @@ impl PartialFulfillmentIntentDataStatic { )?; layouter.assign_region( - || "conditional equal: check returned token nk_com", + || "conditional equal: check returned token npk", |mut region| { config.assign_region( &is_partial_fulfillment, - &self.receiver_nk_com, - &basic_variables.output_note_variables[1] - .note_variables - .nk_com, + &self.receiver_npk, + &basic_variables.output_resource_variables[1] + .resource_variables + .npk, 0, &mut region, ) @@ -249,55 +252,55 @@ impl PartialFulfillmentIntentDataStatic { )?; layouter.assign_region( - || "conditional equal: check returned token app_data_dynamic", + || "conditional equal: check returned token value", |mut region| { config.assign_region( &is_partial_fulfillment, - &self.receiver_app_data_dynamic, - &basic_variables.output_note_variables[1] - .note_variables - .app_data_dynamic, + &self.receiver_value, + &basic_variables.output_resource_variables[1] + .resource_variables + .value, 0, &mut region, ) }, )?; - // value check + // quantity check { - let actual_sold_value = SubInstructions::sub( + let actual_sold_quantity = SubInstructions::sub( sub_chip, - layouter.namespace(|| "expected_sold_value - returned_value"), - &self.sold_token_value, - &basic_variables.output_note_variables[1] - .note_variables - .value, + layouter.namespace(|| "expected_sold_quantity - returned_quantity"), + &self.sold_token_quantity, + &basic_variables.output_resource_variables[1] + .resource_variables + .quantity, )?; - // check (expected_bought_value * actual_sold_value) == (expected_sold_value * actual_bought_value) + // check (expected_bought_quantity * actual_sold_quantity) == (expected_sold_quantity * actual_bought_quantity) // if it's partially fulfilled - let expected_bought_mul_actual_sold_value = MulInstructions::mul( + let expected_bought_mul_actual_sold_quantity = MulInstructions::mul( mul_chip, - layouter.namespace(|| "expected_bought_value * actual_sold_value"), - &self.bought_token_value, - &actual_sold_value, + layouter.namespace(|| "expected_bought_quantity * actual_sold_quantity"), + &self.bought_token_quantity, + &actual_sold_quantity, )?; - let expected_sold_mul_actual_bought_value = MulInstructions::mul( + let expected_sold_mul_actual_bought_quantity = MulInstructions::mul( mul_chip, - layouter.namespace(|| "expected_sold_value * actual_bought_value"), - &self.sold_token_value, - &basic_variables.output_note_variables[0] - .note_variables - .value, + layouter.namespace(|| "expected_sold_quantity * actual_bought_quantity"), + &self.sold_token_quantity, + &basic_variables.output_resource_variables[0] + .resource_variables + .quantity, )?; layouter.assign_region( - || "conditional equal: expected_bought_value * actual_sold_value == expected_sold_value * actual_bought_value", + || "conditional equal: expected_bought_quantity * actual_sold_quantity == expected_sold_quantity * actual_bought_quantity", |mut region| { config.assign_region( &is_partial_fulfillment, - &expected_bought_mul_actual_sold_value, - &expected_sold_mul_actual_bought_value, + &expected_bought_mul_actual_sold_quantity, + &expected_sold_mul_actual_bought_quantity, 0, &mut region, ) diff --git a/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/swap.rs b/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/swap.rs index 40db7c9a..d424677b 100644 --- a/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/swap.rs +++ b/taiga_halo2/src/circuit/vp_examples/partial_fulfillment_intent/swap.rs @@ -1,11 +1,11 @@ -use super::{PartialFulfillmentIntentDataStatic, COMPRESSED_PARTIAL_FULFILLMENT_INTENT_VK}; +use super::{PartialFulfillmentIntentLabel, COMPRESSED_PARTIAL_FULFILLMENT_INTENT_VK}; use crate::{ circuit::{ gadgets::assign_free_advice, - vp_examples::token::{Token, TokenAuthorization, TokenNote, TOKEN_VK}, + vp_examples::token::{Token, TokenAuthorization, TokenResource, TOKEN_VK}, }, - constant::NUM_NOTE, - note::{Note, RandomSeed}, + constant::NUM_RESOURCE, + resource::{RandomSeed, Resource}, utils::poseidon_hash_n, }; use halo2_proofs::arithmetic::Field; @@ -18,7 +18,7 @@ use rand::RngCore; #[derive(Clone, Debug, Default)] pub struct Swap { - pub sell: TokenNote, + pub sell: TokenResource, pub buy: Token, pub auth: TokenAuthorization, } @@ -30,93 +30,95 @@ impl Swap { buy: Token, auth: TokenAuthorization, ) -> Self { - assert_eq!(buy.value() % sell.value(), 0); + assert_eq!(buy.quantity() % sell.quantity(), 0); let sell = { let nk = pallas::Base::random(&mut rng); - sell.create_random_input_token_note(&mut rng, nk, &auth) + sell.create_random_input_token_resource(&mut rng, nk, &auth) }; Swap { sell, buy, auth } } /// Either: - /// - completely fills the swap using a single `TokenNote`, or - /// - partially fills the swap, producing a `TokenNote` and a - /// returned note. + /// - completely fills the swap using a single `TokenResource`, or + /// - partially fills the swap, producing a `TokenResource` and a + /// returned resource. pub fn fill( &self, mut rng: impl RngCore, - intent_note: Note, + intent_resource: Resource, offer: Token, - ) -> ([Note; NUM_NOTE], [Note; NUM_NOTE]) { + ) -> ([Resource; NUM_RESOURCE], [Resource; NUM_RESOURCE]) { assert_eq!(offer.name(), self.buy.name()); - let ratio = self.buy.value() / self.sell.value; - assert_eq!(offer.value() % ratio, 0); + let ratio = self.buy.quantity() / self.sell.quantity; + assert_eq!(offer.quantity() % ratio, 0); - let offer_note = offer.create_random_output_token_note( - self.sell.note().nk_container.get_commitment(), + let offer_resource = offer.create_random_output_token_resource( + self.sell.resource().nk_container.get_npk(), &self.auth, ); - let input_padding_note = Note::random_padding_note(&mut rng); + let input_padding_resource = Resource::random_padding_resource(&mut rng); - let returned_note = if offer.value() < self.buy.value() { - let filled_value = offer.value() / ratio; - let returned_value = self.sell.value - filled_value; - let returned_token = - Token::new(self.sell.token_name().inner().to_string(), returned_value); + let returned_resource = if offer.quantity() < self.buy.quantity() { + let filled_quantity = offer.quantity() / ratio; + let returned_quantity = self.sell.quantity - filled_quantity; + let returned_token = Token::new( + self.sell.token_name().inner().to_string(), + returned_quantity, + ); *returned_token - .create_random_output_token_note( - self.sell.note().nk_container.get_commitment(), + .create_random_output_token_resource( + self.sell.resource().nk_container.get_npk(), &self.auth, ) - .note() + .resource() } else { - Note::random_padding_note(&mut rng) + Resource::random_padding_resource(&mut rng) }; - let input_notes = [intent_note, input_padding_note]; - let output_notes = [*offer_note.note(), returned_note]; + let input_resources = [intent_resource, input_padding_resource]; + let output_resources = [*offer_resource.resource(), returned_resource]; - (input_notes, output_notes) + (input_resources, output_resources) } - pub fn encode_app_data_static(&self) -> pallas::Base { + pub fn encode_label(&self) -> pallas::Base { poseidon_hash_n([ self.sell.encode_name(), - self.sell.encode_value(), + self.sell.encode_quantity(), self.buy.encode_name(), - self.buy.encode_value(), + self.buy.encode_quantity(), // Assuming the sold_token and bought_token have the same TOKEN_VK TOKEN_VK.get_compressed(), - self.sell.note().get_nk_commitment(), - self.sell.note().app_data_dynamic, + self.sell.resource().get_npk(), + self.sell.resource().value, ]) } - pub fn create_intent_note(&self, mut rng: R) -> Note { + pub fn create_intent_resource(&self, mut rng: R) -> Resource { let rseed = RandomSeed::random(&mut rng); - Note::new_input_note( + Resource::new_input_resource( *COMPRESSED_PARTIAL_FULFILLMENT_INTENT_VK, - self.encode_app_data_static(), + self.encode_label(), pallas::Base::zero(), 1u64, - self.sell.note().nk_container.get_nk().unwrap(), - self.sell.note().get_nf().unwrap(), + self.sell.resource().nk_container.get_nk().unwrap(), + self.sell.resource().get_nf().unwrap(), false, rseed, ) } - /// Assign variables encoded in app_static_data - pub fn assign_app_data_static( + /// Assign variables encoded in label + pub fn assign_label( &self, column: Column, mut layouter: impl Layouter, - ) -> Result { + ) -> Result { let token_vp_vk = assign_free_advice( layouter.namespace(|| "witness token vp vk"), column, @@ -129,10 +131,10 @@ impl Swap { Value::known(self.sell.encode_name()), )?; - let sold_token_value = assign_free_advice( - layouter.namespace(|| "witness sold_token_value"), + let sold_token_quantity = assign_free_advice( + layouter.namespace(|| "witness sold_token_quantity"), column, - Value::known(self.sell.encode_value()), + Value::known(self.sell.encode_quantity()), )?; let bought_token = assign_free_advice( @@ -141,32 +143,32 @@ impl Swap { Value::known(self.buy.encode_name()), )?; - let bought_token_value = assign_free_advice( - layouter.namespace(|| "witness bought_token_value"), + let bought_token_quantity = assign_free_advice( + layouter.namespace(|| "witness bought_token_quantity"), column, - Value::known(self.buy.encode_value()), + Value::known(self.buy.encode_quantity()), )?; - let receiver_nk_com = assign_free_advice( - layouter.namespace(|| "witness receiver nk_com"), + let receiver_npk = assign_free_advice( + layouter.namespace(|| "witness receiver npk"), column, - Value::known(self.sell.note().get_nk_commitment()), + Value::known(self.sell.resource().get_npk()), )?; - let receiver_app_data_dynamic = assign_free_advice( - layouter.namespace(|| "witness receiver app_data_dynamic"), + let receiver_value = assign_free_advice( + layouter.namespace(|| "witness receiver value"), column, - Value::known(self.sell.note().app_data_dynamic), + Value::known(self.sell.resource().value), )?; - Ok(PartialFulfillmentIntentDataStatic { + Ok(PartialFulfillmentIntentLabel { token_vp_vk, sold_token, - sold_token_value, + sold_token_quantity, bought_token, - bought_token_value, - receiver_nk_com, - receiver_app_data_dynamic, + bought_token_quantity, + receiver_npk, + receiver_value, }) } } diff --git a/taiga_halo2/src/circuit/vp_examples/receiver_vp.rs b/taiga_halo2/src/circuit/vp_examples/receiver_vp.rs index e9585835..433e6d74 100644 --- a/taiga_halo2/src/circuit/vp_examples/receiver_vp.rs +++ b/taiga_halo2/src/circuit/vp_examples/receiver_vp.rs @@ -3,20 +3,20 @@ use crate::{ blake2s::publicize_default_dynamic_vp_commitments, gadgets::{ add::AddChip, assign_free_advice, poseidon_hash::poseidon_hash_gadget, - target_note_variable::get_owned_note_variable, + target_resource_variable::get_owned_resource_variable, }, - note_encryption_circuit::note_encryption_gadget, + resource_encryption_circuit::resource_encryption_gadget, vp_circuit::{ BasicValidityPredicateVariables, VPVerifyingInfo, ValidityPredicateCircuit, ValidityPredicateConfig, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo, }, vp_examples::signature_verification::COMPRESSED_TOKEN_AUTH_VK, }, - constant::{GENERATOR, NUM_NOTE, SETUP_PARAMS_MAP}, + constant::{GENERATOR, NUM_RESOURCE, SETUP_PARAMS_MAP}, error::TransactionError, - note::{Note, RandomSeed}, - note_encryption::{NoteCiphertext, NotePlaintext, SecretKey}, proof::Proof, + resource::{RandomSeed, Resource}, + resource_encryption::{ResourceCiphertext, ResourcePlaintext, SecretKey}, utils::mod_r_p, vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, @@ -41,14 +41,14 @@ lazy_static! { pub static ref COMPRESSED_RECEIVER_VK: pallas::Base = RECEIVER_VK.get_compressed(); } -// ReceiverValidityPredicateCircuit is used in the token vp as dynamic vp and contains the note encryption constraints. +// ReceiverValidityPredicateCircuit is used in the token vp as dynamic vp and contains the resource encryption constraints. #[derive(Clone, Debug)] pub struct ReceiverValidityPredicateCircuit { - pub owned_note_pub_id: pallas::Base, - pub input_notes: [Note; NUM_NOTE], - pub output_notes: [Note; NUM_NOTE], + pub owned_resource_id: pallas::Base, + pub input_resources: [Resource; NUM_RESOURCE], + pub output_resources: [Resource; NUM_RESOURCE], pub vp_vk: pallas::Base, - pub nonce: pallas::Base, + pub encrypt_nonce: pallas::Base, pub sk: pallas::Base, pub rcv_pk: pallas::Point, pub auth_vp_vk: pallas::Base, @@ -57,11 +57,11 @@ pub struct ReceiverValidityPredicateCircuit { impl Default for ReceiverValidityPredicateCircuit { fn default() -> Self { Self { - owned_note_pub_id: pallas::Base::zero(), - input_notes: [(); NUM_NOTE].map(|_| Note::default()), - output_notes: [(); NUM_NOTE].map(|_| Note::default()), + owned_resource_id: pallas::Base::zero(), + input_resources: [(); NUM_RESOURCE].map(|_| Resource::default()), + output_resources: [(); NUM_RESOURCE].map(|_| Resource::default()), vp_vk: pallas::Base::zero(), - nonce: pallas::Base::zero(), + encrypt_nonce: pallas::Base::zero(), sk: pallas::Base::zero(), rcv_pk: pallas::Point::generator(), auth_vp_vk: pallas::Base::zero(), @@ -77,10 +77,10 @@ impl ValidityPredicateCircuit for ReceiverValidityPredicateCircuit { mut layouter: impl Layouter, basic_variables: BasicValidityPredicateVariables, ) -> Result<(), Error> { - let nonce = assign_free_advice( - layouter.namespace(|| "witness nonce"), + let encrypt_nonce = assign_free_advice( + layouter.namespace(|| "witness encrypt_nonce"), config.advices[0], - Value::known(self.nonce), + Value::known(self.encrypt_nonce), )?; let sk = assign_free_advice( @@ -98,12 +98,12 @@ impl ValidityPredicateCircuit for ReceiverValidityPredicateCircuit { Value::known(self.rcv_pk.to_affine()), )?; - let owned_note_pub_id = basic_variables.get_owned_note_pub_id(); - let app_data_dynamic = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_data_dynamic"), - &owned_note_pub_id, - &basic_variables.get_app_data_dynamic_searchable_pairs(), + let owned_resource_id = basic_variables.get_owned_resource_id(); + let value = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource value"), + &owned_resource_id, + &basic_variables.get_value_searchable_pairs(), )?; let auth_vp_vk = assign_free_advice( @@ -117,10 +117,10 @@ impl ValidityPredicateCircuit for ReceiverValidityPredicateCircuit { Value::known(self.vp_vk), )?; - // Decode the app_data_dynamic, and check the app_data_dynamic encoding - let encoded_app_data_dynamic = poseidon_hash_gadget( + // Decode the value, and check the value encoding + let encoded_value = poseidon_hash_gadget( config.poseidon_config.clone(), - layouter.namespace(|| "app_data_dynamic encoding"), + layouter.namespace(|| "value encoding"), [ rcv_pk.inner().x(), rcv_pk.inner().y(), @@ -130,86 +130,75 @@ impl ValidityPredicateCircuit for ReceiverValidityPredicateCircuit { )?; layouter.assign_region( - || "check app_data_dynamic encoding", - |mut region| { - region.constrain_equal(encoded_app_data_dynamic.cell(), app_data_dynamic.cell()) - }, + || "check value encoding", + |mut region| region.constrain_equal(encoded_value.cell(), value.cell()), )?; - // search target note and get the app_static_data - let app_data_static = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_data_static"), - &owned_note_pub_id, - &basic_variables.get_app_data_static_searchable_pairs(), + // search target resource and get the label + let label = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource label"), + &owned_resource_id, + &basic_variables.get_label_searchable_pairs(), )?; - // search target note and get the app_vk - let app_vk = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_vk"), - &owned_note_pub_id, - &basic_variables.get_app_vk_searchable_pairs(), + // search target resource and get the logic + let logic = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource logic"), + &owned_resource_id, + &basic_variables.get_logic_searchable_pairs(), )?; - // search target note and get the value - let value = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note value"), - &owned_note_pub_id, - &basic_variables.get_value_searchable_pairs(), + // search target resource and get the quantity + let quantity = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource quantity"), + &owned_resource_id, + &basic_variables.get_quantity_searchable_pairs(), )?; - let rho = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note rho"), - &owned_note_pub_id, - &basic_variables.get_rho_searchable_pairs(), + let nonce = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource nonce"), + &owned_resource_id, + &basic_variables.get_nonce_searchable_pairs(), )?; - let nk_com = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note nk_com"), - &owned_note_pub_id, - &basic_variables.get_nk_com_searchable_pairs(), + let npk = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource npk"), + &owned_resource_id, + &basic_variables.get_npk_searchable_pairs(), )?; - let psi = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note psi"), - &owned_note_pub_id, + let psi = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource psi"), + &owned_resource_id, &basic_variables.get_psi_searchable_pairs(), )?; - let rcm = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note psi"), - &owned_note_pub_id, + let rcm = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource psi"), + &owned_resource_id, &basic_variables.get_rcm_searchable_pairs(), )?; - let mut message = vec![ - app_vk, - app_data_static, - app_data_dynamic, - value, - rho, - nk_com, - psi, - rcm, - ]; + let mut message = vec![logic, label, value, quantity, nonce, npk, psi, rcm]; let add_chip = AddChip::::construct(config.add_config.clone(), ()); // Encryption - note_encryption_gadget( - layouter.namespace(|| "note encryption"), + resource_encryption_gadget( + layouter.namespace(|| "resource encryption"), config.advices[0], config.instances, config.poseidon_config, add_chip, ecc_chip, - nonce, + encrypt_nonce, sk, rcv_pk, &mut message, @@ -225,12 +214,12 @@ impl ValidityPredicateCircuit for ReceiverValidityPredicateCircuit { Ok(()) } - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -245,26 +234,27 @@ impl ValidityPredicateCircuit for ReceiverValidityPredicateCircuit { &RandomSeed::random(rng), ); public_inputs.extend(custom_public_input_padding.iter()); - assert_eq!(NUM_NOTE, 2); - let target_note = - if self.get_owned_note_pub_id() == self.get_output_notes()[0].commitment().inner() { - self.get_output_notes()[0] - } else { - self.get_output_notes()[1] - }; + assert_eq!(NUM_RESOURCE, 2); + let target_resource = if self.get_owned_resource_id() + == self.get_output_resources()[0].commitment().inner() + { + self.get_output_resources()[0] + } else { + self.get_output_resources()[1] + }; let message = vec![ - target_note.note_type.app_vk, - target_note.note_type.app_data_static, - target_note.app_data_dynamic, - pallas::Base::from(target_note.value), - target_note.rho.inner(), - target_note.get_nk_commitment(), - target_note.psi, - target_note.rcm, + target_resource.kind.logic, + target_resource.kind.label, + target_resource.value, + pallas::Base::from(target_resource.quantity), + target_resource.nonce.inner(), + target_resource.get_npk(), + target_resource.psi, + target_resource.rcm, ]; - let plaintext = NotePlaintext::padding(&message); + let plaintext = ResourcePlaintext::padding(&message); let key = SecretKey::from_dh_exchange(&self.rcv_pk, &mod_r_p(self.sk)); - let cipher = NoteCiphertext::encrypt(&plaintext, &key, &self.nonce); + let cipher = ResourceCiphertext::encrypt(&plaintext, &key, &self.encrypt_nonce); cipher.inner().iter().for_each(|&c| public_inputs.push(c)); let generator = GENERATOR.to_curve(); @@ -275,8 +265,8 @@ impl ValidityPredicateCircuit for ReceiverValidityPredicateCircuit { public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } @@ -286,35 +276,35 @@ vp_verifying_info_impl!(ReceiverValidityPredicateCircuit); #[test] fn test_halo2_receiver_vp_circuit() { use crate::constant::VP_CIRCUIT_PARAMS_SIZE; - use crate::{note::tests::random_note, utils::poseidon_hash_n}; + use crate::{resource::tests::random_resource, utils::poseidon_hash_n}; use ff::{Field, PrimeField}; use halo2_proofs::dev::MockProver; use rand::rngs::OsRng; let mut rng = OsRng; let (circuit, rcv_sk) = { - let input_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); - let mut output_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); - let nonce = pallas::Base::from_u128(23333u128); + let input_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); + let mut output_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); + let encrypt_nonce = pallas::Base::from_u128(23333u128); let sk = pallas::Base::random(&mut rng); let rcv_sk = pallas::Base::random(&mut rng); let generator = GENERATOR.to_curve(); let rcv_pk = generator * mod_r_p(rcv_sk); let rcv_pk_coord = rcv_pk.to_affine().coordinates().unwrap(); - output_notes[0].app_data_dynamic = poseidon_hash_n([ + output_resources[0].value = poseidon_hash_n([ *rcv_pk_coord.x(), *rcv_pk_coord.y(), *COMPRESSED_TOKEN_AUTH_VK, *COMPRESSED_RECEIVER_VK, ]); - let owned_note_pub_id = output_notes[0].commitment().inner(); + let owned_resource_id = output_resources[0].commitment().inner(); ( ReceiverValidityPredicateCircuit { - owned_note_pub_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, vp_vk: *COMPRESSED_RECEIVER_VK, - nonce, + encrypt_nonce, sk, rcv_pk, auth_vp_vk: *COMPRESSED_TOKEN_AUTH_VK, @@ -333,15 +323,15 @@ fn test_halo2_receiver_vp_circuit() { assert_eq!(prover.verify(), Ok(())); let de_cipher = public_inputs.decrypt(rcv_sk).unwrap(); - assert_eq!(de_cipher[0], circuit.output_notes[0].get_app_vk()); - assert_eq!(de_cipher[1], circuit.output_notes[0].get_app_data_static()); - assert_eq!(de_cipher[2], circuit.output_notes[0].app_data_dynamic); + assert_eq!(de_cipher[0], circuit.output_resources[0].get_logic()); + assert_eq!(de_cipher[1], circuit.output_resources[0].get_label()); + assert_eq!(de_cipher[2], circuit.output_resources[0].value); assert_eq!( de_cipher[3], - pallas::Base::from(circuit.output_notes[0].value) + pallas::Base::from(circuit.output_resources[0].quantity) ); - assert_eq!(de_cipher[4], circuit.output_notes[0].rho.inner()); - assert_eq!(de_cipher[5], circuit.output_notes[0].get_nk_commitment()); - assert_eq!(de_cipher[6], circuit.output_notes[0].get_psi()); - assert_eq!(de_cipher[7], circuit.output_notes[0].get_rcm()); + assert_eq!(de_cipher[4], circuit.output_resources[0].nonce.inner()); + assert_eq!(de_cipher[5], circuit.output_resources[0].get_npk()); + assert_eq!(de_cipher[6], circuit.output_resources[0].get_psi()); + assert_eq!(de_cipher[7], circuit.output_resources[0].get_rcm()); } diff --git a/taiga_halo2/src/circuit/vp_examples/signature_verification.rs b/taiga_halo2/src/circuit/vp_examples/signature_verification.rs index d4a4e766..5bce9e67 100644 --- a/taiga_halo2/src/circuit/vp_examples/signature_verification.rs +++ b/taiga_halo2/src/circuit/vp_examples/signature_verification.rs @@ -3,17 +3,17 @@ use crate::{ blake2s::publicize_default_dynamic_vp_commitments, gadgets::{ assign_free_advice, poseidon_hash::poseidon_hash_gadget, - target_note_variable::get_owned_note_variable, + target_resource_variable::get_owned_resource_variable, }, vp_circuit::{ BasicValidityPredicateVariables, VPVerifyingInfo, ValidityPredicateCircuit, ValidityPredicateConfig, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo, }, }, - constant::{TaigaFixedBasesFull, NUM_NOTE, SETUP_PARAMS_MAP}, + constant::{TaigaFixedBasesFull, NUM_RESOURCE, SETUP_PARAMS_MAP}, error::TransactionError, - note::{Note, RandomSeed}, proof::Proof, + resource::{RandomSeed, Resource}, utils::{mod_r_p, poseidon_hash_n}, vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, @@ -33,8 +33,8 @@ use pasta_curves::{ use rand::rngs::OsRng; use rand::RngCore; -// The message contains the input note nullifiers and output note commitments -const MESSAGE_LEN: usize = NUM_NOTE * 2; +// The message contains the input resource nullifiers and output resource commitments +const MESSAGE_LEN: usize = NUM_RESOURCE * 2; const POSEIDON_HASH_LEN: usize = MESSAGE_LEN + 4; lazy_static! { pub static ref TOKEN_AUTH_VK: ValidityPredicateVerifyingKey = @@ -92,9 +92,9 @@ impl SchnorrSignature { // SignatureVerificationValidityPredicateCircuit uses the schnorr signature. #[derive(Clone, Debug, Default)] pub struct SignatureVerificationValidityPredicateCircuit { - pub owned_note_pub_id: pallas::Base, - pub input_notes: [Note; NUM_NOTE], - pub output_notes: [Note; NUM_NOTE], + pub owned_resource_id: pallas::Base, + pub input_resources: [Resource; NUM_RESOURCE], + pub output_resources: [Resource; NUM_RESOURCE], pub vp_vk: pallas::Base, pub signature: SchnorrSignature, pub receiver_vp_vk: pallas::Base, @@ -102,17 +102,17 @@ pub struct SignatureVerificationValidityPredicateCircuit { impl SignatureVerificationValidityPredicateCircuit { pub fn new( - owned_note_pub_id: pallas::Base, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + owned_resource_id: pallas::Base, + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], vp_vk: pallas::Base, signature: SchnorrSignature, receiver_vp_vk: pallas::Base, ) -> Self { Self { - owned_note_pub_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, vp_vk, signature, receiver_vp_vk, @@ -121,29 +121,29 @@ impl SignatureVerificationValidityPredicateCircuit { pub fn from_sk_and_sign( mut rng: R, - owned_note_pub_id: pallas::Base, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + owned_resource_id: pallas::Base, + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], vp_vk: pallas::Base, sk: pallas::Scalar, receiver_vp_vk: pallas::Base, ) -> Self { - assert_eq!(NUM_NOTE, 2); + assert_eq!(NUM_RESOURCE, 2); let mut message = vec![]; - input_notes + input_resources .iter() - .zip(output_notes.iter()) - .for_each(|(input_note, output_note)| { - let nf = input_note.get_nf().unwrap().inner(); + .zip(output_resources.iter()) + .for_each(|(input_resource, output_resource)| { + let nf = input_resource.get_nf().unwrap().inner(); message.push(nf); - let cm = output_note.commitment(); + let cm = output_resource.commitment(); message.push(cm.inner()); }); let signature = SchnorrSignature::sign(&mut rng, sk, message); Self { - owned_note_pub_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, vp_vk, signature, receiver_vp_vk, @@ -168,13 +168,13 @@ impl ValidityPredicateCircuit for SignatureVerificationValidityPredicateCircuit Value::known(self.signature.pk.to_affine()), )?; - // search target note and get the app_data_dynamic - let owned_note_pub_id = basic_variables.get_owned_note_pub_id(); - let app_data_dynamic = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_data_dynamic"), - &owned_note_pub_id, - &basic_variables.get_app_data_dynamic_searchable_pairs(), + // search target resource and get the value + let owned_resource_id = basic_variables.get_owned_resource_id(); + let value = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource value"), + &owned_resource_id, + &basic_variables.get_value_searchable_pairs(), )?; let auth_vp_vk = assign_free_advice( @@ -188,18 +188,16 @@ impl ValidityPredicateCircuit for SignatureVerificationValidityPredicateCircuit Value::known(self.receiver_vp_vk), )?; - // Decode the app_data_dynamic, and check the app_data_dynamic encoding - let encoded_app_data_dynamic = poseidon_hash_gadget( + // Decode the value, and check the value encoding + let encoded_value = poseidon_hash_gadget( config.poseidon_config.clone(), - layouter.namespace(|| "app_data_dynamic encoding"), + layouter.namespace(|| "value encoding"), [pk.inner().x(), pk.inner().y(), auth_vp_vk, receiver_vp_vk], )?; layouter.assign_region( - || "check app_data_dynamic encoding", - |mut region| { - region.constrain_equal(encoded_app_data_dynamic.cell(), app_data_dynamic.cell()) - }, + || "check value encoding", + |mut region| region.constrain_equal(encoded_value.cell(), value.cell()), )?; let r = NonIdentityPoint::new( @@ -221,9 +219,9 @@ impl ValidityPredicateCircuit for SignatureVerificationValidityPredicateCircuit // Hash(r||P||m) let h_scalar = { - let nfs = basic_variables.get_input_note_nfs(); - let cms = basic_variables.get_output_note_cms(); - assert_eq!(NUM_NOTE, 2); + let nfs = basic_variables.get_input_resource_nfs(); + let cms = basic_variables.get_output_resource_cms(); + assert_eq!(NUM_RESOURCE, 2); let h = poseidon_hash_gadget( config.poseidon_config, layouter.namespace(|| "Poseidon_hash(r, P, m)"), @@ -260,12 +258,12 @@ impl ValidityPredicateCircuit for SignatureVerificationValidityPredicateCircuit Ok(()) } - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { @@ -282,8 +280,8 @@ impl ValidityPredicateCircuit for SignatureVerificationValidityPredicateCircuit public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } @@ -296,24 +294,24 @@ fn test_halo2_sig_verification_vp_circuit() { receiver_vp::COMPRESSED_RECEIVER_VK, token::TokenAuthorization, }; use crate::constant::VP_CIRCUIT_PARAMS_SIZE; - use crate::note::tests::random_note; + use crate::resource::tests::random_resource; use halo2_proofs::dev::MockProver; use rand::rngs::OsRng; let mut rng = OsRng; let circuit = { - let mut input_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); + let mut input_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); + let output_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); let sk = pallas::Scalar::random(&mut rng); let auth_vk = pallas::Base::random(&mut rng); let auth = TokenAuthorization::from_sk_vk(&sk, &auth_vk); - input_notes[0].app_data_dynamic = auth.to_app_data_dynamic(); - let owned_note_pub_id = input_notes[0].get_nf().unwrap().inner(); + input_resources[0].value = auth.to_value(); + let owned_resource_id = input_resources[0].get_nf().unwrap().inner(); SignatureVerificationValidityPredicateCircuit::from_sk_and_sign( &mut rng, - owned_note_pub_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, auth_vk, sk, *COMPRESSED_RECEIVER_VK, diff --git a/taiga_halo2/src/circuit/vp_examples/token.rs b/taiga_halo2/src/circuit/vp_examples/token.rs index 0fd7eb7b..628c76df 100644 --- a/taiga_halo2/src/circuit/vp_examples/token.rs +++ b/taiga_halo2/src/circuit/vp_examples/token.rs @@ -4,7 +4,7 @@ use crate::{ gadgets::{ assign_free_advice, assign_free_constant, poseidon_hash::poseidon_hash_gadget, - target_note_variable::{get_is_input_note_flag, get_owned_note_variable}, + target_resource_variable::{get_is_input_resource_flag, get_owned_resource_variable}, }, vp_circuit::{ BasicValidityPredicateVariables, VPVerifyingInfo, ValidityPredicateCircuit, @@ -16,14 +16,14 @@ use crate::{ }, }, constant::{ - NUM_NOTE, PRF_EXPAND_DYNAMIC_VP_1_CM_R, SETUP_PARAMS_MAP, VP_CIRCUIT_FIRST_DYNAMIC_VP_CM_1, - VP_CIRCUIT_FIRST_DYNAMIC_VP_CM_2, VP_CIRCUIT_SECOND_DYNAMIC_VP_CM_1, - VP_CIRCUIT_SECOND_DYNAMIC_VP_CM_2, + NUM_RESOURCE, PRF_EXPAND_DYNAMIC_VP_1_CM_R, SETUP_PARAMS_MAP, + VP_CIRCUIT_FIRST_DYNAMIC_VP_CM_1, VP_CIRCUIT_FIRST_DYNAMIC_VP_CM_2, + VP_CIRCUIT_SECOND_DYNAMIC_VP_CM_1, VP_CIRCUIT_SECOND_DYNAMIC_VP_CM_2, }, error::TransactionError, - note::{Note, NoteValidityPredicates, RandomSeed}, nullifier::Nullifier, proof::Proof, + resource::{RandomSeed, Resource, ResourceValidityPredicates}, utils::poseidon_hash_n, vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, @@ -65,14 +65,14 @@ impl TokenName { #[derive(Clone, Debug, Default)] pub struct Token { name: TokenName, - value: u64, + quantity: u64, } impl Token { - pub fn new(name: String, value: u64) -> Self { + pub fn new(name: String, quantity: u64) -> Self { Self { name: TokenName(name), - value, + quantity, } } @@ -80,83 +80,83 @@ impl Token { &self.name } - pub fn value(&self) -> u64 { - self.value + pub fn quantity(&self) -> u64 { + self.quantity } pub fn encode_name(&self) -> pallas::Base { self.name.encode() } - pub fn encode_value(&self) -> pallas::Base { - pallas::Base::from(self.value) + pub fn encode_quantity(&self) -> pallas::Base { + pallas::Base::from(self.quantity) } - pub fn create_random_input_token_note( + pub fn create_random_input_token_resource( &self, mut rng: R, nk: pallas::Base, auth: &TokenAuthorization, - ) -> TokenNote { - let app_data_static = self.encode_name(); - let app_data_dynamic = auth.to_app_data_dynamic(); + ) -> TokenResource { + let label = self.encode_name(); + let value = auth.to_value(); let rseed = RandomSeed::random(&mut rng); - let rho = Nullifier::random(&mut rng); - let note = Note::new_input_note( + let nonce = Nullifier::random(&mut rng); + let resource = Resource::new_input_resource( *COMPRESSED_TOKEN_VK, - app_data_static, - app_data_dynamic, - self.value(), + label, + value, + self.quantity(), nk, - rho, + nonce, true, rseed, ); - TokenNote { + TokenResource { token_name: self.name().clone(), - note, + resource, } } - pub fn create_random_output_token_note( + pub fn create_random_output_token_resource( &self, - nk_com: pallas::Base, + npk: pallas::Base, auth: &TokenAuthorization, - ) -> TokenNote { - let app_data_static = self.encode_name(); - let app_data_dynamic = auth.to_app_data_dynamic(); - let note = Note::new_output_note( + ) -> TokenResource { + let label = self.encode_name(); + let value = auth.to_value(); + let resource = Resource::new_output_resource( *COMPRESSED_TOKEN_VK, - app_data_static, - app_data_dynamic, - self.value(), - nk_com, + label, + value, + self.quantity(), + npk, true, ); - TokenNote { + TokenResource { token_name: self.name().clone(), - note, + resource, } } } #[derive(Clone, Debug, Default)] -pub struct TokenNote { +pub struct TokenResource { pub token_name: TokenName, - pub note: Note, + pub resource: Resource, } -impl std::ops::Deref for TokenNote { - type Target = Note; +impl std::ops::Deref for TokenResource { + type Target = Resource; fn deref(&self) -> &Self::Target { - &self.note + &self.resource } } -impl TokenNote { +impl TokenResource { pub fn token_name(&self) -> &TokenName { &self.token_name } @@ -165,12 +165,12 @@ impl TokenNote { self.token_name.encode() } - pub fn encode_value(&self) -> pallas::Base { - pallas::Base::from(self.note().value) + pub fn encode_quantity(&self) -> pallas::Base { + pallas::Base::from(self.resource().quantity) } - pub fn note(&self) -> &Note { - &self.note + pub fn resource(&self) -> &Resource { + &self.resource } pub fn generate_input_token_vps( @@ -178,16 +178,19 @@ impl TokenNote { mut rng: R, auth: TokenAuthorization, auth_sk: pallas::Scalar, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], - ) -> NoteValidityPredicates { - let TokenNote { token_name, note } = self; + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], + ) -> ResourceValidityPredicates { + let TokenResource { + token_name, + resource, + } = self; // token VP - let nf = note.get_nf().unwrap().inner(); + let nf = resource.get_nf().unwrap().inner(); let token_vp = TokenValidityPredicateCircuit { - owned_note_pub_id: nf, - input_notes, - output_notes, + owned_resource_id: nf, + input_resources, + output_resources, token_name: token_name.clone(), auth, receiver_vp_vk: *COMPRESSED_RECEIVER_VK, @@ -198,31 +201,34 @@ impl TokenNote { let token_auth_vp = SignatureVerificationValidityPredicateCircuit::from_sk_and_sign( &mut rng, nf, - input_notes, - output_notes, + input_resources, + output_resources, auth.vk, auth_sk, *COMPRESSED_RECEIVER_VK, ); - NoteValidityPredicates::new(Box::new(token_vp), vec![Box::new(token_auth_vp)]) + ResourceValidityPredicates::new(Box::new(token_vp), vec![Box::new(token_auth_vp)]) } pub fn generate_output_token_vps( &self, mut rng: R, auth: TokenAuthorization, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], - ) -> NoteValidityPredicates { - let TokenNote { token_name, note } = self; + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], + ) -> ResourceValidityPredicates { + let TokenResource { + token_name, + resource, + } = self; - let owned_note_pub_id = note.commitment().inner(); + let owned_resource_id = resource.commitment().inner(); // token VP let token_vp = TokenValidityPredicateCircuit { - owned_note_pub_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, token_name: token_name.clone(), auth, receiver_vp_vk: *COMPRESSED_RECEIVER_VK, @@ -231,29 +237,29 @@ impl TokenNote { // receiver VP let receiver_vp = ReceiverValidityPredicateCircuit { - owned_note_pub_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, vp_vk: *COMPRESSED_RECEIVER_VK, - nonce: pallas::Base::from_u128(rng.gen()), + encrypt_nonce: pallas::Base::from_u128(rng.gen()), sk: pallas::Base::random(&mut rng), rcv_pk: auth.pk, auth_vp_vk: *COMPRESSED_TOKEN_AUTH_VK, }; - NoteValidityPredicates::new(Box::new(token_vp), vec![Box::new(receiver_vp)]) + ResourceValidityPredicates::new(Box::new(token_vp), vec![Box::new(receiver_vp)]) } } // TokenValidityPredicateCircuit #[derive(Clone, Debug)] pub struct TokenValidityPredicateCircuit { - pub owned_note_pub_id: pallas::Base, - pub input_notes: [Note; NUM_NOTE], - pub output_notes: [Note; NUM_NOTE], - // The token_name goes to app_data_static. It can be extended to a list and embedded to app_data_static. + pub owned_resource_id: pallas::Base, + pub input_resources: [Resource; NUM_RESOURCE], + pub output_resources: [Resource; NUM_RESOURCE], + // The token_name goes to label. It can be extended to a list and embedded to label. pub token_name: TokenName, - // The auth goes to app_data_dynamic and defines how to consume and create the note. + // The auth goes to value and defines how to consume and create the resource. pub auth: TokenAuthorization, pub receiver_vp_vk: pallas::Base, // rseed is to generate the randomness for vp commitment @@ -278,9 +284,9 @@ impl Default for TokenAuthorization { impl Default for TokenValidityPredicateCircuit { fn default() -> Self { Self { - owned_note_pub_id: pallas::Base::zero(), - input_notes: [(); NUM_NOTE].map(|_| Note::default()), - output_notes: [(); NUM_NOTE].map(|_| Note::default()), + owned_resource_id: pallas::Base::zero(), + input_resources: [(); NUM_RESOURCE].map(|_| Resource::default()), + output_resources: [(); NUM_RESOURCE].map(|_| Resource::default()), token_name: TokenName("Token_name".to_string()), auth: TokenAuthorization::default(), receiver_vp_vk: pallas::Base::zero(), @@ -297,7 +303,7 @@ impl ValidityPredicateCircuit for TokenValidityPredicateCircuit { mut layouter: impl Layouter, basic_variables: BasicValidityPredicateVariables, ) -> Result<(), Error> { - let owned_note_pub_id = basic_variables.get_owned_note_pub_id(); + let owned_resource_id = basic_variables.get_owned_resource_id(); let token_property = assign_free_advice( layouter.namespace(|| "witness token_property"), @@ -307,18 +313,18 @@ impl ValidityPredicateCircuit for TokenValidityPredicateCircuit { // We can add more constraints on token_property or extend the token_properties. - // search target note and get the app_static_data - let app_data_static = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_data_static"), - &owned_note_pub_id, - &basic_variables.get_app_data_static_searchable_pairs(), + // search target resource and get the label + let label = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource label"), + &owned_resource_id, + &basic_variables.get_label_searchable_pairs(), )?; - // check app_data_static + // check label layouter.assign_region( - || "check app_data_static", - |mut region| region.constrain_equal(token_property.cell(), app_data_static.cell()), + || "check label", + |mut region| region.constrain_equal(token_property.cell(), label.cell()), )?; // Construct an ECC chip @@ -336,12 +342,12 @@ impl ValidityPredicateCircuit for TokenValidityPredicateCircuit { Value::known(self.auth.vk), )?; - // search target note and get the app_data_dynamic - let app_data_dynamic = get_owned_note_variable( - config.get_owned_note_variable_config, - layouter.namespace(|| "get owned note app_data_dynamic"), - &owned_note_pub_id, - &basic_variables.get_app_data_dynamic_searchable_pairs(), + // search target resource and get the value + let value = get_owned_resource_variable( + config.get_owned_resource_variable_config, + layouter.namespace(|| "get owned resource value"), + &owned_resource_id, + &basic_variables.get_value_searchable_pairs(), )?; let receiver_vp_vk = assign_free_advice( @@ -350,10 +356,10 @@ impl ValidityPredicateCircuit for TokenValidityPredicateCircuit { Value::known(self.receiver_vp_vk), )?; - // Decode the app_data_dynamic, and check the app_data_dynamic encoding - let encoded_app_data_dynamic = poseidon_hash_gadget( + // Decode the value, and check the value encoding + let encoded_value = poseidon_hash_gadget( config.poseidon_config, - layouter.namespace(|| "app_data_dynamic encoding"), + layouter.namespace(|| "value encoding"), [ pk.inner().x(), pk.inner().y(), @@ -363,17 +369,15 @@ impl ValidityPredicateCircuit for TokenValidityPredicateCircuit { )?; layouter.assign_region( - || "check app_data_dynamic encoding", - |mut region| { - region.constrain_equal(encoded_app_data_dynamic.cell(), app_data_dynamic.cell()) - }, + || "check value encoding", + |mut region| region.constrain_equal(encoded_value.cell(), value.cell()), )?; // check the is_merkle_checked flag - let is_merkle_checked = get_owned_note_variable( - config.get_owned_note_variable_config, + let is_merkle_checked = get_owned_resource_variable( + config.get_owned_resource_variable_config, layouter.namespace(|| "get is_merkle_checked"), - &owned_note_pub_id, + &owned_resource_id, &basic_variables.get_is_merkle_checked_searchable_pairs(), )?; let constant_one = assign_free_constant( @@ -387,21 +391,21 @@ impl ValidityPredicateCircuit for TokenValidityPredicateCircuit { )?; // VP Commitment - // Commt the sender(authorization method included) vp if it's an input note; - // Commit the receiver(note encryption constraints included) vp if it's an output note. + // Commt the sender(authorization method included) vp if it's an input resource; + // Commit the receiver(resource encryption constraints included) vp if it's an output resource. let first_dynamic_vp = { - let is_input_note = get_is_input_note_flag( - config.get_is_input_note_flag_config, - layouter.namespace(|| "get is_input_note_flag"), - &owned_note_pub_id, - &basic_variables.get_input_note_nfs(), - &basic_variables.get_output_note_cms(), + let is_input_resource = get_is_input_resource_flag( + config.get_is_input_resource_flag_config, + layouter.namespace(|| "get is_input_resource_flag"), + &owned_resource_id, + &basic_variables.get_input_resource_nfs(), + &basic_variables.get_output_resource_cms(), )?; layouter.assign_region( || "conditional select: ", |mut region| { config.conditional_select_config.assign_region( - &is_input_note, + &is_input_resource, &auth_vp_vk, &receiver_vp_vk, 0, @@ -460,18 +464,18 @@ impl ValidityPredicateCircuit for TokenValidityPredicateCircuit { Ok(()) } - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes + fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.input_resources } - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes + fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { + &self.output_resources } fn get_public_inputs(&self, mut rng: impl RngCore) -> ValidityPredicatePublicInputs { let mut public_inputs = self.get_mandatory_public_inputs(); - let dynamic_vp = if self.owned_note_pub_id == self.output_notes[0].commitment().inner() - || self.owned_note_pub_id == self.output_notes[1].commitment().inner() + let dynamic_vp = if self.owned_resource_id == self.output_resources[0].commitment().inner() + || self.owned_resource_id == self.output_resources[1].commitment().inner() { self.receiver_vp_vk } else { @@ -494,8 +498,8 @@ impl ValidityPredicateCircuit for TokenValidityPredicateCircuit { public_inputs.into() } - fn get_owned_note_pub_id(&self) -> pallas::Base { - self.owned_note_pub_id + fn get_owned_resource_id(&self) -> pallas::Base { + self.owned_resource_id } } @@ -514,7 +518,7 @@ impl TokenAuthorization { } } - pub fn to_app_data_dynamic(&self) -> pallas::Base { + pub fn to_value(&self) -> pallas::Base { let pk_coord = self.pk.to_affine().coordinates().unwrap(); poseidon_hash_n::<4>([ *pk_coord.x(), @@ -534,22 +538,22 @@ impl TokenAuthorization { #[test] fn test_halo2_token_vp_circuit() { use crate::constant::VP_CIRCUIT_PARAMS_SIZE; - use crate::note::tests::random_note; + use crate::resource::tests::random_resource; use halo2_proofs::dev::MockProver; use rand::rngs::OsRng; let mut rng = OsRng; let circuit = { - let mut input_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| random_note(&mut rng)); + let mut input_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); + let output_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); let token_name = TokenName("Token_name".to_string()); let auth = TokenAuthorization::random(&mut rng); - input_notes[0].note_type.app_data_static = token_name.encode(); - input_notes[0].app_data_dynamic = auth.to_app_data_dynamic(); + input_resources[0].kind.label = token_name.encode(); + input_resources[0].value = auth.to_value(); TokenValidityPredicateCircuit { - owned_note_pub_id: input_notes[0].get_nf().unwrap().inner(), - input_notes, - output_notes, + owned_resource_id: input_resources[0].get_nf().unwrap().inner(), + input_resources, + output_resources, token_name, auth, receiver_vp_vk: *COMPRESSED_RECEIVER_VK, diff --git a/taiga_halo2/src/constant.rs b/taiga_halo2/src/constant.rs index 0151e592..41711d12 100644 --- a/taiga_halo2/src/constant.rs +++ b/taiga_halo2/src/constant.rs @@ -19,8 +19,8 @@ use lazy_static::lazy_static; use pasta_curves::{group::Curve, pallas, vesta}; use std::collections::HashMap; -/// SWU hash-to-curve personalization for the note commitment generator -pub const NOTE_COMMITMENT_PERSONALIZATION: &str = "Taiga-NoteCommit"; +/// SWU hash-to-curve personalization for the resource commitment generator +pub const RESOURCE_COMMITMENT_PERSONALIZATION: &str = "Taiga-NoteCommit"; pub const TRANSACTION_BINDING_HASH_PERSONALIZATION: &[u8; 16] = b"TxBindingSigHash"; @@ -41,14 +41,14 @@ pub const TAIGA_COMMITMENT_TREE_DEPTH: usize = 32; pub const BASE_BITS_NUM: usize = 255; -/// The number of notes in a (partial)tx. -pub const NUM_NOTE: usize = 2; +/// The number of resources in a (partial)tx. +pub const NUM_RESOURCE: usize = 2; pub const ACTION_NF_PUBLIC_INPUT_ROW_IDX: usize = 0; pub const ACTION_ANCHOR_PUBLIC_INPUT_ROW_IDX: usize = 1; pub const ACTION_OUTPUT_CM_PUBLIC_INPUT_ROW_IDX: usize = 2; -pub const ACTION_NET_VALUE_CM_X_PUBLIC_INPUT_ROW_IDX: usize = 3; -pub const ACTION_NET_VALUE_CM_Y_PUBLIC_INPUT_ROW_IDX: usize = 4; +pub const ACTION_DELTA_CM_X_PUBLIC_INPUT_ROW_IDX: usize = 3; +pub const ACTION_DELTA_CM_Y_PUBLIC_INPUT_ROW_IDX: usize = 4; pub const ACTION_INPUT_VP_CM_1_ROW_IDX: usize = 5; pub const ACTION_INPUT_VP_CM_2_ROW_IDX: usize = 6; pub const ACTION_OUTPUT_VP_CM_1_ROW_IDX: usize = 7; @@ -60,31 +60,32 @@ pub const VALUE_BASE_DOMAIN_POSTFIX: &str = "Taiga-NoteType"; pub const VP_CIRCUIT_PUBLIC_INPUT_NUM: usize = VP_CIRCUIT_MANDATORY_PUBLIC_INPUT_NUM + VP_CIRCUIT_CUSTOM_PUBLIC_INPUT_NUM - + VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_NUM; + + VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_NUM; pub const VP_CIRCUIT_MANDATORY_PUBLIC_INPUT_NUM: usize = 9; pub const VP_CIRCUIT_CUSTOM_PUBLIC_INPUT_NUM: usize = 2; -pub const VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_NUM: usize = NOTE_ENCRYPTION_CIPHERTEXT_NUM + 2; // ciphertext(12) + public_key(2) +pub const VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_NUM: usize = + RESOURCE_ENCRYPTION_CIPHERTEXT_NUM + 2; // ciphertext(12) + public_key(2) pub const VP_CIRCUIT_NULLIFIER_ONE_PUBLIC_INPUT_IDX: usize = 0; pub const VP_CIRCUIT_OUTPUT_CM_ONE_PUBLIC_INPUT_IDX: usize = 1; pub const VP_CIRCUIT_NULLIFIER_TWO_PUBLIC_INPUT_IDX: usize = 2; pub const VP_CIRCUIT_OUTPUT_CM_TWO_PUBLIC_INPUT_IDX: usize = 3; -pub const VP_CIRCUIT_OWNED_NOTE_PUB_ID_PUBLIC_INPUT_IDX: usize = 4; +pub const VP_CIRCUIT_OWNED_RESOURCE_ID_PUBLIC_INPUT_IDX: usize = 4; pub const VP_CIRCUIT_FIRST_DYNAMIC_VP_CM_1: usize = 5; pub const VP_CIRCUIT_FIRST_DYNAMIC_VP_CM_2: usize = 6; pub const VP_CIRCUIT_SECOND_DYNAMIC_VP_CM_1: usize = 7; pub const VP_CIRCUIT_SECOND_DYNAMIC_VP_CM_2: usize = 8; pub const VP_CIRCUIT_CUSTOM_PUBLIC_INPUT_BEGIN_IDX: usize = VP_CIRCUIT_MANDATORY_PUBLIC_INPUT_NUM; -pub const VP_CIRCUIT_NOTE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX: usize = +pub const VP_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_BEGIN_IDX: usize = VP_CIRCUIT_MANDATORY_PUBLIC_INPUT_NUM + VP_CIRCUIT_CUSTOM_PUBLIC_INPUT_NUM; -pub const VP_CIRCUIT_NOTE_ENCRYPTION_NONCE_IDX: usize = 21; -pub const VP_CIRCUIT_NOTE_ENCRYPTION_MAC_IDX: usize = 22; -pub const VP_CIRCUIT_NOTE_ENCRYPTION_PK_X_IDX: usize = 23; -pub const VP_CIRCUIT_NOTE_ENCRYPTION_PK_Y_IDX: usize = 24; +pub const VP_CIRCUIT_RESOURCE_ENCRYPTION_NONCE_IDX: usize = 21; +pub const VP_CIRCUIT_RESOURCE_ENCRYPTION_MAC_IDX: usize = 22; +pub const VP_CIRCUIT_RESOURCE_ENCRYPTION_PK_X_IDX: usize = 23; +pub const VP_CIRCUIT_RESOURCE_ENCRYPTION_PK_Y_IDX: usize = 24; -// Note encryption -pub const NOTE_ENCRYPTION_PLAINTEXT_NUM: usize = 10; -pub const NOTE_ENCRYPTION_CIPHERTEXT_NUM: usize = NOTE_ENCRYPTION_PLAINTEXT_NUM + 2; // msg(10) + MAC(1) + NOUNCE(1) +// Resource encryption +pub const RESOURCE_ENCRYPTION_PLAINTEXT_NUM: usize = 10; +pub const RESOURCE_ENCRYPTION_CIPHERTEXT_NUM: usize = RESOURCE_ENCRYPTION_PLAINTEXT_NUM + 2; // msg(10) + MAC(1) + NOUNCE(1) // Poseidon parameters pub const POSEIDON_RATE: usize = 2; @@ -143,14 +144,14 @@ lazy_static! { // SinsemillaCommit parameters lazy_static! { - pub static ref NOTE_COMMIT_DOMAIN: CommitDomain = - CommitDomain::new(NOTE_COMMITMENT_PERSONALIZATION); - pub static ref NOTE_COMMITMENT_GENERATOR: pallas::Affine = NOTE_COMMIT_DOMAIN.Q().to_affine(); - pub static ref NOTE_COMMITMENT_R_GENERATOR: pallas::Affine = NOTE_COMMIT_DOMAIN.R().to_affine(); + pub static ref RESOURCE_COMMIT_DOMAIN: CommitDomain = + CommitDomain::new(RESOURCE_COMMITMENT_PERSONALIZATION); + pub static ref RESOURCE_COMMITMENT_GENERATOR: pallas::Affine = RESOURCE_COMMIT_DOMAIN.Q().to_affine(); + pub static ref RESOURCE_COMMITMENT_R_GENERATOR: pallas::Affine = RESOURCE_COMMIT_DOMAIN.R().to_affine(); // Generator used in NullifierK and VP pub static ref GENERATOR: pallas::Affine = pallas::Point::generator().to_affine(); // pub static ref R_ZS_AND_US: Vec<(u64, [pallas::Base; H])> = - // find_zs_and_us(*NOTE_COMMITMENT_R_GENERATOR, NUM_WINDOWS).unwrap(); + // find_zs_and_us(*RESOURCE_COMMITMENT_R_GENERATOR, NUM_WINDOWS).unwrap(); // pub static ref R_U: Vec<[[u8; 32]; H]> = R_ZS_AND_US // .iter() // .map(|(_, us)| { @@ -5976,24 +5977,24 @@ pub const GENERATOR_Z: [u64; NUM_WINDOWS] = [ ]; #[derive(Debug, Clone, Eq, PartialEq)] -pub struct NoteCommitmentHashDomain; -impl HashDomains for NoteCommitmentHashDomain { +pub struct ResourceCommitmentHashDomain; +impl HashDomains for ResourceCommitmentHashDomain { fn Q(&self) -> pallas::Affine { - *NOTE_COMMITMENT_GENERATOR + *RESOURCE_COMMITMENT_GENERATOR } } #[derive(Debug, Clone, Eq, PartialEq)] -pub struct NoteCommitmentDomain; -impl CommitDomains - for NoteCommitmentDomain +pub struct ResourceCommitmentDomain; +impl CommitDomains + for ResourceCommitmentDomain { fn r(&self) -> TaigaFixedBasesFull { - TaigaFixedBasesFull::NoteCommitmentR + TaigaFixedBasesFull::ResourceCommitmentR } - fn hash_domain(&self) -> NoteCommitmentHashDomain { - NoteCommitmentHashDomain + fn hash_domain(&self) -> ResourceCommitmentHashDomain { + ResourceCommitmentHashDomain } } @@ -6008,7 +6009,7 @@ impl FixedPoints for TaigaFixedBases { #[derive(Debug, Eq, PartialEq, Clone)] pub enum TaigaFixedBasesFull { - NoteCommitmentR, + ResourceCommitmentR, BaseGenerator, } @@ -6017,21 +6018,21 @@ impl FixedPoint for TaigaFixedBasesFull { fn generator(&self) -> pallas::Affine { match self { - Self::NoteCommitmentR => *NOTE_COMMITMENT_R_GENERATOR, + Self::ResourceCommitmentR => *RESOURCE_COMMITMENT_R_GENERATOR, Self::BaseGenerator => *GENERATOR, } } fn u(&self) -> Vec<[[u8; 32]; H]> { match self { - Self::NoteCommitmentR => R_U.to_vec(), + Self::ResourceCommitmentR => R_U.to_vec(), Self::BaseGenerator => GENERATOR_U.to_vec(), } } fn z(&self) -> Vec { match self { - Self::NoteCommitmentR => R_Z.to_vec(), + Self::ResourceCommitmentR => R_Z.to_vec(), Self::BaseGenerator => GENERATOR_Z.to_vec(), } } @@ -6039,7 +6040,7 @@ impl FixedPoint for TaigaFixedBasesFull { #[derive(Debug, Eq, PartialEq, Clone)] pub enum BaseFieldGenerators { - NoteCommitmentR, + ResourceCommitmentR, BaseGenerator, } @@ -6048,28 +6049,28 @@ impl FixedPoint for BaseFieldGenerators { fn generator(&self) -> pallas::Affine { match self { - Self::NoteCommitmentR => *NOTE_COMMITMENT_R_GENERATOR, + Self::ResourceCommitmentR => *RESOURCE_COMMITMENT_R_GENERATOR, Self::BaseGenerator => *GENERATOR, } } fn u(&self) -> Vec<[[u8; 32]; H]> { match self { - Self::NoteCommitmentR => R_U.to_vec(), + Self::ResourceCommitmentR => R_U.to_vec(), Self::BaseGenerator => GENERATOR_U.to_vec(), } } fn z(&self) -> Vec { match self { - Self::NoteCommitmentR => R_Z.to_vec(), + Self::ResourceCommitmentR => R_Z.to_vec(), Self::BaseGenerator => GENERATOR_Z.to_vec(), } } } // We don't need the short? -// NOTE_COMMITMENT_R_GENERATOR abuse here, replace with a new parameter when needed. +// RESOURCE_COMMITMENT_R_GENERATOR abuse here, replace with a new parameter when needed. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct Short; @@ -6077,7 +6078,7 @@ impl FixedPoint for Short { type FixedScalarKind = ShortScalar; fn generator(&self) -> pallas::Affine { - *NOTE_COMMITMENT_R_GENERATOR + *RESOURCE_COMMITMENT_R_GENERATOR } fn u(&self) -> Vec<[[u8; 32]; H]> { diff --git a/taiga_halo2/src/value_commitment.rs b/taiga_halo2/src/delta_commitment.rs similarity index 57% rename from taiga_halo2/src/value_commitment.rs rename to taiga_halo2/src/delta_commitment.rs index cdbcea3d..27a250de 100644 --- a/taiga_halo2/src/value_commitment.rs +++ b/taiga_halo2/src/delta_commitment.rs @@ -1,5 +1,5 @@ -use crate::constant::NOTE_COMMITMENT_R_GENERATOR; -use crate::note::Note; +use crate::constant::RESOURCE_COMMITMENT_R_GENERATOR; +use crate::resource::Resource; use halo2_proofs::arithmetic::CurveAffine; use pasta_curves::group::cofactor::CofactorCurveAffine; use pasta_curves::group::{Curve, Group, GroupEncoding}; @@ -14,16 +14,20 @@ use serde; #[derive(Copy, Clone, Debug)] #[cfg_attr(feature = "nif", derive(NifTuple))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct ValueCommitment(pallas::Point); - -impl ValueCommitment { - pub fn commit(input_note: &Note, output_note: &Note, blind_r: &pallas::Scalar) -> Self { - let base_input = input_note.get_note_type(); - let base_output = output_note.get_note_type(); - ValueCommitment( - base_input * pallas::Scalar::from(input_note.value) - - base_output * pallas::Scalar::from(output_note.value) - + NOTE_COMMITMENT_R_GENERATOR.to_curve() * blind_r, +pub struct DeltaCommitment(pallas::Point); + +impl DeltaCommitment { + pub fn commit( + input_resource: &Resource, + output_resource: &Resource, + blind_r: &pallas::Scalar, + ) -> Self { + let base_input = input_resource.get_kind(); + let base_output = output_resource.get_kind(); + DeltaCommitment( + base_input * pallas::Scalar::from(input_resource.quantity) + - base_output * pallas::Scalar::from(output_resource.quantity) + + RESOURCE_COMMITMENT_R_GENERATOR.to_curve() * blind_r, ) } @@ -51,7 +55,7 @@ impl ValueCommitment { self.0.to_bytes() } - pub fn from_bytes(bytes: [u8; 32]) -> CtOption { - pallas::Point::from_bytes(&bytes).map(ValueCommitment) + pub fn from_bytes(bytes: [u8; 32]) -> CtOption { + pallas::Point::from_bytes(&bytes).map(DeltaCommitment) } } diff --git a/taiga_halo2/src/error.rs b/taiga_halo2/src/error.rs index 7c5b4c17..3b696593 100644 --- a/taiga_halo2/src/error.rs +++ b/taiga_halo2/src/error.rs @@ -12,10 +12,10 @@ pub enum TransactionError { MissingBindingSignatures, /// Nullifier is not consistent between the action and the vp. InconsistentNullifier, - /// Output note commitment is not consistent between the action and the vp. - InconsistentOutputNoteCommitment, - /// Owned note public id is not consistent between the action and the vp. - InconsistentOwnedNotePubID, + /// Output resource commitment is not consistent between the action and the vp. + InconsistentOutputResourceCommitment, + /// Owned resource id is not consistent between the action and the vp. + InconsistentOwneResourceID, /// IO error IoError(std::io::Error), /// Transparent resource nullifier key is missing @@ -38,11 +38,11 @@ impl Display for TransactionError { InconsistentNullifier => { f.write_str("Nullifier is not consistent between the action and the vp") } - InconsistentOutputNoteCommitment => f.write_str( - "Output note commitment is not consistent between the action and the vp", + InconsistentOutputResourceCommitment => f.write_str( + "Output resource commitment is not consistent between the action and the vp", ), - InconsistentOwnedNotePubID => { - f.write_str("Owned note public id is not consistent between the action and the vp") + InconsistentOwneResourceID => { + f.write_str("Owned resource id is not consistent between the action and the vp") } IoError(e) => f.write_str(&format!("IoError error: {e}")), MissingTransparentResourceNullifierKey => { diff --git a/taiga_halo2/src/executable.rs b/taiga_halo2/src/executable.rs index c7fc3475..2be31744 100644 --- a/taiga_halo2/src/executable.rs +++ b/taiga_halo2/src/executable.rs @@ -1,13 +1,13 @@ use crate::{ - error::TransactionError, merkle_tree::Anchor, note::NoteCommitment, nullifier::Nullifier, - value_commitment::ValueCommitment, + delta_commitment::DeltaCommitment, error::TransactionError, merkle_tree::Anchor, + nullifier::Nullifier, resource::ResourceCommitment, }; // Executable is an unified interface for partial transaction, which is the atomic executable uinit. pub trait Executable { fn execute(&self) -> Result<(), TransactionError>; fn get_nullifiers(&self) -> Vec; - fn get_output_cms(&self) -> Vec; - fn get_value_commitments(&self) -> Vec; + fn get_output_cms(&self) -> Vec; + fn get_delta_commitments(&self) -> Vec; fn get_anchors(&self) -> Vec; } diff --git a/taiga_halo2/src/lib.rs b/taiga_halo2/src/lib.rs index 166bf969..5aa88a66 100644 --- a/taiga_halo2/src/lib.rs +++ b/taiga_halo2/src/lib.rs @@ -5,18 +5,18 @@ pub mod action; pub mod binding_signature; pub mod circuit; pub mod constant; +pub mod delta_commitment; pub mod error; mod executable; pub mod merkle_tree; -pub mod note; -pub mod note_encryption; pub mod nullifier; pub mod proof; +pub mod resource; +pub mod resource_encryption; pub mod shielded_ptx; pub mod taiga_api; pub mod transaction; pub mod transparent_ptx; pub mod utils; -pub mod value_commitment; pub mod vp_commitment; pub mod vp_vk; diff --git a/taiga_halo2/src/merkle_tree.rs b/taiga_halo2/src/merkle_tree.rs index a23d1ba4..1fe05a1d 100644 --- a/taiga_halo2/src/merkle_tree.rs +++ b/taiga_halo2/src/merkle_tree.rs @@ -1,9 +1,9 @@ use std::hash::{Hash, Hasher}; use crate::merkle_tree::LR::{L, R}; -use crate::note::NoteCommitment; +use crate::resource::ResourceCommitment; use crate::utils::poseidon_hash; -use crate::{constant::TAIGA_COMMITMENT_TREE_DEPTH, note::Note}; +use crate::{constant::TAIGA_COMMITMENT_TREE_DEPTH, resource::Resource}; use ff::PrimeField; use halo2_proofs::arithmetic::Field; use pasta_curves::pallas; @@ -19,7 +19,7 @@ use serde; #[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSerialize}; -/// The root of the note commitment Merkletree. +/// The root of the resource commitment Merkletree. #[derive(Eq, PartialEq, Clone, Copy, Debug)] #[cfg_attr(feature = "nif", derive(NifTuple))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -185,14 +185,14 @@ impl From for Node { } } -impl From<&Note> for Node { - fn from(note: &Note) -> Node { - Node(note.commitment().inner()) +impl From<&Resource> for Node { + fn from(resource: &Resource) -> Node { + Node(resource.commitment().inner()) } } -impl From for Node { - fn from(cm: NoteCommitment) -> Node { +impl From for Node { + fn from(cm: ResourceCommitment) -> Node { Node(cm.inner()) } } diff --git a/taiga_halo2/src/nullifier.rs b/taiga_halo2/src/nullifier.rs index 260bee0b..45366ea3 100644 --- a/taiga_halo2/src/nullifier.rs +++ b/taiga_halo2/src/nullifier.rs @@ -1,7 +1,7 @@ use std::hash::Hash; use crate::{ - note::NoteCommitment, + resource::ResourceCommitment, utils::{poseidon_hash_n, prf_nf}, }; use halo2_proofs::arithmetic::Field; @@ -29,23 +29,23 @@ pub struct Nullifier(pallas::Base); #[cfg_attr(feature = "nif", derive(NifTaggedEnum))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum NullifierKeyContainer { - // The NullifierKeyContainer::Commitment is the commitment of NullifierKeyContainer::Key `nk_com = Commitment(nk, 0)` - Commitment(pallas::Base), + // The NullifierKeyContainer::PublicKey is the commitment of NullifierKeyContainer::Key `npk = Commitment(nk, 0)` + PublicKey(pallas::Base), Key(pallas::Base), } impl Nullifier { - // nf = poseidon_hash(nk || \rho || \psi || note_cm), in which note_cm is a field element + // nf = poseidon_hash(nk || nonce || \psi || resource_cm), in which resource_cm is a field element pub fn derive( nk: &NullifierKeyContainer, - rho: &pallas::Base, + nonce: &pallas::Base, psi: &pallas::Base, - cm: &NoteCommitment, + cm: &ResourceCommitment, ) -> Option { match nk { - NullifierKeyContainer::Commitment(_) => None, + NullifierKeyContainer::PublicKey(_) => None, NullifierKeyContainer::Key(key) => { - let nf = Nullifier(poseidon_hash_n([*key, *rho, *psi, cm.inner()])); + let nf = Nullifier(poseidon_hash_n([*key, *nonce, *psi, cm.inner()])); Some(nf) } } @@ -111,8 +111,8 @@ impl NullifierKeyContainer { NullifierKeyContainer::Key(pallas::Base::random(&mut rng)) } - pub fn random_commitment(mut rng: R) -> Self { - NullifierKeyContainer::Commitment(pallas::Base::random(&mut rng)) + pub fn random_npk(mut rng: R) -> Self { + NullifierKeyContainer::PublicKey(pallas::Base::random(&mut rng)) } /// Creates an NullifierKeyContainer::Key. @@ -120,9 +120,9 @@ impl NullifierKeyContainer { NullifierKeyContainer::Key(key) } - /// Creates a NullifierKeyContainer::Commitment. - pub fn from_commitment(cm: pallas::Base) -> Self { - NullifierKeyContainer::Commitment(cm) + /// Creates a NullifierKeyContainer::PublicKey. + pub fn from_npk(cm: pallas::Base) -> Self { + NullifierKeyContainer::PublicKey(cm) } pub fn get_nk(&self) -> Option { @@ -132,9 +132,9 @@ impl NullifierKeyContainer { } } - pub fn get_commitment(&self) -> pallas::Base { + pub fn get_npk(&self) -> pallas::Base { match self { - NullifierKeyContainer::Commitment(v) => *v, + NullifierKeyContainer::PublicKey(v) => *v, NullifierKeyContainer::Key(key) => { // Commitment(nk, zero), use poseidon hash as Commitment. prf_nf(*key, pallas::Base::zero()) @@ -144,10 +144,8 @@ impl NullifierKeyContainer { pub fn to_commitment(&self) -> Self { match self { - NullifierKeyContainer::Commitment(_) => *self, - NullifierKeyContainer::Key(_) => { - NullifierKeyContainer::Commitment(self.get_commitment()) - } + NullifierKeyContainer::PublicKey(_) => *self, + NullifierKeyContainer::Key(_) => NullifierKeyContainer::PublicKey(self.get_npk()), } } } @@ -176,6 +174,6 @@ pub mod tests { } pub fn random_nullifier_key_commitment(mut rng: R) -> NullifierKeyContainer { - NullifierKeyContainer::from_commitment(pallas::Base::random(&mut rng)) + NullifierKeyContainer::from_npk(pallas::Base::random(&mut rng)) } } diff --git a/taiga_halo2/src/note.rs b/taiga_halo2/src/resource.rs similarity index 56% rename from taiga_halo2/src/note.rs rename to taiga_halo2/src/resource.rs index b031dca1..33034dea 100644 --- a/taiga_halo2/src/note.rs +++ b/taiga_halo2/src/resource.rs @@ -4,12 +4,12 @@ use crate::{ vp_examples::{TrivialValidityPredicateCircuit, COMPRESSED_TRIVIAL_VP_VK}, }, constant::{ - NUM_NOTE, POSEIDON_TO_CURVE_INPUT_LEN, PRF_EXPAND_PERSONALIZATION, PRF_EXPAND_PSI, + NUM_RESOURCE, 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::{Anchor, MerklePath, Node}, nullifier::{Nullifier, NullifierKeyContainer}, - shielded_ptx::NoteVPVerifyingInfoSet, + shielded_ptx::ResourceVPVerifyingInfoSet, utils::{poseidon_hash_n, poseidon_to_curve}, }; use blake2b_simd::Params as Blake2bParams; @@ -29,13 +29,13 @@ use serde; #[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSerialize}; -/// A commitment to a note. +/// A commitment to a resource. #[derive(Copy, Debug, Clone, PartialEq, Eq, Default)] #[cfg_attr(feature = "nif", derive(NifTuple))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct NoteCommitment(pallas::Base); +pub struct ResourceCommitment(pallas::Base); -impl NoteCommitment { +impl ResourceCommitment { pub fn inner(&self) -> pallas::Base { self.0 } @@ -45,18 +45,18 @@ impl NoteCommitment { } pub fn from_bytes(bytes: [u8; 32]) -> CtOption { - pallas::Base::from_repr(bytes).map(NoteCommitment) + pallas::Base::from_repr(bytes).map(ResourceCommitment) } } -impl From for NoteCommitment { +impl From for ResourceCommitment { fn from(cm: pallas::Base) -> Self { - NoteCommitment(cm) + ResourceCommitment(cm) } } #[cfg(feature = "borsh")] -impl BorshSerialize for NoteCommitment { +impl BorshSerialize for ResourceCommitment { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { writer.write_all(&self.to_bytes())?; Ok(()) @@ -64,60 +64,60 @@ impl BorshSerialize for NoteCommitment { } #[cfg(feature = "borsh")] -impl BorshDeserialize for NoteCommitment { +impl BorshDeserialize for ResourceCommitment { fn deserialize_reader(reader: &mut R) -> std::io::Result { let mut repr = [0u8; 32]; reader.read_exact(&mut repr)?; let value = Option::from(pallas::Base::from_repr(repr)).ok_or_else(|| { std::io::Error::new( std::io::ErrorKind::InvalidData, - "NoteCommitment value not in field", + "ResourceCommitment value not in field", ) })?; Ok(Self(value)) } } -impl Hash for NoteCommitment { +impl Hash for ResourceCommitment { fn hash(&self, state: &mut H) { self.to_bytes().as_ref().hash(state); } } -/// A note +/// A resource #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] #[cfg_attr(feature = "nif", derive(NifStruct))] -#[cfg_attr(feature = "nif", module = "Taiga.Note")] +#[cfg_attr(feature = "nif", module = "Taiga.Resource")] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Note { - pub note_type: NoteType, - /// app_data_dynamic is the data defined in application vp and will NOT be used to derive type - /// sub-vps and any other data can be encoded to the app_data_dynamic - pub app_data_dynamic: pallas::Base, - /// value denotes the amount of the note. - pub value: u64, +pub struct Resource { + pub kind: ResourceKind, + /// value is the fungible data of the resource + /// sub-vps and any other data can be encoded to the value + pub value: pallas::Base, + /// the quantity of the resource. + pub quantity: u64, /// NullifierKeyContainer contains the nullifier_key or the nullifier_key commitment. pub nk_container: NullifierKeyContainer, - /// old nullifier. Nonce which is a deterministically computed, unique nonce - pub rho: Nullifier, + /// nonce guarantees the uniqueness of the resource computable fields + pub nonce: Nullifier, /// psi is to derive the nullifier pub psi: pallas::Base, - /// rcm is the trapdoor of the note commitment + /// rcm is the trapdoor of the resource commitment pub rcm: pallas::Base, - /// If the is_merkle_checked flag is true, the merkle path authorization(membership) of input note will be checked in ActionProof. + /// If the is_merkle_checked flag is true, the merkle path authorization(membership) of input resource will be checked in ActionProof. pub is_merkle_checked: bool, } -/// The parameters in the NoteType are used to derive note type. +/// The parameters in the ResourceKind are used to derive resource kind. #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] #[cfg_attr(feature = "nif", derive(NifStruct))] -#[cfg_attr(feature = "nif", module = "Taiga.NoteType")] +#[cfg_attr(feature = "nif", module = "Taiga.ResourceKind")] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct NoteType { - /// app_vk is the compressed verifying key of VP - pub app_vk: pallas::Base, - /// app_data_static is the encoded data that is defined in application vp - pub app_data_static: pallas::Base, +pub struct ResourceKind { + /// logic is a hash of a predicate associated with the resource + pub logic: pallas::Base, + /// label specifies the fungibility domain for the resource + pub label: pallas::Base, } #[derive(Copy, Clone, Debug, Default)] @@ -125,130 +125,130 @@ pub struct NoteType { #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))] pub struct RandomSeed([u8; 32]); -/// NoteValidityPredicates includes one application(static) VP and a few dynamic VPs. +/// ResourceValidityPredicates includes one application(static) VP and a few dynamic VPs. #[derive(Clone)] -pub struct NoteValidityPredicates { +pub struct ResourceValidityPredicates { application_vp: Box, dynamic_vps: Vec>, } -impl Note { +impl Resource { #[allow(clippy::too_many_arguments)] - pub fn new_input_note( - app_vk: pallas::Base, - app_data_static: pallas::Base, - app_data_dynamic: pallas::Base, - value: u64, + pub fn new_input_resource( + logic: pallas::Base, + label: pallas::Base, + value: pallas::Base, + quantity: u64, nk: pallas::Base, - rho: Nullifier, + nonce: Nullifier, is_merkle_checked: bool, rseed: RandomSeed, ) -> Self { - let note_type = NoteType::new(app_vk, app_data_static); + let kind = ResourceKind::new(logic, label); Self { - note_type, - app_data_dynamic, + kind, value, + quantity, nk_container: NullifierKeyContainer::Key(nk), is_merkle_checked, - psi: rseed.get_psi(&rho), - rcm: rseed.get_rcm(&rho), - rho, + psi: rseed.get_psi(&nonce), + rcm: rseed.get_rcm(&nonce), + nonce, } } - // The rho, psi, and rcm are not specified until the action is constructed. + // The nonce, psi, and rcm are not specified until the action is constructed. #[allow(clippy::too_many_arguments)] - pub fn new_output_note( - app_vk: pallas::Base, - app_data_static: pallas::Base, - app_data_dynamic: pallas::Base, - value: u64, - nk_com: pallas::Base, + pub fn new_output_resource( + logic: pallas::Base, + label: pallas::Base, + value: pallas::Base, + quantity: u64, + npk: pallas::Base, is_merkle_checked: bool, ) -> Self { - let note_type = NoteType::new(app_vk, app_data_static); + let kind = ResourceKind::new(logic, label); Self { - note_type, - app_data_dynamic, + kind, value, - nk_container: NullifierKeyContainer::Commitment(nk_com), + quantity, + nk_container: NullifierKeyContainer::PublicKey(npk), is_merkle_checked, psi: pallas::Base::default(), rcm: pallas::Base::default(), - rho: Nullifier::default(), + nonce: Nullifier::default(), } } #[allow(clippy::too_many_arguments)] pub fn from_full( - app_vk: pallas::Base, - app_data_static: pallas::Base, - app_data_dynamic: pallas::Base, - value: u64, + logic: pallas::Base, + label: pallas::Base, + value: pallas::Base, + quantity: u64, nk_container: NullifierKeyContainer, - rho: Nullifier, + nonce: Nullifier, is_merkle_checked: bool, psi: pallas::Base, rcm: pallas::Base, ) -> Self { - let note_type = NoteType::new(app_vk, app_data_static); + let kind = ResourceKind::new(logic, label); Self { - note_type, - app_data_dynamic, + kind, value, + quantity, nk_container, is_merkle_checked, psi, rcm, - rho, + nonce, } } - pub fn random_padding_note(mut rng: R) -> Self { - let app_vk = *COMPRESSED_TRIVIAL_VP_VK; - let app_data_static = pallas::Base::random(&mut rng); - let note_type = NoteType::new(app_vk, app_data_static); - let app_data_dynamic = pallas::Base::random(&mut rng); - let rho = Nullifier::from(pallas::Base::random(&mut rng)); + pub fn random_padding_resource(mut rng: R) -> Self { + let logic = *COMPRESSED_TRIVIAL_VP_VK; + let label = pallas::Base::random(&mut rng); + let kind = ResourceKind::new(logic, label); + let value = pallas::Base::random(&mut rng); + let nonce = Nullifier::from(pallas::Base::random(&mut rng)); let nk = NullifierKeyContainer::from_key(pallas::Base::random(&mut rng)); let rseed = RandomSeed::random(&mut rng); - Note { - note_type, - app_data_dynamic, - value: 0, + Resource { + kind, + value, + quantity: 0, nk_container: nk, - rho, - psi: rseed.get_psi(&rho), - rcm: rseed.get_rcm(&rho), + nonce, + psi: rseed.get_psi(&nonce), + rcm: rseed.get_rcm(&nonce), is_merkle_checked: false, } } - // note_commitment = poseidon_hash(app_vk || app_data_static || app_data_dynamic || nk_commitment || rho || psi || is_merkle_checked || value || rcm) - pub fn commitment(&self) -> NoteCommitment { - let compose_is_merkle_checked_value = if self.is_merkle_checked { - pallas::Base::from_u128(1 << 64).square() + pallas::Base::from(self.value) + // resource_commitment = poseidon_hash(logic || label || value || npk || nonce || psi || is_merkle_checked || quantity || rcm) + pub fn commitment(&self) -> ResourceCommitment { + let compose_is_merkle_checked_quantity = if self.is_merkle_checked { + pallas::Base::from_u128(1 << 64).square() + pallas::Base::from(self.quantity) } else { - pallas::Base::from(self.value) + pallas::Base::from(self.quantity) }; let ret = poseidon_hash_n([ - self.get_app_vk(), - self.get_app_data_static(), - self.app_data_dynamic, - self.get_nk_commitment(), - self.rho.inner(), + self.get_logic(), + self.get_label(), + self.value, + self.get_npk(), + self.nonce.inner(), self.psi, - compose_is_merkle_checked_value, + compose_is_merkle_checked_quantity, self.rcm, ]); - NoteCommitment(ret) + ResourceCommitment(ret) } pub fn get_nf(&self) -> Option { Nullifier::derive( &self.nk_container, - &self.rho.inner(), + &self.nonce.inner(), &self.psi, &self.commitment(), ) @@ -258,20 +258,20 @@ impl Note { self.nk_container.get_nk() } - pub fn get_nk_commitment(&self) -> pallas::Base { - self.nk_container.get_commitment() + pub fn get_npk(&self) -> pallas::Base { + self.nk_container.get_npk() } - pub fn get_note_type(&self) -> pallas::Point { - self.note_type.derive_note_type() + pub fn get_kind(&self) -> pallas::Point { + self.kind.derive_kind() } - pub fn get_app_vk(&self) -> pallas::Base { - self.note_type.app_vk + pub fn get_logic(&self) -> pallas::Base { + self.kind.logic } - pub fn get_app_data_static(&self) -> pallas::Base { - self.note_type.app_data_static + pub fn get_label(&self) -> pallas::Base { + self.kind.label } pub fn get_psi(&self) -> pallas::Base { @@ -287,30 +287,30 @@ impl Note { path.root(cm_node) } - pub fn set_rho(&mut self, input_note: &Note, mut rng: R) { + pub fn set_nonce(&mut self, input_resource: &Resource, mut rng: R) { let rseed = RandomSeed::random(&mut rng); - self.rho = input_note.get_nf().unwrap(); - self.psi = rseed.get_psi(&self.rho); - self.rcm = rseed.get_rcm(&self.rho); + self.nonce = input_resource.get_nf().unwrap(); + self.psi = rseed.get_psi(&self.nonce); + self.rcm = rseed.get_rcm(&self.nonce); } } #[cfg(feature = "borsh")] -impl BorshSerialize for Note { +impl BorshSerialize for Resource { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { use byteorder::{LittleEndian, WriteBytesExt}; - // Write app_vk - writer.write_all(&self.note_type.app_vk.to_repr())?; - // Write app_data_static - writer.write_all(&self.note_type.app_data_static.to_repr())?; - // Write app_data_dynamic - writer.write_all(&self.app_data_dynamic.to_repr())?; - // Write note value - writer.write_u64::(self.value)?; + // Write logic + writer.write_all(&self.kind.logic.to_repr())?; + // Write label + writer.write_all(&self.kind.label.to_repr())?; + // Write value + writer.write_all(&self.value.to_repr())?; + // Write resource quantity + writer.write_u64::(self.quantity)?; // Write nk_container match self.nk_container { - NullifierKeyContainer::Commitment(nk) => { + NullifierKeyContainer::PublicKey(nk) => { writer.write_u8(1)?; writer.write_all(&nk.to_repr()) } @@ -319,8 +319,8 @@ impl BorshSerialize for Note { writer.write_all(&nk.to_repr()) } }?; - // Write rho - writer.write_all(&self.rho.to_bytes())?; + // Write nonce + writer.write_all(&self.nonce.to_bytes())?; // Write psi writer.write_all(&self.psi.to_repr())?; // Write rcm @@ -333,31 +333,27 @@ impl BorshSerialize for Note { } #[cfg(feature = "borsh")] -impl BorshDeserialize for Note { +impl BorshDeserialize for Resource { fn deserialize_reader(reader: &mut R) -> std::io::Result { use byteorder::{LittleEndian, ReadBytesExt}; use std::io; - // Read app_vk - let mut app_vk_bytes = [0u8; 32]; - reader.read_exact(&mut app_vk_bytes)?; - let app_vk = Option::from(pallas::Base::from_repr(app_vk_bytes)) - .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "app_vk not in field"))?; - // Read app_data_static - let mut app_data_static_bytes = [0u8; 32]; - reader.read_exact(&mut app_data_static_bytes)?; - let app_data_static = Option::from(pallas::Base::from_repr(app_data_static_bytes)) - .ok_or_else(|| { - io::Error::new(io::ErrorKind::InvalidData, "app_data_static not in field") - })?; - // Read app_data_dynamic - let mut app_data_dynamic_bytes = [0u8; 32]; - reader.read_exact(&mut app_data_dynamic_bytes)?; - let app_data_dynamic = Option::from(pallas::Base::from_repr(app_data_dynamic_bytes)) - .ok_or_else(|| { - io::Error::new(io::ErrorKind::InvalidData, "app_data_dynamic not in field") - })?; - // Read note value - let value = reader.read_u64::()?; + // Read logic + let mut logic_bytes = [0u8; 32]; + reader.read_exact(&mut logic_bytes)?; + let logic = Option::from(pallas::Base::from_repr(logic_bytes)) + .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "logic not in field"))?; + // Read label + let mut label_bytes = [0u8; 32]; + reader.read_exact(&mut label_bytes)?; + let label = Option::from(pallas::Base::from_repr(label_bytes)) + .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "label not in field"))?; + // Read value + let mut value_bytes = [0u8; 32]; + reader.read_exact(&mut value_bytes)?; + let value = Option::from(pallas::Base::from_repr(value_bytes)) + .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "value not in field"))?; + // Read resource quantity + let quantity = reader.read_u64::()?; // Read nk_container let mut nk_container_type = [0u8; 1]; reader.read_exact(&mut nk_container_type)?; @@ -367,15 +363,15 @@ impl BorshDeserialize for Note { let nk = Option::from(pallas::Base::from_repr(nk_container_bytes)) .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "nk not in field"))?; let nk_container = if nk_container_type == 0x01 { - NullifierKeyContainer::from_commitment(nk) + NullifierKeyContainer::from_npk(nk) } else { NullifierKeyContainer::from_key(nk) }; - // Read rho - let mut rho_bytes = [0u8; 32]; - reader.read_exact(&mut rho_bytes)?; - let rho = Option::from(Nullifier::from_bytes(rho_bytes)) - .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "rho not in field"))?; + // Read nonce + let mut nonce_bytes = [0u8; 32]; + reader.read_exact(&mut nonce_bytes)?; + let nonce = Option::from(Nullifier::from_bytes(nonce_bytes)) + .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "nonce not in field"))?; // Read psi let mut psi_bytes = [0u8; 32]; reader.read_exact(&mut psi_bytes)?; @@ -391,14 +387,14 @@ impl BorshDeserialize for Note { reader.read_exact(&mut is_merkle_checked_byte)?; let is_merkle_checked_byte = is_merkle_checked_byte[0]; let is_merkle_checked = is_merkle_checked_byte == 0x01; - // Construct note - Ok(Note::from_full( - app_vk, - app_data_static, - app_data_dynamic, + // Construct resource + Ok(Resource::from_full( + logic, + label, value, + quantity, nk_container, - rho, + nonce, is_merkle_checked, psi, rcm, @@ -406,24 +402,24 @@ impl BorshDeserialize for Note { } } -impl NoteType { +impl ResourceKind { pub fn new(vk: pallas::Base, data: pallas::Base) -> Self { Self { - app_vk: vk, - app_data_static: data, + logic: vk, + label: data, } } - pub fn derive_note_type(&self) -> pallas::Point { - let inputs = [self.app_vk, self.app_data_static]; + pub fn derive_kind(&self) -> pallas::Point { + let inputs = [self.logic, self.label]; poseidon_to_curve::(&inputs) } } -impl Hash for NoteType { +impl Hash for ResourceKind { fn hash(&self, state: &mut H) { - self.app_vk.to_repr().as_ref().hash(state); - self.app_data_static.to_repr().as_ref().hash(state); + self.logic.to_repr().as_ref().hash(state); + self.label.to_repr().as_ref().hash(state); } } @@ -438,26 +434,26 @@ impl RandomSeed { Self(rseed) } - pub fn get_psi(&self, rho: &Nullifier) -> pallas::Base { + pub fn get_psi(&self, nonce: &Nullifier) -> pallas::Base { let mut h = Blake2bParams::new() .hash_length(64) .personal(PRF_EXPAND_PERSONALIZATION) .to_state(); h.update(&[PRF_EXPAND_PSI]); h.update(&self.0); - h.update(&rho.to_bytes()); + h.update(&nonce.to_bytes()); let psi_bytes = *h.finalize().as_array(); pallas::Base::from_uniform_bytes(&psi_bytes) } - pub fn get_rcm(&self, rho: &Nullifier) -> pallas::Base { + pub fn get_rcm(&self, nonce: &Nullifier) -> pallas::Base { let mut h = Blake2bParams::new() .hash_length(64) .personal(PRF_EXPAND_PERSONALIZATION) .to_state(); h.update(&[PRF_EXPAND_RCM]); h.update(&self.0); - h.update(&rho.to_bytes()); + h.update(&nonce.to_bytes()); let rcm_bytes = *h.finalize().as_array(); pallas::Base::from_uniform_bytes(&rcm_bytes) } @@ -500,7 +496,7 @@ impl RandomSeed { } } -impl NoteValidityPredicates { +impl ResourceValidityPredicates { pub fn new( application_vp: Box, dynamic_vps: Vec>, @@ -512,7 +508,7 @@ impl NoteValidityPredicates { } // Generate vp proofs - pub fn build(&self) -> NoteVPVerifyingInfoSet { + pub fn build(&self) -> ResourceVPVerifyingInfoSet { let app_vp_verifying_info = self.application_vp.get_verifying_info(); let app_dynamic_vp_verifying_info = self @@ -521,20 +517,20 @@ impl NoteValidityPredicates { .map(|verifying_info| verifying_info.get_verifying_info()) .collect(); - NoteVPVerifyingInfoSet::new(app_vp_verifying_info, app_dynamic_vp_verifying_info) + ResourceVPVerifyingInfoSet::new(app_vp_verifying_info, app_dynamic_vp_verifying_info) } - // Create an input padding note vps - pub fn create_input_padding_note_vps( - note: &Note, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + // Create an input padding resource vps + pub fn create_input_padding_resource_vps( + resource: &Resource, + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], ) -> Self { - let note_id = note.get_nf().unwrap().inner(); + let owned_resource_id = resource.get_nf().unwrap().inner(); let application_vp = Box::new(TrivialValidityPredicateCircuit::new( - note_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, )); Self { application_vp, @@ -542,17 +538,17 @@ impl NoteValidityPredicates { } } - // Create an output padding note vps - pub fn create_output_padding_note_vps( - note: &Note, - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], + // Create an output padding resource vps + pub fn create_output_padding_resource_vps( + resource: &Resource, + input_resources: [Resource; NUM_RESOURCE], + output_resources: [Resource; NUM_RESOURCE], ) -> Self { - let note_id = note.commitment().inner(); + let owned_resource_id = resource.commitment().inner(); let application_vp = Box::new(TrivialValidityPredicateCircuit::new( - note_id, - input_notes, - output_notes, + owned_resource_id, + input_resources, + output_resources, )); Self { application_vp, @@ -563,77 +559,77 @@ impl NoteValidityPredicates { #[cfg(test)] pub mod tests { - use super::{Note, NoteType, RandomSeed}; + use super::{RandomSeed, Resource, ResourceKind}; use crate::nullifier::tests::*; use halo2_proofs::arithmetic::Field; use pasta_curves::pallas; use rand::{Rng, RngCore}; - pub fn random_note_type(mut rng: R) -> NoteType { - let app_vk = pallas::Base::random(&mut rng); - let app_data_static = pallas::Base::random(&mut rng); - NoteType::new(app_vk, app_data_static) + pub fn random_kind(mut rng: R) -> ResourceKind { + let logic = pallas::Base::random(&mut rng); + let label = pallas::Base::random(&mut rng); + ResourceKind::new(logic, label) } - pub fn random_note(mut rng: R) -> Note { - let rho = random_nullifier(&mut rng); + pub fn random_resource(mut rng: R) -> Resource { + let nonce = random_nullifier(&mut rng); let rseed = RandomSeed::random(&mut rng); - Note { - note_type: random_note_type(&mut rng), - app_data_dynamic: pallas::Base::random(&mut rng), - value: rng.gen(), + Resource { + kind: random_kind(&mut rng), + value: pallas::Base::random(&mut rng), + quantity: rng.gen(), nk_container: random_nullifier_key(&mut rng), is_merkle_checked: true, - psi: rseed.get_psi(&rho), - rcm: rseed.get_rcm(&rho), - rho, + psi: rseed.get_psi(&nonce), + rcm: rseed.get_rcm(&nonce), + nonce, } } #[cfg(feature = "borsh")] #[test] - fn note_borsh_serialization_test() { + fn resource_borsh_serialization_test() { use borsh::BorshDeserialize; use rand::rngs::OsRng; - use crate::note::NoteCommitment; + use crate::resource::ResourceCommitment; let mut rng = OsRng; - let input_note = random_note(&mut rng); + let input_resource = random_resource(&mut rng); { // BorshSerialize - let borsh = borsh::to_vec(&input_note).unwrap(); + let borsh = borsh::to_vec(&input_resource).unwrap(); // BorshDeserialize - let de_note: Note = BorshDeserialize::deserialize(&mut borsh.as_ref()).unwrap(); - assert_eq!(input_note, de_note); + let de_resource: Resource = BorshDeserialize::deserialize(&mut borsh.as_ref()).unwrap(); + assert_eq!(input_resource, de_resource); } - let mut output_note = input_note; + let mut output_resource = input_resource; { - output_note.nk_container = random_nullifier_key_commitment(&mut rng); + output_resource.nk_container = random_nullifier_key_commitment(&mut rng); // BorshSerialize - let borsh = borsh::to_vec(&output_note).unwrap(); + let borsh = borsh::to_vec(&output_resource).unwrap(); // BorshDeserialize - let de_note: Note = BorshDeserialize::deserialize(&mut borsh.as_ref()).unwrap(); - assert_eq!(output_note, de_note); + let de_resource: Resource = BorshDeserialize::deserialize(&mut borsh.as_ref()).unwrap(); + assert_eq!(output_resource, de_resource); } - let icm = input_note.commitment(); + let icm = input_resource.commitment(); { // BorshSerialize let borsh = borsh::to_vec(&icm).unwrap(); // BorshDeserialize - let de_icm: NoteCommitment = + let de_icm: ResourceCommitment = BorshDeserialize::deserialize(&mut borsh.as_ref()).unwrap(); assert_eq!(icm, de_icm); } - let ocm = output_note.commitment(); + let ocm = output_resource.commitment(); { // BorshSerialize let borsh = borsh::to_vec(&ocm).unwrap(); // BorshDeserialize - let de_ocm: NoteCommitment = + let de_ocm: ResourceCommitment = BorshDeserialize::deserialize(&mut borsh.as_ref()).unwrap(); assert_eq!(ocm, de_ocm); } diff --git a/taiga_halo2/src/note_encryption.rs b/taiga_halo2/src/resource_encryption.rs similarity index 75% rename from taiga_halo2/src/note_encryption.rs rename to taiga_halo2/src/resource_encryption.rs index 491b21f1..7e49a710 100644 --- a/taiga_halo2/src/note_encryption.rs +++ b/taiga_halo2/src/resource_encryption.rs @@ -1,5 +1,6 @@ use crate::constant::{ - NOTE_ENCRYPTION_CIPHERTEXT_NUM, NOTE_ENCRYPTION_PLAINTEXT_NUM, POSEIDON_RATE, POSEIDON_WIDTH, + POSEIDON_RATE, POSEIDON_WIDTH, RESOURCE_ENCRYPTION_CIPHERTEXT_NUM, + RESOURCE_ENCRYPTION_PLAINTEXT_NUM, }; use ff::PrimeField; use group::Curve; @@ -8,23 +9,27 @@ use halo2_proofs::arithmetic::CurveAffine; use pasta_curves::pallas; #[derive(Debug, Clone)] -pub struct NoteCiphertext([pallas::Base; NOTE_ENCRYPTION_CIPHERTEXT_NUM]); +pub struct ResourceCiphertext([pallas::Base; RESOURCE_ENCRYPTION_CIPHERTEXT_NUM]); #[derive(Debug, Clone)] -pub struct NotePlaintext([pallas::Base; NOTE_ENCRYPTION_PLAINTEXT_NUM]); +pub struct ResourcePlaintext([pallas::Base; RESOURCE_ENCRYPTION_PLAINTEXT_NUM]); #[derive(Debug, Clone)] pub struct SecretKey(pallas::Point); -impl NoteCiphertext { - pub fn inner(&self) -> &[pallas::Base; NOTE_ENCRYPTION_CIPHERTEXT_NUM] { +impl ResourceCiphertext { + pub fn inner(&self) -> &[pallas::Base; RESOURCE_ENCRYPTION_CIPHERTEXT_NUM] { &self.0 } - pub fn encrypt(message: &NotePlaintext, secret_key: &SecretKey, nonce: &pallas::Base) -> Self { + pub fn encrypt( + message: &ResourcePlaintext, + secret_key: &SecretKey, + encrypt_nonce: &pallas::Base, + ) -> Self { // Init poseidon sponge state let mut poseidon_sponge = - Self::poseidon_sponge_init(message.inner().len(), secret_key, nonce); + Self::poseidon_sponge_init(message.inner().len(), secret_key, encrypt_nonce); // Encrypt let mut cipher = vec![]; @@ -40,8 +45,8 @@ impl NoteCiphertext { } } - // Add nonce - cipher.push(*nonce); + // Add encrypt_nonce + cipher.push(*encrypt_nonce); // Compute the MAC poseidon::permute::<_, poseidon::P128Pow5T3, POSEIDON_WIDTH, POSEIDON_RATE>( @@ -56,9 +61,10 @@ impl NoteCiphertext { pub fn decrypt(&self, secret_key: &SecretKey) -> Option> { let cipher_len = self.0.len(); let mac = self.0[cipher_len - 1]; - let nonce = self.0[cipher_len - 2]; + let encrypt_nonce = self.0[cipher_len - 2]; // Init poseidon sponge state - let mut poseidon_sponge = Self::poseidon_sponge_init(cipher_len - 2, secret_key, &nonce); + let mut poseidon_sponge = + Self::poseidon_sponge_init(cipher_len - 2, secret_key, &encrypt_nonce); // Decrypt let mut msg = vec![]; @@ -91,7 +97,7 @@ impl NoteCiphertext { fn poseidon_sponge_init( message_len: usize, secret_key: &SecretKey, - nonce: &pallas::Base, + encrypt_nonce: &pallas::Base, ) -> poseidon::Sponge< pallas::Base, poseidon::P128Pow5T3, @@ -100,16 +106,16 @@ impl NoteCiphertext { POSEIDON_RATE, > { let key_coord = secret_key.get_coordinates(); - let length_nonce = nonce + let length_nonce = encrypt_nonce + pallas::Base::from(message_len as u64) * pallas::Base::from_u128(1 << 64).square(); let state = [key_coord.0, key_coord.1, length_nonce]; poseidon::Sponge::<_, poseidon::P128Pow5T3, _, POSEIDON_WIDTH, POSEIDON_RATE>::init(state) } } -impl From> for NoteCiphertext { +impl From> for ResourceCiphertext { fn from(input_vec: Vec) -> Self { - NoteCiphertext( + ResourceCiphertext( input_vec .try_into() .expect("public input with incorrect length"), @@ -117,8 +123,8 @@ impl From> for NoteCiphertext { } } -impl NotePlaintext { - pub fn inner(&self) -> &[pallas::Base; NOTE_ENCRYPTION_PLAINTEXT_NUM] { +impl ResourcePlaintext { + pub fn inner(&self) -> &[pallas::Base; RESOURCE_ENCRYPTION_PLAINTEXT_NUM] { &self.0 } @@ -128,16 +134,16 @@ impl NotePlaintext { pub fn padding(msg: &Vec) -> Self { let mut plaintext = msg.clone(); - let padding = - std::iter::repeat(pallas::Base::zero()).take(NOTE_ENCRYPTION_PLAINTEXT_NUM - msg.len()); + let padding = std::iter::repeat(pallas::Base::zero()) + .take(RESOURCE_ENCRYPTION_PLAINTEXT_NUM - msg.len()); plaintext.extend(padding); plaintext.into() } } -impl From> for NotePlaintext { +impl From> for ResourcePlaintext { fn from(input_vec: Vec) -> Self { - NotePlaintext( + ResourcePlaintext( input_vec .try_into() .expect("public input with incorrect length"), @@ -161,7 +167,7 @@ impl SecretKey { } #[test] -fn test_halo2_note_encryption() { +fn test_halo2_resource_encryption() { use ff::Field; use group::Group; use rand::rngs::OsRng; @@ -177,11 +183,11 @@ fn test_halo2_note_encryption() { pallas::Base::one(), pallas::Base::one(), ]; - let plaintext = NotePlaintext::padding(&message.to_vec()); - let nonce = pallas::Base::from_u128(23333u128); + let plaintext = ResourcePlaintext::padding(&message.to_vec()); + let encrypt_nonce = pallas::Base::from_u128(23333u128); // Encryption - let cipher = NoteCiphertext::encrypt(&plaintext, &key, &nonce); + let cipher = ResourceCiphertext::encrypt(&plaintext, &key, &encrypt_nonce); // Decryption let decryption = cipher.decrypt(&key).unwrap(); diff --git a/taiga_halo2/src/shielded_ptx.rs b/taiga_halo2/src/shielded_ptx.rs index f45e1711..301f0f2e 100644 --- a/taiga_halo2/src/shielded_ptx.rs +++ b/taiga_halo2/src/shielded_ptx.rs @@ -2,15 +2,15 @@ use crate::action::{ActionInfo, ActionPublicInputs}; use crate::circuit::vp_circuit::{VPVerifyingInfo, ValidityPredicate}; use crate::constant::{ ACTION_CIRCUIT_PARAMS_SIZE, ACTION_PROVING_KEY, ACTION_VERIFYING_KEY, MAX_DYNAMIC_VP_NUM, - NUM_NOTE, SETUP_PARAMS_MAP, + NUM_RESOURCE, SETUP_PARAMS_MAP, }; +use crate::delta_commitment::DeltaCommitment; use crate::error::TransactionError; use crate::executable::Executable; use crate::merkle_tree::Anchor; -use crate::note::{NoteCommitment, NoteValidityPredicates}; use crate::nullifier::Nullifier; use crate::proof::Proof; -use crate::value_commitment::ValueCommitment; +use crate::resource::{ResourceCommitment, ResourceValidityPredicates}; use halo2_proofs::plonk::Error; use pasta_curves::pallas; use rand::RngCore; @@ -30,9 +30,9 @@ use ff::PrimeField; #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ShieldedPartialTransaction { - actions: [ActionVerifyingInfo; NUM_NOTE], - inputs: [NoteVPVerifyingInfoSet; NUM_NOTE], - outputs: [NoteVPVerifyingInfoSet; NUM_NOTE], + actions: [ActionVerifyingInfo; NUM_RESOURCE], + inputs: [ResourceVPVerifyingInfoSet; NUM_RESOURCE], + outputs: [ResourceVPVerifyingInfoSet; NUM_RESOURCE], binding_sig_r: Option, hints: Vec, } @@ -51,8 +51,8 @@ pub struct ActionVerifyingInfo { #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "nif", derive(NifStruct))] -#[cfg_attr(feature = "nif", module = "Taiga.Note.VerifyingInfo")] -pub struct NoteVPVerifyingInfoSet { +#[cfg_attr(feature = "nif", module = "Taiga.Resource.VerifyingInfo")] +pub struct ResourceVPVerifyingInfoSet { app_vp_verifying_info: VPVerifyingInfo, app_dynamic_vp_verifying_info: Vec, // TODO: add verifier proof and according public inputs. @@ -65,8 +65,8 @@ pub struct NoteVPVerifyingInfoSet { #[cfg_attr(feature = "nif", module = "Taiga.Shielded.PTX")] struct ShieldedPartialTransactionProxy { actions: Vec, - inputs: Vec, - outputs: Vec, + inputs: Vec, + outputs: Vec, binding_sig_r: Option, hints: Vec, } @@ -74,16 +74,16 @@ struct ShieldedPartialTransactionProxy { impl ShieldedPartialTransaction { pub fn from_bytecode( actions: Vec, - input_note_app: Vec, - output_note_app: Vec, + input_resource_app: Vec, + output_resource_app: Vec, hints: Vec, mut rng: R, ) -> Result { - let inputs: Result, _> = input_note_app + let inputs: Result, _> = input_resource_app .into_iter() .map(|bytecode| bytecode.generate_proofs()) .collect(); - let outputs: Result, _> = output_note_app + let outputs: Result, _> = output_resource_app .into_iter() .map(|bytecode| bytecode.generate_proofs()) .collect(); @@ -107,8 +107,8 @@ impl ShieldedPartialTransaction { pub fn build( action_pairs: Vec, - input_note_vps: Vec, - output_note_vps: Vec, + input_resource_vps: Vec, + output_resource_vps: Vec, hints: Vec, mut rng: R, ) -> Result { @@ -123,15 +123,15 @@ impl ShieldedPartialTransaction { .collect(); // Generate input vp proofs - let inputs: Vec = input_note_vps + let inputs: Vec = input_resource_vps .iter() - .map(|input_note_vp| input_note_vp.build()) + .map(|input_resource_vp| input_resource_vp.build()) .collect(); // Generate output vp proofs - let outputs: Vec = output_note_vps + let outputs: Vec = output_resource_vps .iter() - .map(|output_note_vp| output_note_vp.build()) + .map(|output_resource_vp| output_resource_vp.build()) .collect(); Ok(Self { @@ -150,11 +150,11 @@ impl ShieldedPartialTransaction { verifying_info.verify()?; } - // Verify vp proofs from input notes + // Verify vp proofs from input resources for verifying_info in self.inputs.iter() { verifying_info.verify()?; } - // Verify vp proofs from output notes + // Verify vp proofs from output resources for verifying_info in self.outputs.iter() { verifying_info.verify()?; } @@ -164,11 +164,11 @@ impl ShieldedPartialTransaction { // check the nullifiers are from action proofs fn check_nullifiers(&self) -> Result<(), TransactionError> { - assert_eq!(NUM_NOTE, 2); + assert_eq!(NUM_RESOURCE, 2); let action_nfs = self.get_nullifiers(); for vp_info in self.inputs.iter().chain(self.outputs.iter()) { for nfs in vp_info.get_nullifiers().iter() { - // Check the vp actually uses the input notes from action circuits. + // Check the vp actually uses the input resources from action circuits. if !((action_nfs[0].inner() == nfs[0] && action_nfs[1].inner() == nfs[1]) || (action_nfs[0].inner() == nfs[1] && action_nfs[1].inner() == nfs[0])) { @@ -178,49 +178,49 @@ impl ShieldedPartialTransaction { } for (vp_info, action_nf) in self.inputs.iter().zip(action_nfs.iter()) { - // Check the app vp and the sub vps use the same owned_note_id in one note - let owned_note_id = vp_info.app_vp_verifying_info.get_owned_note_pub_id(); + // Check the app vp and the sub vps use the same owned_resource_id in one resource + let owned_resource_id = vp_info.app_vp_verifying_info.get_owned_resource_id(); for logic_vp_verifying_info in vp_info.app_dynamic_vp_verifying_info.iter() { - if owned_note_id != logic_vp_verifying_info.get_owned_note_pub_id() { - return Err(TransactionError::InconsistentOwnedNotePubID); + if owned_resource_id != logic_vp_verifying_info.get_owned_resource_id() { + return Err(TransactionError::InconsistentOwneResourceID); } } - // Check the owned_note_id that vp uses is consistent with the nf from the action circuit - if owned_note_id != action_nf.inner() { - return Err(TransactionError::InconsistentOwnedNotePubID); + // Check the owned_resource_id that vp uses is consistent with the nf from the action circuit + if owned_resource_id != action_nf.inner() { + return Err(TransactionError::InconsistentOwneResourceID); } } Ok(()) } // check the output cms are from action proofs - fn check_note_commitments(&self) -> Result<(), TransactionError> { - assert_eq!(NUM_NOTE, 2); + fn check_resource_commitments(&self) -> Result<(), TransactionError> { + assert_eq!(NUM_RESOURCE, 2); let action_cms = self.get_output_cms(); for vp_info in self.inputs.iter().chain(self.outputs.iter()) { - for cms in vp_info.get_note_commitments().iter() { - // Check the vp actually uses the output notes from action circuits. + for cms in vp_info.get_resource_commitments().iter() { + // Check the vp actually uses the output resources from action circuits. if !((action_cms[0] == cms[0] && action_cms[1] == cms[1]) || (action_cms[0] == cms[1] && action_cms[1] == cms[0])) { - return Err(TransactionError::InconsistentOutputNoteCommitment); + return Err(TransactionError::InconsistentOutputResourceCommitment); } } } for (vp_info, action_cm) in self.outputs.iter().zip(action_cms.iter()) { - // Check that the app vp and the sub vps use the same owned_note_id in one note - let owned_note_id = vp_info.app_vp_verifying_info.get_owned_note_pub_id(); + // Check that the app vp and the sub vps use the same owned_resource_id in one resource + let owned_resource_id = vp_info.app_vp_verifying_info.get_owned_resource_id(); for logic_vp_verifying_info in vp_info.app_dynamic_vp_verifying_info.iter() { - if owned_note_id != logic_vp_verifying_info.get_owned_note_pub_id() { - return Err(TransactionError::InconsistentOwnedNotePubID); + if owned_resource_id != logic_vp_verifying_info.get_owned_resource_id() { + return Err(TransactionError::InconsistentOwneResourceID); } } - // Check the owned_note_id that vp uses is consistent with the cm from the action circuit - if owned_note_id != action_cm.inner() { - return Err(TransactionError::InconsistentOwnedNotePubID); + // Check the owned_resource_id that vp uses is consistent with the cm from the action circuit + if owned_resource_id != action_cm.inner() { + return Err(TransactionError::InconsistentOwneResourceID); } } Ok(()) @@ -270,7 +270,7 @@ impl Executable for ShieldedPartialTransaction { fn execute(&self) -> Result<(), TransactionError> { self.verify_proof()?; self.check_nullifiers()?; - self.check_note_commitments()?; + self.check_resource_commitments()?; Ok(()) } @@ -281,17 +281,17 @@ impl Executable for ShieldedPartialTransaction { .collect() } - fn get_output_cms(&self) -> Vec { + fn get_output_cms(&self) -> Vec { self.actions .iter() .map(|action| action.action_instance.cm) .collect() } - fn get_value_commitments(&self) -> Vec { + fn get_delta_commitments(&self) -> Vec { self.actions .iter() - .map(|action| action.action_instance.cv_net) + .map(|action| action.action_instance.delta) .collect() } @@ -340,14 +340,14 @@ impl BorshSerialize for ShieldedPartialTransaction { impl BorshDeserialize for ShieldedPartialTransaction { fn deserialize_reader(reader: &mut R) -> std::io::Result { use byteorder::ReadBytesExt; - let actions: Vec<_> = (0..NUM_NOTE) + let actions: Vec<_> = (0..NUM_RESOURCE) .map(|_| ActionVerifyingInfo::deserialize_reader(reader)) .collect::>()?; - let inputs: Vec<_> = (0..NUM_NOTE) - .map(|_| NoteVPVerifyingInfoSet::deserialize_reader(reader)) + let inputs: Vec<_> = (0..NUM_RESOURCE) + .map(|_| ResourceVPVerifyingInfoSet::deserialize_reader(reader)) .collect::>()?; - let outputs: Vec<_> = (0..NUM_NOTE) - .map(|_| NoteVPVerifyingInfoSet::deserialize_reader(reader)) + let outputs: Vec<_> = (0..NUM_RESOURCE) + .map(|_| ResourceVPVerifyingInfoSet::deserialize_reader(reader)) .collect::>()?; let binding_sig_r_type = reader.read_u8()?; let binding_sig_r = if binding_sig_r_type == 0 { @@ -418,7 +418,7 @@ impl ActionVerifyingInfo { } } -impl NoteVPVerifyingInfoSet { +impl ResourceVPVerifyingInfoSet { pub fn new( app_vp_verifying_info: VPVerifyingInfo, app_dynamic_vp_verifying_info: Vec, @@ -465,7 +465,7 @@ impl NoteVPVerifyingInfoSet { Ok(()) } - pub fn get_nullifiers(&self) -> Vec<[pallas::Base; NUM_NOTE]> { + pub fn get_nullifiers(&self) -> Vec<[pallas::Base; NUM_RESOURCE]> { let mut nfs = vec![self.app_vp_verifying_info.get_nullifiers()]; self.app_dynamic_vp_verifying_info .iter() @@ -473,11 +473,11 @@ impl NoteVPVerifyingInfoSet { nfs } - pub fn get_note_commitments(&self) -> Vec<[NoteCommitment; NUM_NOTE]> { - let mut cms = vec![self.app_vp_verifying_info.get_note_commitments()]; + pub fn get_resource_commitments(&self) -> Vec<[ResourceCommitment; NUM_RESOURCE]> { + let mut cms = vec![self.app_vp_verifying_info.get_resource_commitments()]; self.app_dynamic_vp_verifying_info .iter() - .for_each(|vp_info| cms.push(vp_info.get_note_commitments())); + .for_each(|vp_info| cms.push(vp_info.get_resource_commitments())); cms } } @@ -490,8 +490,8 @@ pub mod testing { circuit::vp_examples::TrivialValidityPredicateCircuit, constant::TAIGA_COMMITMENT_TREE_DEPTH, merkle_tree::MerklePath, - note::{Note, NoteValidityPredicates, RandomSeed}, nullifier::Nullifier, + resource::{RandomSeed, Resource, ResourceValidityPredicates}, shielded_ptx::ShieldedPartialTransaction, utils::poseidon_hash, }; @@ -502,50 +502,50 @@ pub mod testing { pub fn create_shielded_ptx() -> ShieldedPartialTransaction { let mut rng = OsRng; - // Create empty VP circuit without note info + // Create empty VP circuit without resource info let trivial_vp_circuit = TrivialValidityPredicateCircuit::default(); let trivial_vp_vk = trivial_vp_circuit.get_vp_vk(); let compressed_trivial_vp_vk = trivial_vp_vk.get_compressed(); - // Generate notes - let input_note_1 = { - let app_data_static = pallas::Base::zero(); - // TODO: add real application dynamic VPs and encode them to app_data_dynamic later. + // Generate resources + let input_resource_1 = { + let label = pallas::Base::zero(); + // TODO: add real application dynamic VPs and encode them to value later. let app_dynamic_vp_vk = [compressed_trivial_vp_vk, compressed_trivial_vp_vk]; - // Encode the app_dynamic_vp_vk into app_data_dynamic + // Encode the app_dynamic_vp_vk into value // The encoding method is flexible and defined in the application vp. // Use poseidon hash to encode the two dynamic VPs here - let app_data_dynamic = poseidon_hash(app_dynamic_vp_vk[0], app_dynamic_vp_vk[1]); - let rho = Nullifier::from(pallas::Base::random(&mut rng)); - let value = 5000u64; + let value = poseidon_hash(app_dynamic_vp_vk[0], app_dynamic_vp_vk[1]); + let nonce = Nullifier::from(pallas::Base::random(&mut rng)); + let quantity = 5000u64; let nk = pallas::Base::random(&mut rng); let rseed = RandomSeed::random(&mut rng); let is_merkle_checked = true; - Note::new_input_note( + Resource::new_input_resource( compressed_trivial_vp_vk, - app_data_static, - app_data_dynamic, + label, value, + quantity, nk, - rho, + nonce, is_merkle_checked, rseed, ) }; - let mut output_note_1 = { - let app_data_static = pallas::Base::zero(); - // TODO: add real application dynamic VPs and encode them to app_data_dynamic later. - // If the dynamic VP is not used, set app_data_dynamic pallas::Base::zero() by default. - let app_data_dynamic = pallas::Base::zero(); - let value = 5000u64; - let nk_com = pallas::Base::random(&mut rng); + let mut output_resource_1 = { + let label = pallas::Base::zero(); + // TODO: add real application dynamic VPs and encode them to value later. + // If the dynamic VP is not used, set value pallas::Base::zero() by default. + let value = pallas::Base::zero(); + let quantity = 5000u64; + let npk = pallas::Base::random(&mut rng); let is_merkle_checked = true; - Note::new_output_note( + Resource::new_output_resource( compressed_trivial_vp_vk, - app_data_static, - app_data_dynamic, + label, value, - nk_com, + quantity, + npk, is_merkle_checked, ) }; @@ -553,45 +553,45 @@ pub mod testing { // Construct action pair let merkle_path_1 = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); let action_1 = ActionInfo::new( - input_note_1, + input_resource_1, merkle_path_1, None, - &mut output_note_1, + &mut output_resource_1, &mut rng, ); - // Generate notes - let input_note_2 = { - let app_data_static = pallas::Base::one(); - let app_data_dynamic = pallas::Base::zero(); - let rho = Nullifier::from(pallas::Base::random(&mut rng)); - let value = 10u64; + // Generate resources + let input_resource_2 = { + let label = pallas::Base::one(); + let value = pallas::Base::zero(); + let nonce = Nullifier::from(pallas::Base::random(&mut rng)); + let quantity = 10u64; let nk = pallas::Base::random(&mut rng); let rseed = RandomSeed::random(&mut rng); let is_merkle_checked = true; - Note::new_input_note( + Resource::new_input_resource( compressed_trivial_vp_vk, - app_data_static, - app_data_dynamic, + label, value, + quantity, nk, - rho, + nonce, is_merkle_checked, rseed, ) }; - let mut output_note_2 = { - let app_data_static = pallas::Base::one(); - let app_data_dynamic = pallas::Base::zero(); - let value = 10u64; - let nk_com = pallas::Base::random(&mut rng); + let mut output_resource_2 = { + let label = pallas::Base::one(); + let value = pallas::Base::zero(); + let quantity = 10u64; + let npk = pallas::Base::random(&mut rng); let is_merkle_checked = true; - Note::new_output_note( + Resource::new_output_resource( compressed_trivial_vp_vk, - app_data_static, - app_data_dynamic, + label, value, - nk_com, + quantity, + npk, is_merkle_checked, ) }; @@ -599,44 +599,46 @@ pub mod testing { // Construct action pair let merkle_path_2 = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); let action_2 = ActionInfo::new( - input_note_2, + input_resource_2, merkle_path_2, None, - &mut output_note_2, + &mut output_resource_2, &mut rng, ); - // Create vp circuit and fill the note info + // Create vp circuit and fill the resource info let mut trivial_vp_circuit = TrivialValidityPredicateCircuit { - owned_note_pub_id: input_note_1.get_nf().unwrap().inner(), - input_notes: [input_note_1, input_note_2], - output_notes: [output_note_1, output_note_2], + owned_resource_id: input_resource_1.get_nf().unwrap().inner(), + input_resources: [input_resource_1, input_resource_2], + output_resources: [output_resource_1, output_resource_2], }; let input_application_vp_1 = Box::new(trivial_vp_circuit.clone()); let trivial_app_logic_1: Box = Box::new(trivial_vp_circuit.clone()); let trivial_app_logic_2 = Box::new(trivial_vp_circuit.clone()); let trivial_dynamic_vps = vec![trivial_app_logic_1, trivial_app_logic_2]; - let input_note_1_vps = - NoteValidityPredicates::new(input_application_vp_1, trivial_dynamic_vps); + let input_resource_1_vps = + ResourceValidityPredicates::new(input_application_vp_1, trivial_dynamic_vps); - // The following notes use empty logic vps and use app_data_dynamic with pallas::Base::zero() by default. - trivial_vp_circuit.owned_note_pub_id = input_note_2.get_nf().unwrap().inner(); + // The following resources use empty logic vps and use value with pallas::Base::zero() by default. + trivial_vp_circuit.owned_resource_id = input_resource_2.get_nf().unwrap().inner(); let input_application_vp_2 = Box::new(trivial_vp_circuit.clone()); - let input_note_2_vps = NoteValidityPredicates::new(input_application_vp_2, vec![]); + let input_resource_2_vps = ResourceValidityPredicates::new(input_application_vp_2, vec![]); - trivial_vp_circuit.owned_note_pub_id = output_note_1.commitment().inner(); + trivial_vp_circuit.owned_resource_id = output_resource_1.commitment().inner(); let output_application_vp_1 = Box::new(trivial_vp_circuit.clone()); - let output_note_1_vps = NoteValidityPredicates::new(output_application_vp_1, vec![]); + let output_resource_1_vps = + ResourceValidityPredicates::new(output_application_vp_1, vec![]); - trivial_vp_circuit.owned_note_pub_id = output_note_2.commitment().inner(); + trivial_vp_circuit.owned_resource_id = output_resource_2.commitment().inner(); let output_application_vp_2 = Box::new(trivial_vp_circuit); - let output_note_2_vps = NoteValidityPredicates::new(output_application_vp_2, vec![]); + let output_resource_2_vps = + ResourceValidityPredicates::new(output_application_vp_2, vec![]); // Create shielded partial tx ShieldedPartialTransaction::build( vec![action_1, action_2], - vec![input_note_1_vps, input_note_2_vps], - vec![output_note_1_vps, output_note_2_vps], + vec![input_resource_1_vps, input_resource_2_vps], + vec![output_resource_1_vps, output_resource_2_vps], vec![], &mut rng, ) diff --git a/taiga_halo2/src/taiga_api.rs b/taiga_halo2/src/taiga_api.rs index 6e4084ad..5f32e57e 100644 --- a/taiga_halo2/src/taiga_api.rs +++ b/taiga_halo2/src/taiga_api.rs @@ -4,104 +4,96 @@ use crate::{ }; use crate::{ error::TransactionError, - note::{Note, RandomSeed}, nullifier::Nullifier, + resource::{RandomSeed, Resource}, shielded_ptx::ShieldedPartialTransaction, transaction::{ShieldedPartialTxBundle, Transaction, TransparentPartialTxBundle}, }; use pasta_curves::pallas; use rand::rngs::OsRng; -pub const NOTE_SIZE: usize = 234; +pub const RESOURCE_SIZE: usize = 234; #[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSerialize}; -/// Create a note -/// app_vk is the compressed verifying key of application(static) VP -/// app_data_static is the encoded data that is defined in application vp -/// app_data_dynamic is the data defined in application vp and will NOT be used to derive type -/// value is the quantity of notes +/// Create a resource +/// logic is a hash of a predicate associated with the resource +/// label specifies the fungibility domain for the resource +/// value is the fungible data of the resource /// nk is the nullifier key -/// rho is the old nullifier -/// is_merkle_checked is true for normal notes, false for intent(ephemeral) notes +/// nonce guarantees the uniqueness of the resource computable fields +/// is_merkle_checked is true for normal resources, false for intent(ephemeral) resources /// -/// In practice, input notes are fetched and decrypted from blockchain storage. -/// The create_input_note API is only for test. -pub fn create_input_note( - app_vk: pallas::Base, - app_data_static: pallas::Base, - app_data_dynamic: pallas::Base, - value: u64, +/// In practice, input resources are fetched and decrypted from blockchain storage. +/// The create_input_resource API is only for test. +pub fn create_input_resource( + logic: pallas::Base, + label: pallas::Base, + value: pallas::Base, + quantity: u64, nk: pallas::Base, is_merkle_checked: bool, -) -> Note { +) -> Resource { let rng = OsRng; - let rho = Nullifier::random(rng); + let nonce = Nullifier::random(rng); let rseed = RandomSeed::random(rng); - Note::new_input_note( - app_vk, - app_data_static, - app_data_dynamic, + Resource::new_input_resource( + logic, + label, value, + quantity, nk, - rho, + nonce, is_merkle_checked, rseed, ) } /// -pub fn create_output_note( - app_vk: pallas::Base, - app_data_static: pallas::Base, - app_data_dynamic: pallas::Base, - value: u64, - // The owner of output note has the nullifer key and exposes the nullifier_key commitment to output creator. - nk_com: pallas::Base, +pub fn create_output_resource( + logic: pallas::Base, + label: pallas::Base, + value: pallas::Base, + quantity: u64, + // The owner of output resource has the nullifer key and exposes the nullifier_key commitment to output creator. + npk: pallas::Base, is_merkle_checked: bool, -) -> Note { - Note::new_output_note( - app_vk, - app_data_static, - app_data_dynamic, - value, - nk_com, - is_merkle_checked, - ) +) -> Resource { + Resource::new_output_resource(logic, label, value, quantity, npk, is_merkle_checked) } -/// Note borsh serialization +/// Resource borsh serialization /// -/// Note size: 234 bytes +/// Resource size: 234 bytes /// -/// Note layout: +/// Resource layout: /// | Parameters | type |size(bytes)| /// | - | - | - | -/// | app_vk | pallas::Base | 32 | -/// | app_data_static | pallas::Base | 32 | -/// | app_data_dynamic | pallas::Base | 32 | -/// | value(quantity) | u64 | 8 | +/// | logic | pallas::Base | 32 | +/// | label | pallas::Base | 32 | +/// | value | pallas::Base | 32 | +/// | quantity | u64 | 8 | /// | nk_container type | u8 | 1 | -/// | nk_com/nk | pallas::Base | 32 | -/// | rho | pallas::Base | 32 | +/// | npk | pallas::Base | 32 | +/// | nonce | pallas::Base | 32 | /// | psi | pallas::Base | 32 | /// | rcm | pallas::Base | 32 | /// | is_merkle_checked | u8 | 1 | #[cfg(feature = "borsh")] -pub fn note_serialize(note: &Note) -> std::io::Result> { - let mut result = Vec::with_capacity(NOTE_SIZE); - note.serialize(&mut result)?; +pub fn resource_serialize(resource: &Resource) -> std::io::Result> { + let mut result = Vec::with_capacity(RESOURCE_SIZE); + resource.serialize(&mut result)?; Ok(result) } -/// Note borsh deserialization +/// Resource borsh deserialization #[cfg(feature = "borsh")] -pub fn note_deserialize(bytes: Vec) -> std::io::Result { - if bytes.len() != NOTE_SIZE { +pub fn resource_deserialize(bytes: Vec) -> std::io::Result { + if bytes.len() != RESOURCE_SIZE { return Err(std::io::Error::new( std::io::ErrorKind::InvalidData, - "incorrect note size", + "incorrect resource size", )); } BorshDeserialize::deserialize(&mut bytes.as_ref()) @@ -128,7 +120,7 @@ pub fn note_deserialize(bytes: Vec) -> std::io::Result { /// | binding_sig_r | Option| 1 or (1 + 32) | /// | hints | Vec | - | /// -/// Note: Ultimately, vp proofs won't go to the ptx. It's verifier proofs instead. +/// Resource: Ultimately, vp proofs won't go to the ptx. It's verifier proofs instead. /// The verifier proof may have a much smaller size since the verifier verifying-key /// is a constant and can be cached. #[cfg(feature = "borsh")] @@ -169,12 +161,18 @@ pub fn transaction_deserialize(bytes: Vec) -> std::io::Result { #[cfg(feature = "borsh")] pub fn create_shielded_partial_transaction( actions: Vec, - input_note_app: Vec, - output_note_app: Vec, + input_resource_app: Vec, + output_resource_app: Vec, hints: Vec, ) -> Result { let rng = OsRng; - ShieldedPartialTransaction::from_bytecode(actions, input_note_app, output_note_app, hints, rng) + ShieldedPartialTransaction::from_bytecode( + actions, + input_resource_app, + output_resource_app, + hints, + rng, + ) } /// Create a transaction from partial transactions @@ -227,26 +225,27 @@ pub fn verify_shielded_partial_transaction(ptx_bytes: Vec) -> Result<(), Tra #[cfg(feature = "borsh")] pub mod tests { use crate::{ - note::tests::random_note, nullifier::tests::random_nullifier_key_commitment, taiga_api::*, + nullifier::tests::random_nullifier_key_commitment, resource::tests::random_resource, + taiga_api::*, }; use rand::rngs::OsRng; #[test] - fn note_borsh_serialization_api_test() { + fn resource_borsh_serialization_api_test() { let mut rng = OsRng; - let input_note = random_note(&mut rng); + let input_resource = random_resource(&mut rng); { - let bytes = note_serialize(&input_note).unwrap(); - let de_input_note = note_deserialize(bytes).unwrap(); - assert_eq!(input_note, de_input_note); + let bytes = resource_serialize(&input_resource).unwrap(); + let de_input_resource = resource_deserialize(bytes).unwrap(); + assert_eq!(input_resource, de_input_resource); } { - let mut output_note = input_note; - output_note.nk_container = random_nullifier_key_commitment(&mut rng); - let bytes = note_serialize(&output_note).unwrap(); - let de_output_note = note_deserialize(bytes).unwrap(); - assert_eq!(output_note, de_output_note); + let mut output_resource = input_resource; + output_resource.nk_container = random_nullifier_key_commitment(&mut rng); + let bytes = resource_serialize(&output_resource).unwrap(); + let de_output_resource = resource_deserialize(bytes).unwrap(); + assert_eq!(output_resource, de_output_resource); } } @@ -257,71 +256,71 @@ pub mod tests { use crate::circuit::vp_examples::TrivialValidityPredicateCircuit; use crate::constant::TAIGA_COMMITMENT_TREE_DEPTH; use crate::merkle_tree::MerklePath; - use crate::note::tests::random_note; + use crate::resource::tests::random_resource; let mut rng = OsRng; - // construct notes - let input_note_1 = random_note(&mut rng); - let input_note_1_nf = input_note_1.get_nf().unwrap(); - let mut output_note_1 = random_note(&mut rng); + // construct resources + let input_resource_1 = random_resource(&mut rng); + let input_resource_1_nf = input_resource_1.get_nf().unwrap(); + let mut output_resource_1 = random_resource(&mut rng); let merkle_path_1 = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); let action_1 = ActionInfo::new( - input_note_1, + input_resource_1, merkle_path_1, None, - &mut output_note_1, + &mut output_resource_1, &mut rng, ); - let input_note_2 = random_note(&mut rng); - let input_note_2_nf = input_note_2.get_nf().unwrap(); - let mut output_note_2 = random_note(&mut rng); + let input_resource_2 = random_resource(&mut rng); + let input_resource_2_nf = input_resource_2.get_nf().unwrap(); + let mut output_resource_2 = random_resource(&mut rng); let merkle_path_2 = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); let action_2 = ActionInfo::new( - input_note_2, + input_resource_2, merkle_path_2, None, - &mut output_note_2, + &mut output_resource_2, &mut rng, ); // construct applications - let input_note_1_app = { + let input_resource_1_app = { let app_vp = TrivialValidityPredicateCircuit::new( - input_note_1_nf.inner(), - [input_note_1, input_note_2], - [output_note_1, output_note_2], + input_resource_1_nf.inner(), + [input_resource_1, input_resource_2], + [output_resource_1, output_resource_2], ); ApplicationByteCode::new(app_vp.to_bytecode(), vec![]) }; - let input_note_2_app = { + let input_resource_2_app = { let app_vp = TrivialValidityPredicateCircuit::new( - input_note_2_nf.inner(), - [input_note_1, input_note_2], - [output_note_1, output_note_2], + input_resource_2_nf.inner(), + [input_resource_1, input_resource_2], + [output_resource_1, output_resource_2], ); ApplicationByteCode::new(app_vp.to_bytecode(), vec![]) }; - let output_note_1_app = { + let output_resource_1_app = { let app_vp = TrivialValidityPredicateCircuit::new( - output_note_1.commitment().inner(), - [input_note_1, input_note_2], - [output_note_1, output_note_2], + output_resource_1.commitment().inner(), + [input_resource_1, input_resource_2], + [output_resource_1, output_resource_2], ); ApplicationByteCode::new(app_vp.to_bytecode(), vec![]) }; - let output_note_2_app = { + let output_resource_2_app = { let app_vp = TrivialValidityPredicateCircuit::new( - output_note_2.commitment().inner(), - [input_note_1, input_note_2], - [output_note_1, output_note_2], + output_resource_2.commitment().inner(), + [input_resource_1, input_resource_2], + [output_resource_1, output_resource_2], ); ApplicationByteCode::new(app_vp.to_bytecode(), vec![]) @@ -330,8 +329,8 @@ pub mod tests { // construct ptx let ptx = create_shielded_partial_transaction( vec![action_1, action_2], - vec![input_note_1_app, input_note_2_app], - vec![output_note_1_app, output_note_2_app], + vec![input_resource_1_app, input_resource_2_app], + vec![output_resource_1_app, output_resource_2_app], vec![], ) .unwrap(); diff --git a/taiga_halo2/src/transaction.rs b/taiga_halo2/src/transaction.rs index 09930150..72a0250b 100644 --- a/taiga_halo2/src/transaction.rs +++ b/taiga_halo2/src/transaction.rs @@ -1,13 +1,13 @@ use crate::binding_signature::{BindingSignature, BindingSigningKey, BindingVerificationKey}; use crate::constant::TRANSACTION_BINDING_HASH_PERSONALIZATION; +use crate::delta_commitment::DeltaCommitment; use crate::error::TransactionError; use crate::executable::Executable; use crate::merkle_tree::Anchor; -use crate::note::NoteCommitment; use crate::nullifier::Nullifier; +use crate::resource::ResourceCommitment; use crate::shielded_ptx::ShieldedPartialTransaction; use crate::transparent_ptx::TransparentPartialTransaction; -use crate::value_commitment::ValueCommitment; use blake2b_simd::Params as Blake2bParams; use pasta_curves::{group::Group, pallas}; use rand::{CryptoRng, RngCore}; @@ -40,7 +40,7 @@ pub struct Transaction { pub struct TransactionResult { pub anchors: Vec, pub nullifiers: Vec, - pub output_cms: Vec, + pub output_cms: Vec, } #[derive(Debug, Clone, Default)] @@ -100,13 +100,13 @@ impl Transaction { let mut vk = pallas::Point::identity(); vk = self .shielded_ptx_bundle - .get_value_commitments() + .get_delta_commitments() .iter() .fold(vk, |acc, cv| acc + cv.inner()); vk = self .transparent_ptx_bundle - .get_value_commitments() + .get_delta_commitments() .iter() .fold(vk, |acc, cv| acc + cv.inner()); @@ -128,7 +128,7 @@ impl Transaction { h.update(&cm.to_bytes()); }); shielded_bundle - .get_value_commitments() + .get_delta_commitments() .iter() .for_each(|vc| { h.update(&vc.to_bytes()); @@ -145,7 +145,7 @@ impl Transaction { h.update(&cm.to_bytes()); }); transparent_bundle - .get_value_commitments() + .get_delta_commitments() .iter() .for_each(|vc| { h.update(&vc.to_bytes()); @@ -248,7 +248,7 @@ impl ShieldedPartialTxBundle { partial_tx.execute()?; } - // Return Nullifiers to check double-spent, NoteCommitments to store, anchors to check the root-existence + // Return Nullifiers to check double-spent, ResourceCommitments to store, anchors to check the root-existence Ok(TransactionResult { nullifiers: self.get_nullifiers(), output_cms: self.get_output_cms(), @@ -256,10 +256,10 @@ impl ShieldedPartialTxBundle { }) } - pub fn get_value_commitments(&self) -> Vec { + pub fn get_delta_commitments(&self) -> Vec { self.0 .iter() - .flat_map(|ptx| ptx.get_value_commitments()) + .flat_map(|ptx| ptx.get_delta_commitments()) .collect() } @@ -267,7 +267,7 @@ impl ShieldedPartialTxBundle { self.0.iter().flat_map(|ptx| ptx.get_nullifiers()).collect() } - pub fn get_output_cms(&self) -> Vec { + pub fn get_output_cms(&self) -> Vec { self.0.iter().flat_map(|ptx| ptx.get_output_cms()).collect() } @@ -301,10 +301,10 @@ impl TransparentPartialTxBundle { }) } - pub fn get_value_commitments(&self) -> Vec { + pub fn get_delta_commitments(&self) -> Vec { self.0 .iter() - .flat_map(|ptx| ptx.get_value_commitments()) + .flat_map(|ptx| ptx.get_delta_commitments()) .collect() } @@ -312,7 +312,7 @@ impl TransparentPartialTxBundle { self.0.iter().flat_map(|ptx| ptx.get_nullifiers()).collect() } - pub fn get_output_cms(&self) -> Vec { + pub fn get_output_cms(&self) -> Vec { self.0.iter().flat_map(|ptx| ptx.get_output_cms()).collect() } diff --git a/taiga_halo2/src/transparent_ptx.rs b/taiga_halo2/src/transparent_ptx.rs index b298766d..5a878bab 100644 --- a/taiga_halo2/src/transparent_ptx.rs +++ b/taiga_halo2/src/transparent_ptx.rs @@ -1,7 +1,7 @@ use crate::{ - action::ActionInfo, circuit::vp_bytecode::ApplicationByteCode, constant::NUM_NOTE, - error::TransactionError, executable::Executable, merkle_tree::Anchor, note::NoteCommitment, - nullifier::Nullifier, value_commitment::ValueCommitment, + action::ActionInfo, circuit::vp_bytecode::ApplicationByteCode, constant::NUM_RESOURCE, + delta_commitment::DeltaCommitment, error::TransactionError, executable::Executable, + merkle_tree::Anchor, nullifier::Nullifier, resource::ResourceCommitment, }; use pasta_curves::pallas; @@ -16,26 +16,26 @@ use borsh::{BorshDeserialize, BorshSerialize}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TransparentPartialTransaction { actions: Vec, - input_note_app: Vec, - output_note_app: Vec, + input_resource_app: Vec, + output_resource_app: Vec, hints: Vec, } impl TransparentPartialTransaction { pub fn new( actions: Vec, - input_note_app: Vec, - output_note_app: Vec, + input_resource_app: Vec, + output_resource_app: Vec, hints: Vec, ) -> Self { - assert_eq!(actions.len(), NUM_NOTE); - assert_eq!(input_note_app.len(), NUM_NOTE); - assert_eq!(output_note_app.len(), NUM_NOTE); + assert_eq!(actions.len(), NUM_RESOURCE); + assert_eq!(input_resource_app.len(), NUM_RESOURCE); + assert_eq!(output_resource_app.len(), NUM_RESOURCE); Self { actions, - input_note_app, - output_note_app, + input_resource_app, + output_resource_app, hints, } } @@ -43,22 +43,22 @@ impl TransparentPartialTransaction { impl Executable for TransparentPartialTransaction { fn execute(&self) -> Result<(), TransactionError> { - // check VPs, nullifiers, and note commitments + // check VPs, nullifiers, and resource commitments let action_nfs = self.get_nullifiers(); let action_cms = self.get_output_cms(); - for (vp, nf) in self.input_note_app.iter().zip(action_nfs.iter()) { - let owned_note_id = vp.verify_transparently(&action_nfs, &action_cms)?; - // Check all notes are checked - if owned_note_id != nf.inner() { - return Err(TransactionError::InconsistentOwnedNotePubID); + for (vp, nf) in self.input_resource_app.iter().zip(action_nfs.iter()) { + let owned_resource_id = vp.verify_transparently(&action_nfs, &action_cms)?; + // Check all resources are checked + if owned_resource_id != nf.inner() { + return Err(TransactionError::InconsistentOwneResourceID); } } - for (vp, cm) in self.output_note_app.iter().zip(action_cms.iter()) { - let owned_note_id = vp.verify_transparently(&action_nfs, &action_cms)?; - // Check all notes are checked - if owned_note_id != cm.inner() { - return Err(TransactionError::InconsistentOwnedNotePubID); + for (vp, cm) in self.output_resource_app.iter().zip(action_cms.iter()) { + let owned_resource_id = vp.verify_transparently(&action_nfs, &action_cms)?; + // Check all resources are checked + if owned_resource_id != cm.inner() { + return Err(TransactionError::InconsistentOwneResourceID); } } @@ -69,22 +69,22 @@ impl Executable for TransparentPartialTransaction { fn get_nullifiers(&self) -> Vec { self.actions .iter() - .map(|action| action.get_input_note_nullifer()) + .map(|action| action.get_input_resource_nullifer()) .collect() } // get output cms from actions - fn get_output_cms(&self) -> Vec { + fn get_output_cms(&self) -> Vec { self.actions .iter() - .map(|action| action.get_output_note_cm()) + .map(|action| action.get_output_resource_cm()) .collect() } - fn get_value_commitments(&self) -> Vec { + fn get_delta_commitments(&self) -> Vec { self.actions .iter() - .map(|action| action.get_value_commitment(&pallas::Scalar::zero())) + .map(|action| action.get_delta_commitment(&pallas::Scalar::zero())) .collect() } @@ -103,82 +103,82 @@ impl Executable for TransparentPartialTransaction { pub mod testing { use crate::{ circuit::vp_examples::TrivialValidityPredicateCircuit, - constant::TAIGA_COMMITMENT_TREE_DEPTH, merkle_tree::MerklePath, note::tests::random_note, - transparent_ptx::*, + constant::TAIGA_COMMITMENT_TREE_DEPTH, merkle_tree::MerklePath, + resource::tests::random_resource, transparent_ptx::*, }; use rand::rngs::OsRng; pub fn create_transparent_ptx() -> TransparentPartialTransaction { let mut rng = OsRng; - // construct notes - let input_note_1 = random_note(&mut rng); - let mut output_note_1 = { - let mut note = random_note(&mut rng); - note.note_type = input_note_1.note_type; - note.value = input_note_1.value; - note + // construct resources + let input_resource_1 = random_resource(&mut rng); + let mut output_resource_1 = { + let mut resource = random_resource(&mut rng); + resource.kind = input_resource_1.kind; + resource.quantity = input_resource_1.quantity; + resource }; let merkle_path_1 = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); let action_1 = ActionInfo::new( - input_note_1, + input_resource_1, merkle_path_1, None, - &mut output_note_1, + &mut output_resource_1, &mut rng, ); - let input_note_2 = random_note(&mut rng); - let mut output_note_2 = { - let mut note = random_note(&mut rng); - note.note_type = input_note_2.note_type; - note.value = input_note_2.value; - note + let input_resource_2 = random_resource(&mut rng); + let mut output_resource_2 = { + let mut resource = random_resource(&mut rng); + resource.kind = input_resource_2.kind; + resource.quantity = input_resource_2.quantity; + resource }; let merkle_path_2 = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); let action_2 = ActionInfo::new( - input_note_2, + input_resource_2, merkle_path_2, None, - &mut output_note_2, + &mut output_resource_2, &mut rng, ); // construct applications - let input_note_1_app = { + let input_resource_1_app = { let app_vp = TrivialValidityPredicateCircuit::new( - input_note_1.get_nf().unwrap().inner(), - [input_note_1, input_note_2], - [output_note_1, output_note_2], + input_resource_1.get_nf().unwrap().inner(), + [input_resource_1, input_resource_2], + [output_resource_1, output_resource_2], ); ApplicationByteCode::new(app_vp.to_bytecode(), vec![]) }; - let input_note_2_app = { + let input_resource_2_app = { let app_vp = TrivialValidityPredicateCircuit::new( - input_note_2.get_nf().unwrap().inner(), - [input_note_1, input_note_2], - [output_note_1, output_note_2], + input_resource_2.get_nf().unwrap().inner(), + [input_resource_1, input_resource_2], + [output_resource_1, output_resource_2], ); ApplicationByteCode::new(app_vp.to_bytecode(), vec![]) }; - let output_note_1_app = { + let output_resource_1_app = { let app_vp = TrivialValidityPredicateCircuit::new( - output_note_1.commitment().inner(), - [input_note_1, input_note_2], - [output_note_1, output_note_2], + output_resource_1.commitment().inner(), + [input_resource_1, input_resource_2], + [output_resource_1, output_resource_2], ); ApplicationByteCode::new(app_vp.to_bytecode(), vec![]) }; - let output_note_2_app = { + let output_resource_2_app = { let app_vp = TrivialValidityPredicateCircuit::new( - output_note_2.commitment().inner(), - [input_note_1, input_note_2], - [output_note_1, output_note_2], + output_resource_2.commitment().inner(), + [input_resource_1, input_resource_2], + [output_resource_1, output_resource_2], ); ApplicationByteCode::new(app_vp.to_bytecode(), vec![]) @@ -186,8 +186,8 @@ pub mod testing { TransparentPartialTransaction::new( vec![action_1, action_2], - vec![input_note_1_app, input_note_2_app], - vec![output_note_1_app, output_note_2_app], + vec![input_resource_1_app, input_resource_2_app], + vec![output_resource_1_app, output_resource_2_app], vec![], ) } diff --git a/taiga_halo2/src/utils.rs b/taiga_halo2/src/utils.rs index 206aeed7..bfdcb44f 100644 --- a/taiga_halo2/src/utils.rs +++ b/taiga_halo2/src/utils.rs @@ -28,13 +28,13 @@ pub(crate) fn extract_p(point: &pallas::Point) -> pallas::Base { .unwrap_or_else(pallas::Base::zero) } -/// $PRF^\mathsf{nfOrchard}(nk, \rho) := Poseidon(nk, \rho)$ +/// $PRF^\mathsf{nfOrchard}(nk, nonce) := Poseidon(nk, nonce)$ /// /// Defined in [Zcash Protocol Spec ยง 5.4.2: Pseudo Random Functions][concreteprfs]. /// /// [concreteprfs]: https://zips.z.cash/protocol/nu5.pdf#concreteprfs -pub(crate) fn prf_nf(nk: pallas::Base, rho: pallas::Base) -> pallas::Base { - poseidon_hash(nk, rho) +pub(crate) fn prf_nf(nk: pallas::Base, nonce: pallas::Base) -> pallas::Base { + poseidon_hash(nk, nonce) } pub fn poseidon_hash(left: pallas::Base, right: pallas::Base) -> pallas::Base {