fix eph key computation

This commit is contained in:
Sergio Chouhy 2025-10-02 22:30:33 -03:00
parent ddc127f591
commit e69fb8b1b8
6 changed files with 222 additions and 99 deletions

View File

@ -3,7 +3,7 @@ use nssa_core::{
NullifierPublicKey, SharedSecretKey,
encryption::{EphemeralPublicKey, EphemeralSecretKey, IncomingViewingPublicKey},
};
use rand::{RngCore, rngs::OsRng};
use rand::{rngs::OsRng, RngCore};
use sha2::Digest;
use crate::key_management::secret_holders::OutgoingViewingSecretKey;
@ -27,20 +27,13 @@ pub fn produce_one_sided_shared_secret_receiver(
impl EphemeralKeyHolder {
pub fn new(
receiver_nullifier_public_key: NullifierPublicKey,
sender_outgoing_viewing_secret_key: OutgoingViewingSecretKey,
nonce: u64,
receiver_nullifier_public_key: &NullifierPublicKey,
) -> Self {
let mut nonce_bytes = [0; 16];
OsRng.fill_bytes(&mut nonce_bytes);
let mut hasher = sha2::Sha256::new();
hasher.update(receiver_nullifier_public_key);
hasher.update(nonce.to_le_bytes());
hasher.update([0; 24]);
let hash_recepient = hasher.finalize();
let mut hasher = sha2::Sha256::new();
hasher.update(sender_outgoing_viewing_secret_key);
hasher.update(hash_recepient);
hasher.update(nonce_bytes);
Self {
ephemeral_secret_key: hasher.finalize().into(),
@ -53,11 +46,11 @@ impl EphemeralKeyHolder {
pub fn calculate_shared_secret_sender(
&self,
receiver_incoming_viewing_public_key: IncomingViewingPublicKey,
receiver_incoming_viewing_public_key: &IncomingViewingPublicKey,
) -> SharedSecretKey {
SharedSecretKey::new(
&self.ephemeral_secret_key,
&receiver_incoming_viewing_public_key,
receiver_incoming_viewing_public_key,
)
}

View File

@ -15,5 +15,143 @@
"addr": "9e3d8e654d440e95293aa2dceceb137899a59535e952f747068e7a0ee30965f2",
"balance": 20000
}
],
"initial_commitments": [
{
"npk": [
193,
209,
150,
113,
47,
241,
48,
145,
250,
79,
235,
51,
119,
40,
184,
232,
5,
221,
36,
21,
201,
106,
90,
210,
129,
106,
71,
99,
208,
153,
75,
215
],
"account": {
"program_owner": [
0,
0,
0,
0,
0,
0,
0,
0
],
"balance": 10000,
"data": [],
"nonce": 0
}
},
{
"npk": [
27,
250,
136,
142,
88,
128,
138,
21,
49,
183,
118,
160,
117,
114,
110,
47,
136,
87,
60,
70,
59,
60,
18,
223,
23,
147,
241,
5,
184,
103,
225,
105
],
"account": {
"program_owner": [
0,
0,
0,
0,
0,
0,
0,
0
],
"balance": 20000,
"data": [],
"nonce": 0
}
}
],
"signing_key": [
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37
]
}

View File

@ -405,7 +405,7 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
let from = produce_account_addr_from_hex(from)?;
let to = produce_account_addr_from_hex(to)?;
let (res, secret) = wallet_core
let (res, [secret_from, secret_to]) = wallet_core
.send_private_native_token_transfer_owned_account(from, to, amount)
.await?;
@ -425,14 +425,14 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
let res_acc_from = nssa_core::EncryptionScheme::decrypt(
&from_ebc.ciphertext,
&secret,
&secret_from,
&from_comm,
0,
)
.unwrap();
let res_acc_to =
nssa_core::EncryptionScheme::decrypt(&to_ebc.ciphertext, &secret, &to_comm, 1)
nssa_core::EncryptionScheme::decrypt(&to_ebc.ciphertext, &secret_to, &to_comm, 1)
.unwrap();
println!("Received new from acc {res_acc_from:#?}");
@ -472,7 +472,7 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
let to_ipk =
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
let (res, secret) = wallet_core
let (res, [secret_from, secret_to]) = wallet_core
.send_private_native_token_transfer_outer_account(from, to_npk, to_ipk, amount)
.await?;
@ -492,14 +492,14 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
let res_acc_from = nssa_core::EncryptionScheme::decrypt(
&from_ebc.ciphertext,
&secret,
&secret_from,
&from_comm,
0,
)
.unwrap();
let res_acc_to =
nssa_core::EncryptionScheme::decrypt(&to_ebc.ciphertext, &secret, &to_comm, 1)
nssa_core::EncryptionScheme::decrypt(&to_ebc.ciphertext, &secret_to, &to_comm, 1)
.unwrap();
println!("RES acc {res_acc_from:#?}");
@ -614,9 +614,7 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
let (res, secret) = wallet_core
.send_shielded_native_token_transfer_outer_account(
from, to_npk, to_ipk, amount,
)
.send_shielded_native_token_transfer_outer_account(from, to_npk, to_ipk, amount)
.await?;
println!("Results of tx send is {res:#?}");
@ -712,9 +710,9 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
.get_private_account(&addr)
.unwrap();
println!("Generated new account with addr {addr:#?}");
println!("With key {key:#?}");
println!("With account {account:#?}");
println!("Generated new account with addr {addr}");
println!("With npk {}", hex::encode(&key.nullifer_public_key));
println!("With ipk {}", hex::encode(&key.incoming_viewing_public_key.to_bytes()));
let path = wallet_core.store_persistent_accounts()?;

View File

@ -1,5 +1,6 @@
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
use k256::elliptic_curve::rand_core::{OsRng, RngCore};
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
use nssa::Address;
use nssa_core::{SharedSecretKey, encryption::EphemeralPublicKey};
@ -25,34 +26,30 @@ impl WalletCore {
if from_acc.balance >= balance_to_move {
let program = nssa::program::Program::authenticated_transfer_program();
let npk_from = from_keys.nullifer_public_key;
let ipk_from = from_keys.incoming_viewing_public_key;
from_acc.program_owner = program.id();
let sender_commitment =
nssa_core::Commitment::new(&from_keys.nullifer_public_key, &from_acc);
let sender_commitment = nssa_core::Commitment::new(&npk_from, &from_acc);
let sender_pre = nssa_core::account::AccountWithMetadata {
account: from_acc.clone(),
is_authorized: true,
account_id: (&from_keys.nullifer_public_key).into(),
};
let sender_pre =
nssa_core::account::AccountWithMetadata::new(from_acc.clone(), true, &npk_from);
let recipient_pre = nssa_core::account::AccountWithMetadata {
account: to_acc.clone(),
is_authorized: false,
account_id: to,
};
//Move into different function
let mut esk = [0; 32];
OsRng.fill_bytes(&mut esk);
let shared_secret = SharedSecretKey::new(&esk, &from_keys.incoming_viewing_public_key);
let epk = EphemeralPublicKey::from_scalar(esk);
let eph_holder = EphemeralKeyHolder::new(&npk_from);
let shared_secret = eph_holder.calculate_shared_secret_sender(&ipk_from);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove(
&[sender_pre, recipient_pre],
&nssa::program::Program::serialize_instruction(balance_to_move).unwrap(),
&[1, 0],
&[from_acc.nonce + 1],
&[(from_keys.nullifer_public_key.clone(), shared_secret.clone())],
&[(npk_from.clone(), shared_secret.clone())],
&[(
from_keys.private_key_holder.nullifier_secret_key,
self.sequencer_client
@ -70,9 +67,9 @@ impl WalletCore {
vec![to],
vec![],
vec![(
from_keys.nullifer_public_key.clone(),
from_keys.incoming_viewing_public_key.clone(),
epk,
npk_from.clone(),
ipk_from.clone(),
eph_holder.generate_ephemeral_public_key(),
)],
output,
)

View File

@ -11,7 +11,7 @@ impl WalletCore {
to_npk: nssa_core::NullifierPublicKey,
to_ipk: nssa_core::encryption::IncomingViewingPublicKey,
balance_to_move: u128,
) -> Result<(SendTxResponse, nssa_core::SharedSecretKey), ExecutionFailureKind> {
) -> Result<(SendTxResponse, [nssa_core::SharedSecretKey; 2]), ExecutionFailureKind> {
let Some((from_keys, mut from_acc)) =
self.storage.user_data.get_private_account(&from).cloned()
else {
@ -23,30 +23,23 @@ impl WalletCore {
if from_acc.balance >= balance_to_move {
let program = nssa::program::Program::authenticated_transfer_program();
let from_npk = from_keys.nullifer_public_key;
let from_ipk = from_keys.incoming_viewing_public_key;
from_acc.program_owner = program.id();
let sender_commitment =
nssa_core::Commitment::new(&from_keys.nullifer_public_key, &from_acc);
let sender_commitment = nssa_core::Commitment::new(&from_npk, &from_acc);
let sender_pre = nssa_core::account::AccountWithMetadata {
account: from_acc.clone(),
is_authorized: true,
account_id: (&from_keys.nullifer_public_key).into(),
};
let sender_pre =
nssa_core::account::AccountWithMetadata::new(from_acc.clone(), true, &from_npk);
let recipient_pre = nssa_core::account::AccountWithMetadata {
account: to_acc.clone(),
is_authorized: false,
account_id: (&to_npk).into(),
};
let recipient_pre =
nssa_core::account::AccountWithMetadata::new(to_acc.clone(), false, &to_npk);
let eph_holder = EphemeralKeyHolder::new(
to_npk.clone(),
from_keys.private_key_holder.outgoing_viewing_secret_key,
from_acc.nonce.try_into().unwrap(),
);
let eph_holder = EphemeralKeyHolder::new(&to_npk);
let shared_secret = eph_holder.calculate_shared_secret_sender(to_ipk.clone());
let shared_secret_from = eph_holder.calculate_shared_secret_sender(&from_ipk);
let shared_secret_to = eph_holder.calculate_shared_secret_sender(&to_ipk);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove(
&[sender_pre, recipient_pre],
@ -54,8 +47,8 @@ impl WalletCore {
&[1, 2],
&[from_acc.nonce + 1, to_acc.nonce + 1],
&[
(from_keys.nullifer_public_key.clone(), shared_secret.clone()),
(to_npk.clone(), shared_secret.clone()),
(from_npk.clone(), shared_secret_from.clone()),
(to_npk.clone(), shared_secret_to.clone()),
],
&[(
from_keys.private_key_holder.nullifier_secret_key,
@ -75,8 +68,8 @@ impl WalletCore {
vec![],
vec![
(
from_keys.nullifer_public_key.clone(),
from_keys.incoming_viewing_public_key.clone(),
from_npk.clone(),
from_ipk.clone(),
eph_holder.generate_ephemeral_public_key(),
),
(
@ -103,7 +96,7 @@ impl WalletCore {
Ok((
self.sequencer_client.send_tx_private(tx).await?,
shared_secret,
[shared_secret_from, shared_secret_to],
))
} else {
Err(ExecutionFailureKind::InsufficientFundsError)
@ -115,7 +108,7 @@ impl WalletCore {
from: Address,
to: Address,
balance_to_move: u128,
) -> Result<(SendTxResponse, nssa_core::SharedSecretKey), ExecutionFailureKind> {
) -> Result<(SendTxResponse, [nssa_core::SharedSecretKey; 2]), ExecutionFailureKind> {
let Some((from_keys, mut from_acc)) =
self.storage.user_data.get_private_account(&from).cloned()
else {
@ -127,6 +120,8 @@ impl WalletCore {
return Err(ExecutionFailureKind::KeyNotFoundError);
};
let from_npk = from_keys.nullifer_public_key;
let from_ipk = from_keys.incoming_viewing_public_key;
let to_npk = to_keys.nullifer_public_key.clone();
let to_ipk = to_keys.incoming_viewing_public_key.clone();
@ -136,29 +131,19 @@ impl WalletCore {
from_acc.program_owner = program.id();
to_acc.program_owner = program.id();
let sender_commitment =
nssa_core::Commitment::new(&from_keys.nullifer_public_key, &from_acc);
let receiver_commitment =
nssa_core::Commitment::new(&to_keys.nullifer_public_key, &to_acc);
let sender_commitment = nssa_core::Commitment::new(&from_npk, &from_acc);
let receiver_commitment = nssa_core::Commitment::new(&to_npk, &to_acc);
let sender_pre = nssa_core::account::AccountWithMetadata {
account: from_acc.clone(),
is_authorized: true,
account_id: (&from_keys.nullifer_public_key).into(),
};
let recipient_pre = nssa_core::account::AccountWithMetadata {
account: to_acc.clone(),
is_authorized: true,
account_id: (&to_npk).into(),
};
let sender_pre =
nssa_core::account::AccountWithMetadata::new(from_acc.clone(), true, &from_npk);
let recipient_pre =
nssa_core::account::AccountWithMetadata::new(to_acc.clone(), true, &to_npk);
let eph_holder = EphemeralKeyHolder::new(
to_npk.clone(),
from_keys.private_key_holder.outgoing_viewing_secret_key,
from_acc.nonce.try_into().unwrap(),
);
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_ipk);
let shared_secret = eph_holder.calculate_shared_secret_sender(to_ipk.clone());
let eph_holder_to = EphemeralKeyHolder::new(&to_npk);
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_ipk);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove(
&[sender_pre, recipient_pre],
@ -166,8 +151,8 @@ impl WalletCore {
&[1, 1],
&[from_acc.nonce + 1, to_acc.nonce + 1],
&[
(from_keys.nullifer_public_key.clone(), shared_secret.clone()),
(to_npk.clone(), shared_secret.clone()),
(from_npk.clone(), shared_secret_from.clone()),
(to_npk.clone(), shared_secret_to.clone()),
],
&[
(
@ -197,14 +182,14 @@ impl WalletCore {
vec![],
vec![
(
from_keys.nullifer_public_key.clone(),
from_keys.incoming_viewing_public_key.clone(),
eph_holder.generate_ephemeral_public_key(),
from_npk.clone(),
from_ipk.clone(),
eph_holder_from.generate_ephemeral_public_key(),
),
(
to_npk.clone(),
to_ipk.clone(),
eph_holder.generate_ephemeral_public_key(),
eph_holder_to.generate_ephemeral_public_key(),
),
],
output,
@ -225,7 +210,7 @@ impl WalletCore {
Ok((
self.sequencer_client.send_tx_private(tx).await?,
shared_secret,
[shared_secret_from, shared_secret_to],
))
} else {
Err(ExecutionFailureKind::InsufficientFundsError)

View File

@ -1,5 +1,7 @@
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
use key_protocol::key_management::ephemeral_key_holder::produce_one_sided_shared_secret_receiver;
use key_protocol::key_management::ephemeral_key_holder::{
EphemeralKeyHolder, produce_one_sided_shared_secret_receiver,
};
use nssa::Address;
use crate::WalletCore;
@ -42,7 +44,8 @@ impl WalletCore {
account_id: (&to_npk).into(),
};
let (shared_secret, epk) = produce_one_sided_shared_secret_receiver(&to_ipk);
let eph_holder = EphemeralKeyHolder::new(&to_npk);
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove(
&[sender_pre, recipient_pre],
@ -66,7 +69,11 @@ impl WalletCore {
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output(
vec![from],
vec![from_acc.nonce],
vec![(to_npk.clone(), to_ipk.clone(), epk)],
vec![(
to_npk.clone(),
to_ipk.clone(),
eph_holder.generate_ephemeral_public_key(),
)],
output,
)
.unwrap();
@ -126,7 +133,8 @@ impl WalletCore {
account_id: (&to_npk).into(),
};
let (shared_secret, epk) = produce_one_sided_shared_secret_receiver(&to_ipk);
let eph_holder = EphemeralKeyHolder::new(&to_npk);
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove(
&[sender_pre, recipient_pre],
@ -143,7 +151,11 @@ impl WalletCore {
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output(
vec![from],
vec![from_acc.nonce],
vec![(to_npk.clone(), to_ipk.clone(), epk)],
vec![(
to_npk.clone(),
to_ipk.clone(),
eph_holder.generate_ephemeral_public_key(),
)],
output,
)
.unwrap();