mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-06-29 18:39:30 +00:00
tests: test and flow updates
This commit is contained in:
parent
526f9ccb32
commit
090c368c14
@ -156,7 +156,11 @@ async fn import_private_account() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
let key_chain = KeyChain::new_os_random();
|
||||
let account_id = lee::AccountId::from((&key_chain.nullifier_public_key, 0));
|
||||
let account_id = lee::AccountId::from((
|
||||
&key_chain.nullifier_public_key,
|
||||
&key_chain.viewing_public_key,
|
||||
0,
|
||||
));
|
||||
let account = lee::Account {
|
||||
program_owner: Program::authenticated_transfer_program().id(),
|
||||
balance: 777,
|
||||
@ -213,7 +217,11 @@ async fn import_private_account_second_time_overrides_account_data() -> Result<(
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
let key_chain = KeyChain::new_os_random();
|
||||
let account_id = lee::AccountId::from((&key_chain.nullifier_public_key, 0));
|
||||
let account_id = lee::AccountId::from((
|
||||
&key_chain.nullifier_public_key,
|
||||
&key_chain.viewing_public_key,
|
||||
0,
|
||||
));
|
||||
let key_chain_json =
|
||||
serde_json::to_string(&key_chain).context("Failed to serialize key chain")?;
|
||||
|
||||
|
||||
@ -7,13 +7,12 @@ use integration_tests::{
|
||||
public_mention, verify_commitment_is_in_state,
|
||||
};
|
||||
use lee::{
|
||||
AccountId, SharedSecretKey, execute_and_prove,
|
||||
privacy_preserving_transaction::circuit::ProgramWithDependencies, program::Program,
|
||||
AccountId, execute_and_prove, privacy_preserving_transaction::circuit::ProgramWithDependencies,
|
||||
program::Program,
|
||||
};
|
||||
use lee_core::{
|
||||
EncryptedAccountData, InputAccountIdentity, NullifierPublicKey,
|
||||
account::AccountWithMetadata,
|
||||
encryption::{EphemeralPublicKey, ViewingPublicKey},
|
||||
InputAccountIdentity, NullifierPublicKey, account::AccountWithMetadata,
|
||||
encryption::ViewingPublicKey,
|
||||
};
|
||||
use log::info;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
@ -600,14 +599,14 @@ async fn shielded_transfers_to_two_identifiers_same_npk() -> Result<()> {
|
||||
.await?;
|
||||
|
||||
// Both accounts must be discovered with the correct balances.
|
||||
let account_id_1 = AccountId::for_regular_private_account(&npk, identifier_1);
|
||||
let account_id_1 = AccountId::for_regular_private_account(&npk, &vpk, identifier_1);
|
||||
let acc_1 = ctx
|
||||
.wallet()
|
||||
.get_account_private(account_id_1)
|
||||
.context("account for identifier 1 not found after sync")?;
|
||||
assert_eq!(acc_1.balance, 100);
|
||||
|
||||
let account_id_2 = AccountId::for_regular_private_account(&npk, identifier_2);
|
||||
let account_id_2 = AccountId::for_regular_private_account(&npk, &vpk, identifier_2);
|
||||
let acc_2 = ctx
|
||||
.wallet()
|
||||
.get_account_private(account_id_2)
|
||||
@ -666,11 +665,9 @@ async fn ppt_cant_chain_call_faucet() -> Result<()> {
|
||||
let nsk: lee_core::NullifierSecretKey = [3; 32];
|
||||
let npk = NullifierPublicKey::from(&nsk);
|
||||
let vpk = ViewingPublicKey::from_bytes(vec![4_u8; 1184]).unwrap();
|
||||
let ssk = SharedSecretKey([55_u8; 32]);
|
||||
let epk = EphemeralPublicKey(vec![55_u8; 1088]);
|
||||
let attacker_vault_id = {
|
||||
let seed = vault_core::compute_vault_seed(attacker_id);
|
||||
AccountId::for_private_pda(&vault_program_id, &seed, &npk, 1337)
|
||||
AccountId::for_private_pda(&vault_program_id, &seed, &npk, &vpk, 1337)
|
||||
};
|
||||
let amount: u128 = 1;
|
||||
|
||||
@ -712,10 +709,9 @@ async fn ppt_cant_chain_call_faucet() -> Result<()> {
|
||||
vec![
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
epk,
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&npk, &vpk),
|
||||
vpk,
|
||||
esk: [0; 32],
|
||||
npk,
|
||||
ssk,
|
||||
identifier: 1337,
|
||||
seed: None,
|
||||
},
|
||||
|
||||
@ -12,7 +12,6 @@ use integration_tests::{
|
||||
LEE_PROGRAM_FOR_TEST_PDA_SPEND_PROXY, TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext,
|
||||
verify_commitment_is_in_state,
|
||||
};
|
||||
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
|
||||
use lee::{
|
||||
AccountId, PrivacyPreservingTransaction, ProgramId,
|
||||
privacy_preserving_transaction::{
|
||||
@ -23,7 +22,7 @@ use lee::{
|
||||
program::Program,
|
||||
};
|
||||
use lee_core::{
|
||||
EncryptedAccountData, InputAccountIdentity, NullifierPublicKey,
|
||||
InputAccountIdentity, NullifierPublicKey,
|
||||
account::{Account, AccountWithMetadata},
|
||||
encryption::ViewingPublicKey,
|
||||
program::PdaSeed,
|
||||
@ -52,7 +51,8 @@ async fn fund_private_pda(
|
||||
amount: u128,
|
||||
auth_transfer: &ProgramWithDependencies,
|
||||
) -> Result<()> {
|
||||
let pda_account_id = AccountId::for_private_pda(&authority_program_id, &seed, &npk, identifier);
|
||||
let pda_account_id =
|
||||
AccountId::for_private_pda(&authority_program_id, &seed, &npk, &vpk, identifier);
|
||||
let sender_account = wallet
|
||||
.get_account_public(sender)
|
||||
.await
|
||||
@ -64,20 +64,15 @@ async fn fund_private_pda(
|
||||
let sender_pre = AccountWithMetadata::new(sender_account.clone(), true, sender);
|
||||
let pda_pre = AccountWithMetadata::new(Account::default(), false, pda_account_id);
|
||||
|
||||
let eph_holder = EphemeralKeyHolder::new(&vpk);
|
||||
let ssk = eph_holder.calculate_shared_secret_sender();
|
||||
let epk = eph_holder.ephemeral_public_key().clone();
|
||||
|
||||
let instruction = Program::serialize_instruction(AuthTransferInstruction::Transfer { amount })
|
||||
.context("failed to serialize auth_transfer instruction")?;
|
||||
|
||||
let account_identities = vec![
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
epk,
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&npk, &vpk),
|
||||
vpk,
|
||||
esk: [0; 32],
|
||||
npk,
|
||||
ssk,
|
||||
identifier,
|
||||
seed: Some((seed, authority_program_id)),
|
||||
},
|
||||
@ -182,8 +177,8 @@ async fn private_pda_family_members_receive_and_spend() -> Result<()> {
|
||||
let spend_program =
|
||||
ProgramWithDependencies::new(proxy, [(auth_transfer_id, auth_transfer)].into());
|
||||
|
||||
let alice_pda_0_id = AccountId::for_private_pda(&proxy_id, &seed, &alice_npk, 0);
|
||||
let alice_pda_1_id = AccountId::for_private_pda(&proxy_id, &seed, &alice_npk, 1);
|
||||
let alice_pda_0_id = AccountId::for_private_pda(&proxy_id, &seed, &alice_npk, &alice_vpk, 0);
|
||||
let alice_pda_1_id = AccountId::for_private_pda(&proxy_id, &seed, &alice_npk, &alice_vpk, 1);
|
||||
|
||||
// Use two different public senders to avoid nonce conflicts between the back-to-back txs.
|
||||
let senders = ctx.existing_public_accounts();
|
||||
|
||||
@ -15,7 +15,6 @@ use anyhow::{Context as _, Result};
|
||||
use bytesize::ByteSize;
|
||||
use common::transaction::LeeTransaction;
|
||||
use integration_tests::{TestContext, config::SequencerPartialConfig};
|
||||
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
|
||||
use lee::{
|
||||
Account, AccountId, PrivacyPreservingTransaction, PrivateKey, PublicKey, PublicTransaction,
|
||||
privacy_preserving_transaction::{self as pptx, circuit},
|
||||
@ -23,7 +22,7 @@ use lee::{
|
||||
public_transaction as putx,
|
||||
};
|
||||
use lee_core::{
|
||||
EncryptedAccountData, InputAccountIdentity, MembershipProof, NullifierPublicKey,
|
||||
InputAccountIdentity, MembershipProof, NullifierPublicKey,
|
||||
account::{AccountWithMetadata, Nonce, data::Data},
|
||||
encryption::ViewingPublicKey,
|
||||
};
|
||||
@ -266,7 +265,7 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
||||
data: Data::default(),
|
||||
},
|
||||
true,
|
||||
AccountId::for_regular_private_account(&sender_npk, 0),
|
||||
AccountId::for_regular_private_account(&sender_npk, &sender_vpk, 0),
|
||||
);
|
||||
let recipient_nsk = [2; 32];
|
||||
let recipient_vpk = ViewingPublicKey::from_seed(&[101_u8; 32], &[102_u8; 32]);
|
||||
@ -274,17 +273,9 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
||||
let recipient_pre = AccountWithMetadata::new(
|
||||
Account::default(),
|
||||
false,
|
||||
AccountId::for_regular_private_account(&recipient_npk, 0),
|
||||
AccountId::for_regular_private_account(&recipient_npk, &recipient_vpk, 0),
|
||||
);
|
||||
|
||||
let eph_holder_from = EphemeralKeyHolder::new(&sender_vpk);
|
||||
let sender_ss = eph_holder_from.calculate_shared_secret_sender();
|
||||
let sender_epk = eph_holder_from.ephemeral_public_key().clone();
|
||||
|
||||
let eph_holder_to = EphemeralKeyHolder::new(&recipient_vpk);
|
||||
let recipient_ss = eph_holder_to.calculate_shared_secret_sender();
|
||||
let recipient_epk = eph_holder_to.ephemeral_public_key().clone();
|
||||
|
||||
let balance_to_move: u128 = 1;
|
||||
let proof: MembershipProof = (
|
||||
1,
|
||||
@ -301,18 +292,16 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
||||
.unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: sender_epk,
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&sender_npk, &sender_vpk),
|
||||
ssk: sender_ss,
|
||||
vpk: sender_vpk,
|
||||
esk: [0; 32],
|
||||
nsk: sender_nsk,
|
||||
membership_proof: proof,
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: recipient_epk,
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&recipient_npk, &recipient_vpk),
|
||||
vpk: recipient_vpk,
|
||||
esk: [0; 32],
|
||||
npk: recipient_npk,
|
||||
ssk: recipient_ss,
|
||||
identifier: 0,
|
||||
},
|
||||
],
|
||||
|
||||
@ -907,7 +907,11 @@ fn test_wallet_ffi_transfer_shielded() -> Result<()> {
|
||||
let (to, to_keys) = unsafe {
|
||||
let mut out_keys = FfiPrivateAccountKeys::default();
|
||||
wallet_ffi_create_private_accounts_key(wallet_ffi_handle, &raw mut out_keys).unwrap();
|
||||
let account_id = lee::AccountId::for_regular_private_account(&out_keys.npk(), 0_u128);
|
||||
let account_id = lee::AccountId::for_regular_private_account(
|
||||
&out_keys.npk(),
|
||||
&out_keys.vpk().unwrap(),
|
||||
0_u128,
|
||||
);
|
||||
let to: FfiBytes32 = account_id.into();
|
||||
(to, out_keys)
|
||||
};
|
||||
@ -1044,7 +1048,11 @@ fn test_wallet_ffi_transfer_private() -> Result<()> {
|
||||
let (to, to_keys) = unsafe {
|
||||
let mut out_keys = FfiPrivateAccountKeys::default();
|
||||
wallet_ffi_create_private_accounts_key(wallet_ffi_handle, &raw mut out_keys).unwrap();
|
||||
let account_id = lee::AccountId::for_regular_private_account(&out_keys.npk(), 0_u128);
|
||||
let account_id = lee::AccountId::for_regular_private_account(
|
||||
&out_keys.npk(),
|
||||
&out_keys.vpk().unwrap(),
|
||||
0_u128,
|
||||
);
|
||||
let to: FfiBytes32 = account_id.into();
|
||||
(to, out_keys)
|
||||
};
|
||||
|
||||
@ -334,10 +334,10 @@ mod tests {
|
||||
let program_id: ProgramId = [9; 8];
|
||||
|
||||
let holder = GroupKeyHolder::from_gms(gms);
|
||||
let npk = holder
|
||||
.derive_keys_for_pda(&TEST_PROGRAM_ID, &seed)
|
||||
.generate_nullifier_public_key();
|
||||
let account_id = AccountId::for_private_pda(&program_id, &seed, &npk, u128::MAX);
|
||||
let keys = holder.derive_keys_for_pda(&TEST_PROGRAM_ID, &seed);
|
||||
let npk = keys.generate_nullifier_public_key();
|
||||
let vpk = keys.generate_viewing_public_key();
|
||||
let account_id = AccountId::for_private_pda(&program_id, &seed, &npk, &vpk, u128::MAX);
|
||||
|
||||
let expected_npk = NullifierPublicKey([
|
||||
136, 176, 234, 71, 208, 8, 143, 142, 126, 155, 132, 18, 71, 27, 88, 56, 100, 90, 79,
|
||||
@ -346,7 +346,7 @@ mod tests {
|
||||
// AccountId is derived from (program_id, seed, npk), so it changes when npk changes.
|
||||
// We verify npk is pinned, and AccountId is deterministically derived from it.
|
||||
let expected_account_id =
|
||||
AccountId::for_private_pda(&program_id, &seed, &expected_npk, u128::MAX);
|
||||
AccountId::for_private_pda(&program_id, &seed, &expected_npk, &vpk, u128::MAX);
|
||||
|
||||
assert_eq!(npk, expected_npk);
|
||||
assert_eq!(account_id, expected_account_id);
|
||||
@ -543,13 +543,16 @@ mod tests {
|
||||
let bob_holder =
|
||||
GroupKeyHolder::unseal(&sealed, &bob_vsk).expect("Bob should unseal the GMS");
|
||||
|
||||
let bob_npk = bob_holder
|
||||
.derive_keys_for_pda(&TEST_PROGRAM_ID, &pda_seed)
|
||||
.generate_nullifier_public_key();
|
||||
let bob_group_keys = bob_holder.derive_keys_for_pda(&TEST_PROGRAM_ID, &pda_seed);
|
||||
let bob_npk = bob_group_keys.generate_nullifier_public_key();
|
||||
assert_eq!(alice_npk, bob_npk);
|
||||
|
||||
let alice_account_id = AccountId::for_private_pda(&program_id, &pda_seed, &alice_npk, 0);
|
||||
let bob_account_id = AccountId::for_private_pda(&program_id, &pda_seed, &bob_npk, 0);
|
||||
let alice_vpk = alice_keys.generate_viewing_public_key();
|
||||
let bob_group_vpk = bob_group_keys.generate_viewing_public_key();
|
||||
let alice_account_id =
|
||||
AccountId::for_private_pda(&program_id, &pda_seed, &alice_npk, &alice_vpk, 0);
|
||||
let bob_account_id =
|
||||
AccountId::for_private_pda(&program_id, &pda_seed, &bob_npk, &bob_group_vpk, 0);
|
||||
assert_eq!(alice_account_id, bob_account_id);
|
||||
}
|
||||
|
||||
|
||||
@ -123,10 +123,11 @@ impl KeyTreeNode for ChildKeysPrivate {
|
||||
|
||||
fn account_ids(&self) -> impl Iterator<Item = lee::AccountId> {
|
||||
let npk = self.value.0.nullifier_public_key;
|
||||
let vpk = self.value.0.viewing_public_key.clone();
|
||||
self.value
|
||||
.1
|
||||
.keys()
|
||||
.map(move |kind| lee::AccountId::for_private_account(&npk, kind))
|
||||
.map(move |kind| lee::AccountId::for_private_account(&npk, &vpk, kind))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -277,6 +277,7 @@ impl KeyTree<ChildKeysPrivate> {
|
||||
let node = self.key_map.get(cci)?;
|
||||
let account_id = lee::AccountId::for_regular_private_account(
|
||||
&node.value.0.nullifier_public_key,
|
||||
&node.value.0.viewing_public_key,
|
||||
identifier,
|
||||
);
|
||||
if self.account_id_map.contains_key(&account_id) {
|
||||
|
||||
@ -80,16 +80,6 @@ impl EncryptedAccountData {
|
||||
view_tag,
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the tag as the first byte of SHA256("/LEE/v0.3/ViewTag/" || npk || vpk).
|
||||
#[must_use]
|
||||
pub fn compute_view_tag(npk: &crate::NullifierPublicKey, vpk: &ViewingPublicKey) -> ViewTag {
|
||||
let mut bytes = Vec::new();
|
||||
bytes.extend_from_slice(b"/LEE/v0.3/ViewTag/");
|
||||
bytes.extend_from_slice(&npk.to_byte_array());
|
||||
bytes.extend_from_slice(vpk.to_bytes());
|
||||
Impl::hash_bytes(&bytes).as_bytes()[0]
|
||||
}
|
||||
}
|
||||
|
||||
impl EncryptionScheme {
|
||||
|
||||
@ -11,7 +11,8 @@ pub use commitment::{
|
||||
compute_digest_for_path,
|
||||
};
|
||||
pub use encryption::{
|
||||
EncryptedAccountData, EncryptionScheme, EphemeralPublicKey, SharedSecretKey, ViewTag,
|
||||
EncryptedAccountData, EncryptionScheme, EphemeralPublicKey, EphemeralSecretKey,
|
||||
SharedSecretKey, ViewTag,
|
||||
};
|
||||
pub use nullifier::{Identifier, Nullifier, NullifierPublicKey, NullifierSecretKey};
|
||||
pub use program::PrivateAccountKind;
|
||||
|
||||
@ -178,8 +178,8 @@ mod tests {
|
||||
#![expect(clippy::shadow_unrelated, reason = "We don't care about it in tests")]
|
||||
|
||||
use lee_core::{
|
||||
Commitment, DUMMY_COMMITMENT_HASH, EncryptedAccountData, EncryptionScheme,
|
||||
EphemeralPublicKey, Nullifier, PrivacyPreservingCircuitOutput, SharedSecretKey,
|
||||
Commitment, DUMMY_COMMITMENT_HASH, EncryptionScheme, Nullifier,
|
||||
PrivacyPreservingCircuitOutput, SharedSecretKey,
|
||||
account::{Account, AccountId, AccountWithMetadata, Nonce, data::Data},
|
||||
program::{PdaSeed, PrivateAccountKind},
|
||||
};
|
||||
@ -235,7 +235,8 @@ mod tests {
|
||||
AccountId::new([0; 32]),
|
||||
);
|
||||
|
||||
let recipient_account_id = AccountId::for_regular_private_account(&recipient_keys.npk(), 0);
|
||||
let recipient_account_id =
|
||||
AccountId::for_regular_private_account(&recipient_keys.npk(), &recipient_keys.vpk(), 0);
|
||||
let recipient = AccountWithMetadata::new(Account::default(), false, recipient_account_id);
|
||||
|
||||
let balance_to_move: u128 = 37;
|
||||
@ -268,13 +269,9 @@ mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(
|
||||
&recipient_keys.npk(),
|
||||
&recipient_keys.vpk(),
|
||||
),
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
ssk: shared_secret,
|
||||
identifier: 0,
|
||||
},
|
||||
],
|
||||
@ -317,12 +314,14 @@ mod tests {
|
||||
data: Data::default(),
|
||||
},
|
||||
true,
|
||||
AccountId::for_regular_private_account(&sender_keys.npk(), 0),
|
||||
AccountId::for_regular_private_account(&sender_keys.npk(), &sender_keys.vpk(), 0),
|
||||
);
|
||||
let sender_account_id = AccountId::for_regular_private_account(&sender_keys.npk(), 0);
|
||||
let sender_account_id =
|
||||
AccountId::for_regular_private_account(&sender_keys.npk(), &sender_keys.vpk(), 0);
|
||||
let commitment_sender = Commitment::new(&sender_account_id, &sender_pre.account);
|
||||
|
||||
let recipient_account_id = AccountId::for_regular_private_account(&recipient_keys.npk(), 0);
|
||||
let recipient_account_id =
|
||||
AccountId::for_regular_private_account(&recipient_keys.npk(), &recipient_keys.vpk(), 0);
|
||||
let recipient = AccountWithMetadata::new(Account::default(), false, recipient_account_id);
|
||||
let balance_to_move: u128 = 37;
|
||||
|
||||
@ -372,12 +371,8 @@ mod tests {
|
||||
.unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(
|
||||
&sender_keys.npk(),
|
||||
&sender_keys.vpk(),
|
||||
),
|
||||
ssk: shared_secret_1,
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: commitment_set
|
||||
.get_proof_for(&commitment_sender)
|
||||
@ -385,13 +380,9 @@ mod tests {
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(
|
||||
&recipient_keys.npk(),
|
||||
&recipient_keys.vpk(),
|
||||
),
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
ssk: shared_secret_2,
|
||||
identifier: 0,
|
||||
},
|
||||
],
|
||||
@ -431,7 +422,7 @@ mod tests {
|
||||
let pre = AccountWithMetadata::new(
|
||||
Account::default(),
|
||||
false,
|
||||
AccountId::for_regular_private_account(&account_keys.npk(), 0),
|
||||
AccountId::for_regular_private_account(&account_keys.npk(), &account_keys.vpk(), 0),
|
||||
);
|
||||
|
||||
let validity_window_chain_caller = Program::validity_window_chain_caller();
|
||||
@ -446,9 +437,6 @@ mod tests {
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let shared_secret =
|
||||
SharedSecretKey::encapsulate_deterministic(&account_keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
let program_with_deps = ProgramWithDependencies::new(
|
||||
validity_window_chain_caller,
|
||||
[(validity_window.id(), validity_window)].into(),
|
||||
@ -458,13 +446,9 @@ mod tests {
|
||||
vec![pre],
|
||||
instruction,
|
||||
vec![InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(
|
||||
&account_keys.npk(),
|
||||
&account_keys.vpk(),
|
||||
),
|
||||
vpk: account_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
npk: account_keys.npk(),
|
||||
ssk: shared_secret,
|
||||
identifier: 0,
|
||||
}],
|
||||
&program_with_deps,
|
||||
@ -485,17 +469,17 @@ mod tests {
|
||||
let shared_secret =
|
||||
SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
let account_id = AccountId::for_private_pda(&program.id(), &seed, &npk, identifier);
|
||||
let account_id =
|
||||
AccountId::for_private_pda(&program.id(), &seed, &npk, &keys.vpk(), identifier);
|
||||
let pre_state = AccountWithMetadata::new(Account::default(), false, account_id);
|
||||
|
||||
let (output, _proof) = execute_and_prove(
|
||||
vec![pre_state],
|
||||
Program::serialize_instruction(seed).unwrap(),
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&npk, &keys.vpk()),
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
npk,
|
||||
ssk: shared_secret,
|
||||
identifier,
|
||||
seed: None,
|
||||
}],
|
||||
@ -523,11 +507,9 @@ mod tests {
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
let shared_secret_pda =
|
||||
SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
// PDA (new, private PDA)
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, 0);
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, &keys.vpk(), 0);
|
||||
let pda_pre = AccountWithMetadata::new(Account::default(), false, pda_id);
|
||||
|
||||
let auth_id = auth_transfer.id();
|
||||
@ -541,10 +523,9 @@ mod tests {
|
||||
vec![pda_pre],
|
||||
instruction,
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&npk, &keys.vpk()),
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
npk,
|
||||
ssk: shared_secret_pda,
|
||||
identifier: 0,
|
||||
seed: None,
|
||||
}],
|
||||
@ -565,11 +546,9 @@ mod tests {
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
let shared_secret_pda =
|
||||
SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
// PDA (new, private PDA)
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, 0);
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, &keys.vpk(), 0);
|
||||
let pda_pre = AccountWithMetadata::new(Account::default(), false, pda_id);
|
||||
|
||||
// Recipient (public)
|
||||
@ -596,10 +575,9 @@ mod tests {
|
||||
instruction,
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&npk, &keys.vpk()),
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
npk,
|
||||
ssk: shared_secret_pda,
|
||||
identifier: 0,
|
||||
seed: None,
|
||||
},
|
||||
@ -623,8 +601,6 @@ mod tests {
|
||||
let shared_keys = test_private_account_keys_1();
|
||||
let shared_npk = shared_keys.npk();
|
||||
let shared_identifier: u128 = 42;
|
||||
let shared_secret =
|
||||
SharedSecretKey::encapsulate_deterministic(&shared_keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
// Sender: public account with balance, owned by auth-transfer
|
||||
let sender_id = AccountId::new([99; 32]);
|
||||
@ -639,7 +615,8 @@ mod tests {
|
||||
);
|
||||
|
||||
// Recipient: shared private account (new, unauthorized)
|
||||
let shared_account_id = AccountId::from((&shared_npk, shared_identifier));
|
||||
let shared_account_id =
|
||||
AccountId::from((&shared_npk, &shared_keys.vpk(), shared_identifier));
|
||||
let recipient = AccountWithMetadata::new(Account::default(), false, shared_account_id);
|
||||
|
||||
let balance_to_move: u128 = 100;
|
||||
@ -655,13 +632,9 @@ mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(
|
||||
&shared_npk,
|
||||
&shared_keys.vpk(),
|
||||
),
|
||||
vpk: shared_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
npk: shared_npk,
|
||||
ssk: shared_secret,
|
||||
identifier: shared_identifier,
|
||||
},
|
||||
],
|
||||
@ -681,7 +654,8 @@ mod tests {
|
||||
let keys = test_private_account_keys_1();
|
||||
let identifier: u128 = 99;
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
let account_id = AccountId::for_regular_private_account(&keys.npk(), identifier);
|
||||
let account_id =
|
||||
AccountId::for_regular_private_account(&keys.npk(), &keys.vpk(), identifier);
|
||||
let pre = AccountWithMetadata::new(Account::default(), true, account_id);
|
||||
|
||||
let (output, _) = execute_and_prove(
|
||||
@ -689,9 +663,8 @@ mod tests {
|
||||
Program::serialize_instruction(authenticated_transfer_core::Instruction::Initialize)
|
||||
.unwrap(),
|
||||
vec![InputAccountIdentity::PrivateAuthorizedInit {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&keys.npk(), &keys.vpk()),
|
||||
ssk,
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
nsk: keys.nsk,
|
||||
identifier,
|
||||
}],
|
||||
@ -723,7 +696,8 @@ mod tests {
|
||||
true,
|
||||
AccountId::new([0; 32]),
|
||||
);
|
||||
let recipient_id = AccountId::for_regular_private_account(&keys.npk(), identifier);
|
||||
let recipient_id =
|
||||
AccountId::for_regular_private_account(&keys.npk(), &keys.vpk(), identifier);
|
||||
let recipient = AccountWithMetadata::new(Account::default(), false, recipient_id);
|
||||
|
||||
let (output, _) = execute_and_prove(
|
||||
@ -735,10 +709,9 @@ mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&keys.npk(), &keys.vpk()),
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
npk: keys.npk(),
|
||||
ssk,
|
||||
identifier,
|
||||
},
|
||||
],
|
||||
@ -760,7 +733,8 @@ mod tests {
|
||||
let keys = test_private_account_keys_1();
|
||||
let identifier: u128 = 99;
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
let account_id = AccountId::for_regular_private_account(&keys.npk(), identifier);
|
||||
let account_id =
|
||||
AccountId::for_regular_private_account(&keys.npk(), &keys.vpk(), identifier);
|
||||
let account = Account {
|
||||
program_owner: program.id(),
|
||||
balance: 1,
|
||||
@ -781,9 +755,8 @@ mod tests {
|
||||
.unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&keys.npk(), &keys.vpk()),
|
||||
ssk,
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
nsk: keys.nsk,
|
||||
membership_proof: commitment_set.get_proof_for(&commitment).unwrap(),
|
||||
identifier,
|
||||
@ -813,7 +786,8 @@ mod tests {
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
let auth_transfer_id = auth_transfer.id();
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, identifier);
|
||||
let pda_id =
|
||||
AccountId::for_private_pda(&program.id(), &seed, &npk, &keys.vpk(), identifier);
|
||||
let pda_account = Account {
|
||||
program_owner: auth_transfer_id,
|
||||
balance: 1,
|
||||
@ -837,9 +811,8 @@ mod tests {
|
||||
Program::serialize_instruction((seed, 1_u128, auth_transfer_id, false)).unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&npk, &keys.vpk()),
|
||||
ssk,
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
nsk: keys.nsk,
|
||||
membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(),
|
||||
identifier,
|
||||
@ -867,20 +840,16 @@ mod tests {
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
let shared_secret =
|
||||
SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
let account_id = AccountId::for_private_pda(&program.id(), &seed, &npk, 5);
|
||||
let account_id = AccountId::for_private_pda(&program.id(), &seed, &npk, &keys.vpk(), 5);
|
||||
let pre_state = AccountWithMetadata::new(Account::default(), false, account_id);
|
||||
|
||||
let result = execute_and_prove(
|
||||
vec![pre_state],
|
||||
Program::serialize_instruction(seed).unwrap(),
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&npk, &keys.vpk()),
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
npk,
|
||||
ssk: shared_secret,
|
||||
identifier: 99,
|
||||
seed: None,
|
||||
}],
|
||||
@ -897,10 +866,8 @@ mod tests {
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
let auth_transfer_id = auth_transfer.id();
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, 5);
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, &keys.vpk(), 5);
|
||||
let pda_account = Account {
|
||||
program_owner: auth_transfer_id,
|
||||
balance: 1,
|
||||
@ -922,9 +889,8 @@ mod tests {
|
||||
Program::serialize_instruction((seed, 1_u128, auth_transfer_id, false)).unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&npk, &keys.vpk()),
|
||||
ssk,
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
nsk: keys.nsk,
|
||||
membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(),
|
||||
identifier: 99,
|
||||
|
||||
@ -109,6 +109,7 @@ pub mod tests {
|
||||
|
||||
let npk1 = NullifierPublicKey::from(&nsk1);
|
||||
let npk2 = NullifierPublicKey::from(&nsk2);
|
||||
let vpk = ViewingPublicKey::from_seed(&[7; 32], &[8; 32]);
|
||||
|
||||
let public_account_ids = vec![AccountId::new([1; 32])];
|
||||
|
||||
@ -118,10 +119,10 @@ pub mod tests {
|
||||
|
||||
let encrypted_private_post_states = Vec::new();
|
||||
|
||||
let account_id2 = lee_core::account::AccountId::for_regular_private_account(&npk2, 0);
|
||||
let account_id2 = lee_core::account::AccountId::for_regular_private_account(&npk2, &vpk, 0);
|
||||
let new_commitments = vec![Commitment::new(&account_id2, &account2)];
|
||||
|
||||
let account_id1 = lee_core::account::AccountId::for_regular_private_account(&npk1, 0);
|
||||
let account_id1 = lee_core::account::AccountId::for_regular_private_account(&npk1, &vpk, 0);
|
||||
let old_commitment = Commitment::new(&account_id1, &account1);
|
||||
let new_nullifiers = vec![(
|
||||
Nullifier::for_account_update(&old_commitment, &nsk1),
|
||||
@ -197,7 +198,7 @@ pub mod tests {
|
||||
let npk = NullifierPublicKey::from(&[1; 32]);
|
||||
let vpk = ViewingPublicKey::from_seed(&[2_u8; 32], &[3_u8; 32]);
|
||||
let account = Account::default();
|
||||
let account_id = lee_core::account::AccountId::for_regular_private_account(&npk, 0);
|
||||
let account_id = lee_core::account::AccountId::for_regular_private_account(&npk, &vpk, 0);
|
||||
let commitment = Commitment::new(&account_id, &account);
|
||||
let (shared_secret, epk) = SharedSecretKey::encapsulate_deterministic(&vpk, &[0_u8; 32], 0);
|
||||
let ciphertext = EncryptionScheme::encrypt(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -575,7 +575,7 @@ mod tests {
|
||||
#[test]
|
||||
fn privacy_malicious_programs_cannot_drain_public_victim() {
|
||||
use lee_core::{
|
||||
Commitment, EncryptedAccountData, InputAccountIdentity, SharedSecretKey,
|
||||
Commitment, InputAccountIdentity,
|
||||
account::{Account, AccountWithMetadata},
|
||||
};
|
||||
|
||||
@ -602,8 +602,8 @@ mod tests {
|
||||
|
||||
// Attacker controls a private account.
|
||||
let attacker_keys = test_private_account_keys_1();
|
||||
let attacker_id = AccountId::for_regular_private_account(&attacker_keys.npk(), 0);
|
||||
let (attacker_ssk, attacker_epk) = SharedSecretKey::encapsulate(&attacker_keys.vpk());
|
||||
let attacker_id =
|
||||
AccountId::for_regular_private_account(&attacker_keys.npk(), &attacker_keys.vpk(), 0);
|
||||
|
||||
let victim_id = AccountId::new([20_u8; 32]);
|
||||
let recipient_id = AccountId::new([42_u8; 32]);
|
||||
@ -659,12 +659,8 @@ mod tests {
|
||||
// [2] recipient — first seen in authenticated_transfer's program_output.pre_states
|
||||
let account_identities = vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: attacker_epk,
|
||||
view_tag: EncryptedAccountData::compute_view_tag(
|
||||
&attacker_keys.npk(),
|
||||
&attacker_keys.vpk(),
|
||||
),
|
||||
ssk: attacker_ssk,
|
||||
vpk: attacker_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
nsk: attacker_keys.nsk,
|
||||
membership_proof,
|
||||
identifier: 0,
|
||||
@ -727,7 +723,7 @@ mod tests {
|
||||
#[test]
|
||||
fn privacy_malicious_programs_cannot_drain_private_victim() {
|
||||
use lee_core::{
|
||||
Commitment, EncryptedAccountData, InputAccountIdentity, SharedSecretKey,
|
||||
Commitment, InputAccountIdentity,
|
||||
account::{Account, AccountWithMetadata},
|
||||
};
|
||||
|
||||
@ -757,12 +753,13 @@ mod tests {
|
||||
|
||||
// Attacker controls a private account.
|
||||
let attacker_keys = test_private_account_keys_1();
|
||||
let attacker_id = AccountId::for_regular_private_account(&attacker_keys.npk(), 0);
|
||||
let (attacker_ssk, attacker_epk) = SharedSecretKey::encapsulate(&attacker_keys.vpk());
|
||||
let attacker_id =
|
||||
AccountId::for_regular_private_account(&attacker_keys.npk(), &attacker_keys.vpk(), 0);
|
||||
|
||||
// Victim is a private account — not registered in public chain state.
|
||||
let victim_keys = test_private_account_keys_2();
|
||||
let victim_id = AccountId::for_regular_private_account(&victim_keys.npk(), 0);
|
||||
let victim_id =
|
||||
AccountId::for_regular_private_account(&victim_keys.npk(), &victim_keys.vpk(), 0);
|
||||
let victim_balance = 5_000_u128;
|
||||
|
||||
let recipient_id = AccountId::new([42_u8; 32]);
|
||||
@ -819,12 +816,8 @@ mod tests {
|
||||
// so PrivateAuthorizedUpdate is not an option.
|
||||
let account_identities = vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: attacker_epk,
|
||||
view_tag: EncryptedAccountData::compute_view_tag(
|
||||
&attacker_keys.npk(),
|
||||
&attacker_keys.vpk(),
|
||||
),
|
||||
ssk: attacker_ssk,
|
||||
vpk: attacker_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
nsk: attacker_keys.nsk,
|
||||
membership_proof,
|
||||
identifier: 0,
|
||||
|
||||
@ -819,8 +819,7 @@ mod tests {
|
||||
};
|
||||
use key_protocol::key_management::KeyChain;
|
||||
use lee::{
|
||||
Account, AccountId, Data, EphemeralPublicKey, PrivacyPreservingTransaction,
|
||||
SharedSecretKey, V03State,
|
||||
Account, AccountId, Data, PrivacyPreservingTransaction, V03State,
|
||||
error::LeeError,
|
||||
execute_and_prove,
|
||||
privacy_preserving_transaction::{Message, circuit::ProgramWithDependencies},
|
||||
@ -828,7 +827,7 @@ mod tests {
|
||||
system_bridge_account_id,
|
||||
};
|
||||
use lee_core::{
|
||||
Commitment, EncryptedAccountData, InputAccountIdentity, Nullifier,
|
||||
Commitment, InputAccountIdentity, Nullifier,
|
||||
account::{AccountWithMetadata, Nonce},
|
||||
};
|
||||
use logos_blockchain_core::mantle::ops::channel::ChannelId;
|
||||
@ -1605,8 +1604,11 @@ mod tests {
|
||||
#[test]
|
||||
fn private_bridge_withdraw_invocation_is_dropped() {
|
||||
let sender_keys = KeyChain::new_os_random();
|
||||
let sender_account_id =
|
||||
AccountId::for_regular_private_account(&sender_keys.nullifier_public_key, 0);
|
||||
let sender_account_id = AccountId::for_regular_private_account(
|
||||
&sender_keys.nullifier_public_key,
|
||||
&sender_keys.viewing_public_key,
|
||||
0,
|
||||
);
|
||||
let sender_private_account = Account {
|
||||
program_owner: Program::authenticated_transfer_program().id(),
|
||||
balance: 100,
|
||||
@ -1629,7 +1631,11 @@ mod tests {
|
||||
let sender_pre = AccountWithMetadata::new(
|
||||
sender_private_account,
|
||||
true,
|
||||
(&sender_keys.nullifier_public_key, 0),
|
||||
(
|
||||
&sender_keys.nullifier_public_key,
|
||||
&sender_keys.viewing_public_key,
|
||||
0,
|
||||
),
|
||||
);
|
||||
let bridge_pre = AccountWithMetadata::new(
|
||||
state.get_account_by_id(bridge_account_id),
|
||||
@ -1637,8 +1643,6 @@ mod tests {
|
||||
bridge_account_id,
|
||||
);
|
||||
|
||||
let shared_secret = SharedSecretKey::encapsulate(&sender_keys.viewing_public_key).0;
|
||||
|
||||
let instruction = Program::serialize_instruction(bridge_core::Instruction::Withdraw {
|
||||
amount: 1,
|
||||
bedrock_account_pk: [0; 32],
|
||||
@ -1659,12 +1663,8 @@ mod tests {
|
||||
instruction,
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: EphemeralPublicKey(vec![12_u8; 1088]),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(
|
||||
&sender_keys.nullifier_public_key,
|
||||
&sender_keys.viewing_public_key,
|
||||
),
|
||||
ssk: shared_secret,
|
||||
vpk: sender_keys.viewing_public_key,
|
||||
esk: [0; 32],
|
||||
nsk: sender_keys.private_key_holder.nullifier_secret_key,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&sender_commitment)
|
||||
|
||||
@ -85,6 +85,7 @@ pub struct PublicAccountPublicInitialData {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct PrivateAccountPublicInitialData {
|
||||
pub npk: lee_core::NullifierPublicKey,
|
||||
pub vpk: lee_core::encryption::ViewingPublicKey,
|
||||
pub account: lee_core::account::Account,
|
||||
}
|
||||
|
||||
@ -107,6 +108,7 @@ impl PrivateAccountPrivateInitialData {
|
||||
pub fn account_id(&self) -> lee::AccountId {
|
||||
lee::AccountId::for_regular_private_account(
|
||||
&self.key_chain.nullifier_public_key,
|
||||
&self.key_chain.viewing_public_key,
|
||||
self.identifier,
|
||||
)
|
||||
}
|
||||
@ -184,6 +186,7 @@ pub fn initial_commitments() -> Vec<PrivateAccountPublicInitialData> {
|
||||
.into_iter()
|
||||
.map(|data| PrivateAccountPublicInitialData {
|
||||
npk: data.key_chain.nullifier_public_key,
|
||||
vpk: data.key_chain.viewing_public_key.clone(),
|
||||
account: data.account,
|
||||
})
|
||||
.collect()
|
||||
@ -215,7 +218,8 @@ pub fn initial_state() -> V03State {
|
||||
.iter()
|
||||
.map(|init_comm_data| {
|
||||
let npk = &init_comm_data.npk;
|
||||
let account_id = lee::AccountId::for_regular_private_account(npk, 0);
|
||||
let account_id =
|
||||
lee::AccountId::for_regular_private_account(npk, &init_comm_data.vpk, 0);
|
||||
|
||||
let mut acc = init_comm_data.account.clone();
|
||||
|
||||
@ -390,6 +394,10 @@ mod tests {
|
||||
init_comms[0],
|
||||
PrivateAccountPublicInitialData {
|
||||
npk: NullifierPublicKey(NPK_PRIV_ACC_A),
|
||||
vpk: init_private_accs_keys[0]
|
||||
.key_chain
|
||||
.viewing_public_key
|
||||
.clone(),
|
||||
account: Account {
|
||||
program_owner: DEFAULT_PROGRAM_OWNER,
|
||||
balance: PRIV_ACC_A_INITIAL_BALANCE,
|
||||
@ -403,6 +411,10 @@ mod tests {
|
||||
init_comms[1],
|
||||
PrivateAccountPublicInitialData {
|
||||
npk: NullifierPublicKey(NPK_PRIV_ACC_B),
|
||||
vpk: init_private_accs_keys[1]
|
||||
.key_chain
|
||||
.viewing_public_key
|
||||
.clone(),
|
||||
account: Account {
|
||||
program_owner: DEFAULT_PROGRAM_OWNER,
|
||||
balance: PRIV_ACC_B_INITIAL_BALANCE,
|
||||
|
||||
@ -601,9 +601,10 @@ mod tests {
|
||||
let identifier = u128::from_le_bytes([45; 16]);
|
||||
|
||||
let private_reg_acc_id =
|
||||
AccountId::for_private_account(&npk, &PrivateAccountKind::Regular(identifier));
|
||||
AccountId::for_private_account(&npk, &vpk, &PrivateAccountKind::Regular(identifier));
|
||||
let private_pda_acc_id = AccountId::for_private_account(
|
||||
&npk,
|
||||
&vpk,
|
||||
&PrivateAccountKind::Pda {
|
||||
program_id: [46; 8],
|
||||
seed: PdaSeed::new([47; 32]),
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
use core::fmt;
|
||||
|
||||
use anyhow::Result;
|
||||
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
|
||||
use keycard_wallet::{KeycardWallet, python_path};
|
||||
use lee::{AccountId, PrivateKey, PublicKey, Signature};
|
||||
use lee_core::{
|
||||
Identifier, InputAccountIdentity, MembershipProof, NullifierPublicKey, NullifierSecretKey,
|
||||
SharedSecretKey,
|
||||
EphemeralSecretKey, Identifier, InputAccountIdentity, MembershipProof, NullifierPublicKey,
|
||||
NullifierSecretKey, SharedSecretKey,
|
||||
account::{AccountWithMetadata, Nonce},
|
||||
encryption::{EncryptedAccountData, EphemeralPublicKey, ViewingPublicKey},
|
||||
encryption::ViewingPublicKey,
|
||||
};
|
||||
use rand::{RngCore as _, rngs::OsRng};
|
||||
|
||||
use crate::{ExecutionFailureKind, WalletCore};
|
||||
|
||||
@ -261,10 +261,9 @@ impl AccountManager {
|
||||
identifier,
|
||||
} => {
|
||||
let acc = lee_core::account::Account::default();
|
||||
let auth_acc = AccountWithMetadata::new(acc, false, (&npk, identifier));
|
||||
let eph_holder = EphemeralKeyHolder::new(&vpk);
|
||||
let ssk = eph_holder.calculate_shared_secret_sender();
|
||||
let epk = eph_holder.ephemeral_public_key().clone();
|
||||
let auth_acc = AccountWithMetadata::new(acc, false, (&npk, &vpk, identifier));
|
||||
let mut esk: EphemeralSecretKey = [0; 32];
|
||||
OsRng.fill_bytes(&mut esk);
|
||||
let pre = AccountPreparedData {
|
||||
nsk: None,
|
||||
npk,
|
||||
@ -272,8 +271,7 @@ impl AccountManager {
|
||||
vpk,
|
||||
pre_state: auth_acc,
|
||||
proof: None,
|
||||
ssk,
|
||||
epk,
|
||||
esk,
|
||||
is_pda: false,
|
||||
};
|
||||
|
||||
@ -291,9 +289,8 @@ impl AccountManager {
|
||||
} => {
|
||||
let acc = lee_core::account::Account::default();
|
||||
let auth_acc = AccountWithMetadata::new(acc, false, account_id);
|
||||
let eph_holder = EphemeralKeyHolder::new(&vpk);
|
||||
let ssk = eph_holder.calculate_shared_secret_sender();
|
||||
let epk = eph_holder.ephemeral_public_key().clone();
|
||||
let mut esk: EphemeralSecretKey = [0; 32];
|
||||
OsRng.fill_bytes(&mut esk);
|
||||
let pre = AccountPreparedData {
|
||||
nsk: None,
|
||||
npk,
|
||||
@ -301,8 +298,7 @@ impl AccountManager {
|
||||
vpk,
|
||||
pre_state: auth_acc,
|
||||
proof: None,
|
||||
ssk,
|
||||
epk,
|
||||
esk,
|
||||
is_pda: true,
|
||||
};
|
||||
State::Private(pre)
|
||||
@ -313,7 +309,7 @@ impl AccountManager {
|
||||
vpk,
|
||||
identifier,
|
||||
} => {
|
||||
let account_id = lee::AccountId::from((&npk, identifier));
|
||||
let account_id = lee::AccountId::from((&npk, &vpk, identifier));
|
||||
let pre = private_shared_acc_preparation(
|
||||
wallet, account_id, nsk, npk, vpk, identifier, false,
|
||||
)
|
||||
@ -373,9 +369,18 @@ impl AccountManager {
|
||||
self.states
|
||||
.iter()
|
||||
.filter_map(|state| match state {
|
||||
State::Private(pre) => Some(PrivateAccountKeys { ssk: pre.ssk }),
|
||||
State::Private(pre) => Some(pre),
|
||||
State::Public { .. } | State::PublicKeycard { .. } => None,
|
||||
})
|
||||
.enumerate()
|
||||
.map(|(output_index, pre)| PrivateAccountKeys {
|
||||
ssk: SharedSecretKey::encapsulate_deterministic(
|
||||
&pre.vpk,
|
||||
&pre.esk,
|
||||
u32::try_from(output_index).expect("private output index fits in u32"),
|
||||
)
|
||||
.0,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -390,19 +395,17 @@ impl AccountManager {
|
||||
State::Public { .. } | State::PublicKeycard { .. } => InputAccountIdentity::Public,
|
||||
State::Private(pre) if pre.is_pda => match (pre.nsk, pre.proof.clone()) {
|
||||
(Some(nsk), Some(membership_proof)) => InputAccountIdentity::PrivatePdaUpdate {
|
||||
epk: pre.epk.clone(),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&pre.npk, &pre.vpk),
|
||||
ssk: pre.ssk,
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
nsk,
|
||||
membership_proof,
|
||||
identifier: pre.identifier,
|
||||
seed: None,
|
||||
},
|
||||
_ => InputAccountIdentity::PrivatePdaInit {
|
||||
epk: pre.epk.clone(),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&pre.npk, &pre.vpk),
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
npk: pre.npk,
|
||||
ssk: pre.ssk,
|
||||
identifier: pre.identifier,
|
||||
seed: None,
|
||||
},
|
||||
@ -410,26 +413,23 @@ impl AccountManager {
|
||||
State::Private(pre) => match (pre.nsk, pre.proof.clone()) {
|
||||
(Some(nsk), Some(membership_proof)) => {
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: pre.epk.clone(),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&pre.npk, &pre.vpk),
|
||||
ssk: pre.ssk,
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
nsk,
|
||||
membership_proof,
|
||||
identifier: pre.identifier,
|
||||
}
|
||||
}
|
||||
(Some(nsk), None) => InputAccountIdentity::PrivateAuthorizedInit {
|
||||
epk: pre.epk.clone(),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&pre.npk, &pre.vpk),
|
||||
ssk: pre.ssk,
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
nsk,
|
||||
identifier: pre.identifier,
|
||||
},
|
||||
(None, _) => InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: pre.epk.clone(),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&pre.npk, &pre.vpk),
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
npk: pre.npk,
|
||||
ssk: pre.ssk,
|
||||
identifier: pre.identifier,
|
||||
},
|
||||
},
|
||||
@ -505,13 +505,7 @@ struct AccountPreparedData {
|
||||
vpk: ViewingPublicKey,
|
||||
pre_state: AccountWithMetadata,
|
||||
proof: Option<MembershipProof>,
|
||||
/// Cached shared-secret key derived once at `AccountManager::new`. Reused for both the
|
||||
/// circuit input variant (`account_identities()`) and the message ephemeral-key tuples
|
||||
/// (`private_account_keys()`), so all consumers see the same key. The corresponding
|
||||
/// `EphemeralKeyHolder` uses `OsRng` and would produce a different value on a second call.
|
||||
ssk: SharedSecretKey,
|
||||
/// Cached ephemeral public key, paired with `ssk`.
|
||||
epk: EphemeralPublicKey,
|
||||
esk: EphemeralSecretKey,
|
||||
/// True when this account is a private PDA (owned or foreign). Used by `account_identities()`
|
||||
/// to select `PrivatePdaInit`/`PrivatePdaUpdate` rather than the standalone private variants.
|
||||
is_pda: bool,
|
||||
@ -542,9 +536,8 @@ async fn private_key_tree_acc_preparation(
|
||||
// support from that in the wallet.
|
||||
let sender_pre = AccountWithMetadata::new(from_acc.account.clone(), true, account_id);
|
||||
|
||||
let eph_holder = EphemeralKeyHolder::new(&from_vpk);
|
||||
let ssk = eph_holder.calculate_shared_secret_sender();
|
||||
let epk = eph_holder.ephemeral_public_key().clone();
|
||||
let mut esk: EphemeralSecretKey = [0; 32];
|
||||
OsRng.fill_bytes(&mut esk);
|
||||
|
||||
Ok(AccountPreparedData {
|
||||
nsk: Some(nsk),
|
||||
@ -553,8 +546,7 @@ async fn private_key_tree_acc_preparation(
|
||||
vpk: from_vpk,
|
||||
pre_state: sender_pre,
|
||||
proof,
|
||||
ssk,
|
||||
epk,
|
||||
esk,
|
||||
is_pda,
|
||||
})
|
||||
}
|
||||
@ -582,9 +574,8 @@ async fn private_shared_acc_preparation(
|
||||
.await
|
||||
.unwrap_or(None);
|
||||
|
||||
let eph_holder = EphemeralKeyHolder::new(&vpk);
|
||||
let ssk = eph_holder.calculate_shared_secret_sender();
|
||||
let epk = eph_holder.ephemeral_public_key().clone();
|
||||
let mut esk: EphemeralSecretKey = [0; 32];
|
||||
OsRng.fill_bytes(&mut esk);
|
||||
|
||||
Ok(AccountPreparedData {
|
||||
nsk: Some(nsk),
|
||||
@ -593,8 +584,7 @@ async fn private_shared_acc_preparation(
|
||||
vpk,
|
||||
pre_state,
|
||||
proof,
|
||||
ssk,
|
||||
epk,
|
||||
esk,
|
||||
is_pda,
|
||||
})
|
||||
}
|
||||
|
||||
@ -525,8 +525,11 @@ impl WalletSubcommand for ImportSubcommand {
|
||||
let key_chain: KeyChain = serde_json::from_str(&key_chain_json)
|
||||
.map_err(|err| anyhow::anyhow!("Invalid key chain JSON: {err}"))?;
|
||||
let account = lee::Account::from(account_state);
|
||||
let account_id =
|
||||
lee::AccountId::from((&key_chain.nullifier_public_key, identifier));
|
||||
let account_id = lee::AccountId::from((
|
||||
&key_chain.nullifier_public_key,
|
||||
&key_chain.viewing_public_key,
|
||||
identifier,
|
||||
));
|
||||
|
||||
wallet_core
|
||||
.storage_mut()
|
||||
|
||||
@ -377,7 +377,7 @@ impl WalletCore {
|
||||
let keys = holder.derive_keys_for_pda(&program_id, &pda_seed);
|
||||
let npk = keys.generate_nullifier_public_key();
|
||||
let vpk = keys.generate_viewing_public_key();
|
||||
let account_id = AccountId::for_private_pda(&program_id, &pda_seed, &npk, identifier);
|
||||
let account_id = AccountId::for_private_pda(&program_id, &pda_seed, &npk, &vpk, identifier);
|
||||
|
||||
self.register_shared_account(
|
||||
account_id,
|
||||
@ -419,7 +419,7 @@ impl WalletCore {
|
||||
let keys = holder.derive_keys_for_shared_account(&derivation_seed);
|
||||
let npk = keys.generate_nullifier_public_key();
|
||||
let vpk = keys.generate_viewing_public_key();
|
||||
let account_id = AccountId::from((&npk, identifier));
|
||||
let account_id = AccountId::from((&npk, &vpk, identifier));
|
||||
|
||||
self.register_shared_account(account_id, group_name, identifier, None, None);
|
||||
|
||||
@ -763,7 +763,11 @@ impl WalletCore {
|
||||
)
|
||||
.map(|(kind, res_acc)| {
|
||||
let npk = &key_chain.nullifier_public_key;
|
||||
let account_id = lee::AccountId::for_private_account(npk, &kind);
|
||||
let account_id = lee::AccountId::for_private_account(
|
||||
npk,
|
||||
&key_chain.viewing_public_key,
|
||||
&kind,
|
||||
);
|
||||
(account_id, kind, res_acc)
|
||||
})
|
||||
})
|
||||
|
||||
@ -174,7 +174,8 @@ impl UserKeyChain {
|
||||
.1
|
||||
.first_key_value()
|
||||
.expect("Newly created key chain node must have at least one account");
|
||||
let account_id = AccountId::for_private_account(&npk, kind);
|
||||
let account_id =
|
||||
AccountId::for_private_account(&npk, &node.value.0.viewing_public_key, kind);
|
||||
(account_id, chain_index)
|
||||
}
|
||||
|
||||
@ -240,6 +241,7 @@ impl UserKeyChain {
|
||||
.find_map(|found| {
|
||||
let expected_id = AccountId::for_private_account(
|
||||
&found.key_chain.nullifier_public_key,
|
||||
&found.key_chain.viewing_public_key,
|
||||
found.kind,
|
||||
);
|
||||
(expected_id == account_id).then_some(found)
|
||||
@ -264,8 +266,11 @@ impl UserKeyChain {
|
||||
.iter()
|
||||
.flat_map(|(key, data)| {
|
||||
data.accounts.keys().map(|kind| {
|
||||
let account_id =
|
||||
AccountId::for_private_account(&key.key_chain.nullifier_public_key, kind);
|
||||
let account_id = AccountId::for_private_account(
|
||||
&key.key_chain.nullifier_public_key,
|
||||
&key.key_chain.viewing_public_key,
|
||||
kind,
|
||||
);
|
||||
(account_id, &key.key_chain, key.chain_index.as_ref())
|
||||
})
|
||||
})
|
||||
@ -340,8 +345,11 @@ impl UserKeyChain {
|
||||
// Then try to update imported account
|
||||
for (key, data) in &mut self.imported_private_accounts {
|
||||
for (kind, imported_account) in &mut data.accounts {
|
||||
let expected_id =
|
||||
AccountId::for_private_account(&key.key_chain.nullifier_public_key, kind);
|
||||
let expected_id = AccountId::for_private_account(
|
||||
&key.key_chain.nullifier_public_key,
|
||||
&key.key_chain.viewing_public_key,
|
||||
kind,
|
||||
);
|
||||
if expected_id == account_id {
|
||||
debug!("Updating imported private account {account_id}");
|
||||
*imported_account = account;
|
||||
@ -378,8 +386,11 @@ impl UserKeyChain {
|
||||
|
||||
// Node not yet in account_id_map — find it by checking all nodes
|
||||
for (ci, node) in &mut self.private_key_tree.key_map {
|
||||
let expected_id =
|
||||
lee::AccountId::for_private_account(&node.value.0.nullifier_public_key, &kind);
|
||||
let expected_id = lee::AccountId::for_private_account(
|
||||
&node.value.0.nullifier_public_key,
|
||||
&node.value.0.viewing_public_key,
|
||||
&kind,
|
||||
);
|
||||
if expected_id == account_id {
|
||||
match node.value.1.entry(kind) {
|
||||
Entry::Occupied(mut occupied) => {
|
||||
@ -429,8 +440,11 @@ impl UserKeyChain {
|
||||
.iter()
|
||||
.flat_map(|(key, data)| {
|
||||
data.accounts.keys().map(|kind| {
|
||||
let account_id =
|
||||
AccountId::for_private_account(&key.key_chain.nullifier_public_key, kind);
|
||||
let account_id = AccountId::for_private_account(
|
||||
&key.key_chain.nullifier_public_key,
|
||||
&key.key_chain.viewing_public_key,
|
||||
kind,
|
||||
);
|
||||
(account_id, key.chain_index.as_ref())
|
||||
})
|
||||
})
|
||||
@ -720,7 +734,11 @@ mod tests {
|
||||
let mut user_data = UserKeyChain::default();
|
||||
|
||||
let key_chain = KeyChain::new_os_random();
|
||||
let account_id = AccountId::from((&key_chain.nullifier_public_key, 0));
|
||||
let account_id = AccountId::from((
|
||||
&key_chain.nullifier_public_key,
|
||||
&key_chain.viewing_public_key,
|
||||
0,
|
||||
));
|
||||
let account = lee_core::account::Account::default();
|
||||
|
||||
user_data.add_imported_private_account(key_chain, None, 0, account);
|
||||
@ -735,7 +753,11 @@ mod tests {
|
||||
let mut user_data = UserKeyChain::default();
|
||||
|
||||
let key_chain = KeyChain::new_os_random();
|
||||
let account_id = AccountId::from((&key_chain.nullifier_public_key, 0));
|
||||
let account_id = AccountId::from((
|
||||
&key_chain.nullifier_public_key,
|
||||
&key_chain.viewing_public_key,
|
||||
0,
|
||||
));
|
||||
let account = lee_core::account::Account::default();
|
||||
|
||||
user_data.add_imported_private_account(key_chain, None, 0, account.clone());
|
||||
@ -780,7 +802,11 @@ mod tests {
|
||||
let mut user_data = UserKeyChain::default();
|
||||
|
||||
let key_chain = KeyChain::new_os_random();
|
||||
let account_id = AccountId::from((&key_chain.nullifier_public_key, 0));
|
||||
let account_id = AccountId::from((
|
||||
&key_chain.nullifier_public_key,
|
||||
&key_chain.viewing_public_key,
|
||||
0,
|
||||
));
|
||||
|
||||
let new_account = lee_core::account::Account {
|
||||
balance: 100,
|
||||
@ -801,7 +827,11 @@ mod tests {
|
||||
let mut user_data = UserKeyChain::default();
|
||||
|
||||
let key_chain = KeyChain::new_os_random();
|
||||
let account_id1 = AccountId::from((&key_chain.nullifier_public_key, 0));
|
||||
let account_id1 = AccountId::from((
|
||||
&key_chain.nullifier_public_key,
|
||||
&key_chain.viewing_public_key,
|
||||
0,
|
||||
));
|
||||
let account = lee_core::account::Account::default();
|
||||
user_data.add_imported_private_account(key_chain, None, 0, account);
|
||||
|
||||
|
||||
@ -23,7 +23,11 @@ pub struct InitialPrivateAccountForWallet {
|
||||
impl InitialPrivateAccountForWallet {
|
||||
#[must_use]
|
||||
pub fn account_id(&self) -> AccountId {
|
||||
AccountId::from((&self.key_chain.nullifier_public_key, self.identifier))
|
||||
AccountId::from((
|
||||
&self.key_chain.nullifier_public_key,
|
||||
&self.key_chain.viewing_public_key,
|
||||
self.identifier,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,8 @@ fn bench_encryption(c: &mut Criterion) {
|
||||
let recipient_kc = KeyChain::new_os_random();
|
||||
let npk = recipient_kc.nullifier_public_key;
|
||||
let account = Account::default();
|
||||
let account_id = AccountId::for_regular_private_account(&npk, 0);
|
||||
let account_id =
|
||||
AccountId::for_regular_private_account(&npk, &recipient_kc.viewing_public_key, 0);
|
||||
let commitment = Commitment::new(&account_id, &account);
|
||||
let (shared, _epk) = SharedSecretKey::encapsulate(&recipient_kc.viewing_public_key);
|
||||
let kind = PrivateAccountKind::Regular(0_u128);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user