fix: shared secret receiver fix

This commit is contained in:
Pravdyvy 2026-03-05 12:35:18 +02:00
parent db5d1e5cf7
commit e3764e1911
4 changed files with 254 additions and 19 deletions

View File

@ -68,6 +68,10 @@ impl ChainIndex {
&self.0
}
pub fn index(&self) -> Option<u32> {
self.chain().last().copied()
}
pub fn next_in_line(&self) -> ChainIndex {
let mut chain = self.0.clone();
// ToDo: Add overflow check

View File

@ -62,9 +62,10 @@ impl KeyChain {
pub fn calculate_shared_secret_receiver(
&self,
ephemeral_public_key_sender: EphemeralPublicKey,
index: Option<u32>,
) -> SharedSecretKey {
SharedSecretKey::new(
&self.secret_spending_key.generate_viewing_secret_key(None),
&self.secret_spending_key.generate_viewing_secret_key(index),
&ephemeral_public_key_sender,
)
}
@ -101,8 +102,8 @@ mod tests {
let ephemeral_public_key_sender = EphemeralPublicKey::from_scalar(scalar);
// Calculate shared secret
let _shared_secret =
account_id_key_holder.calculate_shared_secret_receiver(ephemeral_public_key_sender);
let _shared_secret = account_id_key_holder
.calculate_shared_secret_receiver(ephemeral_public_key_sender, None);
}
#[test]

View File

@ -75,6 +75,17 @@ impl EncryptionScheme {
Self::symmetric_transform(&mut buffer, shared_secret, commitment, output_index);
let mut cursor = Cursor::new(buffer.as_slice());
Account::from_cursor(&mut cursor).ok()
Account::from_cursor(&mut cursor)
.inspect_err(|err| {
println!(
"Failed to decode {ciphertext:?} \n
with secret {:?} ,\n
commitment {commitment:?} ,\n
and output_index {output_index} ,\n
with error {err:?}",
shared_secret.0
)
})
.ok()
}
}

View File

@ -363,11 +363,24 @@ impl WalletCore {
);
let tx = PrivacyPreservingTransaction::new(message, witness_set);
let shared_secrets = private_account_keys
let shared_secrets: Vec<_> = private_account_keys
.into_iter()
.map(|keys| keys.ssk)
.collect();
// ["dbfa57c178c287057c94f2fa8caaf78649d1dcac8d4eec0759264a22ebc788b4",
// "e3aa7298c9cc409f001e425caf139d0f5d627201fa60c0868d68f200c9044825"]
// ["dbfa57c178c287057c94f2fa8caaf78649d1dcac8d4eec0759264a22ebc788b4",
// "17a5070917903d5213db9ce9442ba472d8682af318fb5369e5c784c3980cacc9"]
info!(
"shared secrets is {:?}",
shared_secrets
.iter()
.map(|secret| hex::encode(secret.0))
.collect::<Vec<_>>()
);
Ok((
self.sequencer_client.send_tx_private(tx).await?,
shared_secrets,
@ -419,18 +432,19 @@ impl WalletCore {
.user_data
.default_user_private_accounts
.iter()
.map(|(acc_account_id, (key_chain, _))| (*acc_account_id, key_chain))
.chain(
self.storage
.user_data
.private_key_tree
.key_map
.values()
.map(|keys_node| (keys_node.account_id(), &keys_node.value.0)),
);
.map(|(acc_account_id, (key_chain, _))| (*acc_account_id, key_chain, None))
.chain(self.storage.user_data.private_key_tree.key_map.iter().map(
|(chain_index, keys_node)| {
(
keys_node.account_id(),
&keys_node.value.0,
chain_index.index(),
)
},
));
let affected_accounts = private_account_key_chains
.flat_map(|(acc_account_id, key_chain)| {
.flat_map(|(acc_account_id, key_chain, index)| {
let view_tag = EncryptedAccountData::compute_view_tag(
key_chain.nullifer_public_key.clone(),
key_chain.viewing_public_key.clone(),
@ -444,17 +458,20 @@ impl WalletCore {
.filter_map(|(ciph_id, encrypted_data)| {
let ciphertext = &encrypted_data.ciphertext;
let commitment = &tx.message.new_commitments[ciph_id];
let shared_secret =
key_chain.calculate_shared_secret_receiver(encrypted_data.epk.clone());
let shared_secret = key_chain
.calculate_shared_secret_receiver(encrypted_data.epk.clone(), index);
nssa_core::EncryptionScheme::decrypt(
let res = nssa_core::EncryptionScheme::decrypt(
ciphertext,
&shared_secret,
commitment,
ciph_id as u32,
)
);
res
})
.map(move |res_acc| (acc_account_id, res_acc))
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
@ -479,3 +496,205 @@ impl WalletCore {
&self.config_overrides
}
}
#[cfg(test)]
mod tests {
use key_protocol::key_management::{KeyChain, ephemeral_key_holder::EphemeralKeyHolder};
fn account_for_tests() -> KeyChain {
let key_chain_raw = r#"
{
"secret_spending_key": [
208,
155,
82,
128,
101,
206,
20,
95,
241,
147,
159,
231,
207,
78,
152,
28,
114,
111,
61,
69,
254,
51,
242,
28,
28,
195,
170,
242,
160,
24,
47,
189
],
"private_key_holder": {
"nullifier_secret_key": [
142,
76,
154,
157,
42,
40,
174,
199,
151,
63,
2,
216,
52,
103,
81,
42,
200,
177,
189,
49,
81,
39,
166,
139,
203,
154,
156,
166,
88,
159,
11,
151
],
"viewing_secret_key": [
122,
94,
159,
21,
28,
49,
169,
79,
12,
156,
171,
90,
41,
216,
203,
75,
251,
192,
204,
217,
18,
49,
28,
219,
213,
147,
244,
194,
205,
237,
134,
36
]
},
"nullifer_public_key": [
235,
24,
62,
99,
243,
236,
137,
35,
153,
149,
6,
10,
118,
239,
117,
188,
64,
8,
33,
52,
220,
231,
11,
39,
180,
117,
1,
22,
62,
199,
164,
169
],
"viewing_public_key": [
2,
253,
204,
5,
212,
86,
249,
156,
132,
143,
1,
172,
80,
61,
18,
185,
233,
36,
221,
58,
64,
110,
89,
242,
202,
230,
154,
66,
45,
252,
138,
174,
37
]
}
"#;
serde_json::from_str(key_chain_raw).unwrap()
}
#[test]
fn test_1() {
let keys = account_for_tests();
let eph_key_holder = EphemeralKeyHolder::new(&keys.nullifer_public_key);
let key_sender = eph_key_holder.calculate_shared_secret_sender(&keys.viewing_public_key);
let key_receiver = keys.calculate_shared_secret_receiver(
eph_key_holder.generate_ephemeral_public_key(),
Some(2),
);
assert_eq!(key_sender.0, key_receiver.0);
}
}