Skip to content

Commit

Permalink
add address index
Browse files Browse the repository at this point in the history
  • Loading branch information
abenso committed Nov 20, 2024
1 parent a9e804a commit 6eb294e
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 45 deletions.
48 changes: 24 additions & 24 deletions app/src/apdu_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,26 @@ void extractHDPath(uint32_t rx, uint32_t offset) {
memcpy(hdPath, G_io_apdu_buffer + offset, sizeof(uint32_t) * HDPATH_LEN_DEFAULT);

// #{TODO} --> testnet necessary?
const bool mainnet = hdPath[0] == HDPATH_0_DEFAULT && hdPath[1] == HDPATH_1_DEFAULT;
const bool mainnet = hdPath[0] == HDPATH_0_DEFAULT && hdPath[1] == HDPATH_1_DEFAULT && hdPath[2] == HDPATH_2_DEFAULT;

if (!mainnet) {
THROW(APDU_CODE_DATA_INVALID);
}
}

void extractAddressIndex(uint32_t rx, uint32_t offset, address_index_t *address_index) {
if (address_index == NULL) {
THROW(APDU_CODE_DATA_INVALID);
}

// check for account data
if (rx < offset || (rx - offset) < sizeof(address_index_t)) {
THROW(APDU_CODE_WRONG_LENGTH);
}

memcpy(address_index, &G_io_apdu_buffer[offset], sizeof(address_index_t));
}

