mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-07-09 23:39:34 +00:00
feat(wallet): construct and submit dummy inputs
Ciphers submitted currently have no data
This commit is contained in:
parent
8c7f3764a5
commit
3d95594b4f
@ -18,8 +18,7 @@ fn main() {
|
||||
program_outputs,
|
||||
);
|
||||
|
||||
let output =
|
||||
output::compute_circuit_output(execution_state, &account_identities, dummy_inputs);
|
||||
let output = output::compute_circuit_output(execution_state, &account_identities, dummy_inputs);
|
||||
|
||||
env::commit(&output);
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use lee_core::{
|
||||
Commitment, CommitmentSetDigest, DummyInput, EncryptedAccountData, EncryptionScheme, EphemeralSecretKey,
|
||||
InputAccountIdentity, MembershipProof, Nullifier, NullifierPublicKey, NullifierSecretKey,
|
||||
PrivacyPreservingCircuitOutput, PrivateAccountKind, SharedSecretKey,
|
||||
Commitment, CommitmentSetDigest, DummyInput, EncryptedAccountData, EncryptionScheme,
|
||||
EphemeralSecretKey, InputAccountIdentity, MembershipProof, Nullifier, NullifierPublicKey,
|
||||
NullifierSecretKey, PrivacyPreservingCircuitOutput, PrivateAccountKind, SharedSecretKey,
|
||||
account::{Account, AccountId, Nonce},
|
||||
compute_digest_for_path,
|
||||
encryption::{ViewTag, ViewingPublicKey},
|
||||
@ -273,7 +273,9 @@ pub fn compute_circuit_output(
|
||||
fn emit_dummy_output(output: &mut PrivacyPreservingCircuitOutput, dummy: DummyInput) {
|
||||
let nullifier = Nullifier::for_dummy(&dummy.nullifier_seed);
|
||||
let commitment = Commitment::for_dummy(&nullifier, &dummy.commitment_seed);
|
||||
output.new_nullifiers.push((nullifier, dummy.commitment_root));
|
||||
output
|
||||
.new_nullifiers
|
||||
.push((nullifier, dummy.commitment_root));
|
||||
output.new_commitments.push(commitment);
|
||||
output.encrypted_private_post_states.push(dummy.note);
|
||||
}
|
||||
|
||||
@ -2,7 +2,8 @@ use std::collections::{HashMap, VecDeque};
|
||||
|
||||
use borsh::{BorshDeserialize, BorshSerialize};
|
||||
use lee_core::{
|
||||
DummyInput, InputAccountIdentity, PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput,
|
||||
DummyInput, InputAccountIdentity, PrivacyPreservingCircuitInput,
|
||||
PrivacyPreservingCircuitOutput,
|
||||
account::AccountWithMetadata,
|
||||
program::{ChainedCall, InstructionData, ProgramId, ProgramOutput},
|
||||
};
|
||||
|
||||
@ -4,10 +4,14 @@ use anyhow::Result;
|
||||
use keycard_wallet::{KeycardWallet, python_path};
|
||||
use lee::{AccountId, PrivateKey, PublicKey, Signature};
|
||||
use lee_core::{
|
||||
CommitmentSetDigest, DUMMY_COMMITMENT_HASH, Identifier, InputAccountIdentity, MembershipProof,
|
||||
NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
||||
account::{AccountWithMetadata, Nonce},
|
||||
encryption::{ViewTag, ViewingPublicKey},
|
||||
Commitment, CommitmentSetDigest, DUMMY_COMMITMENT_HASH, DummyInput, EncryptionScheme,
|
||||
Identifier, InputAccountIdentity, MembershipProof, NullifierPublicKey, NullifierSecretKey,
|
||||
PrivateAccountKind, SharedSecretKey,
|
||||
account::{Account, AccountWithMetadata, Nonce},
|
||||
encryption::{
|
||||
EncryptedAccountData, EphemeralPublicKey, ML_KEM_768_CIPHERTEXT_LEN, ViewTag,
|
||||
ViewingPublicKey,
|
||||
},
|
||||
};
|
||||
use rand::{RngCore as _, rngs::OsRng};
|
||||
|
||||
@ -410,6 +414,19 @@ impl AccountManager {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Given a count, generate that many dummy inputs with randomized seeds and notes.
|
||||
/// Uses the given commitment root from the account.
|
||||
pub fn dummy_inputs(&self, count: usize) -> Vec<DummyInput> {
|
||||
std::iter::repeat_with(|| DummyInput {
|
||||
nullifier_seed: random_bytes(),
|
||||
commitment_seed: random_bytes(),
|
||||
note: random_dummy_note(),
|
||||
commitment_root: self.dummy_commitment_root,
|
||||
})
|
||||
.take(count)
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Build the per-account input vec for the privacy-preserving circuit. Each variant carries
|
||||
/// exactly the fields the circuit's code path for that account needs, with the ephemeral
|
||||
/// keys (`ssk`) drawn from the cached values that `private_account_keys` and the message
|
||||
@ -627,6 +644,36 @@ fn random_view_tag() -> ViewTag {
|
||||
byte[0]
|
||||
}
|
||||
|
||||
fn random_bytes() -> [u8; 32] {
|
||||
let mut bytes = [0; 32];
|
||||
OsRng.fill_bytes(&mut bytes);
|
||||
bytes
|
||||
}
|
||||
|
||||
/// Generates a random note by encoding a default account with random secret key,
|
||||
/// then generating a random epk value (not connected to the original key) as well
|
||||
/// as a random tag.
|
||||
fn random_dummy_note() -> EncryptedAccountData {
|
||||
let mut secret = [0; 32];
|
||||
OsRng.fill_bytes(&mut secret);
|
||||
// The cipher is currently assumed to have default data. The data padding
|
||||
// leak is a separate issue.
|
||||
let ciphertext = EncryptionScheme::encrypt(
|
||||
&Account::default(),
|
||||
&PrivateAccountKind::Regular(0),
|
||||
&SharedSecretKey(secret),
|
||||
&Commitment::new(&AccountId::new([0; 32]), &Account::default()),
|
||||
0,
|
||||
);
|
||||
let mut epk = vec![0; ML_KEM_768_CIPHERTEXT_LEN];
|
||||
OsRng.fill_bytes(&mut epk);
|
||||
EncryptedAccountData {
|
||||
ciphertext,
|
||||
epk: EphemeralPublicKey(epk),
|
||||
view_tag: random_view_tag(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@ -569,9 +569,13 @@ impl WalletCore {
|
||||
instruction_data: InstructionData,
|
||||
program: &ProgramWithDependencies,
|
||||
) -> Result<(HashType, Vec<SharedSecretKey>), ExecutionFailureKind> {
|
||||
self.send_privacy_preserving_tx_with_pre_check(accounts, instruction_data, program, |_| {
|
||||
Ok(())
|
||||
})
|
||||
self.send_privacy_preserving_tx_with_pre_check(
|
||||
accounts,
|
||||
instruction_data,
|
||||
program,
|
||||
|_| Ok(()),
|
||||
0,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -581,6 +585,7 @@ impl WalletCore {
|
||||
instruction_data: InstructionData,
|
||||
program: &ProgramWithDependencies,
|
||||
tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
|
||||
dummy_count: usize,
|
||||
) -> Result<(HashType, Vec<SharedSecretKey>), ExecutionFailureKind> {
|
||||
let acc_manager = account_manager::AccountManager::new(self, accounts).await?;
|
||||
|
||||
@ -594,12 +599,14 @@ impl WalletCore {
|
||||
)?;
|
||||
|
||||
let private_account_keys = acc_manager.private_account_keys();
|
||||
let (output, proof) = lee::privacy_preserving_transaction::circuit::execute_and_prove(
|
||||
pre_states,
|
||||
instruction_data,
|
||||
acc_manager.account_identities(),
|
||||
&program.to_owned(),
|
||||
)?;
|
||||
let (output, proof) =
|
||||
lee::privacy_preserving_transaction::circuit::execute_and_prove_with_dummy_inputs(
|
||||
pre_states,
|
||||
instruction_data,
|
||||
acc_manager.account_identities(),
|
||||
acc_manager.dummy_inputs(dummy_count),
|
||||
&program.to_owned(),
|
||||
)?;
|
||||
|
||||
let message =
|
||||
lee::privacy_preserving_transaction::message::Message::try_from_circuit_output(
|
||||
|
||||
@ -24,6 +24,7 @@ impl NativeTokenTransfer<'_> {
|
||||
instruction_data,
|
||||
&program.into(),
|
||||
tx_pre_check,
|
||||
0,
|
||||
)
|
||||
.await
|
||||
.map(|(resp, secrets)| {
|
||||
|
||||
@ -58,6 +58,7 @@ impl NativeTokenTransfer<'_> {
|
||||
instruction_data,
|
||||
&program.into(),
|
||||
tx_pre_check,
|
||||
0,
|
||||
)
|
||||
.await
|
||||
.map(|(resp, secrets)| {
|
||||
@ -91,6 +92,7 @@ impl NativeTokenTransfer<'_> {
|
||||
instruction_data,
|
||||
&program.into(),
|
||||
tx_pre_check,
|
||||
0,
|
||||
)
|
||||
.await
|
||||
.map(|(resp, secrets)| {
|
||||
|
||||
@ -24,6 +24,7 @@ impl NativeTokenTransfer<'_> {
|
||||
instruction_data,
|
||||
&program.into(),
|
||||
tx_pre_check,
|
||||
0,
|
||||
)
|
||||
.await
|
||||
.map(|(resp, secrets)| {
|
||||
@ -57,6 +58,7 @@ impl NativeTokenTransfer<'_> {
|
||||
instruction_data,
|
||||
&program.into(),
|
||||
tx_pre_check,
|
||||
0,
|
||||
)
|
||||
.await
|
||||
.map(|(resp, secrets)| {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user