Skip to content

Commit

Permalink
Merge pull request #44 from LedgerHQ/crypto
Browse files Browse the repository at this point in the history
Add crypto ecalls and SDK helpers; add a test app for the SDK
  • Loading branch information
bigspider authored Dec 4, 2024
2 parents 2f42b86 + 9faffac commit c657e36
Show file tree
Hide file tree
Showing 26 changed files with 1,385 additions and 101 deletions.
87 changes: 81 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ jobs:
# build Vanadium VM app

build_application:
build_vanadium_app:
name: Build application using the reusable workflow
uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1
with:
Expand All @@ -124,8 +124,8 @@ jobs:
### Risc-V tests

# build test V-App
build_vapp_test:
name: Build vnd-test on Risc-V target
build_vnd_test:
name: vnd-test, Build on Risc-V target
runs-on: ubuntu-latest
steps:
- name: Set up Rust toolchain
Expand All @@ -147,8 +147,8 @@ jobs:
name: vnd_test_riscv_binary
path: apps/test/app/target/riscv32i-unknown-none-elf/release/vnd-test

run_speculos_integration_tests:
name: Integration tests on Speculos
vnd_test_speculos_integration_tests:
name: vnd-test, Integration tests on Speculos

strategy:
matrix:
Expand All @@ -159,7 +159,7 @@ jobs:
- model: stax

runs-on: ubuntu-latest
needs: [build_application, build_vapp_test]
needs: [build_vanadium_app, build_vnd_test]
steps:
- name: Set up Rust toolchain
uses: actions-rs/toolchain@v1
Expand Down Expand Up @@ -195,5 +195,80 @@ jobs:
env:
VANADIUM_BINARY: ../../../vanadium_binaries/${{ matrix.model }}/release/app-vanadium
VAPP_BINARY: ../../../vnd_test_riscv_binary/vnd-test
run: |
cargo test --features speculos-tests
# build sadik V-App
build_vnd_sadik:
name: vnd-sadik, Build on Risc-V target
runs-on: ubuntu-latest
steps:
- name: Set up Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
target: riscv32i-unknown-none-elf
components: rustfmt, clippy
profile: minimal
- name: Clone
uses: actions/checkout@v4
- name: Build app
working-directory: apps/sadik/app
run: |
cargo +nightly build --release --target riscv32i-unknown-none-elf
- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: vnd_sadik_riscv_binary
path: apps/sadik/app/target/riscv32i-unknown-none-elf/release/vnd-sadik

vnd_sadik_integration_tests:
name: vnd-sadik, Integration tests on Speculos

strategy:
matrix:
include:
# - model: nanox # TODO: reenable once compilation is fixed
- model: nanosplus
- model: flex
- model: stax

runs-on: ubuntu-latest
needs: [build_vanadium_app, build_vnd_sadik]
steps:
- name: Set up Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
target: x86_64-unknown-linux-gnu
components: rustfmt, clippy
profile: minimal
- name: Install Speculos
run: |
pip install speculos
- name: Install dependencies
run: |
sudo apt-get update && \
sudo apt-get install -y libudev-dev pkg-config && \
sudo apt-get install -y qemu-user-static libvncserver-dev
- name: Clone
uses: actions/checkout@v4
- name: Download Vanadium binaries
uses: actions/download-artifact@v4
with:
name: vanadium_binaries
path: ./vanadium_binaries

- name: Download vnd_sadik_riscv_binary
uses: actions/download-artifact@v4
with:
name: vnd_sadik_riscv_binary
path: ./vnd_sadik_riscv_binary

- name: Run integration tests
working-directory: apps/sadik/client
env:
VANADIUM_BINARY: ../../../vanadium_binaries/${{ matrix.model }}/release/app-vanadium
VAPP_BINARY: ../../../vnd_sadik_riscv_binary/vnd-sadik
run: |
cargo test --features speculos-tests
2 changes: 2 additions & 0 deletions app-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ subtle = { version="2.6.1", default-features = false }
hex = "0.4.3"
num-bigint = "0.4.6"
num-traits = "0.2.19"
sha2 = "0.10.8"
ripemd = "0.1.3"

