Skip to content

Commit

Permalink
finalize with serialized script
Browse files Browse the repository at this point in the history
  • Loading branch information
hansieodendaal committed Aug 12, 2024
1 parent 6fa3fad commit 0baae9c
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 125 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 1 addition & 20 deletions applications/minotari_ledger_wallet/common/src/common_types.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
// 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.
// SPDX-License-Identifier: BSD-3-Clause

use alloc::string::String;

Expand Down
24 changes: 3 additions & 21 deletions applications/minotari_ledger_wallet/common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
// 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.
// Copyright 2024 The Tari Project
// SPDX-License-Identifier: BSD-3-Clause

#![no_std]

Expand All @@ -29,3 +10,4 @@ extern crate alloc;

pub mod common_types;
mod utils;
pub use utils::{hex_to_bytes_serialized, PUSH_PUBKEY_IDENTIFIER};
52 changes: 30 additions & 22 deletions applications/minotari_ledger_wallet/common/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
// 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};
// SPDX-License-Identifier: BSD-3-Clause

use alloc::{
borrow::ToOwned,
string::{String, ToString},
vec::Vec,
};

pub const PUSH_PUBKEY_IDENTIFIER: &str = "217e";

/// Convert a u16 to a string
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;
Expand Down Expand Up @@ -50,3 +38,23 @@ pub fn u16_to_string(number: u16) -> String {

String::from_utf8_lossy(&buffer[..pos]).to_string()
}

/// Convert a hex string to serialized bytes made up as an identifier concatenated with data
pub fn hex_to_bytes_serialized(identifier: &str, data: &str) -> Result<Vec<u8>, String> {
if identifier.len() % 2 != 0 {
return Err("Invalid identifier".to_string());
}
if data.len() % 2 != 0 {
return Err("Invalid payload".to_string());
}

let hex = identifier.to_owned() + data;
let hex = hex.as_str();

let mut serialized = Vec::new();
for i in 0..hex.len() / 2 {
let byte = u8::from_str_radix(&hex[i * 2..i * 2 + 2], 16).map_err(|_e| "Invalid hex string".to_string())?;
serialized.push(byte);
}
Ok(serialized)
}
8 changes: 4 additions & 4 deletions applications/minotari_ledger_wallet/comms/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ tari_script = { path = "../../../infrastructure/tari_script" }

minotari_ledger_wallet_common = { path = "../common" }

borsh = "1.2"
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" }
log = "0.4.20"
once_cell = "1.19.0"
rand = "0.8"
serde = { version = "1.0.106", features = ["derive"] }
thiserror = "1.0.26"

