From 77c79d35f5707fea2e450c2af0f030d4d6fac91d Mon Sep 17 00:00:00 2001 From: Song Xuyang Date: Mon, 4 Dec 2023 16:19:47 +0100 Subject: [PATCH] sync with RM: rseed, psi and rcm derivation --- taiga_halo2/benches/compliance_proof.rs | 12 +-- taiga_halo2/benches/vp_proof.rs | 12 +-- .../cascaded_partial_transactions.rs | 6 +- taiga_halo2/examples/tx_examples/token.rs | 2 +- .../tx_examples/token_swap_with_intent.rs | 2 +- taiga_halo2/src/circuit/integrity.rs | 23 +++- taiga_halo2/src/circuit/vp_circuit.rs | 16 +-- .../src/circuit/vp_examples/cascade_intent.rs | 3 +- .../circuit/vp_examples/or_relation_intent.rs | 3 +- .../partial_fulfillment_intent/swap.rs | 6 +- .../src/circuit/vp_examples/receiver_vp.rs | 34 ++++-- taiga_halo2/src/circuit/vp_examples/token.rs | 7 +- taiga_halo2/src/compliance.rs | 2 +- taiga_halo2/src/resource.rs | 101 ++++++------------ taiga_halo2/src/shielded_ptx.rs | 10 +- taiga_halo2/src/taiga_api.rs | 20 ++-- 16 files changed, 124 insertions(+), 135 deletions(-) diff --git a/taiga_halo2/benches/compliance_proof.rs b/taiga_halo2/benches/compliance_proof.rs index ecf3a1e0..654bb53d 100644 --- a/taiga_halo2/benches/compliance_proof.rs +++ b/taiga_halo2/benches/compliance_proof.rs @@ -15,7 +15,7 @@ use taiga_halo2::{ }, merkle_tree::MerklePath, nullifier::{Nullifier, NullifierKeyContainer}, - resource::{RandomSeed, Resource, ResourceKind}, + resource::{Resource, ResourceKind}, }; fn bench_compliance_proof(name: &str, c: &mut Criterion) { @@ -31,16 +31,15 @@ fn bench_compliance_proof(name: &str, c: &mut Criterion) { }; let value = pallas::Base::random(&mut rng); let quantity: u64 = rng.gen(); - let rseed = RandomSeed::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); Resource { kind, value, quantity, nk_container: nk, is_ephemeral: false, - psi: rseed.get_psi(&nonce), - rcm: rseed.get_rcm(&nonce), nonce, + rseed, } }; let mut output_resource = { @@ -53,16 +52,15 @@ fn bench_compliance_proof(name: &str, c: &mut Criterion) { }; let value = pallas::Base::random(&mut rng); let quantity: u64 = rng.gen(); - let rseed = RandomSeed::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); Resource { kind, value, quantity, nk_container: npk, is_ephemeral: false, - psi: rseed.get_psi(&nonce), - rcm: rseed.get_rcm(&nonce), nonce, + rseed, } }; let input_merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); diff --git a/taiga_halo2/benches/vp_proof.rs b/taiga_halo2/benches/vp_proof.rs index 46637580..cf952dd7 100644 --- a/taiga_halo2/benches/vp_proof.rs +++ b/taiga_halo2/benches/vp_proof.rs @@ -10,7 +10,7 @@ use taiga_halo2::{ constant::{NUM_RESOURCE, SETUP_PARAMS_MAP, VP_CIRCUIT_PARAMS_SIZE}, nullifier::{Nullifier, NullifierKeyContainer}, proof::Proof, - resource::{RandomSeed, Resource, ResourceKind}, + resource::{Resource, ResourceKind}, }; fn bench_vp_proof(name: &str, c: &mut Criterion) { @@ -27,16 +27,15 @@ fn bench_vp_proof(name: &str, c: &mut Criterion) { }; let value = pallas::Base::random(&mut rng); let quantity: u64 = rng.gen(); - let rseed = RandomSeed::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); Resource { kind, value, quantity, nk_container: nk, is_ephemeral: false, - psi: rseed.get_psi(&nonce), - rcm: rseed.get_rcm(&nonce), nonce, + rseed, } }); let output_resources = input_resources @@ -51,16 +50,15 @@ fn bench_vp_proof(name: &str, c: &mut Criterion) { }; let value = pallas::Base::random(&mut rng); let quantity: u64 = rng.gen(); - let rseed = RandomSeed::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); Resource { kind, value, quantity, nk_container: npk, is_ephemeral: false, - psi: rseed.get_psi(&nonce), - rcm: rseed.get_rcm(&nonce), nonce, + rseed, } }) .collect::>(); diff --git a/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs b/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs index f08c0911..b93879d3 100644 --- a/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs +++ b/taiga_halo2/examples/tx_examples/cascaded_partial_transactions.rs @@ -31,7 +31,7 @@ pub fn create_transaction(mut rng: R) -> Transaction { 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_resource_1 = - output_token_1.create_random_output_token_resource(bob_npk, &bob_auth); + output_token_1.create_random_output_token_resource(&mut rng, bob_npk, &bob_auth); let input_token_2 = Token::new("eth".to_string(), 2u64); let input_resource_2 = input_token_2.create_random_input_token_resource(&mut rng, alice_nk, &alice_auth); @@ -43,10 +43,10 @@ pub fn create_transaction(mut rng: R) -> Transaction { 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_resource_2 = - output_token_2.create_random_output_token_resource(bob_npk, &bob_auth); + output_token_2.create_random_output_token_resource(&mut rng, bob_npk, &bob_auth); let output_token_3 = Token::new("xan".to_string(), 3u64); let mut output_resource_3 = - output_token_3.create_random_output_token_resource(bob_npk, &bob_auth); + output_token_3.create_random_output_token_resource(&mut rng, bob_npk, &bob_auth); let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); diff --git a/taiga_halo2/examples/tx_examples/token.rs b/taiga_halo2/examples/tx_examples/token.rs index 1202d27f..68a829ac 100644 --- a/taiga_halo2/examples/tx_examples/token.rs +++ b/taiga_halo2/examples/tx_examples/token.rs @@ -34,7 +34,7 @@ pub fn create_token_swap_ptx( // output resource let output_auth = TokenAuthorization::new(output_auth_pk, *COMPRESSED_TOKEN_AUTH_VK); let mut output_resource = - output_token.create_random_output_token_resource(output_npk, &output_auth); + output_token.create_random_output_token_resource(&mut rng, output_npk, &output_auth); // padding the zero resources let padding_input_resource = Resource::random_padding_resource(&mut rng); 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 8ee10ef7..3cbd3b88 100644 --- a/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs +++ b/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs @@ -163,7 +163,7 @@ pub fn consume_token_intent_ptx( let output_auth = TokenAuthorization::new(output_auth_pk, *COMPRESSED_TOKEN_AUTH_VK); 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); + output_token.create_random_output_token_resource(&mut rng, output_npk, &output_auth); // padding the zero resources let padding_input_resource = Resource::random_padding_resource(&mut rng); diff --git a/taiga_halo2/src/circuit/integrity.rs b/taiga_halo2/src/circuit/integrity.rs index f9410770..3aa1a9b6 100644 --- a/taiga_halo2/src/circuit/integrity.rs +++ b/taiga_halo2/src/circuit/integrity.rs @@ -104,6 +104,15 @@ pub fn check_input_resource( Value::known(input_resource.nonce.inner()), )?; + // Witness rseed + let rseed = assign_free_advice( + layouter.namespace(|| "witness rseed"), + advices[0], + Value::known(input_resource.rseed), + )?; + + // We don't need the constraints on psi and rcm derivation for input resource. + // If the psi and rcm are not correct, the existence checking would fail. // Witness psi let psi = assign_free_advice( layouter.namespace(|| "witness psi_input"), @@ -162,8 +171,7 @@ pub fn check_input_resource( value, nonce, npk, - psi, - rcm, + rseed, }; Ok(InputResourceVariables { @@ -218,6 +226,14 @@ pub fn check_output_resource( output_resource.quantity, )?; + // Witness rseed + let rseed = assign_free_advice( + layouter.namespace(|| "witness rseed"), + advices[0], + Value::known(output_resource.rseed), + )?; + + // TODO: constrain on psi and rcm derivation // Witness rcm let rcm = assign_free_advice( layouter.namespace(|| "witness rcm"), @@ -266,8 +282,7 @@ pub fn check_output_resource( value, nonce: old_nf, npk, - psi, - rcm, + rseed, }; Ok(OutputResourceVariables { diff --git a/taiga_halo2/src/circuit/vp_circuit.rs b/taiga_halo2/src/circuit/vp_circuit.rs index 7f3b5f88..e6769def 100644 --- a/taiga_halo2/src/circuit/vp_circuit.rs +++ b/taiga_halo2/src/circuit/vp_circuit.rs @@ -575,8 +575,7 @@ pub struct ResourceVariables { pub value: AssignedCell, pub nonce: AssignedCell, pub npk: AssignedCell, - pub psi: AssignedCell, - pub rcm: AssignedCell, + pub rseed: AssignedCell, } // Variables in the input resource @@ -708,17 +707,10 @@ impl BasicValidityPredicateVariables { ) } - pub fn get_psi_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { + pub fn get_rseed_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { self.get_variable_searchable_pairs( - |variables| variables.resource_variables.psi.clone(), - |variables| variables.resource_variables.psi.clone(), - ) - } - - pub fn get_rcm_searchable_pairs(&self) -> [ResourceSearchableVariablePair; NUM_RESOURCE * 2] { - self.get_variable_searchable_pairs( - |variables| variables.resource_variables.rcm.clone(), - |variables| variables.resource_variables.rcm.clone(), + |variables| variables.resource_variables.rseed.clone(), + |variables| variables.resource_variables.rseed.clone(), ) } } diff --git a/taiga_halo2/src/circuit/vp_examples/cascade_intent.rs b/taiga_halo2/src/circuit/vp_examples/cascade_intent.rs index 1a0700a7..d0f98e03 100644 --- a/taiga_halo2/src/circuit/vp_examples/cascade_intent.rs +++ b/taiga_halo2/src/circuit/vp_examples/cascade_intent.rs @@ -24,6 +24,7 @@ use crate::{ vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, }; +use halo2_proofs::arithmetic::Field; use halo2_proofs::{ circuit::{floor_planner, Layouter, Value}, plonk::{keygen_pk, keygen_vk, Circuit, ConstraintSystem, Error}, @@ -154,7 +155,7 @@ pub fn create_intent_resource( nk: pallas::Base, ) -> Resource { let label = CascadeIntentValidityPredicateCircuit::encode_label(cascade_resource_cm); - let rseed = RandomSeed::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); let nonce = Nullifier::random(&mut rng); Resource::new_input_resource( *COMPRESSED_CASCADE_INTENT_VK, 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 38f9a661..11dd25db 100644 --- a/taiga_halo2/src/circuit/vp_examples/or_relation_intent.rs +++ b/taiga_halo2/src/circuit/vp_examples/or_relation_intent.rs @@ -25,6 +25,7 @@ use crate::{ vp_commitment::ValidityPredicateCommitment, vp_vk::ValidityPredicateVerifyingKey, }; +use halo2_proofs::arithmetic::Field; use halo2_proofs::{ circuit::{floor_planner, Layouter, Value}, plonk::{keygen_pk, keygen_vk, Circuit, ConstraintSystem, Error}, @@ -290,7 +291,7 @@ pub fn create_intent_resource( receiver_npk, receiver_value, ); - let rseed = RandomSeed::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); let nonce = Nullifier::random(&mut rng); Resource::new_input_resource( *COMPRESSED_OR_RELATION_INTENT_VK, 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 bd9fb8fa..549cb166 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 @@ -5,7 +5,7 @@ use crate::{ vp_examples::token::{Token, TokenAuthorization, TokenResource, TOKEN_VK}, }, constant::NUM_RESOURCE, - resource::{RandomSeed, Resource}, + resource::Resource, utils::poseidon_hash_n, }; use halo2_proofs::arithmetic::Field; @@ -56,6 +56,7 @@ impl Swap { assert_eq!(offer.quantity() % ratio, 0); let offer_resource = offer.create_random_output_token_resource( + &mut rng, self.sell.resource().nk_container.get_npk(), &self.auth, ); @@ -71,6 +72,7 @@ impl Swap { ); *returned_token .create_random_output_token_resource( + &mut rng, self.sell.resource().nk_container.get_npk(), &self.auth, ) @@ -99,7 +101,7 @@ impl Swap { } pub fn create_intent_resource(&self, mut rng: R) -> Resource { - let rseed = RandomSeed::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); Resource::new_input_resource( *COMPRESSED_PARTIAL_FULFILLMENT_INTENT_VK, diff --git a/taiga_halo2/src/circuit/vp_examples/receiver_vp.rs b/taiga_halo2/src/circuit/vp_examples/receiver_vp.rs index 433e6d74..f54e61b8 100644 --- a/taiga_halo2/src/circuit/vp_examples/receiver_vp.rs +++ b/taiga_halo2/src/circuit/vp_examples/receiver_vp.rs @@ -172,21 +172,30 @@ impl ValidityPredicateCircuit for ReceiverValidityPredicateCircuit { &basic_variables.get_npk_searchable_pairs(), )?; - let psi = get_owned_resource_variable( + let is_ephemeral = get_owned_resource_variable( config.get_owned_resource_variable_config, - layouter.namespace(|| "get owned resource psi"), + layouter.namespace(|| "get owned resource is_ephemeral"), &owned_resource_id, - &basic_variables.get_psi_searchable_pairs(), + &basic_variables.get_is_ephemeral_searchable_pairs(), )?; - let rcm = get_owned_resource_variable( + let rseed = get_owned_resource_variable( config.get_owned_resource_variable_config, - layouter.namespace(|| "get owned resource psi"), + layouter.namespace(|| "get owned resource rseed"), &owned_resource_id, - &basic_variables.get_rcm_searchable_pairs(), + &basic_variables.get_rseed_searchable_pairs(), )?; - let mut message = vec![logic, label, value, quantity, nonce, npk, psi, rcm]; + let mut message = vec![ + logic, + label, + value, + quantity, + nonce, + npk, + is_ephemeral, + rseed, + ]; let add_chip = AddChip::::construct(config.add_config.clone(), ()); @@ -249,8 +258,8 @@ impl ValidityPredicateCircuit for ReceiverValidityPredicateCircuit { pallas::Base::from(target_resource.quantity), target_resource.nonce.inner(), target_resource.get_npk(), - target_resource.psi, - target_resource.rcm, + pallas::Base::from(target_resource.is_ephemeral as u64), + target_resource.rseed, ]; let plaintext = ResourcePlaintext::padding(&message); let key = SecretKey::from_dh_exchange(&self.rcv_pk, &mod_r_p(self.sk)); @@ -332,6 +341,9 @@ fn test_halo2_receiver_vp_circuit() { ); 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()); + assert_eq!( + de_cipher[6], + pallas::Base::from(circuit.output_resources[0].is_ephemeral) + ); + assert_eq!(de_cipher[7], circuit.output_resources[0].rseed); } diff --git a/taiga_halo2/src/circuit/vp_examples/token.rs b/taiga_halo2/src/circuit/vp_examples/token.rs index 2c605347..8dfc6683 100644 --- a/taiga_halo2/src/circuit/vp_examples/token.rs +++ b/taiga_halo2/src/circuit/vp_examples/token.rs @@ -100,7 +100,7 @@ impl Token { ) -> TokenResource { let label = self.encode_name(); let value = auth.to_value(); - let rseed = RandomSeed::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); let nonce = Nullifier::random(&mut rng); let resource = Resource::new_input_resource( *COMPRESSED_TOKEN_VK, @@ -119,13 +119,15 @@ impl Token { } } - pub fn create_random_output_token_resource( + pub fn create_random_output_token_resource( &self, + mut rng: R, npk: pallas::Base, auth: &TokenAuthorization, ) -> TokenResource { let label = self.encode_name(); let value = auth.to_value(); + let rseed = pallas::Base::random(&mut rng); let resource = Resource::new_output_resource( *COMPRESSED_TOKEN_VK, label, @@ -133,6 +135,7 @@ impl Token { self.quantity(), npk, false, + rseed, ); TokenResource { diff --git a/taiga_halo2/src/compliance.rs b/taiga_halo2/src/compliance.rs index 8ddf36dc..585470e8 100644 --- a/taiga_halo2/src/compliance.rs +++ b/taiga_halo2/src/compliance.rs @@ -138,7 +138,7 @@ impl ComplianceInfo { None => input_resource.calculate_root(&input_merkle_path), }; - output_resource.set_nonce(&input_resource, &mut rng); + output_resource.set_nonce(&input_resource); Self { input_resource, diff --git a/taiga_halo2/src/resource.rs b/taiga_halo2/src/resource.rs index 60ee0cfc..84041199 100644 --- a/taiga_halo2/src/resource.rs +++ b/taiga_halo2/src/resource.rs @@ -100,12 +100,10 @@ pub struct Resource { pub nk_container: NullifierKeyContainer, /// 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 resource commitment - pub rcm: pallas::Base, /// If the is_ephemeral flag is false, the merkle path authorization(membership) of input resource will be checked in ComplianceProof. pub is_ephemeral: bool, + /// randomness seed used to derive whatever randomness needed (e.g., the resource commitment randomness and nullifier derivation randomness) + pub rseed: pallas::Base, } /// The parameters in the ResourceKind are used to derive resource kind. @@ -142,7 +140,7 @@ impl Resource { nk: pallas::Base, nonce: Nullifier, is_ephemeral: bool, - rseed: RandomSeed, + rseed: pallas::Base, ) -> Self { let kind = ResourceKind::new(logic, label); Self { @@ -151,9 +149,8 @@ impl Resource { quantity, nk_container: NullifierKeyContainer::Key(nk), is_ephemeral, - psi: rseed.get_psi(&nonce), - rcm: rseed.get_rcm(&nonce), nonce, + rseed, } } @@ -166,6 +163,7 @@ impl Resource { quantity: u64, npk: pallas::Base, is_ephemeral: bool, + rseed: pallas::Base, ) -> Self { let kind = ResourceKind::new(logic, label); Self { @@ -174,8 +172,7 @@ impl Resource { quantity, nk_container: NullifierKeyContainer::PublicKey(npk), is_ephemeral, - psi: pallas::Base::default(), - rcm: pallas::Base::default(), + rseed, nonce: Nullifier::default(), } } @@ -189,8 +186,7 @@ impl Resource { nk_container: NullifierKeyContainer, nonce: Nullifier, is_ephemeral: bool, - psi: pallas::Base, - rcm: pallas::Base, + rseed: pallas::Base, ) -> Self { let kind = ResourceKind::new(logic, label); Self { @@ -199,9 +195,8 @@ impl Resource { quantity, nk_container, is_ephemeral, - psi, - rcm, nonce, + rseed, } } @@ -212,15 +207,14 @@ impl Resource { 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); + let rseed = pallas::Base::random(&mut rng); Resource { kind, value, quantity: 0, nk_container: nk, nonce, - psi: rseed.get_psi(&nonce), - rcm: rseed.get_rcm(&nonce), + rseed, is_ephemeral: true, } } @@ -238,9 +232,9 @@ impl Resource { self.value, self.get_npk(), self.nonce.inner(), - self.psi, + self.get_psi(), compose_is_ephemeral_quantity, - self.rcm, + self.get_rcm(), ]); ResourceCommitment(ret) } @@ -249,7 +243,7 @@ impl Resource { Nullifier::derive( &self.nk_container, &self.nonce.inner(), - &self.psi, + &self.get_psi(), &self.commitment(), ) } @@ -274,12 +268,14 @@ impl Resource { self.kind.label } + // psi is the randomness used to derive the nullifier pub fn get_psi(&self) -> pallas::Base { - self.psi + poseidon_hash_n([self.rseed, self.nonce.inner()]) } + // rcm is the randomness of resource commitment pub fn get_rcm(&self) -> pallas::Base { - self.rcm + poseidon_hash_n([self.rseed, self.nonce.inner()]) } pub fn calculate_root(&self, path: &MerklePath) -> Anchor { @@ -287,12 +283,8 @@ impl Resource { path.root(cm_node) } - pub fn set_nonce(&mut self, input_resource: &Resource, mut rng: R) { - let rseed = RandomSeed::random(&mut rng); - + pub fn set_nonce(&mut self, input_resource: &Resource) { self.nonce = input_resource.get_nf().unwrap(); - self.psi = rseed.get_psi(&self.nonce); - self.rcm = rseed.get_rcm(&self.nonce); } } @@ -321,12 +313,10 @@ impl BorshSerialize for Resource { }?; // Write nonce writer.write_all(&self.nonce.to_bytes())?; - // Write psi - writer.write_all(&self.psi.to_repr())?; - // Write rcm - writer.write_all(&self.rcm.to_repr())?; // Write is_ephemeral writer.write_u8(if self.is_ephemeral { 1 } else { 0 })?; + // Write rseed + writer.write_all(&self.rseed.to_repr())?; Ok(()) } @@ -372,21 +362,18 @@ impl BorshDeserialize for Resource { 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)?; - let psi = Option::from(pallas::Base::from_repr(psi_bytes)) - .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "psi not in field"))?; - // Read rcm - let mut rcm_bytes = [0u8; 32]; - reader.read_exact(&mut rcm_bytes)?; - let rcm = Option::from(pallas::Base::from_repr(rcm_bytes)) - .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "rcm not in field"))?; + // Read is_ephemeral let mut is_ephemeral_byte = [0u8; 1]; reader.read_exact(&mut is_ephemeral_byte)?; let is_ephemeral_byte = is_ephemeral_byte[0]; let is_ephemeral = is_ephemeral_byte == 0x01; + + // Read rseed + let mut rseed_bytes = [0u8; 32]; + reader.read_exact(&mut rseed_bytes)?; + let rseed = Option::from(pallas::Base::from_repr(rseed_bytes)) + .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "rseed not in field"))?; // Construct resource Ok(Resource::from_full( logic, @@ -396,8 +383,7 @@ impl BorshDeserialize for Resource { nk_container, nonce, is_ephemeral, - psi, - rcm, + rseed, )) } } @@ -434,30 +420,6 @@ impl RandomSeed { Self(rseed) } - 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(&nonce.to_bytes()); - let psi_bytes = *h.finalize().as_array(); - pallas::Base::from_uniform_bytes(&psi_bytes) - } - - 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(&nonce.to_bytes()); - let rcm_bytes = *h.finalize().as_array(); - pallas::Base::from_uniform_bytes(&rcm_bytes) - } - pub fn get_random_padding(&self, padding_len: usize) -> Vec { (0..padding_len) .map(|i| { @@ -559,7 +521,7 @@ impl ResourceValidityPredicates { #[cfg(test)] pub mod tests { - use super::{RandomSeed, Resource, ResourceKind}; + use super::{Resource, ResourceKind}; use crate::nullifier::tests::*; use halo2_proofs::arithmetic::Field; use pasta_curves::pallas; @@ -573,16 +535,15 @@ pub mod tests { pub fn random_resource(mut rng: R) -> Resource { let nonce = random_nullifier(&mut rng); - let rseed = RandomSeed::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); Resource { kind: random_kind(&mut rng), value: pallas::Base::random(&mut rng), quantity: rng.gen(), nk_container: random_nullifier_key(&mut rng), is_ephemeral: false, - psi: rseed.get_psi(&nonce), - rcm: rseed.get_rcm(&nonce), nonce, + rseed, } } diff --git a/taiga_halo2/src/shielded_ptx.rs b/taiga_halo2/src/shielded_ptx.rs index b238fd61..661157b7 100644 --- a/taiga_halo2/src/shielded_ptx.rs +++ b/taiga_halo2/src/shielded_ptx.rs @@ -495,7 +495,7 @@ pub mod testing { constant::TAIGA_COMMITMENT_TREE_DEPTH, merkle_tree::MerklePath, nullifier::Nullifier, - resource::{RandomSeed, Resource, ResourceValidityPredicates}, + resource::{Resource, ResourceValidityPredicates}, shielded_ptx::ShieldedPartialTransaction, utils::poseidon_hash, }; @@ -523,7 +523,7 @@ pub mod testing { 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 rseed = pallas::Base::random(&mut rng); let is_ephemeral = false; Resource::new_input_resource( compressed_trivial_vp_vk, @@ -543,6 +543,7 @@ pub mod testing { let value = pallas::Base::zero(); let quantity = 5000u64; let npk = pallas::Base::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); let is_ephemeral = false; Resource::new_output_resource( compressed_trivial_vp_vk, @@ -551,6 +552,7 @@ pub mod testing { quantity, npk, is_ephemeral, + rseed, ) }; @@ -571,7 +573,7 @@ pub mod testing { 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 rseed = pallas::Base::random(&mut rng); let is_ephemeral = false; Resource::new_input_resource( compressed_trivial_vp_vk, @@ -589,6 +591,7 @@ pub mod testing { let value = pallas::Base::zero(); let quantity = 10u64; let npk = pallas::Base::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); let is_ephemeral = false; Resource::new_output_resource( compressed_trivial_vp_vk, @@ -597,6 +600,7 @@ pub mod testing { quantity, npk, is_ephemeral, + rseed, ) }; diff --git a/taiga_halo2/src/taiga_api.rs b/taiga_halo2/src/taiga_api.rs index 9e2a4e58..3ffe4243 100644 --- a/taiga_halo2/src/taiga_api.rs +++ b/taiga_halo2/src/taiga_api.rs @@ -6,14 +6,15 @@ use crate::{ use crate::{ error::TransactionError, nullifier::Nullifier, - resource::{RandomSeed, Resource}, + resource::Resource, shielded_ptx::ShieldedPartialTransaction, transaction::{ShieldedPartialTxBundle, Transaction, TransparentPartialTxBundle}, }; +use ff::Field; use pasta_curves::pallas; use rand::rngs::OsRng; -pub const RESOURCE_SIZE: usize = 234; +pub const RESOURCE_SIZE: usize = 202; #[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSerialize}; @@ -36,9 +37,9 @@ pub fn create_input_resource( nk: pallas::Base, is_ephemeral: bool, ) -> Resource { - let rng = OsRng; - let nonce = Nullifier::random(rng); - let rseed = RandomSeed::random(rng); + let mut rng = OsRng; + let nonce = Nullifier::random(&mut rng); + let rseed = pallas::Base::random(&mut rng); Resource::new_input_resource( logic, label, @@ -61,12 +62,14 @@ pub fn create_output_resource( npk: pallas::Base, is_ephemeral: bool, ) -> Resource { - Resource::new_output_resource(logic, label, value, quantity, npk, is_ephemeral) + let mut rng = OsRng; + let rseed = pallas::Base::random(&mut rng); + Resource::new_output_resource(logic, label, value, quantity, npk, is_ephemeral, rseed) } /// Resource borsh serialization /// -/// Resource size: 234 bytes +/// Resource size: 202 bytes /// /// Resource layout: /// | Parameters | type |size(bytes)| @@ -78,9 +81,8 @@ pub fn create_output_resource( /// | nk_container type | u8 | 1 | /// | npk | pallas::Base | 32 | /// | nonce | pallas::Base | 32 | -/// | psi | pallas::Base | 32 | -/// | rcm | pallas::Base | 32 | /// | is_ephemeral | u8 | 1 | +/// | rseed | pallas::Base | 32 | #[cfg(feature = "borsh")] pub fn resource_serialize(resource: &Resource) -> std::io::Result> { let mut result = Vec::with_capacity(RESOURCE_SIZE);