Skip to content

Commit

Permalink
Merge pull request #114 from Zondax/support_f4_addresses
Browse files Browse the repository at this point in the history
Support f4 addresses
  • Loading branch information
ftheirs authored Nov 30, 2022
2 parents a1e4c29 + 18db4a5 commit f8e2251
Show file tree
Hide file tree
Showing 51 changed files with 146 additions and 4,216 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ jobs:
run: |
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10
make deps
brew install conan
conan config install https://github.com/conan-io/conanclientcert.git
- run: cmake -DCMAKE_BUILD_TYPE=Debug . && make
- run: GTEST_COLOR=1 ASAN_OPTIONS=detect_leaks=0 ctest -VV

Expand Down
4 changes: 1 addition & 3 deletions app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ ifndef COIN
COIN=FIL
endif

APPVERSION_M=0
APPVERSION_N=22
APPVERSION_P=5
include $(CURDIR)/Makefile.version

$(info COIN = [$(COIN)])
ifeq ($(COIN),FIL)
Expand Down
6 changes: 6 additions & 0 deletions app/Makefile.version
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# This is the major version of this release
APPVERSION_M=0
# This is the minor version of this release
APPVERSION_N=22
# This is the patch version of this release
APPVERSION_P=6
43 changes: 31 additions & 12 deletions app/src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ zxerr_t crypto_sign(uint8_t *signature, uint16_t signatureMaxlen,

#endif

uint8_t decompressLEB128(const uint8_t *input, uint16_t inputSize, uint64_t *v) {
unsigned int i = 0;
uint16_t decompressLEB128(const uint8_t *input, uint16_t inputSize, uint64_t *v) {
uint16_t i = 0;

*v = 0;
uint16_t shift = 0;
Expand All @@ -262,7 +262,7 @@ uint8_t decompressLEB128(const uint8_t *input, uint16_t inputSize, uint64_t *v)
*v |= b << shift;

if (!(input[i] & 0x80u)) {
return 1;
return i + 1;
}

shift += 7;
Expand All @@ -285,6 +285,9 @@ uint16_t formatProtocol(const uint8_t *addressBytes,
return 0;
}

// Clean output buffer
MEMZERO(formattedAddress, formattedAddressSize);

const uint8_t protocol = addressBytes[0];

formattedAddress[0] = isTestnet() ? 't' : 'f';
Expand Down Expand Up @@ -322,27 +325,43 @@ uint16_t formatProtocol(const uint8_t *addressBytes,
payloadSize = ADDRESS_PROTOCOL_BLS_PAYLOAD_LEN;
break;
}
case ADDRESS_PROTOCOL_DELEGATED: {
uint64_t actorId = 0;
const uint16_t actorIdSize = decompressLEB128(addressBytes + 1, addressSize - 1, &actorId);

// Check missing actor id or missing sub-address
if (actorIdSize == 0 || (addressSize <= actorIdSize + 1)) {
return 0;
}

// Copy Actor ID
snprintf(formattedAddress + 2, formattedAddressSize - 2, "%df", actorId);

payloadSize = addressSize - 1 - actorIdSize;
break;
}
default:
return 0;
}

// Remove first byte which is the protocol byte
if (addressSize != payloadSize + 1) {
// Keep only one crc buffer using the biggest size
uint8_t payload_crc[ADDRESS_PROTOCOL_DELEGATED_MAX_SUBADDRESS_LEN + CHECKSUM_LENGTH] = {0};

// f4 addresses contain actorID
const uint16_t actorIdSize = (protocol == ADDRESS_PROTOCOL_DELEGATED) ? (addressSize - payloadSize - 1) : 0;
if (addressSize != payloadSize + 1 + actorIdSize) {
return 0;
}
MEMCPY(payload_crc, addressBytes + 1 + actorIdSize, payloadSize);

uint8_t payload_crc[ADDRESS_PROTOCOL_BLS_PAYLOAD_LEN + CHECKSUM_LENGTH]; // Max size 52 bytes

//We don't want the first byte which is the protocol byte
MEMCPY(payload_crc, addressBytes + 1, addressSize - 1);
// append 4 bytes checksum to payload_crc
blake_hash(addressBytes, addressSize, payload_crc + payloadSize, CHECKSUM_LENGTH);

const uint16_t offset = strnlen((char *) formattedAddress, formattedAddressSize);
// Now prepare the address output
if (base32_encode(payload_crc,
(uint32_t) (payloadSize + CHECKSUM_LENGTH),
(char *)(formattedAddress + 2),
(uint32_t) (formattedAddressSize - 2)) < 0) {
(char *)(formattedAddress + offset),
(uint32_t) (formattedAddressSize - offset)) < 0) {
return 0;
}

Expand Down
4 changes: 3 additions & 1 deletion app/src/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ extern uint32_t hdPath[HDPATH_LEN_DEFAULT];
#define ADDRESS_PROTOCOL_SECP256K1 0x01
#define ADDRESS_PROTOCOL_ACTOR 0x02
#define ADDRESS_PROTOCOL_BLS 0x03
#define ADDRESS_PROTOCOL_DELEGATED 0x04

#define ADDRESS_PROTOCOL_ID_PAYLOAD_LEN 0x00
#define ADDRESS_PROTOCOL_SECP256K1_PAYLOAD_LEN 20
#define ADDRESS_PROTOCOL_ACTOR_PAYLOAD_LEN 20
#define ADDRESS_PROTOCOL_BLS_PAYLOAD_LEN 48
#define ADDRESS_PROTOCOL_DELEGATED_MAX_SUBADDRESS_LEN 54

uint8_t decompressLEB128(const uint8_t *input, uint16_t inputSize, uint64_t *v);
uint16_t decompressLEB128(const uint8_t *input, uint16_t inputSize, uint64_t *v);

uint16_t formatProtocol(const uint8_t *addressBytes, uint16_t addressSize,
uint8_t *formattedAddress,
Expand Down
9 changes: 9 additions & 0 deletions app/src/parser_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@ __Z_INLINE parser_error_t readAddress(address_t *address, CborValue *value) {
// protocol 3
PARSER_ASSERT_OR_ERROR(address->len - 1 == ADDRESS_PROTOCOL_BLS_PAYLOAD_LEN, parser_invalid_address)
break;
case ADDRESS_PROTOCOL_DELEGATED: {
// protocol 4
uint64_t actorId = 0;
const uint16_t actorIdSize = decompressLEB128(address->buffer + 1, address->len - 1, &actorId);
PARSER_ASSERT_OR_ERROR(actorIdSize > 0, parser_invalid_address)
// At least 1 byte in subaddress
PARSER_ASSERT_OR_ERROR(address->len > actorIdSize + 1, parser_invalid_address)
break;
}
default:
return parser_invalid_address;
}
Expand Down
2 changes: 1 addition & 1 deletion deps/nanos-secure-sdk
2 changes: 1 addition & 1 deletion deps/nanosplus-secure-sdk
Submodule nanosplus-secure-sdk updated 74 files
+3 −0 Makefile.conf.cx
+10 −0 README.md
+0 −338 icon.py
+42 −2 include/bagl.h
+1 −1 include/bolos_version.h
+2 −3 include/cx_errors.h
+103 −98 include/cx_stubs.h
+19 −0 include/decorators.h
+4 −1 include/errors.h
+2 −1 include/exceptions.h
+8 −4 include/os_id.h
+0 −5 include/os_nvm.h
+12 −4 include/os_seed.h
+4 −9 include/os_ux.h
+5 −7 include/ox_aes.h
+85 −66 include/ox_bn.h
+1 −1 include/ox_crc.h
+6 −7 include/ox_des.h
+67 −61 include/ox_ec.h
+1 −1 include/ox_rng.h
+6 −1 include/syscalls.h
+245 −176 lib_bagl/src/bagl.c
+379 −667 lib_bagl/src/bagl_font_open_sans_extrabold_11px.inc
+118 −0 lib_bagl/src/bagl_font_open_sans_extrabold_11px_unicode.inc
+478 −766 lib_bagl/src/bagl_font_open_sans_light_16px.inc
+137 −0 lib_bagl/src/bagl_font_open_sans_light_16px_unicode.inc
+372 −660 lib_bagl/src/bagl_font_open_sans_regular_11px.inc
+114 −0 lib_bagl/src/bagl_font_open_sans_regular_11px_unicode.inc
+6 −0 lib_bagl/src/bagl_font_rom.inc
+32 −0 lib_bagl/src/bagl_font_unicode_rom_struct.inc
+11 −1 lib_bagl/src/bagl_fonts.c
+5 −0 lib_cxng/cx.export
+69 −27 lib_cxng/include/lcx_aead.h
+20 −11 lib_cxng/include/lcx_aes.h
+10 −4 lib_cxng/include/lcx_blake2.h
+4 −4 lib_cxng/include/lcx_blake3.h
+157 −0 lib_cxng/include/lcx_chacha.h
+51 −0 lib_cxng/include/lcx_chacha_poly.h
+2 −2 lib_cxng/include/lcx_common.h
+2 −2 lib_cxng/include/lcx_crc.h
+25 −13 lib_cxng/include/lcx_des.h
+8 −4 lib_cxng/include/lcx_ecdh.h
+14 −9 lib_cxng/include/lcx_ecdsa.h
+65 −34 lib_cxng/include/lcx_ecfp.h
+10 −5 lib_cxng/include/lcx_ecschnorr.h
+19 −16 lib_cxng/include/lcx_eddsa.h
+8 −8 lib_cxng/include/lcx_groestl.h
+16 −13 lib_cxng/include/lcx_hash.h
+38 −25 lib_cxng/include/lcx_hmac.h
+94 −47 lib_cxng/include/lcx_math.h
+9 −6 lib_cxng/include/lcx_pbkdf2.h
+54 −0 lib_cxng/include/lcx_poly1305.h
+3 −3 lib_cxng/include/lcx_ripemd160.h
+9 −7 lib_cxng/include/lcx_rng.h
+44 −24 lib_cxng/include/lcx_rsa.h
+12 −4 lib_cxng/include/lcx_sha256.h
+27 −12 lib_cxng/include/lcx_sha3.h
+5 −5 lib_cxng/include/lcx_sha512.h
+4 −0 lib_cxng/include/libcxng.h
+5 −5 lib_cxng/src/cx_aes_gcm.h
+77 −0 lib_cxng/src/cx_chacha_poly.h
+5 −0 lib_cxng/src/cx_exported_functions.c
+116 −0 lib_cxng/src/cx_poly1305.h
+3 −6 lib_cxng/src/cx_ram.c
+10 −0 lib_cxng/src/cx_ram.h
+11 −0 lib_cxng/src/cx_utils.c
+5 −0 lib_cxng/src/cx_utils.h
+5 −0 lib_stusb/usbd_conf.h
+1 −1 lib_ux/src/ux_layout_paging_compute.c
+5 −0 src/cx_stubs.S
+31 −8 src/os_io_seproxyhal.c
+3 −2 src/os_printf.c
+1 −1 src/pic.c
+22 −7 src/syscalls.c
2 changes: 1 addition & 1 deletion deps/nanox-secure-sdk
6 changes: 3 additions & 3 deletions tests/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ TEST(CRYPTO, extractBitsFromLEB128_small) {

auto ret = decompressLEB128(input, sizeof(input), &output);

EXPECT_THAT(ret, ::testing::Eq(1));
EXPECT_THAT(ret, ::testing::Gt(0));
EXPECT_THAT(output, ::testing::Eq(0x81));

char bufferUI[300];
Expand All @@ -120,7 +120,7 @@ TEST(CRYPTO, extractBitsFromLEB128_1byte) {

auto ret = decompressLEB128(input, sizeof(input), &output);

EXPECT_THAT(ret, ::testing::Eq(1));
EXPECT_THAT(ret, ::testing::Gt(0));
EXPECT_THAT(output, ::testing::Eq(1729));

char bufferUI[300];
Expand All @@ -136,7 +136,7 @@ TEST(CRYPTO, extractBitsFromLEB128_big) {

auto ret = decompressLEB128(input, sizeof(input), &output);

EXPECT_THAT(ret, ::testing::Eq(1));
EXPECT_THAT(ret, ::testing::Gt(0));
EXPECT_THAT(output, ::testing::Eq(18446744073709551615u));

char bufferUI[300];
Expand Down
56 changes: 37 additions & 19 deletions tests/testvectors/manual.json
Original file line number Diff line number Diff line change
Expand Up @@ -436,25 +436,6 @@
},
"encoded_tx_hex": "8a0058320300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000583203000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000144000186a01961a8420000430009c40040"
},
{
"description": "Address with unknown protocol",
"encoded_tx": "igBVBAAAAAAAAAAAAAAAAAAAAAAAAAAAVQQAAAAAAAAAAAAAAAAAAAAAAAAAAAFEAAGGoBlhqEIAAEMACcQAQA==",
"valid": false,
"error": "Invalid address format",
"testnet": false,
"message": {
"version": 0,
"to": "faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaryyc34i",
"from": "faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaryyc34i",
"nonce": 1,
"value": "100000",
"gaslimit": "25000",
"gasfeecap": "0",
"gaspremium": "2500",
"method": 0
},
"encoded_tx_hex": "8a0055040000000000000000000000000000000000000000550400000000000000000000000000000000000000000144000186a01961a8420000430009c40040"
},
{
"description": "Negative sign byte",
"encoded_tx": "igBVAdFQBQTk0aw+iayJGkUCWG+r2bQXVQG4gmGdRlWPPZ4xbRG0jc8hEycCagFBARlhqEIAAEMACcQAQA==",
Expand Down Expand Up @@ -595,5 +576,42 @@
"params": [1234]
},
"encoded_tx_hex": "8a0044008bcb534400f59c5300400040400044811904d2"
},
{
"description": "Using Protocol 4 addresses",
"encoded_tx": "notAvailable",
"valid": true,
"error": "",
"testnet": false,
"message": {
"version": 0,
"to": "f410f2qreez6evnfbqs6rvidgwm3b44hpxpvpeuoddga",
"from": "f410f2qreez6evnfbqs6rvidgwm3b44hpxpvpeuoddga",
"nonce": 1,
"value": "100000",
"gaslimit": "25000",
"gasfeecap": "1",
"gaspremium": "1",
"method": 0
},
"encoded_tx_hex": "8a0056040ad4224267c4ab4a184bd1aa066b3361e70efbbeaf56040ad4224267c4ab4a184bd1aa066b3361e70efbbeaf0144000186a01961a84200014200010040"
},
{
"description": "Address with unknown protocol",
"valid": false,
"error": "Invalid address format",
"testnet": false,
"message": {
"version": 0,
"to": "faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazuwnlsi",
"from": "faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazuwnlsi",
"nonce": 1,
"value": "100000",
"gaslimit": 25000,
"gasfeecap": "1",
"gaspremium": "1",
"method": 0
},
"encoded_tx_hex": "8A0055050000000000000000000000000000000000000000550400000000000000000000000000000000000000000144000186A01961A84200014200010040"
}
]
17 changes: 9 additions & 8 deletions tests_zemu/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
"Ledger"
],
"scripts": {
"test": "jest --detectOpenHandles -t 'Standard'"
"test": "ts-node tests/pullImageKillOld.ts && jest"
},
"dependencies": {
"@zondax/ledger-filecoin": "^0.11.2",
"@zondax/zemu": "^0.27.4"
"@zondax/zemu": "^0.34.0"
},
"devDependencies": {
"@types/jest": "^27.4.1",
"@types/jest": "^29.2.3",
"@types/ledgerhq__hw-transport": "^4.21.3",
"@types/secp256k1": "^4.0.2",
"@typescript-eslint/eslint-plugin": "^5.19.0",
Expand All @@ -31,13 +31,14 @@
"eslint": "^8.13.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "^26.1.4",
"eslint-plugin-jest": "^27.1.5",
"eslint-plugin-prettier": "^4.0.0",
"jest": "27.5.1",
"jest": "29.2.2",
"jest-serial-runner": "^1.1.0",
"prettier": "^2.6.2",
"secp256k1": "^4.0.2",
"ts-jest": "^27.1.4",
"typescript": "^4.6.3"
"ts-jest": "^29.0.3",
"prettier": "^2.5.1",
"ts-node": "^10.9.1",
"typescript": "^4.5.3"
}
}
Binary file modified tests_zemu/snapshots/s-mainmenu/00004.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests_zemu/snapshots/s-mainmenu/00010.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests_zemu/snapshots/sp-mainmenu/00004.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests_zemu/snapshots/sp-mainmenu/00010.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests_zemu/snapshots/x-mainmenu/00004.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests_zemu/snapshots/x-mainmenu/00010.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions tests_zemu/tests/pullImageKillOld.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Zemu from '@zondax/zemu'

