175 lines
5.6 KiB
Rust
Raw Normal View History

use common::TreeHashType;
use log::info;
2025-09-15 14:04:49 +03:00
use nssa_core::{
NullifierPublicKey, SharedSecretKey,
encryption::{EphemeralPublicKey, IncomingViewingPublicKey},
};
use secret_holders::{PrivateKeyHolder, SecretSpendingKey, SeedHolder};
use serde::{Deserialize, Serialize};
2025-09-08 15:23:32 +03:00
use sha2::{Digest, digest::FixedOutput};
2024-10-25 09:41:43 +03:00
2025-07-16 10:04:23 -03:00
pub type PublicAccountSigningKey = [u8; 32];
2024-11-25 07:26:16 +02:00
2024-10-30 12:32:36 +02:00
pub mod ephemeral_key_holder;
pub mod secret_holders;
2024-10-25 09:41:43 +03:00
2025-07-29 14:20:03 +03:00
#[derive(Serialize, Deserialize, Clone, Debug)]
2024-10-25 09:41:43 +03:00
///Entrypoint to key management
2025-08-15 14:27:36 +03:00
pub struct KeyChain {
2025-09-15 14:04:49 +03:00
secret_spending_key: SecretSpendingKey,
2025-09-05 14:47:58 +03:00
pub private_key_holder: PrivateKeyHolder,
2025-09-15 14:04:49 +03:00
pub nullifer_public_key: NullifierPublicKey,
pub incoming_viewing_public_key: IncomingViewingPublicKey,
2024-10-25 09:41:43 +03:00
}
2025-08-15 14:27:36 +03:00
impl KeyChain {
2024-10-25 09:41:43 +03:00
pub fn new_os_random() -> Self {
2024-10-30 12:32:36 +02:00
//Currently dropping SeedHolder at the end of initialization.
//Now entirely sure if we need it in the future.
2024-10-25 09:41:43 +03:00
let seed_holder = SeedHolder::new_os_random();
2025-09-15 14:04:49 +03:00
let secret_spending_key = seed_holder.produce_top_secret_key_holder();
2024-10-25 09:41:43 +03:00
2025-09-15 14:04:49 +03:00
let private_key_holder = secret_spending_key.produce_private_key_holder();
2024-10-25 09:41:43 +03:00
2025-09-05 14:47:58 +03:00
let nullifer_public_key = private_key_holder.generate_nullifier_public_key();
let incoming_viewing_public_key = private_key_holder.generate_incoming_viewing_public_key();
2024-10-25 09:41:43 +03:00
2025-08-18 16:15:25 +03:00
Self {
2025-09-15 14:04:49 +03:00
secret_spending_key,
2025-09-05 14:47:58 +03:00
private_key_holder,
2025-08-18 16:15:25 +03:00
nullifer_public_key,
2025-09-05 14:47:58 +03:00
incoming_viewing_public_key,
2024-10-25 09:41:43 +03:00
}
}
2025-09-05 14:47:58 +03:00
pub fn produce_user_address(&self) -> [u8; 32] {
let mut hasher = sha2::Sha256::new();
2025-09-15 14:04:49 +03:00
hasher.update(&self.nullifer_public_key);
2025-09-08 14:48:58 +03:00
hasher.update(self.incoming_viewing_public_key.to_bytes());
2025-09-05 14:47:58 +03:00
<TreeHashType>::from(hasher.finalize_fixed())
}
2024-10-25 09:41:43 +03:00
pub fn calculate_shared_secret_receiver(
&self,
2025-09-15 14:04:49 +03:00
ephemeral_public_key_sender: EphemeralPublicKey,
) -> SharedSecretKey {
SharedSecretKey::new(
&self
.secret_spending_key
.generate_incoming_viewing_secret_key(),
&ephemeral_public_key_sender,
)
2024-10-30 12:32:36 +02:00
}
pub fn log(&self) {
2024-12-30 09:10:04 +02:00
info!(
2025-01-03 08:13:59 +02:00
"Secret spending key is {:?}",
2025-09-15 14:04:49 +03:00
hex::encode(serde_json::to_vec(&self.secret_spending_key).unwrap()),
2024-12-30 09:10:04 +02:00
);
info!(
2025-01-03 08:13:59 +02:00
"Nulifier secret key is {:?}",
2025-09-05 14:47:58 +03:00
hex::encode(serde_json::to_vec(&self.private_key_holder.nullifier_secret_key).unwrap()),
);
info!(
"Viewing secret key is {:?}",
2025-04-04 15:23:19 -04:00
hex::encode(
2025-09-05 14:47:58 +03:00
serde_json::to_vec(&self.private_key_holder.incoming_viewing_secret_key).unwrap()
2025-04-04 15:23:19 -04:00
),
2024-12-30 09:10:04 +02:00
);
info!(
2025-01-03 08:13:59 +02:00
"Viewing secret key is {:?}",
2025-04-04 15:23:19 -04:00
hex::encode(
2025-09-05 14:47:58 +03:00
serde_json::to_vec(&self.private_key_holder.outgoing_viewing_secret_key).unwrap()
2025-04-04 15:23:19 -04:00
),
2024-12-30 09:10:04 +02:00
);
info!(
2025-01-03 08:13:59 +02:00
"Nullifier public key is {:?}",
2025-04-04 14:55:50 -04:00
hex::encode(serde_json::to_vec(&self.nullifer_public_key).unwrap()),
2025-01-03 08:13:59 +02:00
);
info!(
"Viewing public key is {:?}",
2025-09-05 14:47:58 +03:00
hex::encode(serde_json::to_vec(&self.incoming_viewing_public_key).unwrap()),
2024-12-30 09:10:04 +02:00
);
}
2024-10-25 09:41:43 +03:00
}
2024-10-25 14:15:00 +03:00
#[cfg(test)]
mod tests {
2025-09-15 14:04:49 +03:00
use aes_gcm::aead::OsRng;
2025-09-17 08:59:14 +03:00
use k256::AffinePoint;
use rand::RngCore;
2024-10-25 14:15:00 +03:00
use super::*;
2024-11-02 01:34:04 +01:00
#[test]
fn test_new_os_random() {
2025-08-15 14:27:36 +03:00
// Ensure that a new KeyChain instance can be created without errors.
let address_key_holder = KeyChain::new_os_random();
2024-11-02 01:40:44 +01:00
2024-11-02 01:34:04 +01:00
// Check that key holder fields are initialized with expected types
2025-09-15 14:04:49 +03:00
assert_ne!(address_key_holder.nullifer_public_key.as_ref(), &[0u8; 32]);
2024-11-02 01:34:04 +01:00
}
#[test]
fn test_calculate_shared_secret_receiver() {
2025-08-15 14:27:36 +03:00
let address_key_holder = KeyChain::new_os_random();
// Generate a random ephemeral public key sender
2025-09-17 08:59:14 +03:00
let mut scalar = [0; 32];
OsRng.fill_bytes(&mut scalar);
2025-09-15 14:04:49 +03:00
let ephemeral_public_key_sender = EphemeralPublicKey::from_scalar(scalar);
// Calculate shared secret
2025-09-15 14:04:49 +03:00
let _shared_secret =
2024-11-02 01:40:44 +01:00
address_key_holder.calculate_shared_secret_receiver(ephemeral_public_key_sender);
}
2024-10-25 14:15:00 +03:00
#[test]
fn key_generation_test() {
let seed_holder = SeedHolder::new_os_random();
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
2025-09-05 14:47:58 +03:00
let utxo_secret_key_holder = top_secret_key_holder.produce_private_key_holder();
2024-10-25 14:15:00 +03:00
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
2025-09-05 14:47:58 +03:00
let viewing_public_key = utxo_secret_key_holder.generate_incoming_viewing_public_key();
2024-10-25 14:15:00 +03:00
2025-08-18 16:15:25 +03:00
let pub_account_signing_key = nssa::PrivateKey::new_os_random();
2025-07-29 14:20:03 +03:00
2025-08-13 01:33:11 -03:00
let public_key = nssa::PublicKey::new_from_private_key(&pub_account_signing_key);
2025-07-29 14:20:03 +03:00
2025-08-13 13:42:00 +03:00
let address = nssa::Address::from(&public_key);
2025-07-29 14:20:03 +03:00
2024-10-25 14:15:00 +03:00
println!("======Prerequisites======");
println!();
2024-10-25 14:19:42 +03:00
println!(
"Group generator {:?}",
2025-04-04 14:55:50 -04:00
hex::encode(serde_json::to_vec(&AffinePoint::GENERATOR).unwrap())
2024-10-25 14:19:42 +03:00
);
2024-10-25 14:15:00 +03:00
println!();
println!("======Holders======");
println!();
println!("{seed_holder:?}");
println!("{top_secret_key_holder:?}");
println!("{utxo_secret_key_holder:?}");
println!();
println!("======Public data======");
println!();
println!("Address{:?}", hex::encode(address.value()));
2024-10-25 14:19:42 +03:00
println!(
"Nulifier public key {:?}",
2025-04-04 14:55:50 -04:00
hex::encode(serde_json::to_vec(&nullifer_public_key).unwrap())
2024-10-25 14:19:42 +03:00
);
println!(
"Viewing public key {:?}",
2025-04-04 14:55:50 -04:00
hex::encode(serde_json::to_vec(&viewing_public_key).unwrap())
2024-10-25 14:19:42 +03:00
);
2024-10-25 14:15:00 +03:00
}
}