__Z_INLINE bool process_chunk(__Z_UNUSED volatile uint32_t *tx, uint32_t rx) {
const uint8_t payloadType = G_io_apdu_buffer[OFFSET_PAYLOAD_TYPE];
if (rx < OFFSET_DATA) {
Expand Down Expand Up @@ -104,30 +117,13 @@ __Z_INLINE void handleGetAddr(volatile uint32_t *flags, volatile uint32_t *tx, u
const uint8_t requireConfirmation = G_io_apdu_buffer[OFFSET_P1];

// go to the account + randomizer data
uint32_t account_offset = OFFSET_DATA + sizeof(uint32_t) * HDPATH_LEN_DEFAULT;
uint32_t rand_offset = account_offset + sizeof(uint32_t);
address_index_t address_index = {0};
extractAddressIndex(rx, OFFSET_DATA + sizeof(uint32_t) * HDPATH_LEN_DEFAULT, &address_index);

uint32_t account = 0;

// check for account data
if (rx < account_offset || (rx - account_offset) < sizeof(uint32_t)) {
THROW(APDU_CODE_WRONG_LENGTH);
}

U32_BE(&G_io_apdu_buffer[account_offset], account);

uint8_t *randomizer = NULL;
uint8_t rand_data[ADDR_RANDOMIZER_LEN] = {0};

// check if we received the randomizer, if so check also we received
// the expected amount of bytes for it.
if (rx > rand_offset && (rx - rand_offset) >= ADDR_RANDOMIZER_LEN) {
memcpy(rand_data, &G_io_apdu_buffer[rand_offset], ADDR_RANDOMIZER_LEN);
randomizer = &rand_data[0];
}

// TODO: I have to send 0 instead of account to get the same result as penumbra repo
zxerr_t zxerr = app_fill_address(0, randomizer);
// generate hdPath with account
hdPath[2] = 0x80000000u | (uint32_t)address_index.account;

zxerr_t zxerr = app_fill_address(address_index);

if (zxerr != zxerr_ok) {
*tx = 0;
Expand Down Expand Up @@ -156,6 +152,10 @@ __Z_INLINE void handleGetFVK(volatile uint32_t *flags, volatile uint32_t *tx, ui

extractHDPath(rx, OFFSET_DATA);

uint32_t account_offset = OFFSET_DATA + sizeof(uint32_t) * HDPATH_LEN_DEFAULT;
address_index_t address_index = {0};
extractAddressIndex(rx, account_offset, &address_index);

zxerr_t zxerr = app_fill_keys();
*tx = cmdResponseLen;

Expand Down
5 changes: 2 additions & 3 deletions app/src/coin.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ extern "C" {
#define CLA 0x80

// according to penumbra docs:
// m/44'/6532'/x'
// m/44'/6532'/0'
#define HDPATH_LEN_DEFAULT 3
#define HDPATH_0_DEFAULT (0x80000000u | 0x2c) // 44
#define HDPATH_1_DEFAULT (0x80000000u | 0x1984) // 6532

#define HDPATH_2_DEFAULT (0x80000000u | 0u)
#define HDPATH_2_DEFAULT (0x80000000u | 0u) // 0

#define SECP256K1_PK_LEN 65u

Expand Down
9 changes: 3 additions & 6 deletions app/src/common/actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,22 @@

extern uint16_t cmdResponseLen;

__Z_INLINE zxerr_t app_fill_address(uint32_t account, uint8_t *randomizer) {
__Z_INLINE zxerr_t app_fill_address(address_index_t address_index) {
check_app_canary();
// Put data directly in the apdu buffer
MEMZERO(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE);

cmdResponseLen = 0;

zxerr_t error = crypto_fillAddress(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 2, &cmdResponseLen, account, randomizer);
zxerr_t error = crypto_fillAddress(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 2, &cmdResponseLen, address_index.account, address_index.randomizer);

if (error != zxerr_ok || cmdResponseLen == 0) {
THROW(APDU_CODE_EXECUTION_ERROR);
}

// Set flag to show in case of requireConfirmation
// that the address is indeed being randomized
is_randomized = false;
if (randomizer != NULL) {
is_randomized = true;
}
is_randomized = address_index.has_randomizer;

return error;
}
Expand Down
6 changes: 6 additions & 0 deletions app/src/keys_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ typedef struct {
address_t address;
} keys_t;

typedef struct {
uint32_t account;
uint8_t has_randomizer;
uint8_t randomizer[ADDR_RANDOMIZER_LEN];
} __attribute__((packed)) address_index_t;

#ifdef __cplusplus
}
#endif
8 changes: 4 additions & 4 deletions tests_zemu/tests/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IDeviceModel, DEFAULT_START_OPTIONS } from '@zondax/zemu'
import { resolve } from 'path'

export const APP_SEED = 'equip will roof matter pink blind book anxiety banner elbow sun young'
export const PEN_PATH = "m/44'/6532'"
export const PENUMBRA_PATH = "m/44'/6532'/0'"
export const ACCOUNT_ID = 1
export const ACCOUNT_ID2 = 2

Expand All @@ -15,10 +15,10 @@ const APP_PATH_FL = resolve('../app/output/app_flex.elf')

export const models: IDeviceModel[] = [
// { name: 'nanos', prefix: 'S', path: APP_PATH_S },
{ name: 'nanox', prefix: 'X', path: APP_PATH_X },
// { name: 'nanox', prefix: 'X', path: APP_PATH_X },
{ name: 'nanosp', prefix: 'SP', path: APP_PATH_SP },
{ name: 'stax', prefix: 'ST', path: APP_PATH_ST },
{ name: 'flex', prefix: 'FL', path: APP_PATH_FL },
// { name: 'stax', prefix: 'ST', path: APP_PATH_ST },
// { name: 'flex', prefix: 'FL', path: APP_PATH_FL },
]

export const defaultOptions = {
Expand Down
41 changes: 33 additions & 8 deletions tests_zemu/tests/standard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
******************************************************************************* */

import Zemu, { ButtonKind, zondaxMainmenuNavigation, isTouchDevice } from '@zondax/zemu'
import { ACCOUNT_ID, PEN_PATH, defaultOptions, models, txBlobExample } from './common'
import { PenumbraApp } from '@zondax/ledger-penumbra'
import { ACCOUNT_ID, PENUMBRA_PATH, defaultOptions, models, txBlobExample } from './common'
import { PenumbraApp, AddressIndex } from '@zondax/ledger-penumbra'

jest.setTimeout(60000)

Expand Down Expand Up @@ -75,8 +75,13 @@ describe('Standard', function () {
await sim.start({ ...defaultOptions, model: m.name })
const app = new PenumbraApp(sim.getTransport())

const addressIndex: AddressIndex = {
account: ACCOUNT_ID,
randomizer: undefined
}

//Define HDPATH
const resp = await app.getFVK(PEN_PATH, ACCOUNT_ID)
const resp = await app.getFVK(PENUMBRA_PATH, addressIndex)

console.log(resp)

Expand All @@ -94,8 +99,13 @@ describe('Standard', function () {
await sim.start({ ...defaultOptions, model: m.name })
const app = new PenumbraApp(sim.getTransport())

const addressIndex: AddressIndex = {
account: ACCOUNT_ID,
randomizer: undefined
}

//Define HDPATH
const resp = await app.getAddress(PEN_PATH, ACCOUNT_ID)
const resp = await app.getAddress(PENUMBRA_PATH, addressIndex)

console.log(resp)

Expand All @@ -113,8 +123,13 @@ describe('Standard', function () {
await sim.start({ ...defaultOptions, model: m.name })
const app = new PenumbraApp(sim.getTransport())

const addressIndex: AddressIndex = {
account: ACCOUNT_ID,
randomizer: Buffer.from(RANDOMIZER, 'hex')
}

//Define HDPATH
const resp = await app.getAddress(PEN_PATH, ACCOUNT_ID, RANDOMIZER)
const resp = await app.getAddress(PENUMBRA_PATH, addressIndex)

console.log(resp)

Expand All @@ -126,7 +141,7 @@ describe('Standard', function () {
}
})

test.concurrent.each(models)('showAddress', async function (m) {
test.only.each(models)('showAddress', async function (m) {
const sim = new Zemu(m.path)
try {
await sim.start({
Expand All @@ -138,8 +153,13 @@ describe('Standard', function () {

const app = new PenumbraApp(sim.getTransport())

const addressIndex: AddressIndex = {
account: 1,
randomizer: undefined
}

//Define HDPATH
const resp = app.showAddress(PEN_PATH, ACCOUNT_ID)
const resp = app.showAddress(PENUMBRA_PATH, addressIndex)
// Wait until we are not in the main menu
await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot())
await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-show_address`)
Expand Down Expand Up @@ -168,8 +188,13 @@ describe('Standard', function () {

const app = new PenumbraApp(sim.getTransport())

const addressIndex: AddressIndex = {
account: ACCOUNT_ID,
randomizer: Buffer.from(RANDOMIZER, 'hex')
}

//Define HDPATH
const resp = app.showAddress(PEN_PATH, ACCOUNT_ID, RANDOMIZER)
const resp = app.showAddress(PENUMBRA_PATH, addressIndex)
// Wait until we are not in the main menu
await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot())
await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-show_address_randomized`)
Expand Down

0 comments on commit 6eb294e

Please sign in to comment.