Merge branch 'main' into Pravdyvy/deterministic-key-derivation

This commit is contained in:
Pravdyvy
2025-11-27 13:46:35 +02:00
86 changed files with 1910 additions and 2032 deletions
+51 -42
View File
@@ -15,10 +15,10 @@ pub type PublicKey = AffinePoint;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct NSSAUserData {
/// Default public accounts
pub default_pub_account_signing_keys: HashMap<nssa::Address, nssa::PrivateKey>,
pub default_pub_account_signing_keys: HashMap<nssa::AccountId, nssa::PrivateKey>,
/// Default private accounts
pub default_user_private_accounts:
HashMap<nssa::Address, (KeyChain, nssa_core::account::Account)>,
HashMap<nssa::AccountId, (KeyChain, nssa_core::account::Account)>,
/// Tree of public keys
pub public_key_tree: KeyTreePublic,
/// Tree of private keys
@@ -27,13 +27,14 @@ pub struct NSSAUserData {
impl NSSAUserData {
fn valid_public_key_transaction_pairing_check(
accounts_keys_map: &HashMap<nssa::Address, nssa::PrivateKey>,
accounts_keys_map: &HashMap<nssa::AccountId, nssa::PrivateKey>,
) -> bool {
let mut check_res = true;
for (addr, key) in accounts_keys_map {
let expected_addr = nssa::Address::from(&nssa::PublicKey::new_from_private_key(key));
if &expected_addr != addr {
println!("{}, {}", expected_addr, addr);
for (account_id, key) in accounts_keys_map {
let expected_account_id =
nssa::AccountId::from(&nssa::PublicKey::new_from_private_key(key));
if &expected_account_id != account_id {
println!("{}, {}", expected_account_id, account_id);
check_res = false;
}
}
@@ -41,13 +42,13 @@ impl NSSAUserData {
}
fn valid_private_key_transaction_pairing_check(
accounts_keys_map: &HashMap<nssa::Address, (KeyChain, nssa_core::account::Account)>,
accounts_keys_map: &HashMap<nssa::AccountId, (KeyChain, nssa_core::account::Account)>,
) -> bool {
let mut check_res = true;
for (addr, (key, _)) in accounts_keys_map {
let expected_addr = nssa::Address::from(&key.nullifer_public_key);
if expected_addr != *addr {
println!("{}, {}", expected_addr, addr);
for (account_id, (key, _)) in accounts_keys_map {
let expected_account_id = nssa::AccountId::from(&key.nullifer_public_key);
if expected_account_id != *account_id {
println!("{}, {}", expected_account_id, account_id);
check_res = false;
}
}
@@ -55,9 +56,9 @@ impl NSSAUserData {
}
pub fn new_with_accounts(
default_accounts_keys: HashMap<nssa::Address, nssa::PrivateKey>,
default_accounts_keys: HashMap<nssa::AccountId, nssa::PrivateKey>,
default_accounts_key_chains: HashMap<
nssa::Address,
nssa::AccountId,
(KeyChain, nssa_core::account::Account),
>,
public_key_tree: KeyTreePublic,
@@ -65,13 +66,13 @@ impl NSSAUserData {
) -> Result<Self> {
if !Self::valid_public_key_transaction_pairing_check(&default_accounts_keys) {
anyhow::bail!(
"Key transaction pairing check not satisfied, there is addresses, which is not derived from keys"
"Key transaction pairing check not satisfied, there is account_ids, which is not derived from keys"
);
}
if !Self::valid_private_key_transaction_pairing_check(&default_accounts_key_chains) {
anyhow::bail!(
"Key transaction pairing check not satisfied, there is addresses, which is not derived from keys"
"Key transaction pairing check not satisfied, there is account_ids, which is not derived from keys"
);
}
@@ -85,63 +86,65 @@ impl NSSAUserData {
/// Generated new private key for public transaction signatures
///
/// Returns the address of new account
/// Returns the account_id of new account
pub fn generate_new_public_transaction_private_key(
&mut self,
parent_cci: ChainIndex,
) -> nssa::Address {
) -> nssa::AccountId {
self.public_key_tree.generate_new_node(parent_cci).unwrap()
}
/// Returns the signing key for public transaction signatures
pub fn get_pub_account_signing_key(
&self,
address: &nssa::Address,
account_id: &nssa::AccountId,
) -> Option<&nssa::PrivateKey> {
//First seek in defaults
if let Some(key) = self.default_pub_account_signing_keys.get(address) {
// First seek in defaults
if let Some(key) = self.default_pub_account_signing_keys.get(account_id) {
Some(key)
//Then seek in tree
// Then seek in tree
} else {
self.public_key_tree.get_node(*address).map(Into::into)
self.public_key_tree.get_node(*account_id).map(Into::into)
}
}
/// Generated new private key for privacy preserving transactions
///
/// Returns the address of new account
/// Returns the account_id of new account
pub fn generate_new_privacy_preserving_transaction_key_chain(
&mut self,
parent_cci: ChainIndex,
) -> nssa::Address {
) -> nssa::AccountId {
self.private_key_tree.generate_new_node(parent_cci).unwrap()
}
/// Returns the signing key for public transaction signatures
pub fn get_private_account(
&self,
address: &nssa::Address,
account_id: &nssa::AccountId,
) -> Option<&(KeyChain, nssa_core::account::Account)> {
//First seek in defaults
if let Some(key) = self.default_user_private_accounts.get(address) {
// First seek in defaults
if let Some(key) = self.default_user_private_accounts.get(account_id) {
Some(key)
//Then seek in tree
// Then seek in tree
} else {
self.private_key_tree.get_node(*address).map(Into::into)
self.private_key_tree.get_node(*account_id).map(Into::into)
}
}
/// Returns the signing key for public transaction signatures
pub fn get_private_account_mut(
&mut self,
address: &nssa::Address,
account_id: &nssa::AccountId,
) -> Option<&mut (KeyChain, nssa_core::account::Account)> {
//First seek in defaults
if let Some(key) = self.default_user_private_accounts.get_mut(address) {
// First seek in defaults
if let Some(key) = self.default_user_private_accounts.get_mut(account_id) {
Some(key)
//Then seek in tree
// Then seek in tree
} else {
self.private_key_tree.get_node_mut(*address).map(Into::into)
self.private_key_tree
.get_node_mut(*account_id)
.map(Into::into)
}
}
}
@@ -166,21 +169,27 @@ mod tests {
fn test_new_account() {
let mut user_data = NSSAUserData::default();
let addr_pub = user_data.generate_new_public_transaction_private_key(ChainIndex::root());
let addr_private =
let account_id_pub =
user_data.generate_new_public_transaction_private_key(ChainIndex::root());
let account_id_private =
user_data.generate_new_privacy_preserving_transaction_key_chain(ChainIndex::root());
let is_private_key_generated = user_data.get_pub_account_signing_key(&addr_pub).is_some();
let is_private_key_generated = user_data
.get_pub_account_signing_key(&account_id_pub)
.is_some();
assert!(is_private_key_generated);
let is_key_chain_generated = user_data.get_private_account(&addr_private).is_some();
let is_key_chain_generated = user_data.get_private_account(&account_id_private).is_some();
assert!(is_key_chain_generated);
let addr_private_str = addr_private.to_string();
println!("{addr_private_str:#?}");
let key_chain = &user_data.get_private_account(&addr_private).unwrap().0;
let account_id_private_str = account_id_private.to_string();
println!("{account_id_private_str:#?}");
let key_chain = &user_data
.get_private_account(&account_id_private)
.unwrap()
.0;
println!("{key_chain:#?}");
}
}