Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
hansieodendaal committed Jul 18, 2024
1 parent 63788a2 commit 58dd9e9
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 67 deletions.
146 changes: 92 additions & 54 deletions applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

//! # Multi-party Ledger - command line example
use ledger_transport_hid::TransportNativeHID;
// use tari_common_types::types::{PrivateKey, PublicKey};
// use tari_crypto::keys::{PublicKey as PK, SecretKey};
// use tari_utilities::hex::Hex;
Expand Down Expand Up @@ -60,6 +61,56 @@ fn main() {

// GetAppName
println!("\ntest: GetAppName");
if let Err(e) = test_get_app_name(&transport, &ledger) {
println!("\n Error: {}\n", e);
}

// GetVersion
println!("\ntest: GetVersion");
if let Err(e) = test_get_version(&transport, &ledger) {
println!("\n Error: {}\n", e);
}

// GetPublicAlpha
println!("\ntest: GetPublicAlpha");
if let Err(e) = test_public_alpha(&transport, &ledger) {
println!("\n Error: {}\n", e);
}

// GetPublicKey
println!("\ntest: GetPublicKey");
if let Err(e) = test_get_public_key(&transport, &ledger) {
println!("\n Error: {}\n", e);
}

// GetScriptSignature
println!("\ntest: GetScriptSignature");
if let Err(e) = test_get_script_signature(&transport, &ledger) {
println!("\n Error: {}\n", e);
}

// GetViewKey
println!("\ntest: GetViewKey");
if let Err(e) = test_get_view_key(&transport, &ledger) {
println!("\n Error: {}\n", e);
}

// GetDHSharedSecret
println!("\ntest: GetDHSharedSecret");
if let Err(e) = test_get_dh_shared_secret(&transport, &ledger) {
println!("\n Error: {}\n", e);
}

// GetSchnorrSignature
println!("\ntest: GetSchnorrSignature");
if let Err(e) = test_get_schnorr_signature(&transport, &ledger) {
println!("\n Error: {}\n", e);
}

println!("\nTest completed successfully\n");
}

fn test_get_app_name(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result<(), String> {
match ledger
.build_command(Instruction::GetAppName, vec![0])
.execute_with_transport(&transport)
Expand All @@ -68,19 +119,19 @@ fn main() {
let name = match std::str::from_utf8(response.data()) {
Ok(val) => val,
Err(e) => {
println!("\nError: {}\n", e);
return;
return Err(format!("{}", e))
},
};
println!("app name: {}", name);
Ok(())
},
Err(e) => {
println!("\nError: {}\n", e);
Err(format!("{}", e))
},
}
}

// GetVersion
println!("\ntest: GetVersion");
fn test_get_version(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result<(), String> {
match ledger
.build_command(Instruction::GetVersion, vec![0])
.execute_with_transport(&transport)
Expand All @@ -89,42 +140,40 @@ fn main() {
let name = match std::str::from_utf8(response.data()) {
Ok(val) => val,
Err(e) => {
println!("\nError: {}\n", e);
return;
return Err(format!("{}", e))
},
};
println!("version: {}", name);
Ok(())
},
Err(e) => {
println!("\nError: {}\n", e);
Err(format!("{}", e))
},
}
}