[dev-dependencies]
hex-literal = "0.4.1"
30 changes: 15 additions & 15 deletions app-sdk/src/bignum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ impl<'a, const N: usize> BigNumMod<'a, N> {
if modulus.m.ct_eq(&[0u8; N]).into() {
panic!("Modulus cannot be 0");
}
// reduce the buffer my the modulus
// reduce the buffer by the modulus
let mut buffer = buffer;
if 1 != Ecall::bn_modm(
buffer.as_mut_ptr(),
Expand Down Expand Up @@ -478,7 +478,7 @@ mod tests {
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
));
const M2: Modulus<32> = Modulus::from_be_bytes(hex!(
"3d4b0f9e4e4d5b6e5e5d6e7e8e8d9e9e8e8d9e9e8e8d9e9e8e8d9e9e8e8d9e9e"
"3d4b0f9e4e4d5b6e5e5d6e7e8e8d9e9e8e8d9e9e8e8d9e9e8e8d9e9e8e8d9e9d"
));

#[test]
Expand Down Expand Up @@ -571,7 +571,7 @@ mod tests {
}

#[test]
fn test_from_u32() {
fn test_big_num_mod_from_u32() {
let a = BigNumMod::from_u32(2, &M);
assert_eq!(
a.buffer,
Expand All @@ -580,7 +580,7 @@ mod tests {
}

#[test]
fn test_add() {
fn test_big_num_mod_add() {
let a = BigNumMod::from_u32(2, &M);
let b = BigNumMod::from_u32(3, &M);
assert_eq!(&a + &b, BigNumMod::from_u32(5, &M));
Expand Down Expand Up @@ -620,13 +620,13 @@ mod tests {

#[test]
#[should_panic(expected = "Moduli do not match")]
fn test_add_different_modulus() {
fn test_big_num_mod_add_different_modulus() {
// this should panic
let _ = &BigNumMod::from_u32(2, &M) + &BigNumMod::from_u32(3, &M2);
}

#[test]
fn test_sub() {
fn test_big_num_mod_sub() {
let a = BigNumMod::from_u32(5, &M);
let b = BigNumMod::from_u32(3, &M);
assert_eq!(&a - &b, BigNumMod::from_u32(2, &M));
Expand Down Expand Up @@ -667,13 +667,13 @@ mod tests {

#[test]
#[should_panic(expected = "Moduli do not match")]
fn test_sub_different_modulus() {
fn test_big_num_mod_sub_different_modulus() {
// this should panic
let _ = &BigNumMod::from_u32(5, &M) - &BigNumMod::from_u32(3, &M2);
}

#[test]
fn test_mul() {
fn test_big_num_mod_mul() {
let m = Modulus::from_be_bytes(hex!(
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
));
Expand Down Expand Up @@ -717,13 +717,13 @@ mod tests {

#[test]
#[should_panic(expected = "Moduli do not match")]
fn test_mul_different_modulus() {
fn test_big_num_mod_mul_different_modulus() {
// this should panic
let _ = &BigNumMod::from_u32(2, &M) * &BigNumMod::from_u32(3, &M2);
}

#[test]
fn test_pow() {
fn test_big_num_mod_pow() {
let a = M2.new_big_num_mod(hex!(
"a247598432980432940980983408039480095809832048509809580984320985"
));
Expand All @@ -739,28 +739,28 @@ mod tests {

assert_eq!(
a.pow(&BigNum::from_be_bytes(hex!("02"))).buffer,
hex!("22e0b80916f2f35efab04d6d61155f9d1aa9f8f0dff2a2b656cdee1bb7b6dcd7")
hex!("2378a937274b6304f12d26e7170d5d757087246a2db3d5c776faf10984d3331b")
);
assert_eq!(
a.pow(&BigNum::from_be_bytes(hex!("00000002"))).buffer,
hex!("22e0b80916f2f35efab04d6d61155f9d1aa9f8f0dff2a2b656cdee1bb7b6dcd7")
hex!("2378a937274b6304f12d26e7170d5d757087246a2db3d5c776faf10984d3331b")
);
assert_eq!(
a.pow(&BigNum::from_be_bytes(hex!(
"0000000000000000000000000000000000000000000000000000000000000002"
)))
.buffer,
hex!("22e0b80916f2f35efab04d6d61155f9d1aa9f8f0dff2a2b656cdee1bb7b6dcd7")
hex!("2378a937274b6304f12d26e7170d5d757087246a2db3d5c776faf10984d3331b")
);

assert_eq!(
a.pow(&BigNum::from_be_bytes(hex!("23"))).buffer,
hex!("1ed32565487715d9669418dbaa00db9e03f8271af2074857cc6178e6905b0501")
hex!("2c341d219fc6fc7895e4de6a93d48ab77acfc2564beebb7c14a6aa57d3fd575a")
);

assert_eq!(
a.pow(&BigNum::from_be_bytes(hex!("22e0b80916f2f35efab04d6d61155f9d1aa9f8f0dff2a2b656cdee1bb7b6dcd722e0b80916f2f35efab04d6d61155f9d1aa9f8f0dff2a2b656cdee1bb7b6dcd7"))).buffer,
hex!("1329e291eb25b61d17cff7cc9c00457532f917c23f44af7469ed55b6988f0dd1")
hex!("3c0baee8c4e2f7220615013d7402fa5e69e43bc10e55500a5af4f8b966658846")
);
}
}
8 changes: 4 additions & 4 deletions app-sdk/src/ecalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub(crate) trait EcallsInterface {
/// - `len`: Length of `r`, `a`, `b`, and `m`.
///
/// # Returns
/// `true` on success, `false` on error.
/// 1 on success, 0 on error.
fn bn_addm(r: *mut u8, a: *const u8, b: *const u8, m: *const u8, len: usize) -> u32;

/// Subtracts two big numbers `a` and `b` modulo `m`, storing the result in `r`.
Expand All @@ -81,7 +81,7 @@ pub(crate) trait EcallsInterface {
/// - `len`: Length of `r`, `a`, `b`, and `m`.
///
/// # Returns
/// `true` on success, `false` on error.
/// 1 on success, 0 on error.
fn bn_subm(r: *mut u8, a: *const u8, b: *const u8, m: *const u8, len: usize) -> u32;

/// Multiplies two big numbers `a` and `b` modulo `m`, storing the result in `r`.
Expand All @@ -94,7 +94,7 @@ pub(crate) trait EcallsInterface {
/// - `len`: Length of `r`, `a`, `b`, and `m`.
///
/// # Returns
/// `true` on success, `false` on error.
/// 1 on success, 0 on error.
fn bn_multm(r: *mut u8, a: *const u8, b: *const u8, m: *const u8, len: usize) -> u32;

/// Computes `a` to the power of `e` modulo `m`, storing the result in `r`.
Expand All @@ -108,7 +108,7 @@ pub(crate) trait EcallsInterface {
/// - `len`: Length of `r`, `a`, and `m`.
///
/// # Returns
/// `true` on success, `false` on error.
/// 1 on success, 0 on error.
fn bn_powm(
r: *mut u8,
a: *const u8,
Expand Down
Loading

0 comments on commit c657e36

Please sign in to comment.