mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-04 06:13:10 +00:00
fix: keys corect generatin
This commit is contained in:
parent
ebe616247f
commit
324f477b63
@ -42,6 +42,7 @@ ark-ff = "0.5.0"
|
|||||||
tiny-keccak = { version = "2.0.2", features = ["keccak"] }
|
tiny-keccak = { version = "2.0.2", features = ["keccak"] }
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
bip39 = "2.2.0"
|
bip39 = "2.2.0"
|
||||||
|
hmac-sha512 = "1.1.7"
|
||||||
|
|
||||||
rocksdb = { version = "0.21.0", default-features = false, features = [
|
rocksdb = { version = "0.21.0", default-features = false, features = [
|
||||||
"snappy",
|
"snappy",
|
||||||
|
|||||||
@ -16,6 +16,7 @@ hex.workspace = true
|
|||||||
aes-gcm.workspace = true
|
aes-gcm.workspace = true
|
||||||
lazy_static.workspace = true
|
lazy_static.workspace = true
|
||||||
bip39.workspace = true
|
bip39.workspace = true
|
||||||
|
hmac-sha512.workspace = true
|
||||||
|
|
||||||
[dependencies.common]
|
[dependencies.common]
|
||||||
path = "../common"
|
path = "../common"
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
use elliptic_curve::{
|
|
||||||
consts::{B0, B1},
|
|
||||||
generic_array::GenericArray,
|
|
||||||
};
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use sha2::digest::typenum::{UInt, UTerm};
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref NULLIFIER_SECRET_CONST: [u8; 32] =
|
|
||||||
hex::decode(std::env::var("NULLIFIER_SECRET_CONST").unwrap())
|
|
||||||
.unwrap()
|
|
||||||
.try_into()
|
|
||||||
.unwrap();
|
|
||||||
pub static ref VIEWING_SECRET_CONST: [u8; 32] =
|
|
||||||
hex::decode(std::env::var("VIEWING_SECRET_CONST").unwrap())
|
|
||||||
.unwrap()
|
|
||||||
.try_into()
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type CipherText = Vec<u8>;
|
|
||||||
pub type Nonce = GenericArray<u8, UInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>, B0>>;
|
|
||||||
@ -5,7 +5,7 @@ use k256::{AffinePoint, FieldBytes, Scalar};
|
|||||||
use log::info;
|
use log::info;
|
||||||
use rand::{rngs::OsRng, RngCore};
|
use rand::{rngs::OsRng, RngCore};
|
||||||
|
|
||||||
use super::constants_types::{CipherText, Nonce};
|
use super::types::{CipherText, Nonce};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
///Ephemeral secret key holder. Non-clonable as intended for one-time use. Produces ephemeral public keys. Can produce shared secret for sender.
|
///Ephemeral secret key holder. Non-clonable as intended for one-time use. Produces ephemeral public keys. Can produce shared secret for sender.
|
||||||
|
|||||||
@ -1,29 +1,32 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit};
|
use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit};
|
||||||
use constants_types::{CipherText, Nonce};
|
use common::merkle_tree_public::TreeHashType;
|
||||||
|
use elliptic_curve::group::GroupEncoding;
|
||||||
use elliptic_curve::point::AffineCoordinates;
|
use elliptic_curve::point::AffineCoordinates;
|
||||||
use k256::AffinePoint;
|
use k256::AffinePoint;
|
||||||
use log::info;
|
use log::info;
|
||||||
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
|
use secret_holders::{PrivateKeyHolder, SeedHolder, TopSecretKeyHolder};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use sha2::{digest::FixedOutput, Digest};
|
||||||
|
use types::{CipherText, Nonce};
|
||||||
|
|
||||||
use crate::key_protocol_core::PublicKey;
|
use crate::key_protocol_core::PublicKey;
|
||||||
pub type PublicAccountSigningKey = [u8; 32];
|
pub type PublicAccountSigningKey = [u8; 32];
|
||||||
|
|
||||||
pub mod constants_types;
|
|
||||||
pub mod ephemeral_key_holder;
|
pub mod ephemeral_key_holder;
|
||||||
pub mod secret_holders;
|
pub mod secret_holders;
|
||||||
|
pub mod types;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
///Entrypoint to key management
|
///Entrypoint to key management
|
||||||
pub struct KeyChain {
|
pub struct KeyChain {
|
||||||
top_secret_key_holder: TopSecretKeyHolder,
|
top_secret_key_holder: TopSecretKeyHolder,
|
||||||
pub utxo_secret_key_holder: UTXOSecretKeyHolder,
|
pub private_key_holder: PrivateKeyHolder,
|
||||||
///Map for all users accounts
|
///Map for all users accounts
|
||||||
pub_account_signing_keys: HashMap<nssa::Address, nssa::PrivateKey>,
|
pub_account_signing_keys: HashMap<nssa::Address, nssa::PrivateKey>,
|
||||||
pub nullifer_public_key: PublicKey,
|
pub nullifer_public_key: [u8; 32],
|
||||||
pub viewing_public_key: PublicKey,
|
pub incoming_viewing_public_key: PublicKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyChain {
|
impl KeyChain {
|
||||||
@ -33,16 +36,16 @@ impl KeyChain {
|
|||||||
let seed_holder = SeedHolder::new_os_random();
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
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 private_key_holder = top_secret_key_holder.produce_private_key_holder();
|
||||||
|
|
||||||
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
|
let nullifer_public_key = private_key_holder.generate_nullifier_public_key();
|
||||||
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
|
let incoming_viewing_public_key = private_key_holder.generate_incoming_viewing_public_key();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
top_secret_key_holder,
|
top_secret_key_holder,
|
||||||
utxo_secret_key_holder,
|
private_key_holder,
|
||||||
nullifer_public_key,
|
nullifer_public_key,
|
||||||
viewing_public_key,
|
incoming_viewing_public_key,
|
||||||
pub_account_signing_keys: HashMap::new(),
|
pub_account_signing_keys: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,20 +56,29 @@ impl KeyChain {
|
|||||||
let seed_holder = SeedHolder::new_os_random();
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
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 private_key_holder = top_secret_key_holder.produce_private_key_holder();
|
||||||
|
|
||||||
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
|
let nullifer_public_key = private_key_holder.generate_nullifier_public_key();
|
||||||
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
|
let incoming_viewing_public_key = private_key_holder.generate_incoming_viewing_public_key();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
top_secret_key_holder,
|
top_secret_key_holder,
|
||||||
utxo_secret_key_holder,
|
private_key_holder,
|
||||||
nullifer_public_key,
|
nullifer_public_key,
|
||||||
viewing_public_key,
|
incoming_viewing_public_key,
|
||||||
pub_account_signing_keys: accounts,
|
pub_account_signing_keys: accounts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn produce_user_address(&self) -> [u8; 32] {
|
||||||
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
|
||||||
|
hasher.update(&self.nullifer_public_key);
|
||||||
|
hasher.update(&self.incoming_viewing_public_key.to_bytes());
|
||||||
|
|
||||||
|
<TreeHashType>::from(hasher.finalize_fixed())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn generate_new_private_key(&mut self) -> nssa::Address {
|
pub fn generate_new_private_key(&mut self) -> nssa::Address {
|
||||||
let private_key = nssa::PrivateKey::new_os_random();
|
let private_key = nssa::PrivateKey::new_os_random();
|
||||||
let address = nssa::Address::from(&nssa::PublicKey::new_from_private_key(&private_key));
|
let address = nssa::Address::from(&nssa::PublicKey::new_from_private_key(&private_key));
|
||||||
@ -112,14 +124,18 @@ impl KeyChain {
|
|||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
"Nulifier secret key is {:?}",
|
"Nulifier secret key is {:?}",
|
||||||
|
hex::encode(serde_json::to_vec(&self.private_key_holder.nullifier_secret_key).unwrap()),
|
||||||
|
);
|
||||||
|
info!(
|
||||||
|
"Viewing secret key is {:?}",
|
||||||
hex::encode(
|
hex::encode(
|
||||||
serde_json::to_vec(&self.utxo_secret_key_holder.nullifier_secret_key).unwrap()
|
serde_json::to_vec(&self.private_key_holder.incoming_viewing_secret_key).unwrap()
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
"Viewing secret key is {:?}",
|
"Viewing secret key is {:?}",
|
||||||
hex::encode(
|
hex::encode(
|
||||||
serde_json::to_vec(&self.utxo_secret_key_holder.viewing_secret_key).unwrap()
|
serde_json::to_vec(&self.private_key_holder.outgoing_viewing_secret_key).unwrap()
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
@ -128,7 +144,7 @@ impl KeyChain {
|
|||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
"Viewing public key is {:?}",
|
"Viewing public key is {:?}",
|
||||||
hex::encode(serde_json::to_vec(&self.viewing_public_key).unwrap()),
|
hex::encode(serde_json::to_vec(&self.incoming_viewing_public_key).unwrap()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,12 +155,11 @@ mod tests {
|
|||||||
aead::{Aead, KeyInit, OsRng},
|
aead::{Aead, KeyInit, OsRng},
|
||||||
Aes256Gcm,
|
Aes256Gcm,
|
||||||
};
|
};
|
||||||
use constants_types::{CipherText, Nonce};
|
|
||||||
use constants_types::{NULLIFIER_SECRET_CONST, VIEWING_SECRET_CONST};
|
|
||||||
use elliptic_curve::ff::Field;
|
use elliptic_curve::ff::Field;
|
||||||
use elliptic_curve::group::prime::PrimeCurveAffine;
|
use elliptic_curve::group::prime::PrimeCurveAffine;
|
||||||
use elliptic_curve::point::AffineCoordinates;
|
use elliptic_curve::point::AffineCoordinates;
|
||||||
use k256::{AffinePoint, ProjectivePoint, Scalar};
|
use k256::{AffinePoint, ProjectivePoint, Scalar};
|
||||||
|
use types::{CipherText, Nonce};
|
||||||
|
|
||||||
use crate::key_management::ephemeral_key_holder::EphemeralKeyHolder;
|
use crate::key_management::ephemeral_key_holder::EphemeralKeyHolder;
|
||||||
|
|
||||||
@ -156,11 +171,9 @@ mod tests {
|
|||||||
let address_key_holder = KeyChain::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
|
|
||||||
// Check that key holder fields are initialized with expected types
|
// Check that key holder fields are initialized with expected types
|
||||||
|
assert_ne!(address_key_holder.nullifer_public_key, [0u8; 32]);
|
||||||
assert!(!Into::<bool>::into(
|
assert!(!Into::<bool>::into(
|
||||||
address_key_holder.nullifer_public_key.is_identity()
|
address_key_holder.incoming_viewing_public_key.is_identity()
|
||||||
));
|
|
||||||
assert!(!Into::<bool>::into(
|
|
||||||
address_key_holder.viewing_public_key.is_identity()
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,20 +224,6 @@ mod tests {
|
|||||||
assert_eq!(decrypted_data, plaintext);
|
assert_eq!(decrypted_data, plaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_new_os_random_initialization() {
|
|
||||||
// Ensure that KeyChain is initialized correctly
|
|
||||||
let address_key_holder = KeyChain::new_os_random();
|
|
||||||
|
|
||||||
// Check that key holder fields are initialized with expected types and values
|
|
||||||
assert!(!Into::<bool>::into(
|
|
||||||
address_key_holder.nullifer_public_key.is_identity()
|
|
||||||
));
|
|
||||||
assert!(!Into::<bool>::into(
|
|
||||||
address_key_holder.viewing_public_key.is_identity()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_shared_secret_with_identity_point() {
|
fn test_calculate_shared_secret_with_identity_point() {
|
||||||
let address_key_holder = KeyChain::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
@ -359,10 +358,10 @@ mod tests {
|
|||||||
let seed_holder = SeedHolder::new_os_random();
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
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 utxo_secret_key_holder = top_secret_key_holder.produce_private_key_holder();
|
||||||
|
|
||||||
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_incoming_viewing_public_key();
|
||||||
|
|
||||||
let pub_account_signing_key = nssa::PrivateKey::new_os_random();
|
let pub_account_signing_key = nssa::PrivateKey::new_os_random();
|
||||||
|
|
||||||
@ -377,11 +376,6 @@ mod tests {
|
|||||||
"Group generator {:?}",
|
"Group generator {:?}",
|
||||||
hex::encode(serde_json::to_vec(&AffinePoint::GENERATOR).unwrap())
|
hex::encode(serde_json::to_vec(&AffinePoint::GENERATOR).unwrap())
|
||||||
);
|
);
|
||||||
println!(
|
|
||||||
"Nullifier constant {:?}",
|
|
||||||
hex::encode(*NULLIFIER_SECRET_CONST)
|
|
||||||
);
|
|
||||||
println!("Viewing constatnt {:?}", hex::encode(*VIEWING_SECRET_CONST));
|
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
println!("======Holders======");
|
println!("======Holders======");
|
||||||
|
|||||||
@ -1,31 +1,31 @@
|
|||||||
use bip39::Mnemonic;
|
use bip39::Mnemonic;
|
||||||
use common::merkle_tree_public::TreeHashType;
|
use common::merkle_tree_public::TreeHashType;
|
||||||
use elliptic_curve::PrimeField;
|
use elliptic_curve::PrimeField;
|
||||||
use k256::{AffinePoint, FieldBytes, Scalar};
|
use k256::{AffinePoint, Scalar};
|
||||||
use rand::{rngs::OsRng, RngCore};
|
use rand::{rngs::OsRng, RngCore};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{digest::FixedOutput, Digest};
|
use sha2::{digest::FixedOutput, Digest};
|
||||||
|
|
||||||
use super::constants_types::{NULLIFIER_SECRET_CONST, VIEWING_SECRET_CONST};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
///Seed holder. Non-clonable to ensure that different holders use different seeds.
|
///Seed holder. Non-clonable to ensure that different holders use different seeds.
|
||||||
/// Produces `TopSecretKeyHolder` objects.
|
/// Produces `TopSecretKeyHolder` objects.
|
||||||
pub struct SeedHolder {
|
pub struct SeedHolder {
|
||||||
seed: Scalar,
|
//ToDo: Needs to be vec as serde derives is not implemented for [u8; 64]
|
||||||
|
pub(crate) seed: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
///Secret spending key holder. Produces `UTXOSecretKeyHolder` objects.
|
///Secret spending key holder. Produces `PrivateKeyHolder` objects.
|
||||||
pub struct TopSecretKeyHolder {
|
pub struct TopSecretKeyHolder {
|
||||||
pub secret_spending_key: Scalar,
|
pub(crate) secret_spending_key: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
///Nullifier secret key and viewing secret key holder. Produces public keys. Can produce address. Can produce shared secret for recepient.
|
///Private key holder. Produces public keys. Can produce address. Can produce shared secret for recepient.
|
||||||
pub struct UTXOSecretKeyHolder {
|
pub struct PrivateKeyHolder {
|
||||||
pub nullifier_secret_key: Scalar,
|
pub(crate) nullifier_secret_key: [u8; 32],
|
||||||
pub viewing_secret_key: Scalar,
|
pub(crate) incoming_viewing_secret_key: Scalar,
|
||||||
|
pub(crate) outgoing_viewing_secret_key: Scalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeedHolder {
|
impl SeedHolder {
|
||||||
@ -34,73 +34,134 @@ impl SeedHolder {
|
|||||||
OsRng.fill_bytes(&mut enthopy_bytes);
|
OsRng.fill_bytes(&mut enthopy_bytes);
|
||||||
|
|
||||||
let mnemonic = Mnemonic::from_entropy(&enthopy_bytes).unwrap();
|
let mnemonic = Mnemonic::from_entropy(&enthopy_bytes).unwrap();
|
||||||
let seed = mnemonic.to_seed("");
|
let seed_wide = mnemonic.to_seed("mnemonic");
|
||||||
|
|
||||||
let field_bytes = FieldBytes::from_slice(&seed);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
seed: Scalar::from_repr(*field_bytes).unwrap(),
|
seed: seed_wide.to_vec(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_secret_spending_key_hash(&self) -> TreeHashType {
|
pub fn generate_secret_spending_key_hash(&self) -> TreeHashType {
|
||||||
let mut hasher = sha2::Sha256::new();
|
let mut hash = hmac_sha512::HMAC::mac(&self.seed, "NSSA_seed");
|
||||||
|
|
||||||
hasher.update(self.seed.to_bytes());
|
for _ in 1..2048 {
|
||||||
|
hash = hmac_sha512::HMAC::mac(&hash, "NSSA_seed");
|
||||||
|
}
|
||||||
|
|
||||||
<TreeHashType>::from(hasher.finalize_fixed())
|
//Safe unwrap
|
||||||
}
|
*hash.first_chunk::<32>().unwrap()
|
||||||
|
|
||||||
pub fn generate_secret_spending_key_scalar(&self) -> Scalar {
|
|
||||||
let hash = self.generate_secret_spending_key_hash();
|
|
||||||
|
|
||||||
Scalar::from_repr(hash.into()).unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn produce_top_secret_key_holder(&self) -> TopSecretKeyHolder {
|
pub fn produce_top_secret_key_holder(&self) -> TopSecretKeyHolder {
|
||||||
TopSecretKeyHolder {
|
TopSecretKeyHolder {
|
||||||
secret_spending_key: self.generate_secret_spending_key_scalar(),
|
secret_spending_key: self.generate_secret_spending_key_hash(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TopSecretKeyHolder {
|
impl TopSecretKeyHolder {
|
||||||
pub fn generate_nullifier_secret_key(&self) -> Scalar {
|
pub fn generate_nullifier_secret_key(&self) -> [u8; 32] {
|
||||||
let mut hasher = sha2::Sha256::new();
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
|
||||||
hasher.update(self.secret_spending_key.to_bytes());
|
hasher.update("NSSA_keys");
|
||||||
hasher.update(*NULLIFIER_SECRET_CONST);
|
hasher.update(&self.secret_spending_key);
|
||||||
|
hasher.update([1u8]);
|
||||||
|
hasher.update([0u8; 176]);
|
||||||
|
|
||||||
|
<TreeHashType>::from(hasher.finalize_fixed())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_incloming_viewing_secret_key(&self) -> Scalar {
|
||||||
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
|
||||||
|
hasher.update("NSSA_keys");
|
||||||
|
hasher.update(&self.secret_spending_key);
|
||||||
|
hasher.update([2u8]);
|
||||||
|
hasher.update([0u8; 176]);
|
||||||
|
|
||||||
let hash = <TreeHashType>::from(hasher.finalize_fixed());
|
let hash = <TreeHashType>::from(hasher.finalize_fixed());
|
||||||
|
|
||||||
Scalar::from_repr(hash.into()).unwrap()
|
Scalar::from_repr(hash.into()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_viewing_secret_key(&self) -> Scalar {
|
pub fn generate_outgoing_viewing_secret_key(&self) -> Scalar {
|
||||||
let mut hasher = sha2::Sha256::new();
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
|
||||||
hasher.update(self.secret_spending_key.to_bytes());
|
hasher.update("NSSA_keys");
|
||||||
hasher.update(*VIEWING_SECRET_CONST);
|
hasher.update(&self.secret_spending_key);
|
||||||
|
hasher.update([3u8]);
|
||||||
|
hasher.update([0u8; 176]);
|
||||||
|
|
||||||
let hash = <TreeHashType>::from(hasher.finalize_fixed());
|
let hash = <TreeHashType>::from(hasher.finalize_fixed());
|
||||||
|
|
||||||
Scalar::from_repr(hash.into()).unwrap()
|
Scalar::from_repr(hash.into()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn produce_utxo_secret_holder(&self) -> UTXOSecretKeyHolder {
|
pub fn produce_private_key_holder(&self) -> PrivateKeyHolder {
|
||||||
UTXOSecretKeyHolder {
|
PrivateKeyHolder {
|
||||||
nullifier_secret_key: self.generate_nullifier_secret_key(),
|
nullifier_secret_key: self.generate_nullifier_secret_key(),
|
||||||
viewing_secret_key: self.generate_viewing_secret_key(),
|
incoming_viewing_secret_key: self.generate_incloming_viewing_secret_key(),
|
||||||
|
outgoing_viewing_secret_key: self.generate_outgoing_viewing_secret_key(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UTXOSecretKeyHolder {
|
impl PrivateKeyHolder {
|
||||||
pub fn generate_nullifier_public_key(&self) -> AffinePoint {
|
pub fn generate_nullifier_public_key(&self) -> [u8; 32] {
|
||||||
(AffinePoint::GENERATOR * self.nullifier_secret_key).into()
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
|
||||||
|
hasher.update("NSSA_keys");
|
||||||
|
hasher.update(&self.nullifier_secret_key);
|
||||||
|
hasher.update([7u8]);
|
||||||
|
hasher.update([0u8; 176]);
|
||||||
|
|
||||||
|
<TreeHashType>::from(hasher.finalize_fixed())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_viewing_public_key(&self) -> AffinePoint {
|
pub fn generate_incoming_viewing_public_key(&self) -> AffinePoint {
|
||||||
(AffinePoint::GENERATOR * self.viewing_secret_key).into()
|
(AffinePoint::GENERATOR * self.incoming_viewing_secret_key).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn seed_generation_test() {
|
||||||
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
|
|
||||||
|
assert_eq!(seed_holder.seed.len(), 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ssk_generation_test() {
|
||||||
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
|
|
||||||
|
assert_eq!(seed_holder.seed.len(), 64);
|
||||||
|
|
||||||
|
let _ = seed_holder.generate_secret_spending_key_hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ivs_generation_test() {
|
||||||
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
|
|
||||||
|
assert_eq!(seed_holder.seed.len(), 64);
|
||||||
|
|
||||||
|
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
||||||
|
|
||||||
|
let _ = top_secret_key_holder.generate_incloming_viewing_secret_key();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ovs_generation_test() {
|
||||||
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
|
|
||||||
|
assert_eq!(seed_holder.seed.len(), 64);
|
||||||
|
|
||||||
|
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
||||||
|
|
||||||
|
let _ = top_secret_key_holder.generate_outgoing_viewing_secret_key();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
key_protocol/src/key_management/types.rs
Normal file
8
key_protocol/src/key_management/types.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
use elliptic_curve::{
|
||||||
|
consts::{B0, B1},
|
||||||
|
generic_array::GenericArray,
|
||||||
|
};
|
||||||
|
use sha2::digest::typenum::{UInt, UTerm};
|
||||||
|
|
||||||
|
pub type CipherText = Vec<u8>;
|
||||||
|
pub type Nonce = GenericArray<u8, UInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>, B0>>;
|
||||||
Loading…
x
Reference in New Issue
Block a user