Zemu.checkAndPullImage()
Zemu.stopAllEmuContainers()
41 changes: 40 additions & 1 deletion tests_zemu/tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ describe('Standard', function () {
const sim = new Zemu(m.path);
try {
await sim.start({...defaultOptions, model: m.name,});
// await sim.navigateAndCompareSnapshots('.', `${m.prefix.toLowerCase()}-mainmenu`, [1, 1, 1, 1])
await sim.navigateAndCompareSnapshots('.', `${m.prefix.toLowerCase()}-mainmenu`, [1, 0, 0, 4, -5])
} finally {
await sim.close();
Expand Down Expand Up @@ -392,4 +391,44 @@ describe('Standard', function () {
}
});

test.each(models)('transfer using protocol 4 addresses', async function (m) {
const sim = new Zemu(m.path);
try {
await sim.start({...defaultOptions, model: m.name,});
const app = new FilecoinApp(sim.getTransport());

const path = "m/44'/461'/0'/0/1";
const txBlob = Buffer.from(
"8a0056040ad4224267c4ab4a184bd1aa066b3361e70efbbeaf56040ad4224267c4ab4a184bd1aa066b3361e70efbbeaf0144000186a01961a84200014200010040",
"hex",
);

const pkResponse = await app.getAddressAndPubKey(path);
console.log(pkResponse);
expect(pkResponse.return_code).toEqual(0x9000);
expect(pkResponse.error_message).toEqual("No errors");

// do not wait here..
const signatureRequest = app.sign(path, txBlob);

await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot());
await sim.compareSnapshotsAndApprove(".", `${m.prefix.toLowerCase()}-sign_transfer_protocol4`)

let resp = await signatureRequest;
console.log(resp);

expect(resp.return_code).toEqual(0x9000);
expect(resp.error_message).toEqual("No errors");

// Verify signature
const pk = Uint8Array.from(pkResponse.compressed_pk)
const digest = getDigest(txBlob);
const signature = secp256k1.signatureImport(Uint8Array.from(resp.signature_der));
const signatureOk = secp256k1.ecdsaVerify(signature, digest, pk);
expect(signatureOk).toEqual(true);
} finally {
await sim.close();
}
});

})
Loading

0 comments on commit f8e2251

Please sign in to comment.