// GetPublicAlpha
println!("\ntest: GetPublicAlpha");
fn test_public_alpha(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result<(), String> {
match ledger
.build_command(Instruction::GetPublicAlpha, vec![])
.execute_with_transport(&transport)
{
Ok(result) => {
if result.data().len() < 33 {
println!("\nError: result less than 33\n");
return;
return Err(format!("result less than 33, got {} ({:?})", result.data().len(), result))
}

let public_alpha = PublicKey::from_canonical_bytes(&result.data()[1..33]).unwrap();
println!("public_alpha: {}", public_alpha.to_hex());
Ok(())
},
Err(e) => {
println!("\nError: {}\n", e);
return;
Err(format!("{}", e))
},
}
}

// GetPublicKey
println!("\ntest: GetPublicKey");
fn test_get_public_key(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result<(), String> {
let mut data = Vec::new();
let index = OsRng.next_u64().to_le_bytes(); // OsRng.next_u64().to_le_bytes();
let index = OsRng.next_u64().to_le_bytes();
data.extend_from_slice(&index);
let branch_u8 = u64::from(TransactionKeyManagerBranch::CommitmentMask.as_byte()).to_le_bytes();
data.extend_from_slice(&branch_u8);
Expand All @@ -135,21 +184,19 @@ fn main() {
{
Ok(result) => {
if result.data().len() < 33 {
println!("\nError: result less than 33\n");
return;
return Err(format!("result less than 33, got {} ({:?})", result.data().len(), result))
}

let public_key = PublicKey::from_canonical_bytes(&result.data()[1..33]).unwrap();
println!("public_key: {}", public_key.to_hex());
Ok(())
},
Err(e) => {
println!("\nError: {}\n", e);
return;
Err(format!("{}", e))
},
}
}

// GetScriptSignature
println!("\ntest: GetScriptSignature");
fn test_get_script_signature(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result<(), String> {
let mut data = Vec::new();
let network = u64::from(Network::LocalNet.as_byte()).to_le_bytes();
data.extend_from_slice(&network);
Expand All @@ -173,10 +220,8 @@ fn main() {
{
Ok(result) => {
if result.data().len() < 161 {
println!("\nError: result less than 161\n");
return;
return Err(format!("result less than 161, got {} ({:?})", result.data().len(), result))
}

let data = result.data();
let signature = ComAndPubSignature::new(
Commitment::from_canonical_bytes(&data[1..33]).unwrap(),
Expand All @@ -193,38 +238,36 @@ fn main() {
signature.u_a().to_hex(),
signature.u_y().to_hex()
);
Ok(())
},
Err(e) => {
println!("\nError: {}\n", e);
return;
Err(format!("{}", e))
},
}
}

// GetViewKey
println!("\ntest: GetViewKey");
fn test_get_view_key(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result<(), String> {
match ledger
.build_command(Instruction::GetViewKey, vec![])
.execute_with_transport(&transport)
{
Ok(result) => {
if result.data().len() < 33 {
println!("\nError: result less than 33\n");
return;
return Err(format!("result less than 33, got {} ({:?})", result.data().len(), result))
}

let view_key = PrivateKey::from_canonical_bytes(&result.data()[1..33]).unwrap();
println!("view_key: {}", view_key.to_hex());
Ok(())
},
Err(e) => {
println!("\nError: {}\n", e);
return;
Err(format!("{}", e))
},
}
}

// GetDHSharedSecret
println!("\ntest: GetDHSharedSecret");
fn test_get_dh_shared_secret(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result<(), String> {
let mut data = Vec::new();
let index = OsRng.next_u64().to_le_bytes(); // OsRng.next_u64().to_le_bytes();
let index = OsRng.next_u64().to_le_bytes();
data.extend_from_slice(&index);
let branch_u8 = u64::from(TransactionKeyManagerBranch::SenderOffset.as_byte()).to_le_bytes();
data.extend_from_slice(&branch_u8);
Expand All @@ -237,24 +280,22 @@ fn main() {
{
Ok(result) => {
if result.data().len() < 33 {
println!("\nError: result less than 65\n");
return;
return Err(format!("result less than 33, got {} ({:?})", result.data().len(), result))
}

let shared_secret =
DiffieHellmanSharedSecret::<PublicKey>::from_canonical_bytes(&result.data()[1..33]).unwrap();
println!("shared_secret: {}", shared_secret.as_bytes().to_vec().to_hex());
Ok(())
},
Err(e) => {
println!("\nError: {}\n", e);
return;
Err(format!("{}", e))
},
}
}

// GetSchnorrSignature
println!("\ntest: GetSchnorrSignature");
fn test_get_schnorr_signature(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result<(), String> {
let mut data = Vec::new();
let index = OsRng.next_u64().to_le_bytes(); // OsRng.next_u64().to_le_bytes();
let index = OsRng.next_u64().to_le_bytes();
data.extend_from_slice(&index);
let branch_u8 = u64::from(TransactionKeyManagerBranch::Nonce.as_byte()).to_le_bytes();
data.extend_from_slice(&branch_u8);
Expand All @@ -269,8 +310,7 @@ fn main() {
Ok(result) => {
println!("signature data: {:?}", result.data());
if result.data().len() < 65 {
println!("\nError: result less than 65\n");
return;
return Err(format!("result less than 65, got {} ({:?})", result.data().len(), result))
}

let signature = CheckSigSchnorrSignature::new(
Expand All @@ -282,14 +322,12 @@ fn main() {
signature.get_signature().to_hex(),
signature.get_public_nonce().to_hex()
);
Ok(())
},
Err(e) => {
println!("\nError: {}\n", e);
return;
Err(format!("{}", e))
},
}

println!("\nTest completed successfully\n");
}

fn get_random_nonce() -> PrivateKey {
Expand Down
1 change: 1 addition & 0 deletions applications/minotari_ledger_wallet/wallet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ digest = { version = "0.10", default-features = false }
embedded-alloc = "0.5.0"
include_gif = "1.0.1"
ledger_device_sdk = "1.7"
rand_core = { version = "0.6", default_features = false }
zeroize = { version = "1", default-features = false }

# once_cell defined here just to lock the version. Other dependencies may try to go to 1.19 which is incompatabile with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,92 @@ pub fn handler_get_schnorr_signature(comm: &mut Comm) -> Result<(), AppSW> {
Ok(())
}

use ledger_device_sdk::random::Random;
use ledger_device_sdk::random::rand_bytes;
use ledger_device_sdk::random::LedgerRng;
use rand_core::CryptoRng;
use rand_core::{RngCore, Error, impls};

fn get_random_nonce() -> Zeroizing<RistrettoSecretKey> {
use ledger_device_sdk::random::Random;
use ledger_device_sdk::random::rand_bytes;
let mut raw_bytes = [0u8; 64];
rand_bytes(&mut raw_bytes);

SingleMessage::new(&format!("get_random_nonce")).show_and_wait();

let mut raw_bytes = [0u8; 64];
LedgerRng.fill_bytes(&mut raw_bytes);
SingleMessage::new(&format!("{}", raw_bytes.to_hex())).show_and_wait();

let raw_bytes: [u8; 64] = core::array::from_fn(|_| u8::random());
SingleMessage::new(&format!("{}", raw_bytes.to_hex())).show_and_wait();

let v = LedgerRng.next_u64();
SingleMessage::new(&format!("{}", v)).show_and_wait();

if let Some(val) = get_random_bytes::<8>() {
SingleMessage::new(&format!("{:?}", val)).show_and_wait();
}

Zeroizing::new(RistrettoSecretKey::from_uniform_bytes(&raw_bytes).expect("will not fail"))
}

use core::ptr;


const IO_RNG_BASE: u32 = 0x40000000; // Hypothetical base address
const IO_RNG_STATUS_OFFSET: u32 = 0x000;
const IO_RNG_DATA_OFFSET: u32 = 0x004;

fn read_random_byte() -> Option<u8> {
unsafe {
// Wait until the RNG has valid data
for _ in 0..1000 { // Timeout to avoid infinite loop
if ptr::read_volatile((IO_RNG_BASE + IO_RNG_STATUS_OFFSET) as *const u32) & 1 != 0 {
// Read the random byte
return Some(ptr::read_volatile((IO_RNG_BASE + IO_RNG_DATA_OFFSET) as *const u8));
}
}
None // Return None if timeout is reached
}
}

fn get_random_bytes<const N: usize>() -> Option<[u8; N]> {
let mut array = [0u8; N];
for i in 0..N {
match read_random_byte() {
Some(byte) => array[i] = byte,
None => return None, // Return None if reading a byte fails
}
}
Some(array)
}


// /// [`RngCore`] implementation via the [`rand_bytes`] syscall
// #[derive(Copy, Clone, Debug)]
// pub struct LedgerRng;
//
// /// Implement [`RngCore`] (for `[email protected]`) using ledger syscalls
// ///
// /// For backwards compatibility with `[email protected]` see [rand_compat](https://docs.rs/rand-compat/latest/rand_compat/)
// impl RngCore for LedgerRng {
// fn next_u32(&mut self) -> u32 {
// impls::next_u32_via_fill(self)
// }
//
// fn next_u64(&mut self) -> u64 {
// impls::next_u64_via_fill(self)
// }
//
// fn fill_bytes(&mut self, dest: &mut [u8]) {
// if let Err(e) = self.try_fill_bytes(dest) {
// panic!("Error: {}", e);
// }
// }
//
// fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
// getrandom(dest)?;
// Ok(())
// }
// }
//
// /// Mark LedgerRng as safe for cryptographic use
// impl CryptoRng for LedgerRng {}
Loading

0 comments on commit 58dd9e9

Please sign in to comment.