diff --git a/Cargo.lock b/Cargo.lock index e8d2cb49b8..1457faebe4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3373,6 +3373,10 @@ dependencies = [ "zxcvbn", ] +[[package]] +name = "minotari_ledger_wallet_common" +version = "1.0.0-pre.16" + [[package]] name = "minotari_ledger_wallet_comms" version = "1.0.0-pre.18" @@ -3380,8 +3384,7 @@ dependencies = [ "dialoguer 0.11.0", "ledger-transport 0.10.0 (git+https://github.com/Zondax/ledger-rs?rev=20e2a20)", "ledger-transport-hid", - "num-derive", - "num-traits", + "minotari_ledger_wallet_common", "once_cell", "rand 0.9.0-alpha.1", "serde", @@ -6077,6 +6080,7 @@ dependencies = [ "bs58 0.5.1", "chacha20poly1305", "digest 0.10.7", + "minotari_ledger_wallet_common", "newtype-ops", "once_cell", "primitive-types", diff --git a/Cargo.toml b/Cargo.toml index 7ce974b41d..f62a38f6eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ members = [ "applications/minotari_merge_mining_proxy", "applications/minotari_miner", "applications/minotari_ledger_wallet/comms", +# "applications/minotari_ledger_wallet/common", "integration_tests", "hashing", ] diff --git a/applications/minotari_console_wallet/src/automation/commands.rs b/applications/minotari_console_wallet/src/automation/commands.rs index b15ca1e63f..4b62589409 100644 --- a/applications/minotari_console_wallet/src/automation/commands.rs +++ b/applications/minotari_console_wallet/src/automation/commands.rs @@ -971,7 +971,7 @@ pub async fn command_runner( let mut script_signature = Signature::default(); match key_manager_service - .sign_with_challenge_and_message( + .sign_with_nonce_and_challenge( &party_info.wallet_spend_key_id, &party_info.script_nonce_key_id, &challenge, @@ -1007,7 +1007,7 @@ pub async fn command_runner( let mut metadata_signature = Signature::default(); match key_manager_service - .sign_with_challenge_and_message( + .sign_with_nonce_and_challenge( &party_info.sender_offset_key_id, &party_info.sender_offset_nonce_key_id, &challenge, diff --git a/applications/minotari_console_wallet/src/init/mod.rs b/applications/minotari_console_wallet/src/init/mod.rs index 22dacb0532..e580051c3f 100644 --- a/applications/minotari_console_wallet/src/init/mod.rs +++ b/applications/minotari_console_wallet/src/init/mod.rs @@ -27,7 +27,7 @@ use std::{fs, io, path::PathBuf, str::FromStr, sync::Arc, time::Instant}; use log::*; use minotari_app_utilities::{consts, identity_management::setup_node_identity}; #[cfg(feature = "ledger")] -use minotari_ledger_wallet_comms::accessor_methods::{ledger_get_public_alpha, ledger_get_view_key}; +use minotari_ledger_wallet_comms::accessor_methods::{ledger_get_public_spend_key, ledger_get_view_key}; use minotari_wallet::{ error::{WalletError, WalletStorageError}, output_manager_service::storage::database::OutputManagerDatabase, @@ -827,7 +827,7 @@ pub fn prompt_wallet_type( if prompt(connected_hardware_msg) { print!("Scanning for connected Ledger hardware device... "); let account = prompt_ledger_account(boot_mode).expect("An account value"); - match ledger_get_public_alpha(account) { + match ledger_get_public_spend_key(account) { Ok(public_alpha) => match ledger_get_view_key(account) { Ok(view_key) => { let ledger = LedgerWallet::new( diff --git a/applications/minotari_ledger_wallet/common/Cargo.toml b/applications/minotari_ledger_wallet/common/Cargo.toml new file mode 100644 index 0000000000..df34fc8240 --- /dev/null +++ b/applications/minotari_ledger_wallet/common/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "minotari_ledger_wallet_common" +version = "1.0.0-pre.16" +authors = ["The Tari Development Community"] +license = "BSD-3-Clause" +edition = "2021" + +[dependencies] diff --git a/applications/minotari_ledger_wallet/common/src/common_types.rs b/applications/minotari_ledger_wallet/common/src/common_types.rs new file mode 100644 index 0000000000..00b7c0780e --- /dev/null +++ b/applications/minotari_ledger_wallet/common/src/common_types.rs @@ -0,0 +1,334 @@ +// Copyright 2024 The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use alloc::string::String; + +use crate::utils; + +/// Ledger application status words. +#[repr(u16)] +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum AppSW { + Deny = 0xB001, + WrongP1P2 = 0xB002, + InsNotSupported = 0xB003, + ScriptSignatureFail = 0xB004, + RawSchnorrSignatureFail = 0xB005, + SchnorrSignatureFail = 0xB006, + ScriptOffsetNotUnique = 0xB007, + KeyDeriveFail = 0xB008, + KeyDeriveFromCanonical = 0xB009, + KeyDeriveFromUniform = 0xB00A, + RandomNonceFail = 0xB00B, + BadBranchKey = 0xB00C, + WrongApduLength = 0x6e03, // See ledger-device-rust-sdk/ledger_device_sdk/src/io.rs:16 + UserCancelled = 0x6e04, // See ledger-device-rust-sdk/ledger_device_sdk/src/io.rs:16 +} + +impl TryFrom for AppSW { + type Error = String; + + fn try_from(value: u16) -> Result { + match value { + 0xB001 => Ok(AppSW::Deny), + 0xB002 => Ok(AppSW::WrongP1P2), + 0xB003 => Ok(AppSW::InsNotSupported), + 0xB004 => Ok(AppSW::ScriptSignatureFail), + 0xB005 => Ok(AppSW::RawSchnorrSignatureFail), + 0xB006 => Ok(AppSW::SchnorrSignatureFail), + 0xB007 => Ok(AppSW::ScriptOffsetNotUnique), + 0xB008 => Ok(AppSW::KeyDeriveFail), + 0xB009 => Ok(AppSW::KeyDeriveFromCanonical), + 0xB00A => Ok(AppSW::KeyDeriveFromUniform), + 0xB00B => Ok(AppSW::RandomNonceFail), + 0xB00C => Ok(AppSW::BadBranchKey), + 0x6e03 => Ok(AppSW::WrongApduLength), + 0x6e04 => Ok(AppSW::UserCancelled), + _ => Err(String::from("Invalid value for AppSW (") + utils::u16_to_string(value).as_str() + ")"), + } + } +} + +/// Ledger application instructions. +#[repr(u8)] +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum Instruction { + GetVersion = 0x01, + GetAppName = 0x02, + GetPublicSpendKey = 0x03, + GetPublicKey = 0x04, + GetScriptSignature = 0x05, + GetScriptOffset = 0x06, + GetViewKey = 0x07, + GetDHSharedSecret = 0x08, + GetRawSchnorrSignature = 0x09, + GetScriptSchnorrSignature = 0x10, +} + +impl Instruction { + pub fn as_byte(self) -> u8 { + self as u8 + } + + pub fn from_byte(value: u8) -> Option { + match value { + 0x01 => Some(Instruction::GetVersion), + 0x02 => Some(Instruction::GetAppName), + 0x03 => Some(Instruction::GetPublicSpendKey), + 0x04 => Some(Instruction::GetPublicKey), + 0x05 => Some(Instruction::GetScriptSignature), + 0x06 => Some(Instruction::GetScriptOffset), + 0x07 => Some(Instruction::GetViewKey), + 0x08 => Some(Instruction::GetDHSharedSecret), + 0x09 => Some(Instruction::GetRawSchnorrSignature), + 0x10 => Some(Instruction::GetScriptSchnorrSignature), + _ => None, + } + } +} + +/// Key manager branches shared by the Ledger application and the wallet. +#[repr(u8)] +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum Branch { + DataEncryption = 0x00, + MetadataEphemeralNonce = 0x01, + CommitmentMask = 0x02, + Nonce = 0x03, + KernelNonce = 0x04, + SenderOffset = 0x05, + SenderOffsetLedger = 0x06, + Spend = 0x07, + RandomKey = 0x08, +} + +impl Branch { + pub fn as_byte(self) -> u8 { + self as u8 + } + + pub fn from_byte(value: u8) -> Option { + match value { + 0x00 => Some(Branch::DataEncryption), + 0x01 => Some(Branch::MetadataEphemeralNonce), + 0x02 => Some(Branch::CommitmentMask), + 0x03 => Some(Branch::Nonce), + 0x04 => Some(Branch::KernelNonce), + 0x05 => Some(Branch::SenderOffset), + 0x06 => Some(Branch::SenderOffsetLedger), + 0x07 => Some(Branch::Spend), + 0x08 => Some(Branch::RandomKey), + _ => None, + } + } +} + +#[cfg(test)] +mod test { + use crate::common_types::{AppSW, Instruction}; + + #[test] + fn test_app_sw_conversion() { + let mappings = [ + (0xB001, AppSW::Deny), + (0xB002, AppSW::WrongP1P2), + (0xB003, AppSW::InsNotSupported), + (0xB004, AppSW::ScriptSignatureFail), + (0xB005, AppSW::RawSchnorrSignatureFail), + (0xB006, AppSW::SchnorrSignatureFail), + (0xB007, AppSW::ScriptOffsetNotUnique), + (0xB008, AppSW::KeyDeriveFail), + (0xB009, AppSW::KeyDeriveFromCanonical), + (0xB00A, AppSW::KeyDeriveFromUniform), + (0xB00B, AppSW::RandomNonceFail), + (0xB00C, AppSW::BadBranchKey), + (0x6e03, AppSW::WrongApduLength), + (0x6e04, AppSW::UserCancelled), + ]; + + for (value, expected_app_sw) in &mappings { + match expected_app_sw { + AppSW::Deny => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::WrongP1P2 => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::InsNotSupported => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::ScriptSignatureFail => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::RawSchnorrSignatureFail => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::SchnorrSignatureFail => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::ScriptOffsetNotUnique => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::KeyDeriveFail => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::KeyDeriveFromCanonical => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::KeyDeriveFromUniform => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::RandomNonceFail => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::BadBranchKey => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::WrongApduLength => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + AppSW::UserCancelled => { + assert_eq!(AppSW::try_from(*value).unwrap(), *expected_app_sw); + }, + } + } + } + + #[test] + fn test_instruction_conversion() { + let mappings = [ + (0x01, Instruction::GetVersion), + (0x02, Instruction::GetAppName), + (0x03, Instruction::GetPublicSpendKey), + (0x04, Instruction::GetPublicKey), + (0x05, Instruction::GetScriptSignature), + (0x06, Instruction::GetScriptOffset), + (0x07, Instruction::GetViewKey), + (0x08, Instruction::GetDHSharedSecret), + (0x09, Instruction::GetRawSchnorrSignature), + (0x10, Instruction::GetScriptSchnorrSignature), + ]; + + for (expected_byte, instruction) in &mappings { + match instruction { + Instruction::GetVersion => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + Instruction::GetAppName => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + Instruction::GetPublicSpendKey => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + Instruction::GetPublicKey => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + Instruction::GetScriptSignature => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + Instruction::GetScriptOffset => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + Instruction::GetViewKey => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + Instruction::GetDHSharedSecret => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + Instruction::GetRawSchnorrSignature => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + Instruction::GetScriptSchnorrSignature => { + assert_eq!(instruction.as_byte(), *expected_byte); + assert_eq!(Instruction::from_byte(*expected_byte), Some(*instruction)); + }, + } + } + } + + #[test] + fn test_branch_conversion() { + use crate::common_types::Branch; + + let mappings = [ + (0x00, Branch::DataEncryption), + (0x01, Branch::MetadataEphemeralNonce), + (0x02, Branch::CommitmentMask), + (0x03, Branch::Nonce), + (0x04, Branch::KernelNonce), + (0x05, Branch::SenderOffset), + (0x06, Branch::SenderOffsetLedger), + (0x07, Branch::Spend), + (0x08, Branch::RandomKey), + ]; + + for (expected_byte, branch) in &mappings { + match branch { + Branch::DataEncryption => { + assert_eq!(branch.as_byte(), *expected_byte); + assert_eq!(Branch::from_byte(*expected_byte), Some(*branch)); + }, + Branch::MetadataEphemeralNonce => { + assert_eq!(branch.as_byte(), *expected_byte); + assert_eq!(Branch::from_byte(*expected_byte), Some(*branch)); + }, + Branch::CommitmentMask => { + assert_eq!(branch.as_byte(), *expected_byte); + assert_eq!(Branch::from_byte(*expected_byte), Some(*branch)); + }, + Branch::Nonce => { + assert_eq!(branch.as_byte(), *expected_byte); + assert_eq!(Branch::from_byte(*expected_byte), Some(*branch)); + }, + Branch::KernelNonce => { + assert_eq!(branch.as_byte(), *expected_byte); + assert_eq!(Branch::from_byte(*expected_byte), Some(*branch)); + }, + Branch::SenderOffset => { + assert_eq!(branch.as_byte(), *expected_byte); + assert_eq!(Branch::from_byte(*expected_byte), Some(*branch)); + }, + Branch::SenderOffsetLedger => { + assert_eq!(branch.as_byte(), *expected_byte); + assert_eq!(Branch::from_byte(*expected_byte), Some(*branch)); + }, + Branch::Spend => { + assert_eq!(branch.as_byte(), *expected_byte); + assert_eq!(Branch::from_byte(*expected_byte), Some(*branch)); + }, + Branch::RandomKey => { + assert_eq!(branch.as_byte(), *expected_byte); + assert_eq!(Branch::from_byte(*expected_byte), Some(*branch)); + }, + } + } + } +} diff --git a/applications/minotari_ledger_wallet/common/src/lib.rs b/applications/minotari_ledger_wallet/common/src/lib.rs new file mode 100644 index 0000000000..63906a1000 --- /dev/null +++ b/applications/minotari_ledger_wallet/common/src/lib.rs @@ -0,0 +1,31 @@ +// Copyright 2024 The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#![no_std] + +//! # Common types shared by the Ledger application and the rest of the Tari codebase. +/// Note: `ledger-device-rust-sdk` cannot be included in this crate as it can only be compiled for no-std and the +/// rest of the Tari code base is compiled for std. +extern crate alloc; + +pub mod common_types; +mod utils; diff --git a/applications/minotari_ledger_wallet/common/src/utils.rs b/applications/minotari_ledger_wallet/common/src/utils.rs new file mode 100644 index 0000000000..935a4358c8 --- /dev/null +++ b/applications/minotari_ledger_wallet/common/src/utils.rs @@ -0,0 +1,52 @@ +// Copyright 2024 The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use alloc::string::{String, ToString}; + +pub fn u16_to_string(number: u16) -> String { + let mut buffer = [0u8; 6]; // Maximum length for a 16-bit integer (including null terminator) + let mut pos = 0; + + if number == 0 { + buffer[pos] = b'0'; + pos += 1; + } else { + let mut num = number; + + let mut digits = [0u8; 6]; + let mut num_digits = 0; + + while num > 0 { + digits[num_digits] = b'0' + (num % 10) as u8; + num /= 10; + num_digits += 1; + } + + while num_digits > 0 { + num_digits -= 1; + buffer[pos] = digits[num_digits]; + pos += 1; + } + } + + String::from_utf8_lossy(&buffer[..pos]).to_string() +} diff --git a/applications/minotari_ledger_wallet/comms/Cargo.toml b/applications/minotari_ledger_wallet/comms/Cargo.toml index 64a3cf2878..643426d0b3 100644 --- a/applications/minotari_ledger_wallet/comms/Cargo.toml +++ b/applications/minotari_ledger_wallet/comms/Cargo.toml @@ -12,11 +12,11 @@ tari_common = { path = "../../../common" } tari_common_types = { path = "../../../base_layer/common_types" } tari_script = { path = "../../../infrastructure/tari_script" } +minotari_ledger_wallet_common = { path = "../common" } + dialoguer = { version = "0.11" } ledger-transport = { git = "https://github.com/Zondax/ledger-rs", rev = "20e2a20" } ledger-transport-hid = { git = "https://github.com/Zondax/ledger-rs", rev = "20e2a20" } -num-derive = "0.4.2" -num-traits = "0.2.15" serde = { version = "1.0.106", features = ["derive"] } thiserror = "1.0.26" diff --git a/applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs b/applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs index a17756259f..a66acef66d 100644 --- a/applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs +++ b/applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs @@ -8,8 +8,8 @@ use minotari_ledger_wallet_comms::{ accessor_methods::{ ledger_get_app_name, ledger_get_dh_shared_secret, - ledger_get_public_alpha, ledger_get_public_key, + ledger_get_public_spend_key, ledger_get_raw_schnorr_signature, ledger_get_script_offset, ledger_get_script_schnorr_signature, @@ -37,7 +37,7 @@ use rand::rngs::OsRng; use rand::RngCore; use tari_common::configuration::Network; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, types::{Commitment, PrivateKey, PublicKey}, }; use tari_crypto::{ @@ -103,7 +103,7 @@ fn main() { // GetPublicAlpha println!("\ntest: GetPublicAlpha"); let account = OsRng.next_u64(); - match ledger_get_public_alpha(account) { + match ledger_get_public_spend_key(account) { Ok(public_alpha) => println!("public_alpha: {}", public_alpha.to_hex()), Err(e) => { println!("\nError: {}\n", e); diff --git a/applications/minotari_ledger_wallet/comms/src/accessor_methods.rs b/applications/minotari_ledger_wallet/comms/src/accessor_methods.rs index ce7f1ecee5..75d48b1c6b 100644 --- a/applications/minotari_ledger_wallet/comms/src/accessor_methods.rs +++ b/applications/minotari_ledger_wallet/comms/src/accessor_methods.rs @@ -22,11 +22,12 @@ use std::sync::Mutex; +use minotari_ledger_wallet_common::common_types::{AppSW, Instruction}; use once_cell::sync::Lazy; use rand::{rngs::OsRng, RngCore}; use tari_common::configuration::Network; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, types::{ComAndPubSignature, Commitment, PrivateKey, PublicKey, Signature}, }; use tari_crypto::dhke::DiffieHellmanSharedSecret; @@ -35,7 +36,7 @@ use tari_utilities::ByteArray; use crate::{ error::LedgerDeviceError, - ledger_wallet::{AppSW, Command, Instruction, EXPECTED_NAME, EXPECTED_VERSION}, + ledger_wallet::{Command, EXPECTED_NAME, EXPECTED_VERSION}, }; // hash_domain!(CheckSigHashDomain, "com.tari.script.check_sig", 1); @@ -95,7 +96,8 @@ fn verify() -> Result<(), LedgerDeviceError> { let private_key_branch = TransactionKeyManagerBranch::SenderOffsetLedger; let mut nonce = [0u8; 32]; OsRng.fill_bytes(&mut nonce); - match ledger_get_script_schnorr_signature(account, private_key_index, private_key_branch, &nonce) { + let signature_a = match ledger_get_script_schnorr_signature(account, private_key_index, private_key_branch, &nonce) + { Ok(signature) => match ledger_get_public_key(account, private_key_index, private_key_branch) { Ok(public_key) => { if !signature.verify(&public_key, nonce) { @@ -103,6 +105,7 @@ fn verify() -> Result<(), LedgerDeviceError> { "'Minotari Wallet' application could not create a valid signature".to_string(), )); } + signature }, Err(e) => { return Err(LedgerDeviceError::Processing(format!( @@ -117,6 +120,21 @@ fn verify() -> Result<(), LedgerDeviceError> { e ))) }, + }; + match ledger_get_script_schnorr_signature(account, private_key_index, private_key_branch, &nonce) { + Ok(signature_b) => { + if signature_a == signature_b { + return Err(LedgerDeviceError::Processing( + "'Minotari Wallet' application is not creating unique signatures".to_string(), + )); + } + }, + Err(e) => { + return Err(LedgerDeviceError::Processing(format!( + "'Minotari Wallet' application could not create a signature ({:?})", + e + ))) + }, } Ok(()) @@ -165,16 +183,16 @@ pub fn ledger_get_version() -> Result { } /// Get the public alpha key from the ledger device -pub fn ledger_get_public_alpha(account: u64) -> Result { +pub fn ledger_get_public_spend_key(account: u64) -> Result { verify_ledger_application()?; - match Command::>::build_command(account, Instruction::GetPublicAlpha, vec![]).execute() { + match Command::>::build_command(account, Instruction::GetPublicSpendKey, vec![]).execute() { Ok(result) => { if result.data().len() < 33 { return Err(LedgerDeviceError::Processing(format!( "GetPublicAlpha: expected 33 bytes, got {} ({:?})", result.data().len(), - AppSW::from(result.retcode()) + AppSW::try_from(result.retcode())? ))); } let public_alpha = PublicKey::from_canonical_bytes(&result.data()[1..33])?; @@ -203,7 +221,7 @@ pub fn ledger_get_public_key( return Err(LedgerDeviceError::Processing(format!( "GetPublicAlpha: expected 33 bytes, got {} ({:?})", result.data().len(), - AppSW::from(result.retcode()) + AppSW::try_from(result.retcode())? ))); } let public_key = PublicKey::from_canonical_bytes(&result.data()[1..33])?; @@ -247,7 +265,7 @@ pub fn ledger_get_script_signature( return Err(LedgerDeviceError::Processing(format!( "GetScriptSignature: expected 161 bytes, got {} ({:?})", result.data().len(), - AppSW::from(result.retcode()) + AppSW::try_from(result.retcode())? ))); } let data = result.data(); @@ -306,7 +324,7 @@ pub fn ledger_get_script_offset( return Err(LedgerDeviceError::Processing(format!( "GetScriptOffset: expected 33 bytes, got {} ({:?})", result.data().len(), - AppSW::from(result.retcode()) + AppSW::try_from(result.retcode())? ))); } let script_offset = PrivateKey::from_canonical_bytes(&result.data()[1..33])?; @@ -326,7 +344,7 @@ pub fn ledger_get_view_key(account: u64) -> Result::from_canonical_bytes(&result.data()[1..33])?; @@ -390,7 +408,7 @@ pub fn ledger_get_raw_schnorr_signature( return Err(LedgerDeviceError::Processing(format!( "GetRawSchnorrSignature: expected 65 bytes, got {} ({:?})", result.data().len(), - AppSW::from(result.retcode()) + AppSW::try_from(result.retcode())? ))); } @@ -427,7 +445,7 @@ pub fn ledger_get_script_schnorr_signature( return Err(LedgerDeviceError::Processing(format!( "GetScriptSchnorrSignature: expected 65 bytes, got {} ({:?})", result.data().len(), - AppSW::from(result.retcode()) + AppSW::try_from(result.retcode())? ))); } diff --git a/applications/minotari_ledger_wallet/comms/src/error.rs b/applications/minotari_ledger_wallet/comms/src/error.rs index c9afc2e03f..e3aec92985 100644 --- a/applications/minotari_ledger_wallet/comms/src/error.rs +++ b/applications/minotari_ledger_wallet/comms/src/error.rs @@ -55,3 +55,9 @@ impl From for LedgerDeviceError { LedgerDeviceError::ByteArrayError(e.to_string()) } } + +impl From for LedgerDeviceError { + fn from(e: String) -> Self { + LedgerDeviceError::Processing(e) + } +} diff --git a/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs b/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs index 0e455c999c..b192045b1d 100644 --- a/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs +++ b/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs @@ -24,91 +24,16 @@ use std::ops::Deref; use ledger_transport::{APDUAnswer, APDUCommand}; use ledger_transport_hid::{hidapi::HidApi, TransportNativeHID}; -use num_derive::FromPrimitive; -use num_traits::FromPrimitive; +use minotari_ledger_wallet_common::common_types::Instruction; use once_cell::sync::Lazy; use tari_utilities::ByteArray; use crate::error::LedgerDeviceError; -#[repr(u8)] -#[derive(FromPrimitive, Debug, Copy, Clone, PartialEq)] -pub enum Instruction { - GetVersion = 0x01, - GetAppName = 0x02, - GetPublicAlpha = 0x03, - GetPublicKey = 0x04, - GetScriptSignature = 0x05, - GetScriptOffset = 0x06, - GetViewKey = 0x07, - GetDHSharedSecret = 0x08, - GetRawSchnorrSignature = 0x09, - GetScriptSchnorrSignature = 0x10, -} - -#[repr(u16)] -#[derive(FromPrimitive, Debug, Copy, Clone, PartialEq)] -pub enum AppSW { - Deny = 0xB001, - WrongP1P2 = 0xB002, - InsNotSupported = 0xB003, - ClaNotSupported = 0xB004, - ScriptSignatureFail = 0xB005, - MetadataSignatureFail = 0xB006, - RawSchnorrSignatureFail = 0xB007, - SchnorrSignatureFail = 0xB008, - ScriptOffsetNotUnique = 0xB009, - KeyDeriveFail = 0xB00A, - KeyDeriveFromCanonical = 0xB00B, - KeyDeriveFromUniform = 0xB00C, - VersionParsingFail = 0xB00D, - TooManyPayloads = 0xB00E, - RandomNonceFail = 0xB00F, - BadBranchKey = 0xB010, - WrongApduLength = 0x6e03, // See ledger-device-rust-sdk/ledger_device_sdk/src/io.rs:16 - UserCancelled = 0x6e04, // See ledger-device-rust-sdk/ledger_device_sdk/src/io.rs:16 -} - -impl From for AppSW { - fn from(value: u16) -> Self { - match value { - 0xB001 => AppSW::Deny, - 0xB002 => AppSW::WrongP1P2, - 0xB003 => AppSW::InsNotSupported, - 0xB004 => AppSW::ClaNotSupported, - 0xB005 => AppSW::ScriptSignatureFail, - 0xB006 => AppSW::MetadataSignatureFail, - 0xB007 => AppSW::RawSchnorrSignatureFail, - 0xB008 => AppSW::SchnorrSignatureFail, - 0xB009 => AppSW::ScriptOffsetNotUnique, - 0xB00A => AppSW::KeyDeriveFail, - 0xB00B => AppSW::KeyDeriveFromCanonical, - 0xB00C => AppSW::KeyDeriveFromUniform, - 0xB00D => AppSW::VersionParsingFail, - 0xB00E => AppSW::TooManyPayloads, - 0xB00F => AppSW::RandomNonceFail, - 0xB010 => AppSW::BadBranchKey, - 0x6e03 => AppSW::WrongApduLength, - 0x6e04 => AppSW::UserCancelled, - _ => AppSW::Deny, - } - } -} - pub const EXPECTED_NAME: &str = "minotari_ledger_wallet"; pub const EXPECTED_VERSION: &str = "1.0.0-pre.16"; const WALLET_CLA: u8 = 0x80; -impl Instruction { - pub fn as_byte(self) -> u8 { - self as u8 - } - - pub fn from_byte(value: u8) -> Option { - FromPrimitive::from_u8(value) - } -} - pub fn get_transport() -> Result { let hid = hidapi()?; let transport = TransportNativeHID::new(hid).map_err(|e| LedgerDeviceError::NativeTransport(e.to_string()))?; diff --git a/applications/minotari_ledger_wallet/wallet/Cargo.toml b/applications/minotari_ledger_wallet/wallet/Cargo.toml index e27ca4c3ac..048890b074 100644 --- a/applications/minotari_ledger_wallet/wallet/Cargo.toml +++ b/applications/minotari_ledger_wallet/wallet/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" tari_crypto = { version = "0.20.3", default-features = false, features = ["borsh"]} tari_hashing = { path = "../../../hashing", version = "1.0.0-pre.18" } +minotari_ledger_wallet_common = { path = "../common" } + blake2 = { version = "0.10", default-features = false } borsh = { version = "1.2", default-features = false } critical-section = { version = "1.1.1" } diff --git a/applications/minotari_ledger_wallet/wallet/src/handlers/get_schnorr_signature.rs b/applications/minotari_ledger_wallet/wallet/src/handlers/get_schnorr_signature.rs index 0ff27f7f76..80c1b3a1b2 100644 --- a/applications/minotari_ledger_wallet/wallet/src/handlers/get_schnorr_signature.rs +++ b/applications/minotari_ledger_wallet/wallet/src/handlers/get_schnorr_signature.rs @@ -101,14 +101,9 @@ pub fn handler_get_script_schnorr_signature(comm: &mut Comm) -> Result<(), AppSW let mut nonce_bytes = [0u8; 32]; nonce_bytes.clone_from_slice(&data[24..56]); - let random_nonce_a = get_random_nonce()?.deref().clone(); - let random_nonce_b = get_random_nonce()?.deref().clone(); - if random_nonce_a == random_nonce_b { - SingleMessage::new("Nonces not unique!").show_and_wait(); - return Err(AppSW::SchnorrSignatureFail); - } + let random_nonce = get_random_nonce()?.deref().clone(); let signature = - match CheckSigSchnorrSignature::sign_with_nonce_and_message(&private_key, random_nonce_a, &nonce_bytes) { + match CheckSigSchnorrSignature::sign_with_nonce_and_message(&private_key, random_nonce, &nonce_bytes) { Ok(sig) => sig, Err(e) => { SingleMessage::new(&format!("Signing error:",)).show_and_wait(); diff --git a/applications/minotari_ledger_wallet/wallet/src/main.rs b/applications/minotari_ledger_wallet/wallet/src/main.rs index 039b8bd8c9..4a6b861b92 100644 --- a/applications/minotari_ledger_wallet/wallet/src/main.rs +++ b/applications/minotari_ledger_wallet/wallet/src/main.rs @@ -44,6 +44,11 @@ use ledger_device_sdk::{ io::{ApduHeader, Comm, Event, Reply, StatusWords}, ui::gadgets::SingleMessage, }; +use minotari_ledger_wallet_common::common_types::{ + AppSW as AppSWMapping, + Branch as BranchMapping, + Instruction as InstructionMapping, +}; ledger_device_sdk::set_panic!(ledger_device_sdk::exiting_panic); @@ -89,22 +94,18 @@ unsafe impl critical_section::Impl for MyCriticalSection { // Application status words. #[repr(u16)] pub enum AppSW { - Deny = 0xB001, - WrongP1P2 = 0xB002, - InsNotSupported = 0xB003, - ClaNotSupported = 0xB004, - ScriptSignatureFail = 0xB005, - MetadataSignatureFail = 0xB006, - RawSchnorrSignatureFail = 0xB007, - SchnorrSignatureFail = 0xB008, - ScriptOffsetNotUnique = 0xB009, - KeyDeriveFail = 0xB00A, - KeyDeriveFromCanonical = 0xB00B, - KeyDeriveFromUniform = 0xB00C, - VersionParsingFail = 0xB00D, - TooManyPayloads = 0xB00E, - RandomNonceFail = 0xB00F, - BadBranchKey = 0xB010, + Deny = AppSWMapping::Deny as u16, + WrongP1P2 = AppSWMapping::WrongP1P2 as u16, + InsNotSupported = AppSWMapping::InsNotSupported as u16, + ScriptSignatureFail = AppSWMapping::ScriptSignatureFail as u16, + RawSchnorrSignatureFail = AppSWMapping::RawSchnorrSignatureFail as u16, + SchnorrSignatureFail = AppSWMapping::SchnorrSignatureFail as u16, + ScriptOffsetNotUnique = AppSWMapping::ScriptOffsetNotUnique as u16, + KeyDeriveFail = AppSWMapping::KeyDeriveFail as u16, + KeyDeriveFromCanonical = AppSWMapping::KeyDeriveFromCanonical as u16, + KeyDeriveFromUniform = AppSWMapping::KeyDeriveFromUniform as u16, + RandomNonceFail = AppSWMapping::RandomNonceFail as u16, + BadBranchKey = AppSWMapping::BadBranchKey as u16, WrongApduLength = StatusWords::BadLen as u16, // See ledger-device-rust-sdk/ledger_device_sdk/src/io.rs:16 UserCancelled = StatusWords::UserCancelled as u16, // See ledger-device-rust-sdk/ledger_device_sdk/src/io.rs:16 } @@ -150,16 +151,18 @@ impl KeyType { } fn from_branch_key(n: u64) -> Result { - // These numbers need to match the TransactionKeyManagerBranches in: - // base_layer/core/src/transactions/key_manager/interface.rs - // See `pub enum TransactionKeyManagerBranch` in - // `tari_wallet/src/transaction_service/transaction_key_manager.rs` for the mapping of the branch key to - // the key type. - match n { - 6 => Ok(Self::OneSidedSenderOffset), - 7 => Ok(Self::Spend), - 8 => Ok(Self::Random), - _ => Err(AppSW::BadBranchKey), + if n > u64::from(u8::MAX) { + return Err(AppSW::BadBranchKey); + } + if let Some(branch) = BranchMapping::from_byte(n as u8) { + match branch { + BranchMapping::SenderOffsetLedger => Ok(Self::OneSidedSenderOffset), + BranchMapping::Spend => Ok(Self::Spend), + BranchMapping::RandomKey => Ok(Self::Random), + _ => Err(AppSW::BadBranchKey), + } + } else { + return Err(AppSW::BadBranchKey); } } } @@ -179,21 +182,22 @@ impl TryFrom for Instruction { /// Note that CLA is not checked here. Instead the method [`Comm::set_expected_cla`] is used in /// [`sample_main`] to have this verification automatically performed by the SDK. fn try_from(value: ApduHeader) -> Result { - match (value.ins, value.p1, value.p2) { - (0x01, 0, 0) => Ok(Instruction::GetVersion), - (0x02, 0, 0) => Ok(Instruction::GetAppName), - (0x03, 0, 0) => Ok(Instruction::GetPublicSpendKey), - (0x04, 0, 0) => Ok(Instruction::GetPublicKey), - (0x05, 0, 0) => Ok(Instruction::GetScriptSignature), - (0x06, 0..=MAX_PAYLOADS, 0 | P2_MORE) => Ok(Instruction::GetScriptOffset { + let ins = InstructionMapping::from_byte(value.ins).ok_or(AppSW::InsNotSupported)?; + match (ins, value.p1, value.p2) { + (InstructionMapping::GetVersion, 0, 0) => Ok(Instruction::GetVersion), + (InstructionMapping::GetAppName, 0, 0) => Ok(Instruction::GetAppName), + (InstructionMapping::GetPublicSpendKey, 0, 0) => Ok(Instruction::GetPublicSpendKey), + (InstructionMapping::GetPublicKey, 0, 0) => Ok(Instruction::GetPublicKey), + (InstructionMapping::GetScriptSignature, 0, 0) => Ok(Instruction::GetScriptSignature), + (InstructionMapping::GetScriptOffset, 0..=MAX_PAYLOADS, 0 | P2_MORE) => Ok(Instruction::GetScriptOffset { chunk: value.p1, more: value.p2 == P2_MORE, }), - (0x07, 0, 0) => Ok(Instruction::GetViewKey), - (0x08, 0, 0) => Ok(Instruction::GetDHSharedSecret), - (0x09, 0, 0) => Ok(Instruction::GetRawSchnorrSignature), - (0x10, 0, 0) => Ok(Instruction::GetScriptSchnorrSignature), - (0x06, _, _) => Err(AppSW::WrongP1P2), + (InstructionMapping::GetViewKey, 0, 0) => Ok(Instruction::GetViewKey), + (InstructionMapping::GetDHSharedSecret, 0, 0) => Ok(Instruction::GetDHSharedSecret), + (InstructionMapping::GetRawSchnorrSignature, 0, 0) => Ok(Instruction::GetRawSchnorrSignature), + (InstructionMapping::GetScriptSchnorrSignature, 0, 0) => Ok(Instruction::GetScriptSchnorrSignature), + (InstructionMapping::GetScriptSchnorrSignature, _, _) => Err(AppSW::WrongP1P2), (_, _, _) => Err(AppSW::InsNotSupported), } } diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index cc7889c38f..cf0093de88 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -36,7 +36,7 @@ use minotari_app_grpc::{ }; use minotari_app_utilities::consts; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, tari_address::TariAddress, types::{Commitment, FixedHash, PublicKey, Signature}, }; diff --git a/base_layer/common_types/Cargo.toml b/base_layer/common_types/Cargo.toml index 540b31b26e..6856d34f50 100644 --- a/base_layer/common_types/Cargo.toml +++ b/base_layer/common_types/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" tari_crypto = { version = "0.20.3" } tari_utilities = { version = "0.7" } tari_common = { path = "../../common", version = "1.0.0-pre.18" } +minotari_ledger_wallet_common = { path = "../../applications/minotari_ledger_wallet/common" } chacha20poly1305 = "0.10.1" bitflags = { version = "2.4", features = ["serde"] } borsh = "1.2" diff --git a/base_layer/common_types/src/key_manager.rs b/base_layer/common_types/src/key_branches.rs similarity index 89% rename from base_layer/common_types/src/key_manager.rs rename to base_layer/common_types/src/key_branches.rs index f81b0c11e5..7af11f3d2e 100644 --- a/base_layer/common_types/src/key_manager.rs +++ b/base_layer/common_types/src/key_branches.rs @@ -20,6 +20,7 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use minotari_ledger_wallet_common::common_types::Branch; use strum_macros::EnumIter; use crate::WALLET_COMMS_AND_SPEND_KEY_BRANCH; @@ -29,15 +30,15 @@ use crate::WALLET_COMMS_AND_SPEND_KEY_BRANCH; // These byte reps must stay in sync with the ledger representations at: // applications/minotari_ledger_wallet/wallet/src/main.rs pub enum TransactionKeyManagerBranch { - DataEncryption = 0x00, - MetadataEphemeralNonce = 0x01, - CommitmentMask = 0x02, - Nonce = 0x03, - KernelNonce = 0x04, - SenderOffset = 0x05, - SenderOffsetLedger = 0x06, - Spend = 0x07, - RandomKey = 0x08, + DataEncryption = Branch::DataEncryption as u8, + MetadataEphemeralNonce = Branch::MetadataEphemeralNonce as u8, + CommitmentMask = Branch::CommitmentMask as u8, + Nonce = Branch::Nonce as u8, + KernelNonce = Branch::KernelNonce as u8, + SenderOffset = Branch::SenderOffset as u8, + SenderOffsetLedger = Branch::SenderOffsetLedger as u8, + Spend = Branch::Spend as u8, + RandomKey = Branch::RandomKey as u8, } const DATA_ENCRYPTION: &str = "data encryption"; diff --git a/base_layer/common_types/src/lib.rs b/base_layer/common_types/src/lib.rs index 018b2d902e..b0d6c50ca1 100644 --- a/base_layer/common_types/src/lib.rs +++ b/base_layer/common_types/src/lib.rs @@ -30,7 +30,7 @@ pub mod emoji; pub mod encryption; pub mod epoch; pub mod grpc_authentication; -pub mod key_manager; +pub mod key_branches; pub mod serializers; pub mod tari_address; pub mod transaction; diff --git a/base_layer/core/src/blocks/faucets/mod.rs b/base_layer/core/src/blocks/faucets/mod.rs index 2ad43e2bee..5c7971a3fb 100644 --- a/base_layer/core/src/blocks/faucets/mod.rs +++ b/base_layer/core/src/blocks/faucets/mod.rs @@ -26,7 +26,7 @@ mod test { use rand::rngs::OsRng; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, tari_address::TariAddress, types::{Commitment, PrivateKey, PublicKey, Signature}, }; diff --git a/base_layer/core/src/transactions/coinbase_builder.rs b/base_layer/core/src/transactions/coinbase_builder.rs index ab65d4f190..29cff78884 100644 --- a/base_layer/core/src/transactions/coinbase_builder.rs +++ b/base_layer/core/src/transactions/coinbase_builder.rs @@ -23,7 +23,7 @@ use log::*; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, tari_address::TariAddress, types::{Commitment, PrivateKey}, }; @@ -502,7 +502,7 @@ pub async fn generate_coinbase_with_wallet_output( #[cfg(test)] mod test { use tari_common::configuration::Network; - use tari_common_types::{key_manager::TransactionKeyManagerBranch, tari_address::TariAddress, types::Commitment}; + use tari_common_types::{key_branches::TransactionKeyManagerBranch, tari_address::TariAddress, types::Commitment}; use crate::{ consensus::{emission::Emission, ConsensusManager, ConsensusManagerBuilder}, diff --git a/base_layer/core/src/transactions/key_manager/inner.rs b/base_layer/core/src/transactions/key_manager/inner.rs index c5d9f778a2..bd0a520c73 100644 --- a/base_layer/core/src/transactions/key_manager/inner.rs +++ b/base_layer/core/src/transactions/key_manager/inner.rs @@ -38,7 +38,7 @@ use rand::rngs::OsRng; use rand::RngCore; use strum::IntoEnumIterator; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, types::{ComAndPubSignature, Commitment, PrivateKey, PublicKey, RangeProof, Signature}, wallet_types::WalletType, }; @@ -172,10 +172,7 @@ where TBackend: KeyManagerBackend + 'static let mut km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .write() .await; self.db.increment_key_index(branch)?; @@ -229,10 +226,7 @@ where TBackend: KeyManagerBackend + 'static pub async fn get_static_key(&self, branch: &str) -> Result { match self.key_managers.get(branch) { - None => Err(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - ))), + None => Err(self.unknown_key_branch_error(branch)), Some(_) => Ok(KeyId::Managed { branch: branch.to_string(), index: 0, @@ -240,7 +234,6 @@ where TBackend: KeyManagerBackend + 'static } } - #[allow(clippy::too_many_lines)] pub async fn get_public_key_at_key_id(&self, key_id: &TariKeyId) -> Result { match key_id { KeyId::Managed { branch, index } => { @@ -274,19 +267,13 @@ where TBackend: KeyManagerBackend + 'static .ok_or(KeyManagerServiceError::LedgerViewKeyInaccessible)?; Ok(PublicKey::from_secret_key(&view_key)) }, - _ => Err(KeyManagerServiceError::BranchNotSupported(format!( - "{}, {}", - branch, self.wallet_type - ))), + _ => Err(self.branch_not_supported_error(branch)), }, _ => { let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; Ok(km.derive_public_key(*index)?.key) @@ -298,10 +285,7 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; let branch_key = km.get_private_key(*index)?; @@ -321,6 +305,14 @@ where TBackend: KeyManagerBackend + 'static } } + fn unknown_key_branch_error(&self, branch: &str) -> KeyManagerServiceError { + KeyManagerServiceError::UnknownKeyBranch(format!("{}, {}", branch, self.wallet_type)) + } + + fn branch_not_supported_error(&self, branch: &str) -> KeyManagerServiceError { + KeyManagerServiceError::BranchNotSupported(format!("{}, {}", branch, self.wallet_type)) + } + #[allow(clippy::too_many_lines)] pub(crate) async fn get_private_key(&self, key_id: &TariKeyId) -> Result { match key_id { @@ -360,10 +352,7 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; let key = km.get_private_key(*index)?; @@ -375,20 +364,14 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(&TransactionKeyManagerBranch::Spend.get_branch_key()) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; let private_alpha = km.get_private_key(0)?; let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; let branch_key = km.get_private_key(*index)?; @@ -409,10 +392,7 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; let branch_key = km.get_private_key(*index)?; @@ -533,10 +513,7 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(&branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(&branch))? .read() .await; let key = km.get_private_key(index)?; @@ -593,10 +570,7 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; @@ -627,10 +601,7 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; @@ -666,10 +637,7 @@ where TBackend: KeyManagerBackend + 'static let mut km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .write() .await; let current_index = km.key_index(); @@ -736,9 +704,7 @@ where TBackend: KeyManagerBackend + 'static .map_err(TransactionError::LedgerDeviceError) } }, - _ => Err(TransactionError::from(KeyManagerServiceError::BranchNotSupported( - format!("{}, {}", branch, self.wallet_type), - ))), + _ => Err(TransactionError::from(self.branch_not_supported_error(branch))), }, _ => Err(TransactionError::UnsupportedTariKeyId(format!( "Expected 'KeyId::Managed', got {}", @@ -782,9 +748,7 @@ where TBackend: KeyManagerBackend + 'static .map(diffie_hellman_stealth_domain_hasher) } }, - _ => Err(TransactionError::from(KeyManagerServiceError::BranchNotSupported( - format!("{}, {}", branch, self.wallet_type), - ))), + _ => Err(TransactionError::from(self.branch_not_supported_error(branch))), }, _ => Err(TransactionError::UnsupportedTariKeyId(format!( "Expected 'KeyId::Managed', got {}", @@ -857,7 +821,6 @@ where TBackend: KeyManagerBackend + 'static match (&self.wallet_type, script_key_id) { ( WalletType::Ledger(ledger), - // TODO: Is this correct? Should it not be 'KeyId::Managed'? KeyId::Derived { branch, label: _, @@ -877,10 +840,7 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; let branch_key = km @@ -1033,7 +993,6 @@ where TBackend: KeyManagerBackend + 'static }) } - #[allow(clippy::too_many_lines)] pub async fn get_script_offset( &self, script_key_ids: &[TariKeyId], @@ -1059,10 +1018,7 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( - "{}, {}", - branch, self.wallet_type - )))? + .ok_or(self.unknown_key_branch_error(branch))? .read() .await; let branch_key = km @@ -1164,7 +1120,7 @@ where TBackend: KeyManagerBackend + 'static pub async fn sign_script_message( &self, private_key_id: &TariKeyId, - nonce: &[u8], + challenge: &[u8], ) -> Result { match &self.wallet_type { WalletType::Ledger(ledger) => { @@ -1184,7 +1140,7 @@ where TBackend: KeyManagerBackend + 'static ledger.account, *index, TransactionKeyManagerBranch::from_key(branch), - nonce, + challenge, )?; Ok(signature) }, @@ -1197,14 +1153,14 @@ where TBackend: KeyManagerBackend + 'static }, _ => { let private_key = self.get_private_key(private_key_id).await?; - let signature = CheckSigSchnorrSignature::sign(&private_key, nonce, &mut OsRng)?; + let signature = CheckSigSchnorrSignature::sign(&private_key, challenge, &mut OsRng)?; Ok(signature) }, } } - pub async fn sign_with_challenge_and_message( + pub async fn sign_with_nonce_and_challenge( &self, private_key_id: &TariKeyId, nonce_key_id: &TariKeyId, diff --git a/base_layer/core/src/transactions/key_manager/interface.rs b/base_layer/core/src/transactions/key_manager/interface.rs index d5d7e4edee..d299365445 100644 --- a/base_layer/core/src/transactions/key_manager/interface.rs +++ b/base_layer/core/src/transactions/key_manager/interface.rs @@ -226,7 +226,7 @@ pub trait TransactionKeyManagerInterface: KeyManagerInterface { challenge: &[u8], ) -> Result; - async fn sign_with_challenge_and_message( + async fn sign_with_nonce_and_challenge( &self, private_key_id: &TariKeyId, nonce: &TariKeyId, diff --git a/base_layer/core/src/transactions/key_manager/mod.rs b/base_layer/core/src/transactions/key_manager/mod.rs index 0563dc8bcd..b1c356c574 100644 --- a/base_layer/core/src/transactions/key_manager/mod.rs +++ b/base_layer/core/src/transactions/key_manager/mod.rs @@ -47,4 +47,4 @@ pub use memory_db_key_manager::{ mod error; pub use error::CoreKeyManagerError; -pub use tari_common_types::key_manager::TransactionKeyManagerBranch; +pub use tari_common_types::key_branches::TransactionKeyManagerBranch; diff --git a/base_layer/core/src/transactions/key_manager/wrapper.rs b/base_layer/core/src/transactions/key_manager/wrapper.rs index eac880839c..0701391f2d 100644 --- a/base_layer/core/src/transactions/key_manager/wrapper.rs +++ b/base_layer/core/src/transactions/key_manager/wrapper.rs @@ -473,7 +473,7 @@ where TBackend: KeyManagerBackend + 'static .await } - async fn sign_with_challenge_and_message( + async fn sign_with_nonce_and_challenge( &self, private_key_id: &TariKeyId, nonce: &TariKeyId, @@ -482,7 +482,7 @@ where TBackend: KeyManagerBackend + 'static self.transaction_key_manager_inner .read() .await - .sign_with_challenge_and_message(private_key_id, nonce, challenge) + .sign_with_nonce_and_challenge(private_key_id, nonce, challenge) .await } diff --git a/base_layer/core/src/transactions/test_helpers.rs b/base_layer/core/src/transactions/test_helpers.rs index 712ed541d1..7c147f48fa 100644 --- a/base_layer/core/src/transactions/test_helpers.rs +++ b/base_layer/core/src/transactions/test_helpers.rs @@ -26,7 +26,7 @@ use rand::rngs::OsRng; use tari_common::configuration::Network; use tari_common_sqlite::{error::SqliteStorageError, sqlite_connection_pool::PooledDbConnection}; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, types::{Commitment, PrivateKey, PublicKey, Signature}, }; use tari_crypto::keys::{PublicKey as PK, SecretKey}; diff --git a/base_layer/core/src/transactions/transaction_components/wallet_output.rs b/base_layer/core/src/transactions/transaction_components/wallet_output.rs index aa626f02fb..f910bee48a 100644 --- a/base_layer/core/src/transactions/transaction_components/wallet_output.rs +++ b/base_layer/core/src/transactions/transaction_components/wallet_output.rs @@ -276,7 +276,7 @@ impl WalletOutput { &message, ); let script_key_partial_script_signature = key_manager - .sign_with_challenge_and_message(&self.script_key_id, &ephemeral_public_key_self.key_id, &challenge) + .sign_with_nonce_and_challenge(&self.script_key_id, &ephemeral_public_key_self.key_id, &challenge) .await?; let script_signature = &commitment_partial_script_signature + &script_key_partial_script_signature; diff --git a/base_layer/core/src/transactions/transaction_components/wallet_output_builder.rs b/base_layer/core/src/transactions/transaction_components/wallet_output_builder.rs index 075a3a2f19..0bae2d5c6a 100644 --- a/base_layer/core/src/transactions/transaction_components/wallet_output_builder.rs +++ b/base_layer/core/src/transactions/transaction_components/wallet_output_builder.rs @@ -22,7 +22,7 @@ use derivative::Derivative; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, types::{ComAndPubSignature, PublicKey}, }; use tari_script::{ExecutionStack, TariScript}; @@ -259,7 +259,7 @@ impl WalletOutputBuilder { &metadata_message, ); let sender_partial_metadata_signature_self = key_manager - .sign_with_challenge_and_message(sender_offset_key_id, &ephemeral_pubkey_self.key_id, &challenge) + .sign_with_nonce_and_challenge(sender_offset_key_id, &ephemeral_pubkey_self.key_id, &challenge) .await?; let metadata_signature = &receiver_partial_metadata_signature + &sender_partial_metadata_signature_self; diff --git a/base_layer/core/src/transactions/transaction_protocol/recipient.rs b/base_layer/core/src/transactions/transaction_protocol/recipient.rs index 54964e8e90..e1945008c9 100644 --- a/base_layer/core/src/transactions/transaction_protocol/recipient.rs +++ b/base_layer/core/src/transactions/transaction_protocol/recipient.rs @@ -165,7 +165,7 @@ impl ReceiverTransactionProtocol { #[cfg(test)] mod test { - use tari_common_types::{key_manager::TransactionKeyManagerBranch, types::PublicKey}; + use tari_common_types::{key_branches::TransactionKeyManagerBranch, types::PublicKey}; use tari_crypto::keys::PublicKey as PublicKeyTrait; use tari_key_manager::key_manager_service::{KeyId, KeyManagerInterface}; use tari_script::TariScript; diff --git a/base_layer/core/src/transactions/transaction_protocol/sender.rs b/base_layer/core/src/transactions/transaction_protocol/sender.rs index 5114ec6252..bca80c2d01 100644 --- a/base_layer/core/src/transactions/transaction_protocol/sender.rs +++ b/base_layer/core/src/transactions/transaction_protocol/sender.rs @@ -870,7 +870,7 @@ impl fmt::Display for SenderState { #[cfg(test)] mod test { - use tari_common_types::{key_manager::TransactionKeyManagerBranch, types::PrivateKey}; + use tari_common_types::{key_branches::TransactionKeyManagerBranch, types::PrivateKey}; use tari_crypto::signatures::CommitmentAndPublicKeySignature; use tari_key_manager::key_manager_service::KeyManagerInterface; use tari_script::{inputs, script, ExecutionStack, TariScript}; diff --git a/base_layer/core/src/transactions/transaction_protocol/single_receiver.rs b/base_layer/core/src/transactions/transaction_protocol/single_receiver.rs index 2394a7df16..d8791eff52 100644 --- a/base_layer/core/src/transactions/transaction_protocol/single_receiver.rs +++ b/base_layer/core/src/transactions/transaction_protocol/single_receiver.rs @@ -20,7 +20,7 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use tari_common_types::key_manager::TransactionKeyManagerBranch; +use tari_common_types::key_branches::TransactionKeyManagerBranch; use crate::{ consensus::ConsensusConstants, diff --git a/base_layer/core/src/transactions/transaction_protocol/transaction_initializer.rs b/base_layer/core/src/transactions/transaction_protocol/transaction_initializer.rs index 688f39767e..1c669ab8fd 100644 --- a/base_layer/core/src/transactions/transaction_protocol/transaction_initializer.rs +++ b/base_layer/core/src/transactions/transaction_protocol/transaction_initializer.rs @@ -25,7 +25,7 @@ use std::fmt::{Debug, Error, Formatter}; use log::*; use serde::{Deserialize, Serialize}; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, transaction::TxId, types::{Commitment, PrivateKey, PublicKey, Signature}, }; diff --git a/base_layer/core/src/validation/block_body/test.rs b/base_layer/core/src/validation/block_body/test.rs index 1da8739e89..f6d8d7b2e8 100644 --- a/base_layer/core/src/validation/block_body/test.rs +++ b/base_layer/core/src/validation/block_body/test.rs @@ -22,7 +22,7 @@ use std::sync::Arc; use tari_common::configuration::Network; -use tari_common_types::{key_manager::TransactionKeyManagerBranch, tari_address::TariAddress}; +use tari_common_types::{key_branches::TransactionKeyManagerBranch, tari_address::TariAddress}; use tari_key_manager::key_manager_service::KeyId; use tari_script::{push_pubkey_script, script}; use tari_test_utils::unpack_enum; diff --git a/base_layer/core/tests/helpers/block_builders.rs b/base_layer/core/tests/helpers/block_builders.rs index 36474d0f7c..13f4384b68 100644 --- a/base_layer/core/tests/helpers/block_builders.rs +++ b/base_layer/core/tests/helpers/block_builders.rs @@ -23,7 +23,7 @@ use std::{convert::TryFrom, sync::Arc}; use rand::{rngs::OsRng, RngCore}; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, types::{Commitment, FixedHash}, }; use tari_core::{ diff --git a/base_layer/core/tests/tests/mempool.rs b/base_layer/core/tests/tests/mempool.rs index 05773f7d8e..1532414fa5 100644 --- a/base_layer/core/tests/tests/mempool.rs +++ b/base_layer/core/tests/tests/mempool.rs @@ -25,7 +25,7 @@ use std::{convert::TryFrom, ops::Deref, sync::Arc, time::Duration}; use randomx_rs::RandomXFlag; use tari_common::configuration::Network; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, types::{Commitment, PrivateKey, PublicKey, Signature}, }; use tari_comms_dht::domain_message::OutboundDomainMessage; diff --git a/base_layer/core/tests/tests/node_comms_interface.rs b/base_layer/core/tests/tests/node_comms_interface.rs index 395b2c9541..73f08589d6 100644 --- a/base_layer/core/tests/tests/node_comms_interface.rs +++ b/base_layer/core/tests/tests/node_comms_interface.rs @@ -23,7 +23,7 @@ use std::sync::{Arc, RwLock}; use tari_common::configuration::Network; -use tari_common_types::key_manager::TransactionKeyManagerBranch; +use tari_common_types::key_branches::TransactionKeyManagerBranch; use tari_comms::test_utils::mocks::create_connectivity_mock; use tari_core::{ base_node::comms_interface::{ diff --git a/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs b/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs index ca79d70992..c5cbbf3cf3 100644 --- a/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs +++ b/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs @@ -24,7 +24,7 @@ use std::time::Instant; use log::*; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, transaction::TxId, types::{FixedHash, PrivateKey}, }; diff --git a/base_layer/wallet/src/output_manager_service/service.rs b/base_layer/wallet/src/output_manager_service/service.rs index e81b4a8402..5edaf80c40 100644 --- a/base_layer/wallet/src/output_manager_service/service.rs +++ b/base_layer/wallet/src/output_manager_service/service.rs @@ -27,7 +27,7 @@ use futures::{pin_mut, StreamExt}; use log::*; use rand::{rngs::OsRng, RngCore}; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, tari_address::TariAddress, transaction::TxId, types::{BlockHash, Commitment, HashOutput, PrivateKey, PublicKey}, diff --git a/base_layer/wallet/src/transaction_service/service.rs b/base_layer/wallet/src/transaction_service/service.rs index d5b55810bf..8455e9723f 100644 --- a/base_layer/wallet/src/transaction_service/service.rs +++ b/base_layer/wallet/src/transaction_service/service.rs @@ -36,7 +36,7 @@ use sha2::Sha256; use tari_common::configuration::Network; use tari_common_types::{ burnt_proof::BurntProof, - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, tari_address::{TariAddress, TariAddressFeatures}, transaction::{ImportStatus, TransactionDirection, TransactionStatus, TxId}, types::{CommitmentFactory, FixedHash, HashOutput, PrivateKey, PublicKey, Signature}, diff --git a/base_layer/wallet/tests/output_manager_service_tests/service.rs b/base_layer/wallet/tests/output_manager_service_tests/service.rs index 4ace381341..52f059a474 100644 --- a/base_layer/wallet/tests/output_manager_service_tests/service.rs +++ b/base_layer/wallet/tests/output_manager_service_tests/service.rs @@ -43,7 +43,7 @@ use minotari_wallet::{ }; use rand::{rngs::OsRng, RngCore}; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, transaction::TxId, types::{ComAndPubSignature, FixedHash, PublicKey}, }; diff --git a/base_layer/wallet/tests/transaction_service_tests/storage.rs b/base_layer/wallet/tests/transaction_service_tests/storage.rs index 596a897d35..d43bba31ad 100644 --- a/base_layer/wallet/tests/transaction_service_tests/storage.rs +++ b/base_layer/wallet/tests/transaction_service_tests/storage.rs @@ -42,7 +42,7 @@ use minotari_wallet::{ use rand::{rngs::OsRng, RngCore}; use tari_common::configuration::Network; use tari_common_types::{ - key_manager::TransactionKeyManagerBranch, + key_branches::TransactionKeyManagerBranch, tari_address::TariAddress, transaction::{TransactionDirection, TransactionStatus, TxId}, types::{FixedHash, PrivateKey, PublicKey, Signature},