Skip to content

Commit

Permalink
Make Alpha keys in software wallets derivable
Browse files Browse the repository at this point in the history
  • Loading branch information
brianp committed Jun 27, 2024
1 parent f39476e commit 7544a5c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 40 deletions.
2 changes: 1 addition & 1 deletion applications/minotari_console_wallet/src/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ pub async fn init_wallet(

let node_identity = {
let comms_secret_key = match read_or_create_wallet_type(wallet_type.clone(), &wallet_db)? {
WalletType::Software(_) => derive_comms_secret_key(&master_seed)?,
WalletType::Software => derive_comms_secret_key(&master_seed)?,
WalletType::Ledger(wallet) => wallet.view_key.ok_or(ExitError::new(
ExitCode::ConfigError,
"Ledger wallet requires a view key to be set in the config",
Expand Down
38 changes: 6 additions & 32 deletions base_layer/common_types/src/wallet_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,58 +26,32 @@ use std::{
fmt::{Display, Formatter},
};

use chacha20poly1305::aead::OsRng;
#[cfg(feature = "ledger")]
use ledger_transport::APDUCommand;
#[cfg(feature = "ledger")]
use minotari_ledger_wallet_comms::ledger_wallet::{Command, Instruction};
use serde::{Deserialize, Serialize};
use tari_common::configuration::Network;
use tari_crypto::{
keys::{PublicKey as PublicKeyTrait, SecretKey},
ristretto::RistrettoPublicKey,
};
use tari_crypto::ristretto::RistrettoPublicKey;

use crate::types::{PrivateKey, PublicKey};
use crate::types::PrivateKey;

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub enum WalletType {
Software(SoftwareWallet),
#[default]
Software,
Ledger(LedgerWallet),
}

impl Display for WalletType {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
WalletType::Software(software_wallet) => write!(f, "Software({software_wallet})"),
WalletType::Software => write!(f, "Software"),
WalletType::Ledger(ledger_wallet) => write!(f, "Ledger({ledger_wallet})"),
}
}
}

impl Default for WalletType {
fn default() -> Self {
let k: PrivateKey = SecretKey::random(&mut OsRng);
WalletType::Software(SoftwareWallet {
private_alpha: k.clone(),
public_alpha: PublicKey::from_secret_key(&k),
})
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SoftwareWallet {
pub public_alpha: PublicKey,
pub private_alpha: PrivateKey,
}

impl Display for SoftwareWallet {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "pubkey {}", self.public_alpha)?;
Ok(())
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LedgerWallet {
account: u64,
Expand Down
32 changes: 25 additions & 7 deletions base_layer/core/src/transactions/key_manager/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,18 @@ where TBackend: KeyManagerBackend<PublicKey> + 'static
},
KeyId::Derived { branch, label, index } => {
let public_alpha = match &self.wallet_type {
WalletType::Software(software_wallet) => &software_wallet.public_alpha,
WalletType::Software => {
let km = self
.key_managers
.get(&TransactionKeyManagerBranch::Alpha.get_branch_key())
.ok_or(KeyManagerServiceError::UnknownKeyBranch)?
.read()
.await;

PublicKey::from_secret_key(&km.get_private_key(0)?)
},
WalletType::Ledger(ledger) => {
ledger.public_alpha.as_ref().ok_or(KeyManagerServiceError::LedgerError(
ledger.public_alpha.clone().ok_or(KeyManagerServiceError::LedgerError(
"Key manager set to use ledger, ledger alpha public key missing".to_string(),
))?
},
Expand Down Expand Up @@ -455,7 +464,16 @@ where TBackend: KeyManagerBackend<PublicKey> + 'static
},
KeyId::Derived { branch, label, index } => match &self.wallet_type {
WalletType::Ledger(_) => Err(KeyManagerServiceError::LedgerPrivateKeyInaccessible),
WalletType::Software(software_wallet) => {
WalletType::Software => {
let km = self
.key_managers
.get(&TransactionKeyManagerBranch::Alpha.get_branch_key())
.ok_or(KeyManagerServiceError::UnknownKeyBranch)?
.read()
.await;

let private_alpha = km.get_private_key(0)?;

let km = self
.key_managers
.get(branch)
Expand All @@ -468,7 +486,7 @@ where TBackend: KeyManagerBackend<PublicKey> + 'static
let private_key = PrivateKey::from_uniform_bytes(hasher.as_ref()).map_err(|_| {
KeyManagerServiceError::UnknownError(format!("Invalid private key for {}", label))
})?;
let private_key = private_key + &software_wallet.private_alpha;
let private_key = private_key + &private_alpha;
Ok(private_key)
},
},
Expand Down Expand Up @@ -759,7 +777,7 @@ where TBackend: KeyManagerBackend<PublicKey> + 'static
label: _,
index,
} => match &self.wallet_type {
WalletType::Software(_software_wallet) => {
WalletType::Software => {
total_script_private_key =
total_script_private_key + self.get_private_key(script_key_id).await?;
},
Expand All @@ -780,7 +798,7 @@ where TBackend: KeyManagerBackend<PublicKey> + 'static
}

match &self.wallet_type {
WalletType::Software(_software_wallet) => {
WalletType::Software => {
let mut total_sender_offset_private_key = PrivateKey::default();
for sender_offset_key_id in sender_offset_key_ids {
total_sender_offset_private_key =
Expand Down Expand Up @@ -1041,7 +1059,7 @@ where TBackend: KeyManagerBackend<PublicKey> + 'static
metadata_signature_message: &[u8; 32],
) -> Result<ComAndPubSignature, TransactionError> {
match &self.wallet_type {
WalletType::Software(_software_wallet) => {
WalletType::Software => {
let ephemeral_private_key = self.get_private_key(ephemeral_private_nonce_id).await?;
let ephemeral_pubkey = PublicKey::from_secret_key(&ephemeral_private_key);
let sender_offset_private_key = self.get_private_key(sender_offset_key_id).await?; // Take the index and use it to find the key from ledger
Expand Down
3 changes: 3 additions & 0 deletions base_layer/core/src/transactions/key_manager/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub enum TxoStage {
#[derive(Clone, Copy, EnumIter)]
pub enum TransactionKeyManagerBranch {
DataEncryption = 0x00,
Alpha = 0x01,
MetadataEphemeralNonce = 0x02,
CommitmentMask = 0x03,
Nonce = 0x04,
Expand All @@ -70,6 +71,7 @@ impl TransactionKeyManagerBranch {
pub fn get_branch_key(self) -> String {
match self {
TransactionKeyManagerBranch::DataEncryption => "data encryption".to_string(),
TransactionKeyManagerBranch::Alpha => "alpha".to_string(),
TransactionKeyManagerBranch::CommitmentMask => "commitment mask".to_string(),
TransactionKeyManagerBranch::Nonce => "nonce".to_string(),
TransactionKeyManagerBranch::MetadataEphemeralNonce => "metadata ephemeral nonce".to_string(),
Expand All @@ -81,6 +83,7 @@ impl TransactionKeyManagerBranch {
pub fn from_key(key: &str) -> Self {
match key {
"data encryption" => TransactionKeyManagerBranch::DataEncryption,
"alpha" => TransactionKeyManagerBranch::Alpha,
"commitment mask" => TransactionKeyManagerBranch::CommitmentMask,
"metadata ephemeral nonce" => TransactionKeyManagerBranch::MetadataEphemeralNonce,
"kernel nonce" => TransactionKeyManagerBranch::KernelNonce,
Expand Down

0 comments on commit 7544a5c

Please sign in to comment.