feat(circuit): supply a view_tag on private-account updates

This commit is contained in:
agureev 2026-07-10 17:17:31 +04:00
parent 027ab5a0d9
commit 1549e2f4e5
29 changed files with 52 additions and 19 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -294,6 +294,7 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_vpk, vpk: sender_vpk,
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_nsk, nsk: sender_nsk,
membership_proof: proof, membership_proof: proof,
identifier: 0, identifier: 0,

View File

@ -4,7 +4,7 @@ use lee_core::{
PrivacyPreservingCircuitOutput, PrivateAccountKind, SharedSecretKey, PrivacyPreservingCircuitOutput, PrivateAccountKind, SharedSecretKey,
account::{Account, AccountId, Nonce}, account::{Account, AccountId, Nonce},
compute_digest_for_path, compute_digest_for_path,
encryption::ViewingPublicKey, encryption::{ViewTag, ViewingPublicKey},
}; };
use crate::execution_state::ExecutionState; use crate::execution_state::ExecutionState;
@ -66,6 +66,7 @@ pub fn compute_circuit_output(
*commitment_root, *commitment_root,
); );
let new_nonce = Nonce::private_account_nonce_init(&account_id); let new_nonce = Nonce::private_account_nonce_init(&account_id);
let view_tag = EncryptedAccountData::compute_view_tag(&npk, vpk);
emit_private_output( emit_private_output(
&mut output, &mut output,
@ -73,7 +74,7 @@ pub fn compute_circuit_output(
post_state, post_state,
&account_id, &account_id,
&PrivateAccountKind::Regular(*identifier), &PrivateAccountKind::Regular(*identifier),
&npk, view_tag,
vpk, vpk,
random_seed, random_seed,
new_nullifier, new_nullifier,
@ -83,6 +84,7 @@ pub fn compute_circuit_output(
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk, vpk,
random_seed, random_seed,
view_tag,
nsk, nsk,
membership_proof, membership_proof,
identifier, identifier,
@ -110,7 +112,7 @@ pub fn compute_circuit_output(
post_state, post_state,
&account_id, &account_id,
&PrivateAccountKind::Regular(*identifier), &PrivateAccountKind::Regular(*identifier),
&npk, *view_tag,
vpk, vpk,
random_seed, random_seed,
new_nullifier, new_nullifier,
@ -142,6 +144,7 @@ pub fn compute_circuit_output(
*commitment_root, *commitment_root,
); );
let new_nonce = Nonce::private_account_nonce_init(&account_id); let new_nonce = Nonce::private_account_nonce_init(&account_id);
let view_tag = EncryptedAccountData::compute_view_tag(npk, vpk);
emit_private_output( emit_private_output(
&mut output, &mut output,
@ -149,7 +152,7 @@ pub fn compute_circuit_output(
post_state, post_state,
&account_id, &account_id,
&PrivateAccountKind::Regular(*identifier), &PrivateAccountKind::Regular(*identifier),
npk, view_tag,
vpk, vpk,
random_seed, random_seed,
new_nullifier, new_nullifier,
@ -190,6 +193,7 @@ pub fn compute_circuit_output(
let (authority_program_id, seed) = pda_seed_by_position let (authority_program_id, seed) = pda_seed_by_position
.get(&pos) .get(&pos)
.expect("PrivatePdaInit position must be in pda_seed_by_position"); .expect("PrivatePdaInit position must be in pda_seed_by_position");
let view_tag = EncryptedAccountData::compute_view_tag(npk, vpk);
emit_private_output( emit_private_output(
&mut output, &mut output,
&mut output_index, &mut output_index,
@ -200,7 +204,7 @@ pub fn compute_circuit_output(
seed: *seed, seed: *seed,
identifier: *identifier, identifier: *identifier,
}, },
npk, view_tag,
vpk, vpk,
random_seed, random_seed,
new_nullifier, new_nullifier,
@ -210,6 +214,7 @@ pub fn compute_circuit_output(
InputAccountIdentity::PrivatePdaUpdate { InputAccountIdentity::PrivatePdaUpdate {
vpk, vpk,
random_seed, random_seed,
view_tag,
nsk, nsk,
membership_proof, membership_proof,
identifier, identifier,
@ -234,7 +239,6 @@ pub fn compute_circuit_output(
let new_nonce = pre_state.account.nonce.private_account_nonce_increment(nsk); let new_nonce = pre_state.account.nonce.private_account_nonce_increment(nsk);
let account_id = pre_state.account_id; let account_id = pre_state.account_id;
let npk = NullifierPublicKey::from(nsk);
let (authority_program_id, seed) = pda_seed_by_position let (authority_program_id, seed) = pda_seed_by_position
.get(&pos) .get(&pos)
.expect("PrivatePdaUpdate position must be in pda_seed_by_position"); .expect("PrivatePdaUpdate position must be in pda_seed_by_position");
@ -248,7 +252,7 @@ pub fn compute_circuit_output(
seed: *seed, seed: *seed,
identifier: *identifier, identifier: *identifier,
}, },
&npk, *view_tag,
vpk, vpk,
random_seed, random_seed,
new_nullifier, new_nullifier,
@ -271,7 +275,7 @@ fn emit_private_output(
post_state: Account, post_state: Account,
account_id: &AccountId, account_id: &AccountId,
kind: &PrivateAccountKind, kind: &PrivateAccountKind,
npk: &NullifierPublicKey, view_tag: ViewTag,
vpk: &ViewingPublicKey, vpk: &ViewingPublicKey,
random_seed: &[u8; 32], random_seed: &[u8; 32],
new_nullifier: (Nullifier, CommitmentSetDigest), new_nullifier: (Nullifier, CommitmentSetDigest),
@ -287,15 +291,6 @@ fn emit_private_output(
let esk = EphemeralSecretKey::new(account_id, random_seed, &new_nonce); let esk = EphemeralSecretKey::new(account_id, random_seed, &new_nonce);
let (shared_secret, epk) = SharedSecretKey::encapsulate_deterministic(vpk, &esk); 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( let encrypted_account = EncryptionScheme::encrypt(
&post_with_updated_nonce, &post_with_updated_nonce,
kind, kind,

View File

@ -4,7 +4,7 @@ use crate::{
Commitment, CommitmentSetDigest, Identifier, MembershipProof, Nullifier, NullifierPublicKey, Commitment, CommitmentSetDigest, Identifier, MembershipProof, Nullifier, NullifierPublicKey,
NullifierSecretKey, NullifierSecretKey,
account::{Account, AccountWithMetadata}, account::{Account, AccountWithMetadata},
encryption::{EncryptedAccountData, ViewingPublicKey}, encryption::{EncryptedAccountData, ViewTag, ViewingPublicKey},
program::{BlockValidityWindow, PdaSeed, ProgramId, ProgramOutput, TimestampValidityWindow}, program::{BlockValidityWindow, PdaSeed, ProgramId, ProgramOutput, TimestampValidityWindow},
}; };
@ -42,6 +42,7 @@ pub enum InputAccountIdentity {
PrivateAuthorizedUpdate { PrivateAuthorizedUpdate {
vpk: ViewingPublicKey, vpk: ViewingPublicKey,
random_seed: [u8; 32], random_seed: [u8; 32],
view_tag: ViewTag,
nsk: NullifierSecretKey, nsk: NullifierSecretKey,
membership_proof: MembershipProof, membership_proof: MembershipProof,
identifier: Identifier, identifier: Identifier,
@ -79,6 +80,7 @@ pub enum InputAccountIdentity {
PrivatePdaUpdate { PrivatePdaUpdate {
vpk: ViewingPublicKey, vpk: ViewingPublicKey,
random_seed: [u8; 32], random_seed: [u8; 32],
view_tag: ViewTag,
nsk: NullifierSecretKey, nsk: NullifierSecretKey,
membership_proof: MembershipProof, membership_proof: MembershipProof,
identifier: Identifier, identifier: Identifier,

View File

@ -198,6 +198,7 @@ fn prove_privacy_preserving_execution_circuit_fully_private() {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: commitment_set membership_proof: commitment_set
.get_proof_for(&commitment_sender) .get_proof_for(&commitment_sender)
@ -574,6 +575,7 @@ fn private_authorized_update_encrypts_regular_kind_with_identifier() {
vec![InputAccountIdentity::PrivateAuthorizedUpdate { vec![InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: keys.vpk(), vpk: keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: keys.nsk, nsk: keys.nsk,
membership_proof: commitment_set.get_proof_for(&commitment).unwrap(), membership_proof: commitment_set.get_proof_for(&commitment).unwrap(),
identifier, identifier,
@ -630,6 +632,7 @@ fn private_pda_update_encrypts_pda_kind_with_identifier() {
InputAccountIdentity::PrivatePdaUpdate { InputAccountIdentity::PrivatePdaUpdate {
vpk: keys.vpk(), vpk: keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: keys.nsk, nsk: keys.nsk,
membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(), membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(),
identifier, identifier,
@ -708,6 +711,7 @@ fn private_pda_update_identifier_mismatch_fails() {
InputAccountIdentity::PrivatePdaUpdate { InputAccountIdentity::PrivatePdaUpdate {
vpk: keys.vpk(), vpk: keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: keys.nsk, nsk: keys.nsk,
membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(), membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(),
identifier: 99, identifier: 99,

View File

@ -74,6 +74,7 @@ fn private_changer_claimer_no_data_change_no_claim_succeeds() {
vec![InputAccountIdentity::PrivateAuthorizedUpdate { vec![InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: (0, vec![]), membership_proof: (0, vec![]),
identifier: 0, identifier: 0,
@ -104,6 +105,7 @@ fn private_changer_claimer_data_change_no_claim_fails() {
vec![InputAccountIdentity::PrivateAuthorizedUpdate { vec![InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: (0, vec![]), membership_proof: (0, vec![]),
identifier: 0, identifier: 0,

View File

@ -64,6 +64,7 @@ fn circuit_fails_if_invalid_auth_keys_are_provided() {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: recipient_keys.nsk, nsk: recipient_keys.nsk,
membership_proof: (0, vec![]), membership_proof: (0, vec![]),
identifier: 0, identifier: 0,
@ -113,6 +114,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_balance_is_provid
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: (0, vec![]), membership_proof: (0, vec![]),
identifier: 0, identifier: 0,
@ -162,6 +164,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_program_owner_is_
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: (0, vec![]), membership_proof: (0, vec![]),
identifier: 0, identifier: 0,
@ -211,6 +214,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_data_is_provided(
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: (0, vec![]), membership_proof: (0, vec![]),
identifier: 0, identifier: 0,
@ -260,6 +264,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_nonce_is_provided
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: (0, vec![]), membership_proof: (0, vec![]),
identifier: 0, identifier: 0,
@ -307,6 +312,7 @@ fn circuit_should_fail_if_new_private_account_is_provided_with_default_values_bu
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: (0, vec![]), membership_proof: (0, vec![]),
identifier: 0, identifier: 0,
@ -694,6 +700,7 @@ fn circuit_should_fail_if_there_are_repeated_ids() {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: (1, vec![]), membership_proof: (1, vec![]),
identifier: 0, identifier: 0,
@ -701,6 +708,7 @@ fn circuit_should_fail_if_there_are_repeated_ids() {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: (1, vec![]), membership_proof: (1, vec![]),
identifier: 0, identifier: 0,
@ -1020,6 +1028,7 @@ fn two_private_pda_family_members_receive_and_spend() {
InputAccountIdentity::PrivatePdaUpdate { InputAccountIdentity::PrivatePdaUpdate {
vpk: alice_keys.vpk(), vpk: alice_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: alice_keys.nsk, nsk: alice_keys.nsk,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&commitment_pda_0) .get_proof_for_commitment(&commitment_pda_0)
@ -1057,6 +1066,7 @@ fn two_private_pda_family_members_receive_and_spend() {
InputAccountIdentity::PrivatePdaUpdate { InputAccountIdentity::PrivatePdaUpdate {
vpk: alice_keys.vpk(), vpk: alice_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: alice_keys.nsk, nsk: alice_keys.nsk,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&commitment_pda_1) .get_proof_for_commitment(&commitment_pda_1)
@ -1108,6 +1118,7 @@ fn two_private_pda_family_members_receive_and_spend() {
InputAccountIdentity::PrivatePdaUpdate { InputAccountIdentity::PrivatePdaUpdate {
vpk: alice_keys.vpk(), vpk: alice_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: alice_keys.nsk, nsk: alice_keys.nsk,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&commitment_pda_1_after_spend) .get_proof_for_commitment(&commitment_pda_1_after_spend)

View File

@ -328,6 +328,7 @@ fn authorized_public_account_claiming_succeeds_when_executed_privately() {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&sender_commitment) .get_proof_for_commitment(&sender_commitment)
@ -443,6 +444,7 @@ fn private_chained_call(number_of_calls: u32) {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: from_keys.vpk(), vpk: from_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: from_keys.nsk, nsk: from_keys.nsk,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&from_commitment) .get_proof_for_commitment(&from_commitment)
@ -452,6 +454,7 @@ fn private_chained_call(number_of_calls: u32) {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: to_keys.vpk(), vpk: to_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: to_keys.nsk, nsk: to_keys.nsk,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&to_commitment) .get_proof_for_commitment(&to_commitment)

View File

@ -330,6 +330,7 @@ fn private_balance_transfer_for_tests(
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&sender_commitment) .get_proof_for_commitment(&sender_commitment)
@ -384,6 +385,7 @@ fn deshielded_balance_transfer_for_tests(
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.vpk(), vpk: sender_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.nsk, nsk: sender_keys.nsk,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&sender_commitment) .get_proof_for_commitment(&sender_commitment)

View File

@ -524,6 +524,7 @@ fn malicious_authorization_changer_should_fail_in_privacy_preserving_circuit() {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: recipient_keys.vpk(), vpk: recipient_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: recipient_keys.nsk, nsk: recipient_keys.nsk,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&recipient_commitment) .get_proof_for_commitment(&recipient_commitment)

View File

@ -167,6 +167,7 @@ fn privacy_malicious_programs_cannot_drain_public_victim() {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: attacker_keys.vpk(), vpk: attacker_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: attacker_keys.nsk, nsk: attacker_keys.nsk,
membership_proof, membership_proof,
identifier: 0, identifier: 0,
@ -327,6 +328,7 @@ fn privacy_malicious_programs_cannot_drain_private_victim() {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: attacker_keys.vpk(), vpk: attacker_keys.vpk(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: attacker_keys.nsk, nsk: attacker_keys.nsk,
membership_proof, membership_proof,
identifier: 0, identifier: 0,

View File

@ -862,6 +862,7 @@ fn private_bridge_withdraw_invocation_is_dropped() {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: sender_keys.viewing_public_key.clone(), vpk: sender_keys.viewing_public_key.clone(),
random_seed: [0; 32], random_seed: [0; 32],
view_tag: 0,
nsk: sender_keys.private_key_holder.nullifier_secret_key, nsk: sender_keys.private_key_holder.nullifier_secret_key,
membership_proof: state membership_proof: state
.get_proof_for_commitment(&sender_commitment) .get_proof_for_commitment(&sender_commitment)

View File

@ -7,7 +7,7 @@ use lee_core::{
CommitmentSetDigest, DUMMY_COMMITMENT_HASH, Identifier, InputAccountIdentity, MembershipProof, CommitmentSetDigest, DUMMY_COMMITMENT_HASH, Identifier, InputAccountIdentity, MembershipProof,
NullifierPublicKey, NullifierSecretKey, SharedSecretKey, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
account::{AccountWithMetadata, Nonce}, account::{AccountWithMetadata, Nonce},
encryption::ViewingPublicKey, encryption::{ViewTag, ViewingPublicKey},
}; };
use rand::{RngCore as _, rngs::OsRng}; use rand::{RngCore as _, rngs::OsRng};
@ -423,6 +423,7 @@ impl AccountManager {
(Some(nsk), Some(membership_proof)) => InputAccountIdentity::PrivatePdaUpdate { (Some(nsk), Some(membership_proof)) => InputAccountIdentity::PrivatePdaUpdate {
vpk: pre.vpk.clone(), vpk: pre.vpk.clone(),
random_seed: pre.random_seed, random_seed: pre.random_seed,
view_tag: random_view_tag(),
nsk, nsk,
membership_proof, membership_proof,
identifier: pre.identifier, identifier: pre.identifier,
@ -442,6 +443,7 @@ impl AccountManager {
InputAccountIdentity::PrivateAuthorizedUpdate { InputAccountIdentity::PrivateAuthorizedUpdate {
vpk: pre.vpk.clone(), vpk: pre.vpk.clone(),
random_seed: pre.random_seed, random_seed: pre.random_seed,
view_tag: random_view_tag(),
nsk, nsk,
membership_proof, membership_proof,
identifier: pre.identifier, 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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;