Skip to content
This repository has been archived by the owner on Aug 22, 2024. It is now read-only.

Commit

Permalink
feat: impl get_public_key call with bs58 print of key
Browse files Browse the repository at this point in the history
  • Loading branch information
dj8yf0μl committed Dec 26, 2023
1 parent b62a8ca commit 39f3247
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 215 deletions.
50 changes: 4 additions & 46 deletions Cargo.lock

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

7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ edition = "2021"
ledger_device_sdk = "1.4.0"
ledger_secure_sdk_sys = "1.0.2"
include_gif = "1.0.1"
serde = {version="1.0.192", default_features = false, features = ["derive"]}
serde-json-core = { git = "https://github.com/rust-embedded-community/serde-json-core"}
hex = { version = "0.4.3", default-features = false, features = ["serde"] }
bs58 = { version = "0.5.0", default-features = false }
numtoa = "0.2.4"

[profile.release]
Expand All @@ -19,9 +18,9 @@ lto = true


[package.metadata.ledger]
curve = ["secp256k1"]
curve = ["ed25519"]
flags = "0"
path = ["44'/1'"]
path = ["44'/397'"]
name = "Rust Near"

[package.metadata.ledger.nanos]
Expand Down
16 changes: 5 additions & 11 deletions src/app_ui/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,21 @@
*****************************************************************************/

use crate::AppSW;
use crate::utils::PublicKeyBe;
use core::str::from_utf8_mut;
use ledger_device_sdk::ui::bitmaps::{CROSSMARK, EYE, VALIDATE_14};
use ledger_device_sdk::ui::gadgets::{Field, MultiFieldReview};

// Display only the last 20 bytes of the address
const DISPLAY_ADDR_BYTES_LEN: usize = 20;

