mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-07-17 13:20:17 +00:00
feat(circuit): supply a view_tag on private-account updates
This commit is contained in:
parent
027ab5a0d9
commit
1549e2f4e5
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -862,6 +862,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)
|
||||
|
||||
@ -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::*;
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user