mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-06-30 02:49:53 +00:00
Merge pull request #569 from logos-blockchain/marvin/chacha-aead
fix(encryption): strengthen esk generation logic
This commit is contained in:
commit
5a23b54a6f
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.
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.
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.
@ -710,7 +710,7 @@ async fn ppt_cant_chain_call_faucet() -> Result<()> {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
vpk,
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier: 1337,
|
||||
seed: None,
|
||||
|
||||
@ -71,7 +71,7 @@ async fn fund_private_pda(
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
vpk,
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier,
|
||||
seed: Some((seed, authority_program_id)),
|
||||
|
||||
@ -293,14 +293,14 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_vpk,
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_nsk,
|
||||
membership_proof: proof,
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_vpk,
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_npk,
|
||||
identifier: 0,
|
||||
},
|
||||
|
||||
@ -4,7 +4,7 @@ use crate::{
|
||||
Commitment, CommitmentSetDigest, Identifier, MembershipProof, Nullifier, NullifierPublicKey,
|
||||
NullifierSecretKey,
|
||||
account::{Account, AccountWithMetadata},
|
||||
encryption::{EncryptedAccountData, EphemeralSecretKey, ViewingPublicKey},
|
||||
encryption::{EncryptedAccountData, ViewingPublicKey},
|
||||
program::{BlockValidityWindow, PdaSeed, ProgramId, ProgramOutput, TimestampValidityWindow},
|
||||
};
|
||||
|
||||
@ -32,7 +32,7 @@ pub enum InputAccountIdentity {
|
||||
/// and matched against `pre_state.account_id`.
|
||||
PrivateAuthorizedInit {
|
||||
vpk: ViewingPublicKey,
|
||||
esk: EphemeralSecretKey,
|
||||
random_seed: [u8; 32],
|
||||
nsk: NullifierSecretKey,
|
||||
identifier: Identifier,
|
||||
},
|
||||
@ -40,7 +40,7 @@ pub enum InputAccountIdentity {
|
||||
/// membership proof.
|
||||
PrivateAuthorizedUpdate {
|
||||
vpk: ViewingPublicKey,
|
||||
esk: EphemeralSecretKey,
|
||||
random_seed: [u8; 32],
|
||||
nsk: NullifierSecretKey,
|
||||
membership_proof: MembershipProof,
|
||||
identifier: Identifier,
|
||||
@ -49,7 +49,7 @@ pub enum InputAccountIdentity {
|
||||
/// doesn't yet exist on chain). No `nsk`, no membership proof.
|
||||
PrivateUnauthorized {
|
||||
vpk: ViewingPublicKey,
|
||||
esk: EphemeralSecretKey,
|
||||
random_seed: [u8; 32],
|
||||
npk: NullifierPublicKey,
|
||||
identifier: Identifier,
|
||||
},
|
||||
@ -59,7 +59,7 @@ pub enum InputAccountIdentity {
|
||||
/// as the 4th input.
|
||||
PrivatePdaInit {
|
||||
vpk: ViewingPublicKey,
|
||||
esk: EphemeralSecretKey,
|
||||
random_seed: [u8; 32],
|
||||
npk: NullifierPublicKey,
|
||||
identifier: Identifier,
|
||||
/// When `Some((seed, authority_program_id))`, the circuit binds this position via the
|
||||
@ -75,7 +75,7 @@ pub enum InputAccountIdentity {
|
||||
/// previously-seen authorization in a chained call.
|
||||
PrivatePdaUpdate {
|
||||
vpk: ViewingPublicKey,
|
||||
esk: EphemeralSecretKey,
|
||||
random_seed: [u8; 32],
|
||||
nsk: NullifierSecretKey,
|
||||
membership_proof: MembershipProof,
|
||||
identifier: Identifier,
|
||||
|
||||
@ -12,7 +12,30 @@ pub mod shared_key_derivation;
|
||||
|
||||
pub type Scalar = [u8; 32];
|
||||
|
||||
pub type EphemeralSecretKey = [u8; 32];
|
||||
#[derive(Serialize, Deserialize, Clone, Copy)]
|
||||
pub struct EphemeralSecretKey(pub [u8; 32]);
|
||||
|
||||
impl EphemeralSecretKey {
|
||||
/// Derives an ephemeral secret key from OS randomness and account-specific values.
|
||||
///
|
||||
/// For updates, `nonce` carries `nsk`-derived entropy, making `esk` strong even
|
||||
/// with a compromised RNG. For inits, `nonce` is deterministic, so `random_seed`
|
||||
/// is the sole entropy source.
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
account_id: &crate::account::AccountId,
|
||||
random_seed: &[u8; 32],
|
||||
nonce: &crate::account::Nonce,
|
||||
) -> Self {
|
||||
const PREFIX: &[u8; 14] = b"/LEE/v0.3/esk/";
|
||||
let mut input = [0_u8; 14 + 32 + 32 + 16];
|
||||
input[0..14].copy_from_slice(PREFIX);
|
||||
input[14..46].copy_from_slice(account_id.value());
|
||||
input[46..78].copy_from_slice(random_seed);
|
||||
input[78..94].copy_from_slice(&nonce.0.to_le_bytes());
|
||||
Self(Impl::hash_bytes(&input).as_bytes().try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy)]
|
||||
pub struct SharedSecretKey(pub [u8; 32]);
|
||||
@ -237,4 +260,41 @@ mod tests {
|
||||
"wrong shared secret must not produce the correct plaintext"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn esk_is_deterministic() {
|
||||
let account_id = AccountId::new([1_u8; 32]);
|
||||
let random_seed = [2_u8; 32];
|
||||
let nonce = crate::account::Nonce(42);
|
||||
let esk1 = EphemeralSecretKey::new(&account_id, &random_seed, &nonce);
|
||||
let esk2 = EphemeralSecretKey::new(&account_id, &random_seed, &nonce);
|
||||
assert_eq!(esk1.0, esk2.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn esk_differs_for_different_account_id() {
|
||||
let random_seed = [2_u8; 32];
|
||||
let nonce = crate::account::Nonce(42);
|
||||
let esk_a = EphemeralSecretKey::new(&AccountId::new([0_u8; 32]), &random_seed, &nonce);
|
||||
let esk_b = EphemeralSecretKey::new(&AccountId::new([1_u8; 32]), &random_seed, &nonce);
|
||||
assert_ne!(esk_a.0, esk_b.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn esk_differs_for_different_random_seed() {
|
||||
let account_id = AccountId::new([1_u8; 32]);
|
||||
let nonce = crate::account::Nonce(42);
|
||||
let esk_a = EphemeralSecretKey::new(&account_id, &[0_u8; 32], &nonce);
|
||||
let esk_b = EphemeralSecretKey::new(&account_id, &[1_u8; 32], &nonce);
|
||||
assert_ne!(esk_a.0, esk_b.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn esk_differs_for_different_nonce() {
|
||||
let account_id = AccountId::new([1_u8; 32]);
|
||||
let random_seed = [2_u8; 32];
|
||||
let esk_a = EphemeralSecretKey::new(&account_id, &random_seed, &crate::account::Nonce(0));
|
||||
let esk_b = EphemeralSecretKey::new(&account_id, &random_seed, &crate::account::Nonce(1));
|
||||
assert_ne!(esk_a.0, esk_b.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,32 +80,18 @@ impl SharedSecretKey {
|
||||
(Self(ss_bytes), EphemeralPublicKey(ct.to_vec()))
|
||||
}
|
||||
|
||||
/// Deterministically encapsulate a shared secret toward `ek` with a given
|
||||
/// `esk` and `output_index`.
|
||||
/// Deterministically encapsulate a shared secret toward `ek` using a
|
||||
/// pre-derived `esk` as the ML-KEM encapsulation randomness.
|
||||
///
|
||||
/// This function runs inside the privacy-preserving circuit, generating
|
||||
/// the shared secret for ciphertext generation.
|
||||
///
|
||||
/// Important: since `ek` is assumed to be public, the uniqueness of the
|
||||
/// secret is reliant upon the uniqueness of the ephemeral secret key for
|
||||
/// a note in a given position. It is hence important to generate it
|
||||
/// with high entropy, for which the prover is responsible.
|
||||
/// The `esk` must be derived via `derive_esk(account_id, random_seed, nonce)`
|
||||
/// which binds it to the account and incorporates OS entropy.
|
||||
#[must_use]
|
||||
pub fn encapsulate_deterministic(
|
||||
ek: &MlKem768EncapsulationKey,
|
||||
esk: &[u8; 32],
|
||||
output_index: u32,
|
||||
esk: &crate::encryption::EphemeralSecretKey,
|
||||
) -> (Self, EphemeralPublicKey) {
|
||||
use risc0_zkvm::sha::{Impl, Sha256 as _};
|
||||
|
||||
const PREFIX: &[u8; 21] = b"/LEE/v0.3/KDF-ML-KEM/";
|
||||
let mut input = [0; 21 + 32 + 4];
|
||||
input[0..21].copy_from_slice(PREFIX);
|
||||
input[21..53].copy_from_slice(esk);
|
||||
input[53..57].copy_from_slice(&output_index.to_le_bytes());
|
||||
let hash = Impl::hash_bytes(&input);
|
||||
let m: ml_kem::B32 =
|
||||
ml_kem::array::Array::try_from(hash.as_bytes()).expect("SHA-256 output is 32 bytes");
|
||||
let m: ml_kem::B32 = ml_kem::array::Array::try_from(esk.0.as_slice())
|
||||
.expect("EphemeralSecretKey is 32 bytes");
|
||||
|
||||
let ek_bytes: ml_kem::kem::Key<ml_kem::EncapsulationKey768> =
|
||||
ek.0.as_slice()
|
||||
|
||||
@ -178,7 +178,7 @@ mod tests {
|
||||
#![expect(clippy::shadow_unrelated, reason = "We don't care about it in tests")]
|
||||
|
||||
use lee_core::{
|
||||
Commitment, DUMMY_COMMITMENT_HASH, EncryptionScheme, Nullifier,
|
||||
Commitment, DUMMY_COMMITMENT_HASH, EncryptionScheme, EphemeralSecretKey, Nullifier,
|
||||
PrivacyPreservingCircuitOutput, SharedSecretKey,
|
||||
account::{Account, AccountId, AccountWithMetadata, Nonce, data::Data},
|
||||
program::{PdaSeed, PrivateAccountKind},
|
||||
@ -257,8 +257,10 @@ mod tests {
|
||||
|
||||
let expected_sender_pre = sender.clone();
|
||||
|
||||
let init_nonce = Nonce::private_account_nonce_init(&recipient_account_id);
|
||||
let esk = EphemeralSecretKey::new(&recipient_account_id, &[0; 32], &init_nonce);
|
||||
let shared_secret =
|
||||
SharedSecretKey::encapsulate_deterministic(&recipient_keys.vpk(), &[0_u8; 32], 0).0;
|
||||
SharedSecretKey::encapsulate_deterministic(&recipient_keys.vpk(), &esk).0;
|
||||
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender, recipient],
|
||||
@ -270,7 +272,7 @@ mod tests {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -357,11 +359,16 @@ mod tests {
|
||||
Commitment::new(&recipient_account_id, &expected_private_account_2),
|
||||
];
|
||||
|
||||
let sender_new_nonce = sender_nonce.private_account_nonce_increment(&sender_keys.nsk);
|
||||
let sender_esk = EphemeralSecretKey::new(&sender_account_id, &[0; 32], &sender_new_nonce);
|
||||
let shared_secret_1 =
|
||||
SharedSecretKey::encapsulate_deterministic(&sender_keys.vpk(), &[0_u8; 32], 0).0;
|
||||
SharedSecretKey::encapsulate_deterministic(&sender_keys.vpk(), &sender_esk).0;
|
||||
|
||||
let recipient_init_nonce = Nonce::private_account_nonce_init(&recipient_account_id);
|
||||
let recipient_esk =
|
||||
EphemeralSecretKey::new(&recipient_account_id, &[0; 32], &recipient_init_nonce);
|
||||
let shared_secret_2 =
|
||||
SharedSecretKey::encapsulate_deterministic(&recipient_keys.vpk(), &[0_u8; 32], 1).0;
|
||||
SharedSecretKey::encapsulate_deterministic(&recipient_keys.vpk(), &recipient_esk).0;
|
||||
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender_pre, recipient],
|
||||
@ -372,7 +379,7 @@ mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: commitment_set
|
||||
.get_proof_for(&commitment_sender)
|
||||
@ -381,7 +388,7 @@ mod tests {
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -447,7 +454,7 @@ mod tests {
|
||||
instruction,
|
||||
vec![InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: account_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: account_keys.npk(),
|
||||
identifier: 0,
|
||||
}],
|
||||
@ -466,11 +473,12 @@ mod tests {
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
let identifier: u128 = 99;
|
||||
let shared_secret =
|
||||
SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
let account_id =
|
||||
AccountId::for_private_pda(&program.id(), &seed, &npk, &keys.vpk(), identifier);
|
||||
let init_nonce = Nonce::private_account_nonce_init(&account_id);
|
||||
let esk = EphemeralSecretKey::new(&account_id, &[0; 32], &init_nonce);
|
||||
let shared_secret = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &esk).0;
|
||||
|
||||
let pre_state = AccountWithMetadata::new(Account::default(), false, account_id);
|
||||
|
||||
let (output, _proof) = execute_and_prove(
|
||||
@ -478,7 +486,7 @@ mod tests {
|
||||
Program::serialize_instruction(seed).unwrap(),
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier,
|
||||
seed: None,
|
||||
@ -524,7 +532,7 @@ mod tests {
|
||||
instruction,
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier: 0,
|
||||
seed: None,
|
||||
@ -576,7 +584,7 @@ mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier: 0,
|
||||
seed: None,
|
||||
@ -633,7 +641,7 @@ mod tests {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: shared_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: shared_npk,
|
||||
identifier: shared_identifier,
|
||||
},
|
||||
@ -653,9 +661,11 @@ mod tests {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
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(), &keys.vpk(), identifier);
|
||||
let nonce = Nonce::private_account_nonce_init(&account_id);
|
||||
let esk = EphemeralSecretKey::new(&account_id, &[0; 32], &nonce);
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &esk).0;
|
||||
let pre = AccountWithMetadata::new(Account::default(), true, account_id);
|
||||
|
||||
let (output, _) = execute_and_prove(
|
||||
@ -664,7 +674,7 @@ mod tests {
|
||||
.unwrap(),
|
||||
vec![InputAccountIdentity::PrivateAuthorizedInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: keys.nsk,
|
||||
identifier,
|
||||
}],
|
||||
@ -695,7 +705,7 @@ mod tests {
|
||||
.unwrap(),
|
||||
vec![InputAccountIdentity::PrivateAuthorizedInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: keys.nsk,
|
||||
identifier,
|
||||
}],
|
||||
@ -742,7 +752,7 @@ mod tests {
|
||||
vec![InputAccountIdentity::PrivateAuthorizedInit {
|
||||
// use a different vpk
|
||||
vpk: foreign_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
// but the same nsk
|
||||
nsk: keys.nsk,
|
||||
identifier,
|
||||
@ -760,7 +770,11 @@ mod tests {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let keys = test_private_account_keys_1();
|
||||
let identifier: u128 = 99;
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
let recipient_id =
|
||||
AccountId::for_regular_private_account(&keys.npk(), &keys.vpk(), identifier);
|
||||
let init_nonce = Nonce::private_account_nonce_init(&recipient_id);
|
||||
let esk = EphemeralSecretKey::new(&recipient_id, &[0; 32], &init_nonce);
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &esk).0;
|
||||
|
||||
let sender = AccountWithMetadata::new(
|
||||
Account {
|
||||
@ -771,8 +785,6 @@ mod tests {
|
||||
true,
|
||||
AccountId::new([0; 32]),
|
||||
);
|
||||
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(
|
||||
@ -785,7 +797,7 @@ mod tests {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: keys.npk(),
|
||||
identifier,
|
||||
},
|
||||
@ -807,9 +819,11 @@ mod tests {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
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(), &keys.vpk(), identifier);
|
||||
let update_nonce = Nonce::default().private_account_nonce_increment(&keys.nsk);
|
||||
let esk = EphemeralSecretKey::new(&account_id, &[0; 32], &update_nonce);
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &esk).0;
|
||||
let account = Account {
|
||||
program_owner: program.id(),
|
||||
balance: 1,
|
||||
@ -831,7 +845,7 @@ mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: keys.nsk,
|
||||
membership_proof: commitment_set.get_proof_for(&commitment).unwrap(),
|
||||
identifier,
|
||||
@ -858,11 +872,12 @@ mod tests {
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
let identifier: u128 = 99;
|
||||
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, &keys.vpk(), identifier);
|
||||
let update_nonce = Nonce::default().private_account_nonce_increment(&keys.nsk);
|
||||
let esk = EphemeralSecretKey::new(&pda_id, &[0; 32], &update_nonce);
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &esk).0;
|
||||
let pda_account = Account {
|
||||
program_owner: auth_transfer_id,
|
||||
balance: 1,
|
||||
@ -887,7 +902,7 @@ mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: keys.nsk,
|
||||
membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(),
|
||||
identifier,
|
||||
@ -923,7 +938,7 @@ mod tests {
|
||||
Program::serialize_instruction(seed).unwrap(),
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier: 99,
|
||||
seed: None,
|
||||
@ -965,7 +980,7 @@ mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: keys.nsk,
|
||||
membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(),
|
||||
identifier: 99,
|
||||
|
||||
@ -89,8 +89,8 @@ impl Message {
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use lee_core::{
|
||||
Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, PrivateAccountKind,
|
||||
SharedSecretKey,
|
||||
Commitment, EncryptionScheme, EphemeralSecretKey, Nullifier, NullifierPublicKey,
|
||||
PrivateAccountKind, SharedSecretKey,
|
||||
account::{Account, AccountId, Nonce},
|
||||
encryption::ViewingPublicKey,
|
||||
program::{BlockValidityWindow, TimestampValidityWindow},
|
||||
@ -200,7 +200,8 @@ pub mod tests {
|
||||
let account = Account::default();
|
||||
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 (shared_secret, epk) =
|
||||
SharedSecretKey::encapsulate_deterministic(&vpk, &EphemeralSecretKey([0_u8; 32]));
|
||||
let ciphertext = EncryptionScheme::encrypt(
|
||||
&account,
|
||||
&PrivateAccountKind::Regular(0),
|
||||
|
||||
@ -1419,7 +1419,7 @@ pub mod tests {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -1470,7 +1470,7 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&sender_commitment)
|
||||
@ -1479,7 +1479,7 @@ pub mod tests {
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -1526,7 +1526,7 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&sender_commitment)
|
||||
@ -2099,14 +2099,14 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: recipient_keys.nsk,
|
||||
membership_proof: (0, vec![]),
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -2147,14 +2147,14 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: (0, vec![]),
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -2195,14 +2195,14 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: (0, vec![]),
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -2243,14 +2243,14 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: (0, vec![]),
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -2291,14 +2291,14 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: (0, vec![]),
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -2337,14 +2337,14 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: (0, vec![]),
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: recipient_keys.npk(),
|
||||
identifier: 0,
|
||||
},
|
||||
@ -2383,7 +2383,7 @@ pub mod tests {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier: u128::MAX,
|
||||
seed: None,
|
||||
@ -2416,7 +2416,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(seed).unwrap(),
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier: u128::MAX,
|
||||
seed: None,
|
||||
@ -2457,7 +2457,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(seed).unwrap(),
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys_b.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: npk_b,
|
||||
identifier: u128::MAX,
|
||||
seed: None,
|
||||
@ -2494,7 +2494,7 @@ pub mod tests {
|
||||
Program::serialize_instruction((seed, seed, callee_id)).unwrap(),
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier: u128::MAX,
|
||||
seed: None,
|
||||
@ -2534,7 +2534,7 @@ pub mod tests {
|
||||
Program::serialize_instruction((claim_seed, wrong_delegated_seed, callee_id)).unwrap(),
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier: u128::MAX,
|
||||
seed: None,
|
||||
@ -2584,14 +2584,14 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys_a.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: keys_a.npk(),
|
||||
identifier: u128::MAX,
|
||||
seed: None,
|
||||
},
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys_b.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: keys_b.npk(),
|
||||
identifier: u128::MAX,
|
||||
seed: None,
|
||||
@ -2633,7 +2633,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(()).unwrap(),
|
||||
vec![InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk,
|
||||
identifier: u128::MAX,
|
||||
seed: None,
|
||||
@ -2720,14 +2720,14 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: (1, vec![]),
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: (1, vec![]),
|
||||
identifier: 0,
|
||||
@ -3075,7 +3075,7 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&sender_commitment)
|
||||
@ -3194,7 +3194,7 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: from_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: from_keys.nsk,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&from_commitment)
|
||||
@ -3203,7 +3203,7 @@ pub mod tests {
|
||||
},
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: to_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: to_keys.nsk,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&to_commitment)
|
||||
@ -3465,7 +3465,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(instruction).unwrap(),
|
||||
vec![InputAccountIdentity::PrivateAuthorizedInit {
|
||||
vpk: private_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: private_keys.nsk,
|
||||
identifier: 0,
|
||||
}],
|
||||
@ -3510,7 +3510,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(0_u128).unwrap(),
|
||||
vec![InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: private_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: private_keys.npk(),
|
||||
identifier: 0,
|
||||
}],
|
||||
@ -3559,7 +3559,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(instruction).unwrap(),
|
||||
vec![InputAccountIdentity::PrivateAuthorizedInit {
|
||||
vpk: private_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: private_keys.nsk,
|
||||
identifier: 0,
|
||||
}],
|
||||
@ -3600,7 +3600,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(()).unwrap(),
|
||||
vec![InputAccountIdentity::PrivateAuthorizedInit {
|
||||
vpk: private_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: private_keys.nsk,
|
||||
identifier: 0,
|
||||
}],
|
||||
@ -3681,7 +3681,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(instruction).unwrap(),
|
||||
vec![InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: (0, vec![]),
|
||||
identifier: 0,
|
||||
@ -3711,7 +3711,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(instruction).unwrap(),
|
||||
vec![InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.nsk,
|
||||
membership_proof: (0, vec![]),
|
||||
identifier: 0,
|
||||
@ -3773,7 +3773,7 @@ pub mod tests {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: recipient_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: recipient_keys.nsk,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&recipient_commitment)
|
||||
@ -3929,7 +3929,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(instruction).unwrap(),
|
||||
vec![InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: account_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: account_keys.npk(),
|
||||
identifier: 0,
|
||||
}],
|
||||
@ -3994,7 +3994,7 @@ pub mod tests {
|
||||
Program::serialize_instruction(instruction).unwrap(),
|
||||
vec![InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: account_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: account_keys.npk(),
|
||||
identifier: 0,
|
||||
}],
|
||||
@ -4549,7 +4549,7 @@ pub mod tests {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: alice_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: alice_npk,
|
||||
identifier: 0,
|
||||
seed: Some((seed, proxy_id)),
|
||||
@ -4586,7 +4586,7 @@ pub mod tests {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: alice_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
npk: alice_npk,
|
||||
identifier: 1,
|
||||
seed: Some((seed, proxy_id)),
|
||||
@ -4626,7 +4626,7 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
vpk: alice_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: alice_keys.nsk,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&commitment_pda_0)
|
||||
@ -4664,7 +4664,7 @@ pub mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
vpk: alice_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: alice_keys.nsk,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&commitment_pda_1)
|
||||
@ -4721,7 +4721,7 @@ pub mod tests {
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
vpk: alice_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: alice_keys.nsk,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&commitment_pda_1_after_spend)
|
||||
|
||||
@ -660,7 +660,7 @@ mod tests {
|
||||
let account_identities = vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: attacker_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: attacker_keys.nsk,
|
||||
membership_proof,
|
||||
identifier: 0,
|
||||
@ -817,7 +817,7 @@ mod tests {
|
||||
let account_identities = vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: attacker_keys.vpk(),
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: attacker_keys.nsk,
|
||||
membership_proof,
|
||||
identifier: 0,
|
||||
|
||||
@ -1664,7 +1664,7 @@ mod tests {
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.viewing_public_key,
|
||||
esk: [0; 32],
|
||||
random_seed: [0; 32],
|
||||
nsk: sender_keys.private_key_holder.nullifier_secret_key,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&sender_commitment)
|
||||
|
||||
@ -4,8 +4,8 @@ use anyhow::Result;
|
||||
use keycard_wallet::{KeycardWallet, python_path};
|
||||
use lee::{AccountId, PrivateKey, PublicKey, Signature};
|
||||
use lee_core::{
|
||||
EphemeralSecretKey, Identifier, InputAccountIdentity, MembershipProof, NullifierPublicKey,
|
||||
NullifierSecretKey, SharedSecretKey,
|
||||
Identifier, InputAccountIdentity, MembershipProof, NullifierPublicKey, NullifierSecretKey,
|
||||
SharedSecretKey,
|
||||
account::{AccountWithMetadata, Nonce},
|
||||
encryption::ViewingPublicKey,
|
||||
};
|
||||
@ -262,8 +262,8 @@ impl AccountManager {
|
||||
} => {
|
||||
let acc = lee_core::account::Account::default();
|
||||
let auth_acc = AccountWithMetadata::new(acc, false, (&npk, &vpk, identifier));
|
||||
let mut esk: EphemeralSecretKey = [0; 32];
|
||||
OsRng.fill_bytes(&mut esk);
|
||||
let mut random_seed: [u8; 32] = [0; 32];
|
||||
OsRng.fill_bytes(&mut random_seed);
|
||||
let pre = AccountPreparedData {
|
||||
nsk: None,
|
||||
npk,
|
||||
@ -271,7 +271,7 @@ impl AccountManager {
|
||||
vpk,
|
||||
pre_state: auth_acc,
|
||||
proof: None,
|
||||
esk,
|
||||
random_seed,
|
||||
is_pda: false,
|
||||
};
|
||||
|
||||
@ -289,8 +289,8 @@ impl AccountManager {
|
||||
} => {
|
||||
let acc = lee_core::account::Account::default();
|
||||
let auth_acc = AccountWithMetadata::new(acc, false, account_id);
|
||||
let mut esk: EphemeralSecretKey = [0; 32];
|
||||
OsRng.fill_bytes(&mut esk);
|
||||
let mut random_seed: [u8; 32] = [0; 32];
|
||||
OsRng.fill_bytes(&mut random_seed);
|
||||
let pre = AccountPreparedData {
|
||||
nsk: None,
|
||||
npk,
|
||||
@ -298,7 +298,7 @@ impl AccountManager {
|
||||
vpk,
|
||||
pre_state: auth_acc,
|
||||
proof: None,
|
||||
esk,
|
||||
random_seed,
|
||||
is_pda: true,
|
||||
};
|
||||
State::Private(pre)
|
||||
@ -372,14 +372,22 @@ impl AccountManager {
|
||||
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,
|
||||
.map(|pre| {
|
||||
let nonce = if pre.proof.is_some() {
|
||||
pre.pre_state.account.nonce.private_account_nonce_increment(
|
||||
pre.nsk.as_ref().expect("update variant must have nsk"),
|
||||
)
|
||||
} else {
|
||||
lee_core::account::Nonce::private_account_nonce_init(&pre.pre_state.account_id)
|
||||
};
|
||||
let esk = lee_core::EphemeralSecretKey::new(
|
||||
&pre.pre_state.account_id,
|
||||
&pre.random_seed,
|
||||
&nonce,
|
||||
);
|
||||
PrivateAccountKeys {
|
||||
ssk: SharedSecretKey::encapsulate_deterministic(&pre.vpk, &esk).0,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@ -396,7 +404,7 @@ impl AccountManager {
|
||||
State::Private(pre) if pre.is_pda => match (pre.nsk, pre.proof.clone()) {
|
||||
(Some(nsk), Some(membership_proof)) => InputAccountIdentity::PrivatePdaUpdate {
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
random_seed: pre.random_seed,
|
||||
nsk,
|
||||
membership_proof,
|
||||
identifier: pre.identifier,
|
||||
@ -404,7 +412,7 @@ impl AccountManager {
|
||||
},
|
||||
_ => InputAccountIdentity::PrivatePdaInit {
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
random_seed: pre.random_seed,
|
||||
npk: pre.npk,
|
||||
identifier: pre.identifier,
|
||||
seed: None,
|
||||
@ -414,7 +422,7 @@ impl AccountManager {
|
||||
(Some(nsk), Some(membership_proof)) => {
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
random_seed: pre.random_seed,
|
||||
nsk,
|
||||
membership_proof,
|
||||
identifier: pre.identifier,
|
||||
@ -422,13 +430,13 @@ impl AccountManager {
|
||||
}
|
||||
(Some(nsk), None) => InputAccountIdentity::PrivateAuthorizedInit {
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
random_seed: pre.random_seed,
|
||||
nsk,
|
||||
identifier: pre.identifier,
|
||||
},
|
||||
(None, _) => InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk: pre.vpk.clone(),
|
||||
esk: pre.esk,
|
||||
random_seed: pre.random_seed,
|
||||
npk: pre.npk,
|
||||
identifier: pre.identifier,
|
||||
},
|
||||
@ -505,7 +513,7 @@ struct AccountPreparedData {
|
||||
vpk: ViewingPublicKey,
|
||||
pre_state: AccountWithMetadata,
|
||||
proof: Option<MembershipProof>,
|
||||
esk: EphemeralSecretKey,
|
||||
random_seed: [u8; 32],
|
||||
/// 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,
|
||||
@ -536,8 +544,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 mut esk: EphemeralSecretKey = [0; 32];
|
||||
OsRng.fill_bytes(&mut esk);
|
||||
let mut random_seed: [u8; 32] = [0; 32];
|
||||
OsRng.fill_bytes(&mut random_seed);
|
||||
|
||||
Ok(AccountPreparedData {
|
||||
nsk: Some(nsk),
|
||||
@ -546,7 +554,7 @@ async fn private_key_tree_acc_preparation(
|
||||
vpk: from_vpk,
|
||||
pre_state: sender_pre,
|
||||
proof,
|
||||
esk,
|
||||
random_seed,
|
||||
is_pda,
|
||||
})
|
||||
}
|
||||
@ -574,8 +582,8 @@ async fn private_shared_acc_preparation(
|
||||
.await
|
||||
.unwrap_or(None);
|
||||
|
||||
let mut esk: EphemeralSecretKey = [0; 32];
|
||||
OsRng.fill_bytes(&mut esk);
|
||||
let mut random_seed: [u8; 32] = [0; 32];
|
||||
OsRng.fill_bytes(&mut random_seed);
|
||||
|
||||
Ok(AccountPreparedData {
|
||||
nsk: Some(nsk),
|
||||
@ -584,7 +592,7 @@ async fn private_shared_acc_preparation(
|
||||
vpk,
|
||||
pre_state,
|
||||
proof,
|
||||
esk,
|
||||
random_seed,
|
||||
is_pda,
|
||||
})
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ pub fn compute_circuit_output(
|
||||
}
|
||||
InputAccountIdentity::PrivateAuthorizedInit {
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
nsk,
|
||||
identifier,
|
||||
} => {
|
||||
@ -74,14 +74,14 @@ pub fn compute_circuit_output(
|
||||
&PrivateAccountKind::Regular(*identifier),
|
||||
&npk,
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
new_nullifier,
|
||||
new_nonce,
|
||||
);
|
||||
}
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
nsk,
|
||||
membership_proof,
|
||||
identifier,
|
||||
@ -111,14 +111,14 @@ pub fn compute_circuit_output(
|
||||
&PrivateAccountKind::Regular(*identifier),
|
||||
&npk,
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
new_nullifier,
|
||||
new_nonce,
|
||||
);
|
||||
}
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
npk,
|
||||
identifier,
|
||||
} => {
|
||||
@ -149,14 +149,14 @@ pub fn compute_circuit_output(
|
||||
&PrivateAccountKind::Regular(*identifier),
|
||||
npk,
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
new_nullifier,
|
||||
new_nonce,
|
||||
);
|
||||
}
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
npk,
|
||||
identifier,
|
||||
seed: _,
|
||||
@ -199,14 +199,14 @@ pub fn compute_circuit_output(
|
||||
},
|
||||
npk,
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
new_nullifier,
|
||||
new_nonce,
|
||||
);
|
||||
}
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
nsk,
|
||||
membership_proof,
|
||||
identifier,
|
||||
@ -247,7 +247,7 @@ pub fn compute_circuit_output(
|
||||
},
|
||||
&npk,
|
||||
vpk,
|
||||
esk,
|
||||
random_seed,
|
||||
new_nullifier,
|
||||
new_nonce,
|
||||
);
|
||||
@ -270,7 +270,7 @@ fn emit_private_output(
|
||||
kind: &PrivateAccountKind,
|
||||
npk: &NullifierPublicKey,
|
||||
vpk: &ViewingPublicKey,
|
||||
esk: &EphemeralSecretKey,
|
||||
random_seed: &[u8; 32],
|
||||
new_nullifier: (Nullifier, CommitmentSetDigest),
|
||||
new_nonce: Nonce,
|
||||
) {
|
||||
@ -281,7 +281,8 @@ fn emit_private_output(
|
||||
|
||||
let commitment_post = Commitment::new(account_id, &post_with_updated_nonce);
|
||||
|
||||
let (shared_secret, epk) = SharedSecretKey::encapsulate_deterministic(vpk, esk, *output_index);
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user