pub fn ui_display_pk(addr: &[u8]) -> Result<bool, AppSW> {
let mut addr_hex = [0u8; DISPLAY_ADDR_BYTES_LEN * 2 + 2];
addr_hex[..2].copy_from_slice("0x".as_bytes());
hex::encode_to_slice(
&addr[addr.len() - DISPLAY_ADDR_BYTES_LEN..],
&mut addr_hex[2..],
)
.unwrap();
let addr_hex = from_utf8_mut(&mut addr_hex).unwrap();
addr_hex[2..].make_ascii_uppercase();
pub fn ui_display_pk(public_key: &PublicKeyBe) -> Result<bool, AppSW> {
let mut out_buf = [0u8; 60];
let full_key = public_key.display_str(&mut out_buf)?;

let my_field = [Field {
name: "Address",
value: addr_hex,
value: full_key,
}];

let my_review = MultiFieldReview::new(
Expand Down
91 changes: 42 additions & 49 deletions src/app_ui/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/
use crate::handlers::sign_tx::Tx;
// use crate::handlers::sign_tx::Tx;
use crate::utils::concatenate;
use crate::AppSW;
use ledger_device_sdk::ui::bitmaps::{CROSSMARK, EYE, VALIDATE_14};
Expand All @@ -23,56 +23,49 @@ use numtoa::NumToA;

const MAX_COIN_LENGTH: usize = 10;

/// Displays a transaction and returns true if user approved it.
///
/// This method can return [`AppSW::TxDisplayFail`] error if the coin name length is too long.
///
/// # Arguments
///
/// * `tx` - Transaction to be displayed for validation
pub fn ui_display_tx(tx: &Tx) -> Result<bool, AppSW> {
// Generate string for amount
let mut numtoa_buf = [0u8; 20];
let mut value_buf = [0u8; 20 + MAX_COIN_LENGTH + 1];
// pub fn ui_display_tx(tx: &Tx) -> Result<bool, AppSW> {
// // Generate string for amount
// let mut numtoa_buf = [0u8; 20];
// let mut value_buf = [0u8; 20 + MAX_COIN_LENGTH + 1];

let value_str = concatenate(
&[tx.coin, " ", tx.value.numtoa_str(10, &mut numtoa_buf)],
&mut value_buf,
)
.map_err(|_| AppSW::TxDisplayFail)?; // Fails if value_buf is too small
// let value_str = concatenate(
// &[tx.coin, " ", tx.value.numtoa_str(10, &mut numtoa_buf)],
// &mut value_buf,
// )
// .map_err(|_| AppSW::TxDisplayFail)?; // Fails if value_buf is too small

// Generate destination address string in hexadecimal format.
let mut to_str = [0u8; 42];
to_str[..2].copy_from_slice("0x".as_bytes());
hex::encode_to_slice(tx.to, &mut to_str[2..]).unwrap();
to_str[2..].make_ascii_uppercase();
// // Generate destination address string in hexadecimal format.
// let mut to_str = [0u8; 42];
// to_str[..2].copy_from_slice("0x".as_bytes());
// hex::encode_to_slice(tx.to, &mut to_str[2..]).unwrap();
// to_str[2..].make_ascii_uppercase();

// Define transaction review fields
let my_fields = [
Field {
name: "Amount",
value: value_str,
},
Field {
name: "Destination",
value: core::str::from_utf8(&to_str).unwrap(),
},
Field {
name: "Memo",
value: tx.memo,
},
];
// // Define transaction review fields
// let my_fields = [
// Field {
// name: "Amount",
// value: value_str,
// },
// Field {
// name: "Destination",
// value: core::str::from_utf8(&to_str).unwrap(),
// },
// Field {
// name: "Memo",
// value: tx.memo,
// },
// ];

// Create transaction review
let my_review = MultiFieldReview::new(
&my_fields,
&["Review ", "Transaction"],
Some(&EYE),
"Approve",
Some(&VALIDATE_14),
"Reject",
Some(&CROSSMARK),
);
// // Create transaction review
// let my_review = MultiFieldReview::new(
// &my_fields,
// &["Review ", "Transaction"],
// Some(&EYE),
// "Approve",
// Some(&VALIDATE_14),
// "Reject",
// Some(&CROSSMARK),
// );

Ok(my_review.show())
}
// Ok(my_review.show())
// }
55 changes: 15 additions & 40 deletions src/handlers/get_public_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
*****************************************************************************/

use crate::app_ui::address::ui_display_pk;
use crate::utils::{read_bip32_path, MAX_ALLOWED_PATH_LEN};
use crate::utils::{bip32_derive, PathBip32, PublicKeyBe};
use crate::AppSW;
use ledger_device_sdk::ecc::{Secp256k1, SeedDerive};
use ledger_device_sdk::ecc::{Ed25519, SeedDerive};
use ledger_device_sdk::io::Comm;
use ledger_secure_sdk_sys::{
cx_hash_no_throw, cx_hash_t, cx_keccak_init_no_throw, cx_sha3_t, CX_LAST, CX_OK,
Expand All @@ -27,56 +27,31 @@ use ledger_secure_sdk_sys::{
#[cfg(feature = "speculos")]
use ledger_device_sdk::testing;

use numtoa::NumToA;

pub fn handler_get_public_key(comm: &mut Comm, display: bool) -> Result<(), AppSW> {
let mut path = [0u32; MAX_ALLOWED_PATH_LEN];
let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?;
let path_len = read_bip32_path(data, &mut path)?;
let path = PathBip32::parse(data)?;

#[cfg(feature = "speculos")]
path.debug_print();

let pk = Secp256k1::derive_from_path(&path[..path_len])
let pk = bip32_derive(&path.0)
.public_key()
.map_err(|_| AppSW::KeyDeriveFail)?;

// Display address on device if requested
if display {
let mut keccak256: cx_sha3_t = Default::default();
let mut address: [u8; 32] = [0u8; 32];

unsafe {
if cx_keccak_init_no_throw(&mut keccak256, 256) != CX_OK {
return Err(AppSW::AddrDisplayFail);
}
let pk = PublicKeyBe::from_little_endian(pk);

let mut pk_mut = pk.pubkey;
let pk_ptr = pk_mut.as_mut_ptr().offset(1);
if cx_hash_no_throw(
&mut keccak256.header as *mut cx_hash_t,
CX_LAST,
pk_ptr,
64_usize,
address.as_mut_ptr(),
address.len(),
) != CX_OK
{
return Err(AppSW::AddrDisplayFail);
}
}
#[cfg(feature = "speculos")]
pk.debug_print()?;

#[cfg(feature = "speculos")]
testing::debug_print("showing public key\n");
if !ui_display_pk(&address)? {
#[cfg(feature = "speculos")]
testing::debug_print("denied\n");
if display {
if !ui_display_pk(&pk)? {
return Err(AppSW::Deny);
}
}

comm.append(&[pk.pubkey.len() as u8]);
comm.append(&pk.pubkey);
// Rust SDK key derivation API does not return chaincode yet
// so we just append a dummy chaincode.
const CHAINCODE_LEN: usize = 32;
comm.append(&[CHAINCODE_LEN as u8]); // Dummy chaincode length
comm.append(&[0u8; CHAINCODE_LEN]); // Dummy chaincode
comm.append(&pk.0);

Ok(())
}
Loading

0 comments on commit 39f3247

Please sign in to comment.