rand = "0.8"
once_cell = "1.19.0"
log = "0.4.20"
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use minotari_ledger_wallet_comms::{
accessor_methods::{
ledger_get_app_name,
ledger_get_dh_shared_secret,
ledger_get_one_sided_metadata_signature,
ledger_get_public_key,
ledger_get_public_spend_key,
ledger_get_raw_schnorr_signature,
Expand Down Expand Up @@ -289,6 +290,38 @@ fn main() {
},
}

// GetOneSidedMetadataSignature
println!("\ntest: GetOneSidedMetadataSignature");
let sender_offset_key_index = OsRng.next_u64();
let mut metadata_signature_message_common = [0u8; 32];
OsRng.fill_bytes(&mut metadata_signature_message_common);
let receiver_public_spend_key = PublicKey::from_secret_key(&get_random_nonce());
let commitment_mask = get_random_nonce();

match ledger_get_one_sided_metadata_signature(
account,
network,
version,
12345,
sender_offset_key_index,
&commitment_mask,
&receiver_public_spend_key,
&metadata_signature_message_common,
) {
Ok(signature) => println!(
"signature: ({},{},{},{},{})",
signature.ephemeral_commitment().to_hex(),
signature.ephemeral_pubkey().to_hex(),
signature.u_a().to_hex(),
signature.u_x().to_hex(),
signature.u_y().to_hex()
),
Err(e) => {
println!("\nError: {}\n", e);
return;
},
}

// Test ledger app not started
println!("\ntest: Ledger app not running");
prompt_with_message("Exit the 'MinoTari Wallet' Ledger app and press Enter to continue..");
Expand Down
24 changes: 22 additions & 2 deletions applications/minotari_ledger_wallet/comms/src/accessor_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@

use std::sync::Mutex;

use borsh::BorshSerialize;
use log::debug;
use minotari_ledger_wallet_common::common_types::{AppSW, Instruction};
use minotari_ledger_wallet_common::{
common_types::{AppSW, Instruction},
hex_to_bytes_serialized,
PUSH_PUBKEY_IDENTIFIER,
};
use once_cell::sync::Lazy;
use rand::{rngs::OsRng, RngCore};
use tari_common::configuration::Network;
Expand All @@ -32,7 +37,7 @@ use tari_common_types::{
types::{ComAndPubSignature, Commitment, PrivateKey, PublicKey, Signature},
};
use tari_crypto::dhke::DiffieHellmanSharedSecret;
use tari_script::CheckSigSchnorrSignature;
use tari_script::{script, CheckSigSchnorrSignature};
use tari_utilities::{hex::Hex, ByteArray};

use crate::{
Expand Down Expand Up @@ -569,6 +574,21 @@ pub fn ledger_get_one_sided_metadata_signature(
);
verify_ledger_application()?;

// Ensure that the serialized script produce expected results
let script = script!(PushPubKey(Box::new(receiver_public_spend_key.clone())));
let mut serialized_script = Vec::new();
script
.serialize(&mut serialized_script)
.map_err(|e| LedgerDeviceError::Processing(e.to_string()))?;
let ledger_serialized_script =
hex_to_bytes_serialized(PUSH_PUBKEY_IDENTIFIER, &receiver_public_spend_key.to_hex())?;
if serialized_script != ledger_serialized_script.clone() {
return Err(LedgerDeviceError::Processing(format!(
"PushPubKey script serialization mismatch: expected {:?}, got {:?}",
serialized_script, ledger_serialized_script
)));
}

let mut data = Vec::new();
data.extend_from_slice(&u64::from(network.as_byte()).to_le_bytes());
data.extend_from_slice(&u64::from(txo_version).to_le_bytes());
Expand Down
63 changes: 63 additions & 0 deletions applications/minotari_ledger_wallet/comms/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,66 @@
pub mod accessor_methods;
pub mod error;
pub mod ledger_wallet;

#[cfg(test)]
mod test {
use borsh::BorshSerialize;
use minotari_ledger_wallet_common::{hex_to_bytes_serialized, PUSH_PUBKEY_IDENTIFIER};
use rand::rngs::OsRng;
use tari_crypto::{
keys::{PublicKey, SecretKey},
ristretto::{RistrettoPublicKey, RistrettoSecretKey},
};
use tari_script::{script, slice_to_boxed_message};
use tari_utilities::{hex::Hex, ByteArray};

const NOP_IDENTIFIER: &str = "0173";
const PUSH_ONE_IDENTIFIER: &str = "017c";
const CHECK_SIG_VERIFY_IDENTIFIER: &str = "21ad";

#[test]
// This is testing the serialization of the 'PushPubKey' script and the byte representation of the script as needed
// for native serialization in the tari ledger wallet code. Other script types where the exact hex representation of
// the script payload could easily be determined are tested in the same way to verify the concept.
// This test should highlight if any changes are made to the script serialization. Primary script:
// - 'script!(PushPubKey(Box::new(<PUB_KEY>)))'
// and additional ones used for testing:
// - 'script!(Nop)'
// - 'script!(PushOne)'
// - `CheckSigVerify(<MESSAGE>))`
fn test_push_pub_key_serialized_byte_representation() {
let mut scripts = Vec::new();

scripts.push((script!(Nop), NOP_IDENTIFIER, "".to_string()));
scripts.push((script!(PushOne), PUSH_ONE_IDENTIFIER, "".to_string()));

for pub_key in [
RistrettoPublicKey::default(),
RistrettoPublicKey::from_secret_key(&RistrettoSecretKey::random(&mut OsRng)),
] {
scripts.push((
script!(PushPubKey(Box::new(pub_key.clone()))),
PUSH_PUBKEY_IDENTIFIER,
pub_key.to_hex(),
));
}

let key = RistrettoSecretKey::random(&mut OsRng);
let msg = slice_to_boxed_message(key.as_bytes());
scripts.push((script!(CheckSigVerify(msg)), CHECK_SIG_VERIFY_IDENTIFIER, key.to_hex()));

for (script, hex_identifier, hex_payload) in scripts {
let mut serialized = Vec::new();
script.serialize(&mut serialized).unwrap();
let hex_data = hex_identifier.to_owned() + &hex_payload;
assert_eq!(hex_data, serialized.to_vec().to_hex());
assert_eq!(
hex_to_bytes_serialized(hex_identifier, &hex_payload).unwrap(),
serialized.as_slice(),
"Change in script serialization detected: {:?}, expected {}",
script,
hex_identifier
);
}
}
}
Loading

0 comments on commit 0baae9c

Please sign in to comment.