diff --git a/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin b/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin index bacba91e..e14d1dc8 100644 Binary files a/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin and b/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin differ diff --git a/artifacts/lez/programs/amm.bin b/artifacts/lez/programs/amm.bin index 11382930..b96eebd8 100644 Binary files a/artifacts/lez/programs/amm.bin and b/artifacts/lez/programs/amm.bin differ diff --git a/artifacts/lez/programs/associated_token_account.bin b/artifacts/lez/programs/associated_token_account.bin index 1f01ba89..78f16a02 100644 Binary files a/artifacts/lez/programs/associated_token_account.bin and b/artifacts/lez/programs/associated_token_account.bin differ diff --git a/artifacts/lez/programs/authenticated_transfer.bin b/artifacts/lez/programs/authenticated_transfer.bin index 2fc88f43..c6ec4626 100644 Binary files a/artifacts/lez/programs/authenticated_transfer.bin and b/artifacts/lez/programs/authenticated_transfer.bin differ diff --git a/artifacts/lez/programs/bridge.bin b/artifacts/lez/programs/bridge.bin index 8ee361a7..7814f1b2 100644 Binary files a/artifacts/lez/programs/bridge.bin and b/artifacts/lez/programs/bridge.bin differ diff --git a/artifacts/lez/programs/clock.bin b/artifacts/lez/programs/clock.bin index 45467bd3..10cc941c 100644 Binary files a/artifacts/lez/programs/clock.bin and b/artifacts/lez/programs/clock.bin differ diff --git a/artifacts/lez/programs/faucet.bin b/artifacts/lez/programs/faucet.bin index 6204eb9c..ea890c1d 100644 Binary files a/artifacts/lez/programs/faucet.bin and b/artifacts/lez/programs/faucet.bin differ diff --git a/artifacts/lez/programs/pinata.bin b/artifacts/lez/programs/pinata.bin index 8f16d3e1..6926fcaf 100644 Binary files a/artifacts/lez/programs/pinata.bin and b/artifacts/lez/programs/pinata.bin differ diff --git a/artifacts/lez/programs/pinata_token.bin b/artifacts/lez/programs/pinata_token.bin index 0caf5046..059efb7a 100644 Binary files a/artifacts/lez/programs/pinata_token.bin and b/artifacts/lez/programs/pinata_token.bin differ diff --git a/artifacts/lez/programs/token.bin b/artifacts/lez/programs/token.bin index 1786fa01..3c714feb 100644 Binary files a/artifacts/lez/programs/token.bin and b/artifacts/lez/programs/token.bin differ diff --git a/artifacts/lez/programs/vault.bin b/artifacts/lez/programs/vault.bin index d670b6bc..c7182b13 100644 Binary files a/artifacts/lez/programs/vault.bin and b/artifacts/lez/programs/vault.bin differ diff --git a/integration_tests/tests/tps.rs b/integration_tests/tests/tps.rs index 71fb132b..7141303e 100644 --- a/integration_tests/tests/tps.rs +++ b/integration_tests/tests/tps.rs @@ -294,6 +294,7 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_vpk, random_seed: [0; 32], + view_tag: 0, nsk: sender_nsk, membership_proof: proof, identifier: 0, diff --git a/lee/privacy_preserving_circuit/src/output.rs b/lee/privacy_preserving_circuit/src/output.rs index c9543e05..c5d962d6 100644 --- a/lee/privacy_preserving_circuit/src/output.rs +++ b/lee/privacy_preserving_circuit/src/output.rs @@ -4,7 +4,7 @@ use lee_core::{ PrivacyPreservingCircuitOutput, PrivateAccountKind, SharedSecretKey, account::{Account, AccountId, Nonce}, compute_digest_for_path, - encryption::ViewingPublicKey, + encryption::{ViewTag, ViewingPublicKey}, }; use crate::execution_state::ExecutionState; @@ -66,6 +66,7 @@ pub fn compute_circuit_output( *commitment_root, ); let new_nonce = Nonce::private_account_nonce_init(&account_id); + let view_tag = EncryptedAccountData::compute_view_tag(&npk, vpk); emit_private_output( &mut output, @@ -73,7 +74,7 @@ pub fn compute_circuit_output( post_state, &account_id, &PrivateAccountKind::Regular(*identifier), - &npk, + view_tag, vpk, random_seed, new_nullifier, @@ -83,6 +84,7 @@ pub fn compute_circuit_output( InputAccountIdentity::PrivateAuthorizedUpdate { vpk, random_seed, + view_tag, nsk, membership_proof, identifier, @@ -110,7 +112,7 @@ pub fn compute_circuit_output( post_state, &account_id, &PrivateAccountKind::Regular(*identifier), - &npk, + *view_tag, vpk, random_seed, new_nullifier, @@ -142,6 +144,7 @@ pub fn compute_circuit_output( *commitment_root, ); let new_nonce = Nonce::private_account_nonce_init(&account_id); + let view_tag = EncryptedAccountData::compute_view_tag(npk, vpk); emit_private_output( &mut output, @@ -149,7 +152,7 @@ pub fn compute_circuit_output( post_state, &account_id, &PrivateAccountKind::Regular(*identifier), - npk, + view_tag, vpk, random_seed, new_nullifier, @@ -190,6 +193,7 @@ pub fn compute_circuit_output( let (authority_program_id, seed) = pda_seed_by_position .get(&pos) .expect("PrivatePdaInit position must be in pda_seed_by_position"); + let view_tag = EncryptedAccountData::compute_view_tag(npk, vpk); emit_private_output( &mut output, &mut output_index, @@ -200,7 +204,7 @@ pub fn compute_circuit_output( seed: *seed, identifier: *identifier, }, - npk, + view_tag, vpk, random_seed, new_nullifier, @@ -210,6 +214,7 @@ pub fn compute_circuit_output( InputAccountIdentity::PrivatePdaUpdate { vpk, random_seed, + view_tag, nsk, membership_proof, identifier, @@ -234,7 +239,6 @@ pub fn compute_circuit_output( let new_nonce = pre_state.account.nonce.private_account_nonce_increment(nsk); let account_id = pre_state.account_id; - let npk = NullifierPublicKey::from(nsk); let (authority_program_id, seed) = pda_seed_by_position .get(&pos) .expect("PrivatePdaUpdate position must be in pda_seed_by_position"); @@ -248,7 +252,7 @@ pub fn compute_circuit_output( seed: *seed, identifier: *identifier, }, - &npk, + *view_tag, vpk, random_seed, new_nullifier, @@ -271,7 +275,7 @@ fn emit_private_output( post_state: Account, account_id: &AccountId, kind: &PrivateAccountKind, - npk: &NullifierPublicKey, + view_tag: ViewTag, vpk: &ViewingPublicKey, random_seed: &[u8; 32], new_nullifier: (Nullifier, CommitmentSetDigest), @@ -287,15 +291,6 @@ fn emit_private_output( let esk = EphemeralSecretKey::new(account_id, random_seed, &new_nonce); let (shared_secret, epk) = SharedSecretKey::encapsulate_deterministic(vpk, &esk); - // Currently the view tag is properlty generated for all accounts. - // To increase privacy, this will be changed in the later version - // to only be generated explicitly for initialized accounts and - // fed by the prover directly for updated accounts. - // - // See issue 573: - // https://github.com/logos-blockchain/logos-execution-zone/issues/573 - let view_tag = EncryptedAccountData::compute_view_tag(npk, vpk); - let encrypted_account = EncryptionScheme::encrypt( &post_with_updated_nonce, kind, diff --git a/lee/state_machine/core/src/circuit_io.rs b/lee/state_machine/core/src/circuit_io.rs index d441ff19..8db29342 100644 --- a/lee/state_machine/core/src/circuit_io.rs +++ b/lee/state_machine/core/src/circuit_io.rs @@ -4,7 +4,7 @@ use crate::{ Commitment, CommitmentSetDigest, Identifier, MembershipProof, Nullifier, NullifierPublicKey, NullifierSecretKey, account::{Account, AccountWithMetadata}, - encryption::{EncryptedAccountData, ViewingPublicKey}, + encryption::{EncryptedAccountData, ViewTag, ViewingPublicKey}, program::{BlockValidityWindow, PdaSeed, ProgramId, ProgramOutput, TimestampValidityWindow}, }; @@ -42,6 +42,7 @@ pub enum InputAccountIdentity { PrivateAuthorizedUpdate { vpk: ViewingPublicKey, random_seed: [u8; 32], + view_tag: ViewTag, nsk: NullifierSecretKey, membership_proof: MembershipProof, identifier: Identifier, @@ -79,6 +80,7 @@ pub enum InputAccountIdentity { PrivatePdaUpdate { vpk: ViewingPublicKey, random_seed: [u8; 32], + view_tag: ViewTag, nsk: NullifierSecretKey, membership_proof: MembershipProof, identifier: Identifier, diff --git a/lee/state_machine/src/privacy_preserving_transaction/circuit/tests.rs b/lee/state_machine/src/privacy_preserving_transaction/circuit/tests.rs index 005a9230..225d542a 100644 --- a/lee/state_machine/src/privacy_preserving_transaction/circuit/tests.rs +++ b/lee/state_machine/src/privacy_preserving_transaction/circuit/tests.rs @@ -198,6 +198,7 @@ fn prove_privacy_preserving_execution_circuit_fully_private() { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: commitment_set .get_proof_for(&commitment_sender) @@ -574,6 +575,7 @@ fn private_authorized_update_encrypts_regular_kind_with_identifier() { vec![InputAccountIdentity::PrivateAuthorizedUpdate { vpk: keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: keys.nsk, membership_proof: commitment_set.get_proof_for(&commitment).unwrap(), identifier, @@ -630,6 +632,7 @@ fn private_pda_update_encrypts_pda_kind_with_identifier() { InputAccountIdentity::PrivatePdaUpdate { vpk: keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: keys.nsk, membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(), identifier, @@ -708,6 +711,7 @@ fn private_pda_update_identifier_mismatch_fails() { InputAccountIdentity::PrivatePdaUpdate { vpk: keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: keys.nsk, membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(), identifier: 99, diff --git a/lee/state_machine/src/state/tests/changer_claimer.rs b/lee/state_machine/src/state/tests/changer_claimer.rs index 9a581c63..f6bb4932 100644 --- a/lee/state_machine/src/state/tests/changer_claimer.rs +++ b/lee/state_machine/src/state/tests/changer_claimer.rs @@ -74,6 +74,7 @@ fn private_changer_claimer_no_data_change_no_claim_succeeds() { vec![InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, @@ -104,6 +105,7 @@ fn private_changer_claimer_data_change_no_claim_fails() { vec![InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, diff --git a/lee/state_machine/src/state/tests/circuit.rs b/lee/state_machine/src/state/tests/circuit.rs index c13a7370..0b234b30 100644 --- a/lee/state_machine/src/state/tests/circuit.rs +++ b/lee/state_machine/src/state/tests/circuit.rs @@ -64,6 +64,7 @@ fn circuit_fails_if_invalid_auth_keys_are_provided() { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: recipient_keys.nsk, membership_proof: (0, vec![]), identifier: 0, @@ -113,6 +114,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_balance_is_provid InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, @@ -162,6 +164,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_program_owner_is_ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, @@ -211,6 +214,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_data_is_provided( InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, @@ -260,6 +264,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_nonce_is_provided InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, @@ -307,6 +312,7 @@ fn circuit_should_fail_if_new_private_account_is_provided_with_default_values_bu InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, @@ -694,6 +700,7 @@ fn circuit_should_fail_if_there_are_repeated_ids() { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: (1, vec![]), identifier: 0, @@ -701,6 +708,7 @@ fn circuit_should_fail_if_there_are_repeated_ids() { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: (1, vec![]), identifier: 0, @@ -1020,6 +1028,7 @@ fn two_private_pda_family_members_receive_and_spend() { InputAccountIdentity::PrivatePdaUpdate { vpk: alice_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: alice_keys.nsk, membership_proof: state .get_proof_for_commitment(&commitment_pda_0) @@ -1057,6 +1066,7 @@ fn two_private_pda_family_members_receive_and_spend() { InputAccountIdentity::PrivatePdaUpdate { vpk: alice_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: alice_keys.nsk, membership_proof: state .get_proof_for_commitment(&commitment_pda_1) @@ -1108,6 +1118,7 @@ fn two_private_pda_family_members_receive_and_spend() { InputAccountIdentity::PrivatePdaUpdate { vpk: alice_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: alice_keys.nsk, membership_proof: state .get_proof_for_commitment(&commitment_pda_1_after_spend) diff --git a/lee/state_machine/src/state/tests/claiming.rs b/lee/state_machine/src/state/tests/claiming.rs index acfe9834..acd96ef6 100644 --- a/lee/state_machine/src/state/tests/claiming.rs +++ b/lee/state_machine/src/state/tests/claiming.rs @@ -328,6 +328,7 @@ fn authorized_public_account_claiming_succeeds_when_executed_privately() { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: state .get_proof_for_commitment(&sender_commitment) @@ -443,6 +444,7 @@ fn private_chained_call(number_of_calls: u32) { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: from_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: from_keys.nsk, membership_proof: state .get_proof_for_commitment(&from_commitment) @@ -452,6 +454,7 @@ fn private_chained_call(number_of_calls: u32) { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: to_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: to_keys.nsk, membership_proof: state .get_proof_for_commitment(&to_commitment) diff --git a/lee/state_machine/src/state/tests/mod.rs b/lee/state_machine/src/state/tests/mod.rs index 55a99ead..96e08dc2 100644 --- a/lee/state_machine/src/state/tests/mod.rs +++ b/lee/state_machine/src/state/tests/mod.rs @@ -330,6 +330,7 @@ fn private_balance_transfer_for_tests( InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: state .get_proof_for_commitment(&sender_commitment) @@ -384,6 +385,7 @@ fn deshielded_balance_transfer_for_tests( InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.nsk, membership_proof: state .get_proof_for_commitment(&sender_commitment) diff --git a/lee/state_machine/src/state/tests/privacy_preserving.rs b/lee/state_machine/src/state/tests/privacy_preserving.rs index 8c33e202..34a61c19 100644 --- a/lee/state_machine/src/state/tests/privacy_preserving.rs +++ b/lee/state_machine/src/state/tests/privacy_preserving.rs @@ -524,6 +524,7 @@ fn malicious_authorization_changer_should_fail_in_privacy_preserving_circuit() { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: recipient_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: recipient_keys.nsk, membership_proof: state .get_proof_for_commitment(&recipient_commitment) diff --git a/lee/state_machine/src/validated_state_diff/tests.rs b/lee/state_machine/src/validated_state_diff/tests.rs index c471676c..e8bb3f14 100644 --- a/lee/state_machine/src/validated_state_diff/tests.rs +++ b/lee/state_machine/src/validated_state_diff/tests.rs @@ -167,6 +167,7 @@ fn privacy_malicious_programs_cannot_drain_public_victim() { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: attacker_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: attacker_keys.nsk, membership_proof, identifier: 0, @@ -327,6 +328,7 @@ fn privacy_malicious_programs_cannot_drain_private_victim() { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: attacker_keys.vpk(), random_seed: [0; 32], + view_tag: 0, nsk: attacker_keys.nsk, membership_proof, identifier: 0, diff --git a/lez/sequencer/core/src/tests.rs b/lez/sequencer/core/src/tests.rs index 4b5ebfbc..45ad3d4d 100644 --- a/lez/sequencer/core/src/tests.rs +++ b/lez/sequencer/core/src/tests.rs @@ -849,6 +849,7 @@ fn private_bridge_withdraw_invocation_is_dropped() { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.viewing_public_key.clone(), random_seed: [0; 32], + view_tag: 0, nsk: sender_keys.private_key_holder.nullifier_secret_key, membership_proof: state .get_proof_for_commitment(&sender_commitment) diff --git a/lez/wallet/src/account_manager.rs b/lez/wallet/src/account_manager.rs index a5f900d6..55e1d01d 100644 --- a/lez/wallet/src/account_manager.rs +++ b/lez/wallet/src/account_manager.rs @@ -7,7 +7,7 @@ use lee_core::{ CommitmentSetDigest, DUMMY_COMMITMENT_HASH, Identifier, InputAccountIdentity, MembershipProof, NullifierPublicKey, NullifierSecretKey, SharedSecretKey, account::{AccountWithMetadata, Nonce}, - encryption::ViewingPublicKey, + encryption::{ViewTag, ViewingPublicKey}, }; use rand::{RngCore as _, rngs::OsRng}; @@ -423,6 +423,7 @@ impl AccountManager { (Some(nsk), Some(membership_proof)) => InputAccountIdentity::PrivatePdaUpdate { vpk: pre.vpk.clone(), random_seed: pre.random_seed, + view_tag: random_view_tag(), nsk, membership_proof, identifier: pre.identifier, @@ -442,6 +443,7 @@ impl AccountManager { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: pre.vpk.clone(), random_seed: pre.random_seed, + view_tag: random_view_tag(), nsk, membership_proof, identifier: pre.identifier, @@ -618,6 +620,13 @@ async fn private_shared_acc_preparation( }) } +/// Generate random byte using OS randomness. +fn random_view_tag() -> ViewTag { + let mut byte: [u8; 1] = [0; 1]; + OsRng.fill_bytes(&mut byte); + byte[0] +} + #[cfg(test)] mod tests { use super::*;