mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-08-25 19:31:11 +00:00
fix(wallet-ffi): revert zero-ing of derived keys
This commit is contained in:
@@ -10,7 +10,7 @@ use std::{
|
||||
use lee::{Data, ProgramId, SharedSecretKey};
|
||||
use lee_core::{
|
||||
encryption::MlKem768EncapsulationKey, program::PdaSeed, AuthorizationSecretKey,
|
||||
NullifierPublicKey,
|
||||
NullifierPublicKey, NullifierSecretKey,
|
||||
};
|
||||
use wallet::{account::AccountIdWithPrivacy, AccountIdentity};
|
||||
|
||||
@@ -462,9 +462,13 @@ impl From<AccountIdentity> for FfiAccountIdentity {
|
||||
ptr::null()
|
||||
};
|
||||
|
||||
let nsk = NullifierSecretKey::from(&ask);
|
||||
|
||||
Self {
|
||||
kind: FfiAccountIdentityKind::PrivateShared,
|
||||
authorization_secret_key: ask.0.into(),
|
||||
nullifier_secret_key: nsk.into(),
|
||||
nullifier_public_key: NullifierPublicKey::from(&nsk).0.into(),
|
||||
viewing_public_key: vpk_data,
|
||||
viewing_public_key_len: vpk_len,
|
||||
identifier: identifier.into(),
|
||||
@@ -490,6 +494,7 @@ impl From<AccountIdentity> for FfiAccountIdentity {
|
||||
kind: FfiAccountIdentityKind::PrivatePdaShared,
|
||||
account_id: account_id.into(),
|
||||
nullifier_secret_key: nsk.into(),
|
||||
nullifier_public_key: NullifierPublicKey::from(&nsk).0.into(),
|
||||
viewing_public_key: vpk_data,
|
||||
viewing_public_key_len: vpk_len,
|
||||
identifier: identifier.into(),
|
||||
@@ -579,8 +584,16 @@ impl TryFrom<&FfiAccountIdentity> for AccountIdentity {
|
||||
Err(WalletFfiError::InvalidKeyValue)
|
||||
}?;
|
||||
|
||||
let ask = AuthorizationSecretKey(value.authorization_secret_key.data);
|
||||
let nsk = NullifierSecretKey::from(&ask);
|
||||
if value.nullifier_secret_key.data != nsk
|
||||
|| value.nullifier_public_key.data != NullifierPublicKey::from(&nsk).0
|
||||
{
|
||||
return Err(WalletFfiError::InvalidKeyValue);
|
||||
}
|
||||
|
||||
Ok(Self::PrivateShared {
|
||||
ask: AuthorizationSecretKey(value.authorization_secret_key.data),
|
||||
ask,
|
||||
vpk,
|
||||
identifier: value.identifier.into(),
|
||||
})
|
||||
@@ -599,9 +612,14 @@ impl TryFrom<&FfiAccountIdentity> for AccountIdentity {
|
||||
Err(WalletFfiError::InvalidKeyValue)
|
||||
}?;
|
||||
|
||||
let nsk = value.nullifier_secret_key.data;
|
||||
if value.nullifier_public_key.data != NullifierPublicKey::from(&nsk).0 {
|
||||
return Err(WalletFfiError::InvalidKeyValue);
|
||||
}
|
||||
|
||||
Ok(Self::PrivatePdaShared {
|
||||
account_id: value.account_id.into(),
|
||||
nsk: value.nullifier_secret_key.data,
|
||||
nsk,
|
||||
vpk,
|
||||
identifier: value.identifier.into(),
|
||||
})
|
||||
@@ -663,7 +681,7 @@ mod tests {
|
||||
};
|
||||
use wallet::AccountIdentity;
|
||||
|
||||
use crate::{FfiAccountIdentity, FfiAccountIdentityKind};
|
||||
use crate::{error::WalletFfiError, FfiAccountIdentity, FfiAccountIdentityKind, FfiBytes32};
|
||||
|
||||
#[test]
|
||||
fn account_identity_roundtrip() {
|
||||
@@ -766,6 +784,10 @@ mod tests {
|
||||
FfiAccountIdentityKind::PrivatePdaShared
|
||||
);
|
||||
|
||||
assert_eq!(ffi_acc_identity_7.nullifier_secret_key.data, nsk);
|
||||
assert_eq!(ffi_acc_identity_7.nullifier_public_key.data, npk.0);
|
||||
assert_eq!(ffi_acc_identity_8.nullifier_public_key.data, npk.0);
|
||||
|
||||
let acc_identity_res_1: AccountIdentity = (&ffi_acc_identity_1).try_into().unwrap();
|
||||
let acc_identity_res_2: AccountIdentity = (&ffi_acc_identity_2).try_into().unwrap();
|
||||
let acc_identity_res_2_5: AccountIdentity = (&ffi_acc_identity_2_5).try_into().unwrap();
|
||||
@@ -786,4 +808,49 @@ mod tests {
|
||||
assert_eq!(acc_identity_res_7, acc_identity_7);
|
||||
assert_eq!(acc_identity_res_8, acc_identity_8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inconsistent_derived_keys_are_rejected() {
|
||||
let ask = AuthorizationSecretKey([43; 32]);
|
||||
let nsk = NullifierSecretKey::from(&ask);
|
||||
let vpk = ViewingPublicKey::from_seed(&[44; 32], &[54; 32]);
|
||||
let identifier = u128::from_le_bytes([45; 16]);
|
||||
|
||||
let shared = AccountIdentity::PrivateShared {
|
||||
ask,
|
||||
vpk: vpk.clone(),
|
||||
identifier,
|
||||
};
|
||||
let pda_shared = AccountIdentity::PrivatePdaShared {
|
||||
account_id: AccountId::new([46; 32]),
|
||||
nsk,
|
||||
vpk,
|
||||
identifier,
|
||||
};
|
||||
|
||||
let mut tampered_nsk: FfiAccountIdentity = shared.clone().into();
|
||||
tampered_nsk.nullifier_secret_key.data[0] ^= 1;
|
||||
let mut tampered_npk: FfiAccountIdentity = shared.clone().into();
|
||||
tampered_npk.nullifier_public_key.data[0] ^= 1;
|
||||
let mut zeroed: FfiAccountIdentity = shared.into();
|
||||
zeroed.nullifier_secret_key = FfiBytes32::default();
|
||||
zeroed.nullifier_public_key = FfiBytes32::default();
|
||||
let mut tampered_pda_npk: FfiAccountIdentity = pda_shared.clone().into();
|
||||
tampered_pda_npk.nullifier_public_key.data[0] ^= 1;
|
||||
let mut zeroed_pda: FfiAccountIdentity = pda_shared.into();
|
||||
zeroed_pda.nullifier_public_key = FfiBytes32::default();
|
||||
|
||||
for inconsistent in [
|
||||
&tampered_nsk,
|
||||
&tampered_npk,
|
||||
&zeroed,
|
||||
&tampered_pda_npk,
|
||||
&zeroed_pda,
|
||||
] {
|
||||
assert_eq!(
|
||||
AccountIdentity::try_from(inconsistent).unwrap_err(),
|
||||
WalletFfiError::InvalidKeyValue
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user