fix: key proctocol crate updated

This commit is contained in:
Oleksandr Pravdyvyi 2025-08-18 16:15:25 +03:00
parent 4268830d18
commit e617cac69c
No known key found for this signature in database
GPG Key ID: 9F8955C63C443871
10 changed files with 126 additions and 129 deletions

View File

@ -17,6 +17,7 @@ hex.workspace = true
aes-gcm.workspace = true aes-gcm.workspace = true
lazy_static.workspace = true lazy_static.workspace = true
tiny-keccak.workspace = true tiny-keccak.workspace = true
nssa-core = { path = "../nssa/core" }
[dependencies.common] [dependencies.common]
path = "../common" path = "../common"

View File

@ -1,15 +1,15 @@
use std::collections::HashMap;
use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit}; use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit};
use constants_types::{CipherText, Nonce}; use constants_types::{CipherText, Nonce};
use elliptic_curve::point::AffineCoordinates; use elliptic_curve::point::AffineCoordinates;
use k256::AffinePoint; use k256::AffinePoint;
use log::info; use log::info;
use rand::{rngs::OsRng, Rng};
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder}; use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::key_protocol_core::PublicKey; use crate::key_protocol_core::PublicKey;
pub type PublicAccountSigningKey = [u8; 32]; pub type PublicAccountSigningKey = [u8; 32];
use nssa::{self};
pub mod constants_types; pub mod constants_types;
pub mod ephemeral_key_holder; pub mod ephemeral_key_holder;
@ -20,7 +20,8 @@ pub mod secret_holders;
pub struct KeyChain { pub struct KeyChain {
top_secret_key_holder: TopSecretKeyHolder, top_secret_key_holder: TopSecretKeyHolder,
pub utxo_secret_key_holder: UTXOSecretKeyHolder, pub utxo_secret_key_holder: UTXOSecretKeyHolder,
pub_account_signing_key: nssa::PrivateKey, ///Map for all users accounts
pub_account_signing_keys: HashMap<nssa::Address, nssa::PrivateKey>,
pub nullifer_public_key: PublicKey, pub nullifer_public_key: PublicKey,
pub viewing_public_key: PublicKey, pub viewing_public_key: PublicKey,
} }
@ -37,26 +38,50 @@ impl KeyChain {
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key(); let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key(); let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
let mut rng = OsRng; Self {
let pub_account_signing_key = loop { top_secret_key_holder,
match nssa::PrivateKey::try_new(rng.gen()) { utxo_secret_key_holder,
Ok(key) => break key, nullifer_public_key,
Err(_) => continue, viewing_public_key,
} pub_account_signing_keys: HashMap::new(),
}; }
}
pub fn new_os_random_with_accounts(accounts: HashMap<nssa::Address, nssa::PrivateKey>) -> Self {
//Currently dropping SeedHolder at the end of initialization.
//Now entirely sure if we need it in the future.
let seed_holder = SeedHolder::new_os_random();
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
let utxo_secret_key_holder = top_secret_key_holder.produce_utxo_secret_holder();
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
Self { Self {
top_secret_key_holder, top_secret_key_holder,
utxo_secret_key_holder, utxo_secret_key_holder,
nullifer_public_key, nullifer_public_key,
viewing_public_key, viewing_public_key,
pub_account_signing_key, pub_account_signing_keys: accounts,
} }
} }
pub fn generate_new_private_key(&mut self) -> nssa::Address {
let private_key = nssa::PrivateKey::new_os_random();
let address = nssa::Address::from(&nssa::PublicKey::new_from_private_key(&private_key));
self.pub_account_signing_keys.insert(address, private_key);
address
}
/// Returns the signing key for public transaction signatures /// Returns the signing key for public transaction signatures
pub fn get_pub_account_signing_key(&self) -> &nssa::PrivateKey { pub fn get_pub_account_signing_key(
&self.pub_account_signing_key &self,
address: &nssa::Address,
) -> Option<&nssa::PrivateKey> {
self.pub_account_signing_keys.get(address)
} }
pub fn calculate_shared_secret_receiver( pub fn calculate_shared_secret_receiver(
@ -318,9 +343,15 @@ mod tests {
#[test] #[test]
fn test_get_public_account_signing_key() { fn test_get_public_account_signing_key() {
let address_key_holder = KeyChain::new_os_random(); let mut address_key_holder = KeyChain::new_os_random();
let signing_key = address_key_holder.get_pub_account_signing_key();
assert_eq!(signing_key, &address_key_holder.pub_account_signing_key); let address = address_key_holder.generate_new_private_key();
let is_private_key_generated = address_key_holder
.get_pub_account_signing_key(&address)
.is_some();
assert!(is_private_key_generated);
} }
#[test] #[test]
@ -333,13 +364,7 @@ mod tests {
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key(); let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key(); let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
let mut rng = OsRng; let pub_account_signing_key = nssa::PrivateKey::new_os_random();
let pub_account_signing_key = loop {
match nssa::PrivateKey::try_new(rng.gen()) {
Ok(key) => break key,
Err(_) => continue,
}
};
let public_key = nssa::PublicKey::new_from_private_key(&pub_account_signing_key); let public_key = nssa::PublicKey::new_from_private_key(&pub_account_signing_key);

View File

@ -1,3 +0,0 @@
// TODO: Consider wrapping `AccountAddress` in a struct.
pub type AccountAddress = [u8; 32];

View File

@ -1,8 +1,7 @@
use std::collections::HashMap;
use anyhow::Result; use anyhow::Result;
use common::transaction::Tag;
use k256::AffinePoint; use k256::AffinePoint;
use log::info;
use nssa::Address;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::key_management::{ use crate::key_management::{
@ -13,58 +12,10 @@ use crate::key_management::{
pub type PublicKey = AffinePoint; pub type PublicKey = AffinePoint;
#[derive(Clone, Debug)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct NSSAUserData { pub struct NSSAUserData {
pub key_holder: KeyChain, pub key_holder: KeyChain,
pub address: Address, pub accounts: HashMap<nssa::Address, nssa_core::account::Account>,
pub balance: u64,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NSSAUserDataForSerialization {
pub key_holder: KeyChain,
pub address: Address,
pub balance: u64,
}
impl From<NSSAUserData> for NSSAUserDataForSerialization {
fn from(value: NSSAUserData) -> Self {
NSSAUserDataForSerialization {
key_holder: value.key_holder,
address: value.address,
balance: value.balance,
}
}
}
impl From<NSSAUserDataForSerialization> for NSSAUserData {
fn from(value: NSSAUserDataForSerialization) -> Self {
NSSAUserData {
key_holder: value.key_holder,
address: value.address,
balance: value.balance,
}
}
}
impl Serialize for NSSAUserData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let account_for_serialization: NSSAUserDataForSerialization = From::from(self.clone());
account_for_serialization.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for NSSAUserData {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let account_for_serialization = <NSSAUserDataForSerialization>::deserialize(deserializer)?;
Ok(account_for_serialization.into())
}
} }
///A strucure, which represents all the visible(public) information ///A strucure, which represents all the visible(public) information
@ -76,8 +27,6 @@ impl<'de> Deserialize<'de> for NSSAUserData {
pub struct NSSAUserDataPublicMask { pub struct NSSAUserDataPublicMask {
pub nullifier_public_key: AffinePoint, pub nullifier_public_key: AffinePoint,
pub viewing_public_key: AffinePoint, pub viewing_public_key: AffinePoint,
pub address: Address,
pub balance: u64,
} }
impl NSSAUserDataPublicMask { impl NSSAUserDataPublicMask {
@ -90,39 +39,45 @@ impl NSSAUserDataPublicMask {
NSSAUserData::encrypt_data(ephemeral_key_holder, viewing_public_key_receiver, data) NSSAUserData::encrypt_data(ephemeral_key_holder, viewing_public_key_receiver, data)
} }
pub fn make_tag(&self) -> Tag { //ToDo: Part of a private keys update
self.address.value()[0] // pub fn make_tag(&self) -> Tag {
} // self.address.value()[0]
// }
} }
impl NSSAUserData { impl NSSAUserData {
pub fn new() -> Self { pub fn new() -> Self {
let key_holder = KeyChain::new_os_random(); let key_holder = KeyChain::new_os_random();
let public_key =
nssa::PublicKey::new_from_private_key(key_holder.get_pub_account_signing_key());
let address = nssa::Address::from(&public_key);
let balance = 0;
Self { Self {
key_holder, key_holder,
address, accounts: HashMap::new(),
balance,
} }
} }
pub fn new_with_balance(balance: u64) -> Self { pub fn new_with_accounts(
let key_holder = KeyChain::new_os_random(); accounts_keys: HashMap<nssa::Address, nssa::PrivateKey>,
let public_key = accounts: HashMap<nssa::Address, nssa_core::account::Account>,
nssa::PublicKey::new_from_private_key(key_holder.get_pub_account_signing_key()); ) -> Self {
let address = nssa::Address::from(&public_key); let key_holder = KeyChain::new_os_random_with_accounts(accounts_keys);
Self { Self {
key_holder, key_holder,
address, accounts,
balance,
} }
} }
pub fn generate_new_account(&mut self) -> nssa::Address {
let address = self.key_holder.generate_new_private_key();
self.accounts.insert(address, nssa_core::account::Account::default());
address
}
pub fn get_account_balance(&self, address: &nssa::Address) -> u128 {
self.accounts.get(address).map(|acc| acc.balance).unwrap_or(0)
}
pub fn encrypt_data( pub fn encrypt_data(
ephemeral_key_holder: &EphemeralKeyHolder, ephemeral_key_holder: &EphemeralKeyHolder,
viewing_public_key_receiver: AffinePoint, viewing_public_key_receiver: AffinePoint,
@ -141,27 +96,23 @@ impl NSSAUserData {
.decrypt_data(ephemeral_public_key_sender, ciphertext, nonce) .decrypt_data(ephemeral_public_key_sender, ciphertext, nonce)
} }
pub fn update_public_balance(&mut self, new_balance: u64) { pub fn update_account_balance(&mut self, address: nssa::Address, new_balance: u128) {
self.balance = new_balance; self.accounts
.entry(address)
.and_modify(|acc| acc.balance = new_balance)
.or_insert(nssa_core::account::Account::default());
} }
pub fn log(&self) { //ToDo: Part of a private keys update
info!("Keys generated"); // pub fn make_tag(&self) -> Tag {
info!("NSSAUserData address is {:?}", hex::encode(self.address)); // self.address.value()[0]
info!("NSSAUserData balance is {:?}", self.balance); // }
}
pub fn make_tag(&self) -> Tag {
self.address.value()[0]
}
///Produce account public mask ///Produce account public mask
pub fn make_account_public_mask(&self) -> NSSAUserDataPublicMask { pub fn make_account_public_mask(&self) -> NSSAUserDataPublicMask {
NSSAUserDataPublicMask { NSSAUserDataPublicMask {
nullifier_public_key: self.key_holder.nullifer_public_key, nullifier_public_key: self.key_holder.nullifer_public_key,
viewing_public_key: self.key_holder.viewing_public_key, viewing_public_key: self.key_holder.viewing_public_key,
address: self.address,
balance: self.balance,
} }
} }
} }
@ -178,25 +129,31 @@ mod tests {
#[test] #[test]
fn test_new_account() { fn test_new_account() {
let account = NSSAUserData::new(); let mut user_data = NSSAUserData::new();
assert_eq!(account.balance, 0); let addr = user_data.generate_new_account();
assert_eq!(user_data.get_account_balance(&addr), 0);
} }
#[test] #[test]
fn test_update_public_balance() { fn test_update_balance() {
let mut account = NSSAUserData::new(); let mut user_data = NSSAUserData::new();
account.update_public_balance(500);
assert_eq!(account.balance, 500); let address = user_data.generate_new_account();
user_data.update_account_balance(address, 500);
assert_eq!(user_data.get_account_balance(&address), 500);
} }
#[test] //ToDo: Part of a private keys update
fn accounts_accounts_mask_tag_consistency() { // #[test]
let account = NSSAUserData::new(); // fn accounts_accounts_mask_tag_consistency() {
// let account = NSSAUserData::new();
let account_mask = account.make_account_public_mask(); // let account_mask = account.make_account_public_mask();
assert_eq!(account.make_tag(), account_mask.make_tag()); // assert_eq!(account.make_tag(), account_mask.make_tag());
} // }
} }

View File

@ -1,2 +1,2 @@
pub mod key_protocol_core;
pub mod key_management; pub mod key_management;
pub mod key_protocol_core;

View File

@ -1,3 +1,4 @@
use rand::{Rng, rngs::OsRng};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::error::NssaError; use crate::error::NssaError;
@ -8,6 +9,17 @@ use crate::error::NssaError;
pub struct PrivateKey([u8; 32]); pub struct PrivateKey([u8; 32]);
impl PrivateKey { impl PrivateKey {
pub fn new_os_random() -> Self {
let mut rng = OsRng;
loop {
match Self::try_new(rng.r#gen()) {
Ok(key) => break key,
Err(_) => continue,
};
}
}
fn is_valid_key(value: [u8; 32]) -> bool { fn is_valid_key(value: [u8; 32]) -> bool {
secp256k1::SecretKey::from_byte_array(value).is_ok() secp256k1::SecretKey::from_byte_array(value).is_ok()
} }
@ -33,4 +45,10 @@ mod tests {
let key = PrivateKey::try_new([1; 32]).unwrap(); let key = PrivateKey::try_new([1; 32]).unwrap();
assert_eq!(key.value(), &key.0); assert_eq!(key.value(), &key.0);
} }
#[test]
fn test_produce_key() {
let key = PrivateKey::new_os_random();
println!("{:?}", key.0);
}
} }

View File

@ -1,9 +1,9 @@
use std::collections::HashMap; use std::collections::HashMap;
//TODO: NOT USER DATA, ACCOUNT //TODO: NOT USER DATA, ACCOUNT
use key_protocol::key_protocol_core::NSSAUserData;
use anyhow::Result; use anyhow::Result;
use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree;
use key_protocol::key_protocol_core::NSSAUserData;
use nssa::Address; use nssa::Address;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -32,7 +32,7 @@ pub struct WalletConfig {
///Sequencer polling duration for new blocks in seconds ///Sequencer polling duration for new blocks in seconds
pub seq_poll_timeout_secs: u64, pub seq_poll_timeout_secs: u64,
///Initial accounts for wallet ///Initial accounts for wallet
/// ///
/// TODO: NOT USRE DATA, ACCOUNT /// TODO: NOT USRE DATA, ACCOUNT
pub initial_accounts: Vec<NSSAUserData>, pub initial_accounts: Vec<NSSAUserData>,
} }

View File

@ -1,7 +1,7 @@
use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr}; use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr};
use key_protocol::key_protocol_core::NSSAUserData;
use anyhow::Result; use anyhow::Result;
use key_protocol::key_protocol_core::NSSAUserData;
use nssa::Address; use nssa::Address;
use crate::{config::WalletConfig, HOME_DIR_ENV_VAR}; use crate::{config::WalletConfig, HOME_DIR_ENV_VAR};
@ -28,7 +28,7 @@ pub fn produce_account_addr_from_hex(hex_str: String) -> Result<Address> {
///Fetch list of accounts stored at `NSSA_WALLET_HOME_DIR/curr_accounts.json` ///Fetch list of accounts stored at `NSSA_WALLET_HOME_DIR/curr_accounts.json`
/// ///
/// If file not present, it is considered as empty list of persistent accounts /// If file not present, it is considered as empty list of persistent accounts
/// ///
/// ToDo: NOT USER DATA, ACCOUNT /// ToDo: NOT USER DATA, ACCOUNT
pub fn fetch_persistent_accounts() -> Result<Vec<NSSAUserData>> { pub fn fetch_persistent_accounts() -> Result<Vec<NSSAUserData>> {
let home = get_home()?; let home = get_home()?;

View File

@ -5,10 +5,10 @@ use common::{
ExecutionFailureKind, ExecutionFailureKind,
}; };
use key_protocol::key_protocol_core::NSSAUserData;
use anyhow::Result; use anyhow::Result;
use chain_storage::WalletChainStore; use chain_storage::WalletChainStore;
use config::WalletConfig; use config::WalletConfig;
use key_protocol::key_protocol_core::NSSAUserData;
use log::info; use log::info;
use nssa::Address; use nssa::Address;
@ -55,7 +55,6 @@ impl WalletCore {
pub async fn create_new_account(&mut self) -> Address { pub async fn create_new_account(&mut self) -> Address {
let account = NSSAUserData::new(); let account = NSSAUserData::new();
account.log();
let addr = account.address; let addr = account.address;