Skip to content
This repository was archived by the owner on Jun 6, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
.mypy_cache/
__pycache__/
app/app-rust/lib/risc-v/
app/app-rust/lib/x64/
app/build/
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ A few apps are available in the [app/](app/) folder:

- [app/app-ethereum/](app/app-ethereum/) is a subset of the current [Ethereum app](https://github.com/LedgerHQ/app-ethereum), with the addition of EIP-712 support
- [app/app-swap/](app/app-ethereum/) is a subset of the current [Exchange app](https://github.com/LedgerHQ/app-exchange)
- [app/app-rust/](app/app-rust/): also implements some features of the Exchange app, in Rust.
- 2 SDKs are available, a [C SDK](app/sdk/) and a [Rust SDK](app/app-rust/src/sdk/).
- [app-rust/](app-rust/): also implements some features of the Exchange app, in Rust.
- 2 SDKs are available, a [C SDK](app/sdk/) and a [Rust SDK](app-rust/src/sdk/).

The Nano RISC-V VM app is in [vm/](vm/) and Python tools to interact with the VM app are in [host/](host/).

Expand Down
4 changes: 3 additions & 1 deletion app/app-rust/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Cargo.lock
target/
target/
lib/risc-v
lib/x64
1 change: 1 addition & 0 deletions app/app-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ hex = { version = "0.4.3", default-features = false, features = ["alloc"] }
hex-literal = "0.3.4"
quick-protobuf = { version = "0.8.0", default-features = false }
serde = { version = "1.0.*", default-features = false, features = ["derive", "alloc"] }
exapp_sdk = { path = "../../exapp-sdk" }

[profile.dev]
panic = "abort"
Expand Down
2 changes: 1 addition & 1 deletion app/app-rust/src/btc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use hex_literal::hex;

use currency::*;
use error::{Result, *};
use sdk::crypto::*;
use exapp_sdk::crypto::*;

pub struct Btc {}

Expand Down
2 changes: 1 addition & 1 deletion app/app-rust/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::string::{String, ToString};
use alloc::{fmt, format};

use sdk::SdkError;
use exapp_sdk::SdkError;

#[derive(Debug)]
pub struct AppError {
Expand Down
2 changes: 1 addition & 1 deletion app/app-rust/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use hex_literal::hex;

use currency::*;
use error::*;
use sdk::crypto::*;
use exapp_sdk::crypto::*;

pub struct Eth {}

Expand Down
20 changes: 11 additions & 9 deletions app/app-rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(default_alloc_error_handler)]
#![cfg_attr(target_arch = "riscv32", no_main, no_std)]
#![cfg_attr(target_arch = "riscv32", no_std, no_main)]

extern crate alloc;
extern crate bech32;
Expand All @@ -9,6 +8,7 @@ extern crate hex_literal;
extern crate primitive_types;
extern crate quick_protobuf;
extern crate serde;
extern crate exapp_sdk;

#[cfg(not(target_arch = "riscv32"))]
extern crate core;
Expand All @@ -20,7 +20,6 @@ mod eth;
mod ledger_swap;
mod message;
mod partner;
mod sdk;
mod swap;
mod ui;
mod version;
Expand All @@ -37,6 +36,8 @@ use message::message::mod_Response::OneOfresponse;
use message::message::*;
use swap::*;

use exapp_sdk::fatal;

#[cfg(test)]
use hex_literal::hex;

Expand Down Expand Up @@ -108,19 +109,20 @@ fn test_get_version() {
assert_eq!(response, hex!("0a070a05312e322e33"));
}

pub fn main() {
#[no_mangle]
pub extern "C" fn main() {
version::setup_app();

loop {
sdk::ux::ux_idle();
exapp_sdk::ux::ux_idle();

let buffer = sdk::xrecv(512);
let buffer = exapp_sdk::xrecv(512);

sdk::ux::app_loading_start("Handling request...\x00");
exapp_sdk::ux::app_loading_start("Handling request...\x00");

let result = handle_req(&buffer);
sdk::xsend(&result);
exapp_sdk::xsend(&result);

sdk::ux::app_loading_stop();
exapp_sdk::ux::app_loading_stop();
}
}
2 changes: 1 addition & 1 deletion app/app-rust/src/partner.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use error::Result;
use message::message::*;
use sdk::crypto::{CtxSha256, CxCurve, EcfpPublicKey};
use exapp_sdk::crypto::{CtxSha256, CxCurve, EcfpPublicKey};

static LEDGER_PUBKEY: &[u8; 65] = &[
0x04, 0x20, 0xDA, 0x62, 0x00, 0x3C, 0x0C, 0xE0, 0x97, 0xE3, 0x36, 0x44, 0xA1, 0x0F, 0xE4, 0xC3,
Expand Down
4 changes: 2 additions & 2 deletions app/app-rust/src/swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use error::*;
use ledger_swap::ledger_swap::*;
use message::message::*;
use partner::*;
use sdk::crypto::{get_random_bytes, CtxSha256, CxCurve, EcfpPublicKey};
use sdk::ux::app_loading_start;
use exapp_sdk::crypto::{get_random_bytes, CtxSha256, CxCurve, EcfpPublicKey};
use exapp_sdk::ux::app_loading_start;
use ui::sign_tx_validation;

// mutable static is unsafe (because of threads)
Expand Down
4 changes: 2 additions & 2 deletions app/app-rust/src/ui.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use sdk::glyphs::{ICON_CROSSMARK, ICON_EYE, ICON_VALIDATE};
use sdk::ux::*;
use exapp_sdk::glyphs::{ICON_CROSSMARK, ICON_EYE, ICON_VALIDATE};
use exapp_sdk::ux::*;

pub fn sign_tx_validation(send_amount: &str, get_amount: &str, fees: &str) -> bool {
let swap_ui: [UxItem; 6] = [
Expand Down
21 changes: 21 additions & 0 deletions exapp-sdk/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[target.x86_64-unknown-linux-gnu]
rustflags = [
"-L../app/build/native/sdk",
"-L./lib/x64/",
"-lcxng",
"-lsdk",
"-lspeculos",
"-lcrypto",
]

[target.riscv32i-unknown-none-elf]
rustflags = [
"-l", "sdk", "-L", "../app/build/sdk",
"-l", "ux", "-L", "../app/build/sdk/ux",

# link against libc coming from the RISC-V container (/usr/local/riscv32-unknown-linux-gnu/lib/libc.a)
"-l", "c", "-L", "./lib/risc-v/",
]

[build]
target = "riscv32i-unknown-none-elf"
4 changes: 4 additions & 0 deletions exapp-sdk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Cargo.lock
target/
lib/risc-v/
lib/x64/
22 changes: 22 additions & 0 deletions exapp-sdk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "exapp_sdk"
version = "0.1.0"
edition = "2021"
authors = ["greenknot"]

[lib]
name = "exapp_sdk"
path = "src/lib.rs"

[dev-dependencies]
hex-literal = "0.3.4"

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"
strip = true
opt-level = "z"
#codegen-units = 1
lto = true
17 changes: 17 additions & 0 deletions exapp-sdk/lib/create-lib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

set -e

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

mkdir -p "${SCRIPT_DIR}/risc-v/" "${SCRIPT_DIR}/x64/"

# retrieve /usr/local/lib/libcrypto.a from the native container
docker run --rm --entrypoint tar -i native -cf - /usr/local/lib/libcrypto.a \
| tar -C "${SCRIPT_DIR}/x64/" --strip-components=3 -xf -

# retrieve /usr/local/riscv32-unknown-linux-gnu/lib/libc.a from the risc-v container
docker run --rm --entrypoint tar -i riscv -cf - /usr/local/riscv32-unknown-linux-gnu/lib/libc.a \
| tar -C "${SCRIPT_DIR}/risc-v/" --strip-components=4 -xf -

find "${SCRIPT_DIR}" -type f -name 'lib*.a' -ls
14 changes: 8 additions & 6 deletions app/app-rust/src/sdk/crypto.rs → exapp-sdk/src/crypto.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#[cfg(test)]
use hex_literal::hex;

use sdk::*;
use crate::{
ecall_hash_update, fatal, ecall::{ecall_hash_final, ecall_derive_node_bip32, ecall_cx_ecfp_generate_pair, ecall_get_random_bytes, ecall_ecdsa_verify}, SdkError
};

#[repr(C)]
pub struct CtxSha256 {
Expand Down Expand Up @@ -185,7 +187,7 @@ pub fn derive_node_bip32(
path: &[u32],
privkey_data: Option<&mut [u8]>,
chain_code: Option<&mut [u8]>,
) -> Result<()> {
) -> Result<(), SdkError> {
let privkey_data = if let Some(p) = privkey_data {
p.as_mut_ptr()
} else {
Expand All @@ -210,7 +212,7 @@ pub fn ecfp_generate_keypair(
pubkey: &mut EcfpPublicKey,
privkey: &mut EcfpPrivateKey,
keep_privkey: bool,
) -> Result<()> {
) -> Result<(), SdkError> {
if !unsafe { ecall_cx_ecfp_generate_pair(curve, pubkey, privkey, keep_privkey) } {
Err(SdkError::KeyGeneration)
} else {
Expand All @@ -237,15 +239,15 @@ impl EcfpPublicKey {
&self.w
}

pub fn verify(&self, hash: &[u8; 32], sig: &[u8]) -> Result<()> {
pub fn verify(&self, hash: &[u8; 32], sig: &[u8]) -> Result<(), SdkError> {
if !unsafe { ecall_ecdsa_verify(self, hash.as_ptr(), sig.as_ptr(), sig.len()) } {
Err(SdkError::SignatureVerification)
} else {
Ok(())
}
}

pub fn from_path(curve: CxCurve, path: &[u32]) -> Result<EcfpPublicKey> {
pub fn from_path(curve: CxCurve, path: &[u32]) -> Result<EcfpPublicKey, SdkError> {
let mut privkey = EcfpPrivateKey::from_path(curve, path)?;
let mut pubkey = EcfpPublicKey {
curve,
Expand All @@ -266,7 +268,7 @@ impl EcfpPrivateKey {
}
}

pub fn from_path(curve: CxCurve, path: &[u32]) -> Result<EcfpPrivateKey> {
pub fn from_path(curve: CxCurve, path: &[u32]) -> Result<EcfpPrivateKey, SdkError> {
let mut privkey = Self::new(curve, &[0; 32]);
derive_node_bip32(curve, path, Some(&mut privkey.d), None)?;
Ok(privkey)
Expand Down
4 changes: 2 additions & 2 deletions app/app-rust/src/sdk/ecall.rs → exapp-sdk/src/ecall.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use sdk::crypto::{CtxHashGuest, CxCurve, CxHashId, EcfpPrivateKey, EcfpPublicKey};
use sdk::ux::BaglComponent;
use crate::crypto::{CtxHashGuest, CxCurve, CxHashId, EcfpPrivateKey, EcfpPublicKey};
use crate::ux::BaglComponent;

extern "C" {
pub fn ecall_app_loading_start(status: *const u8);
Expand Down
2 changes: 1 addition & 1 deletion app/app-rust/src/sdk/glyphs.rs → exapp-sdk/src/glyphs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use sdk::ux::*;
use crate::ux::*;

static ICON_LEFT_COLORS: [u32; 2] = [0x00000000, 0x00ffffff];
static ICON_LEFT_BITMAP: [u8; 4] = [0x48, 0x12, 0x42, 0x08];
Expand Down
29 changes: 4 additions & 25 deletions app/app-rust/src/sdk/mod.rs → exapp-sdk/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#![cfg_attr(target_arch = "riscv32", no_main, no_std)]

#![allow(dead_code)] // XXX

extern crate alloc;

mod allocator;
pub mod crypto;
mod ecall;
Expand All @@ -9,9 +13,6 @@ pub mod ux;
use alloc::vec::Vec;
use alloc::{fmt, vec};

#[cfg(target_arch = "riscv32")]
use main;

use self::ecall::*;

#[global_allocator]
Expand Down Expand Up @@ -51,25 +52,3 @@ pub fn xrecv(size: usize) -> Vec<u8> {
pub fn xsend(buffer: &[u8]) {
unsafe { ecall_xsend(buffer.as_ptr(), buffer.len() as usize) }
}

#[cfg(target_arch = "riscv32")]
#[panic_handler]
fn my_panic(_info: &core::panic::PanicInfo) -> ! {
fatal("panic");
loop {}
}

#[cfg(target_arch = "riscv32")]
#[no_mangle]
pub fn atexit(_f: *const u8) {
/* required by libcrypto */
fatal("atexit");
panic!("atexit called");
}

#[cfg(target_arch = "riscv32")]
#[no_mangle]
pub fn _start(_argc: isize, _argv: *const *const u8) -> isize {
main();
0
}
4 changes: 2 additions & 2 deletions app/app-rust/src/sdk/ux.rs → exapp-sdk/src/ux.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use sdk::glyphs::*;
use sdk::{
use crate::glyphs::*;
use crate::{
ecall_app_loading_start, ecall_app_loading_stop, ecall_bagl_draw_with_context,
ecall_bagl_hal_draw_bitmap_within_rect, ecall_screen_update, ecall_ux_idle, ecall_wait_button,
};
Expand Down