From 0d966168fd4447a5fbde35afff3b619b312ca6e7 Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Fri, 27 Sep 2024 09:50:54 +0100 Subject: [PATCH] improve printing code mechanism --- CMakeLists.txt | 172 +++++++++++++++++---------------- Makefile | 4 +- app/Makefile | 2 +- app/Makefile.version | 2 +- app/src/apdu_handler.c | 13 --- app/src/crypto_helper.c | 12 ++- app/src/crypto_helper/chacha.c | 3 + app/src/parser.c | 64 +++++++++--- app/src/parser_impl.c | 10 ++ app/src/parser_impl.h | 2 + app/src/parser_txdef.h | 44 +++++++++ 11 files changed, 210 insertions(+), 118 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7850b9..5c48a68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,18 +1,18 @@ -#******************************************************************************* -#* (c) 2018-2024 Zondax AG -#* -#* Licensed under the Apache License, Version 2.0 (the "License"); -#* you may not use this file except in compliance with the License. -#* You may obtain a copy of the License at -#* -#* http://www.apache.org/licenses/LICENSE-2.0 -#* -#* Unless required by applicable law or agreed to in writing, software -#* distributed under the License is distributed on an "AS IS" BASIS, -#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -#* See the License for the specific language governing permissions and -#* limitations under the License. -#******************************************************************************** +# ******************************************************************************* +# * (c) 2018-2024 Zondax AG +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# ******************************************************************************** cmake_minimum_required(VERSION 3.28) include("cmake/HunterGate.cmake") HunterGate( @@ -22,17 +22,17 @@ HunterGate( ) if(CMAKE_GENERATOR MATCHES "Ninja") - message(FATAL_ERROR "This project does not support the Ninja generator. " - "Please use Unix Makefiles or another supported generator. " - "This error is typical in CLion. In this case, switch to generator Unix Makefiles.") + message(FATAL_ERROR "This project does not support the Ninja generator. " + "Please use Unix Makefiles or another supported generator. " + "This error is typical in CLion. In this case, switch to generator Unix Makefiles.") endif() -######################################################## +# ####################################################### project(ledger-ironfish VERSION 0.0.0) set(CMAKE_CXX_STANDARD 20) cmake_policy(SET CMP0025 NEW) -cmake_policy(SET CMP0144 NEW) +# cmake_policy(SET CMP0144 NEW) set(HUNTER_STATUS_DEBUG ON) set(HUNTER_TLS_VERIFY OFF) @@ -60,22 +60,22 @@ if(ENABLE_FUZZING) SET(ENABLE_SANITIZERS ON CACHE BOOL "Sanitizer automatically enabled" FORCE) SET(CMAKE_BUILD_TYPE Debug) - if (DEFINED ENV{FUZZ_LOGGING}) + if(DEFINED ENV{FUZZ_LOGGING}) add_definitions(-DFUZZING_LOGGING) message(FATAL_ERROR "Fuzz logging enabled") endif() set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=-*,bugprone-*,cert-*,clang-analyzer-*,-cert-err58-cpp,misc-*) - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0) message(FATAL_ERROR "Clang version must be at least 10.0!") endif() else() message(FATAL_ERROR - "You are using an unsupported compiler! Fuzzing only works with Clang 10.\n" - "1. Install clang-10 \n" - "2. Pass -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10") + "You are using an unsupported compiler! Fuzzing only works with Clang 10.\n" + "1. Install clang-10 \n" + "2. Pass -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10") endif() string(APPEND CMAKE_C_FLAGS " -fsanitize=fuzzer-no-link") @@ -95,67 +95,69 @@ if(ENABLE_SANITIZERS) string(APPEND CMAKE_LINKER_FLAGS " -fsanitize=address,undefined -fsanitize-recover=address,undefined") endif() -set (RETRIEVE_MAJOR_CMD - "cat ${CMAKE_CURRENT_SOURCE_DIR}/app/Makefile.version | grep APPVERSION_M | cut -b 14- | tr -d '\n'" +set(RETRIEVE_MAJOR_CMD + "cat ${CMAKE_CURRENT_SOURCE_DIR}/app/Makefile.version | grep APPVERSION_M | cut -b 14- | tr -d '\n'" ) -set (RETRIEVE_MINOR_CMD - "cat ${CMAKE_CURRENT_SOURCE_DIR}/app/Makefile.version | grep APPVERSION_N | cut -b 14- | tr -d '\n'" +set(RETRIEVE_MINOR_CMD + "cat ${CMAKE_CURRENT_SOURCE_DIR}/app/Makefile.version | grep APPVERSION_N | cut -b 14- | tr -d '\n'" ) execute_process( - COMMAND bash "-c" ${RETRIEVE_MAJOR_CMD} - RESULT_VARIABLE MAJOR_RESULT - OUTPUT_VARIABLE MAJOR_VERSION + COMMAND bash "-c" ${RETRIEVE_MAJOR_CMD} + RESULT_VARIABLE MAJOR_RESULT + OUTPUT_VARIABLE MAJOR_VERSION ) execute_process( - COMMAND bash "-c" ${RETRIEVE_MINOR_CMD} - RESULT_VARIABLE MINOR_RESULT - OUTPUT_VARIABLE MINOR_VERSION + COMMAND bash "-c" ${RETRIEVE_MINOR_CMD} + RESULT_VARIABLE MINOR_RESULT + OUTPUT_VARIABLE MINOR_VERSION ) -message(STATUS "LEDGER_MAJOR_VERSION [${MAJOR_RESULT}]: ${MAJOR_VERSION}" ) -message(STATUS "LEDGER_MINOR_VERSION [${MINOR_RESULT}]: ${MINOR_VERSION}" ) +message(STATUS "LEDGER_MAJOR_VERSION [${MAJOR_RESULT}]: ${MAJOR_VERSION}") +message(STATUS "LEDGER_MINOR_VERSION [${MINOR_RESULT}]: ${MINOR_VERSION}") add_definitions( -DLEDGER_MAJOR_VERSION=${MAJOR_VERSION} -DLEDGER_MINOR_VERSION=${MINOR_VERSION} ) - # ############################################################# # ############################################################# # Static Libraries file(GLOB_RECURSE LIB_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/app_mode.c - ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/base58.c - ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/bech32.c - ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/bignum.c - ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/hexutils.c - ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/zxmacros.c - ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/zxformat.c - #### - ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser.c - ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl.c - ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl_common.c - ${CMAKE_CURRENT_SOURCE_DIR}/app/src/crypto_helper.c - #### - ${CMAKE_CURRENT_SOURCE_DIR}/deps/blake2/ref/blake2b-ref.c - ${CMAKE_CURRENT_SOURCE_DIR}/app/src/blake2s/blake2s-ref.c - ) + ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/app_mode.c + ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/base58.c + ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/bech32.c + ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/bignum.c + ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/hexutils.c + ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/zxmacros.c + ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/zxformat.c + + # ### + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser.c + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl.c + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/crypto_helper.c + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/crypto_helper/chacha.c + + # ### + ${CMAKE_CURRENT_SOURCE_DIR}/deps/blake2/ref/blake2b-ref.c + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/blake2s/blake2s-ref.c +) add_library(app_lib STATIC ${LIB_SRC}) target_include_directories(app_lib PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/include - ${CMAKE_CURRENT_SOURCE_DIR}/app/src - ${CMAKE_CURRENT_SOURCE_DIR}/app/src/lib - ${CMAKE_CURRENT_SOURCE_DIR}/app/src/common - ${CMAKE_CURRENT_SOURCE_DIR}/app/rust/include - ${CMAKE_CURRENT_SOURCE_DIR}/deps/blake2/ref - - ) + ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/include + ${CMAKE_CURRENT_SOURCE_DIR}/app/src + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/lib + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/crypto_helper + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/common + ${CMAKE_CURRENT_SOURCE_DIR}/app/rust/include + ${CMAKE_CURRENT_SOURCE_DIR}/deps/blake2/ref +) -############################################################## -## Rust library for CPP tests +# ############################################################# +# # Rust library for CPP tests set(RUST_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/app/rust") # Determine the Rust target triple based on the host system @@ -204,39 +206,41 @@ add_dependencies(rslib RustLibBuild) # Ensure your C++ targets depend on the Rust library being built first # For example, for your app_lib static library: add_dependencies(app_lib rslib) -############################################################## -# Tests + +# ############################################################# +# Tests file(GLOB_RECURSE TESTS_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp) add_executable(unittests ${TESTS_SRC}) target_include_directories(unittests PRIVATE - ${gtest_SOURCE_DIR}/include - ${gmock_SOURCE_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/app/src - ${CMAKE_CURRENT_SOURCE_DIR}/app/src/lib - ### - ${CMAKE_CURRENT_SOURCE_DIR}/deps/blake2/ref - ) + ${gtest_SOURCE_DIR}/include + ${gmock_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/app/src + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/lib + + # ## + ${CMAKE_CURRENT_SOURCE_DIR}/deps/blake2/ref +) target_link_libraries(unittests PRIVATE - app_lib - rslib - GTest::gtest_main - fmt::fmt - JsonCpp::JsonCpp) + app_lib + rslib + GTest::gtest_main + fmt::fmt + JsonCpp::JsonCpp) add_compile_definitions(TESTVECTORS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/tests/") add_test(NAME unittests COMMAND unittests) set_tests_properties(unittests PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests) -############################################################## -############################################################## -# Fuzz Targets +# ############################################################# +# ############################################################# +# Fuzz Targets if(ENABLE_FUZZING) set(FUZZ_TARGETS parser_parse - ) + ) foreach(target ${FUZZ_TARGETS}) add_executable(fuzz-${target} ${CMAKE_CURRENT_SOURCE_DIR}/fuzz/${target}.cpp) diff --git a/Makefile b/Makefile index 116f0c1..97ea98e 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ ifeq ($(BOLOS_SDK),) # When not using the SDK, we override and build the XL complete app ZXLIB_COMPILE_STAX ?= 1 -PRODUCTION_BUILD ?= 0 +PRODUCTION_BUILD ?= 1 include $(CURDIR)/deps/ledger-zxlib/dockerized_build.mk else @@ -38,6 +38,6 @@ default: endif test_all: - PRODUCTION_BUILD=1 make + PRODUCTION_BUILD=1 APP_TESTING=1 make make zemu_install make zemu_test diff --git a/app/Makefile b/app/Makefile index 7e568b9..fd6319a 100755 --- a/app/Makefile +++ b/app/Makefile @@ -27,7 +27,7 @@ include $(CURDIR)/../deps/ledger-zxlib/makefiles/Makefile.installer_script include $(BOLOS_SDK)/Makefile.defines $(info ************ TARGET_NAME = [$(TARGET_NAME)]) -PRODUCTION_BUILD ?= 0 +PRODUCTION_BUILD ?= 1 $(info ************ PRODUCTION_BUILD = [$(if $(filter 1,$(PRODUCTION_BUILD)),PRODUCTION BUILD,INTERNAL USE)]) DEFINES += PRODUCTION_BUILD=$(PRODUCTION_BUILD) diff --git a/app/Makefile.version b/app/Makefile.version index 7ea8201..05311d3 100644 --- a/app/Makefile.version +++ b/app/Makefile.version @@ -3,4 +3,4 @@ APPVERSION_M=0 # This is the minor version APPVERSION_N=0 # This is the patch version -APPVERSION_P=12 +APPVERSION_P=13 diff --git a/app/src/apdu_handler.c b/app/src/apdu_handler.c index c7e68b3..8ac5881 100644 --- a/app/src/apdu_handler.c +++ b/app/src/apdu_handler.c @@ -164,12 +164,6 @@ __Z_INLINE void handle_getversion(__Z_UNUSED volatile uint32_t *flags, volatile THROW(APDU_CODE_OK); } -#if defined(APP_TESTING) -void handleTest(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { - THROW(APDU_CODE_OK); -} -#endif - void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { volatile uint16_t sw = 0; @@ -201,13 +195,6 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { break; } -#if defined(APP_TESTING) - case INS_TEST: { - handleTest(flags, tx, rx); - THROW(APDU_CODE_OK); - break; - } -#endif default: THROW(APDU_CODE_INS_NOT_SUPPORTED); } diff --git a/app/src/crypto_helper.c b/app/src/crypto_helper.c index 719d5f1..eedcb3f 100644 --- a/app/src/crypto_helper.c +++ b/app/src/crypto_helper.c @@ -242,7 +242,7 @@ parser_error_t crypto_calculate_key_for_encryption_keys(const uint8_t *note, con #if defined(LEDGER_SPECIFIC) cx_blake2b_t ctx = {0}; - ASSERT_CX_OK(cx_blake2b_init2_no_throw(&ctx, 32, NULL, 0, (uint8_t *)SHARED_KEY_PERSONALIZATION, + ASSERT_CX_OK(cx_blake2b_init2_no_throw(&ctx, 256, NULL, 0, (uint8_t *)SHARED_KEY_PERSONALIZATION, sizeof(SHARED_KEY_PERSONALIZATION))); ASSERT_CX_OK(cx_blake2b_update(&ctx, ovk, 32)); ASSERT_CX_OK(cx_blake2b_update(&ctx, note, VALUE_COMMITMENT_SIZE + NOTE_COMMITMENT_SIZE + EPHEMERAL_PUBLIC_KEY_SIZE)); @@ -274,6 +274,9 @@ parser_error_t crypto_decrypt_merkle_note(parser_tx_t *txObj, const uint8_t *m_n uint8_t cc_nonce[CHACHA_NONCE_SIZE] = {0}; CHECK_ERROR(chacha(note_encryption_key, sizeof(note_encryption_key), m_note + NOTE_ENCRYPTION_KEYS_OFFSET, ENCRYPTED_SHARED_KEY_SIZE, encryption_key, cc_nonce, 1)); +#if defined(LEDGER_SPECIFIC) + io_seproxyhal_io_heartbeat(); +#endif CHECK_APP_CANARY() // Extract public address and secret key from the note encryption key @@ -286,14 +289,19 @@ parser_error_t crypto_decrypt_merkle_note(parser_tx_t *txObj, const uint8_t *m_n uint8_t shared_key[32] = {0}; const uint8_t *ephemeral_public_key = m_note + VALUE_COMMITMENT_SIZE + NOTE_COMMITMENT_SIZE; CHECK_ERROR(shared_secret(secret_key, public_address, ephemeral_public_key, shared_key)); +#if defined(LEDGER_SPECIFIC) + io_seproxyhal_io_heartbeat(); +#endif CHECK_APP_CANARY() // Finally decrypt the note uint8_t plain_text[ENCRYPTED_NOTE_SIZE] = {0}; CHECK_ERROR(chacha(plain_text, sizeof(plain_text), m_note + ENCRYPTED_NOTE_OFFSET, ENCRYPTED_NOTE_SIZE, shared_key, cc_nonce, 1)); +#if defined(LEDGER_SPECIFIC) + io_seproxyhal_io_heartbeat(); +#endif CHECK_APP_CANARY() - // Fill the txObj with the decrypted note txObj->outputs.decrypted_note.value = *(uint64_t *)(plain_text + SCALAR_SIZE); MEMCPY(txObj->outputs.decrypted_note.asset_id, plain_text + SCALAR_SIZE + AMOUNT_VALUE_SIZE + MEMO_SIZE, diff --git a/app/src/crypto_helper/chacha.c b/app/src/crypto_helper/chacha.c index 7a5cdb1..0652632 100644 --- a/app/src/crypto_helper/chacha.c +++ b/app/src/crypto_helper/chacha.c @@ -116,6 +116,9 @@ parser_error_t chacha(uint8_t *out, size_t out_len, const uint8_t *in, size_t in input[14] = U8TO32_LITTLE(nonce + 4); input[15] = U8TO32_LITTLE(nonce + 8); while (in_len > 0) { +#if defined(LEDGER_SPECIFIC) + io_seproxyhal_io_heartbeat(); +#endif todo = sizeof(buf); if (in_len < todo) { todo = in_len; diff --git a/app/src/parser.c b/app/src/parser.c index dfaf56a..4b73cd4 100644 --- a/app/src/parser.c +++ b/app/src/parser.c @@ -23,8 +23,10 @@ #include "coin.h" #include "crypto.h" +#include "crypto_helper.h" #include "parser_common.h" #include "parser_impl.h" +#include "rslib.h" parser_error_t parser_init_context(parser_context_t *ctx, const uint8_t *buffer, uint16_t bufferSize) { ctx->offset = 0; @@ -64,7 +66,10 @@ parser_error_t parser_validate(parser_context_t *ctx) { parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_items) { UNUSED(ctx); - *num_items = 5; + + // Txversion + (ownner + amount + asset id) * n_output + fee + expiration + *num_items = 1 + ctx->tx_obj->outputs.elements * 3 + 2; + if (*num_items == 0) { return parser_unexpected_number_items; } @@ -85,6 +90,7 @@ static parser_error_t checkSanity(uint8_t numItems, uint8_t displayIdx) { return parser_ok; } +uint8_t out_idx = 0; parser_error_t parser_getItem(const parser_context_t *ctx, uint8_t displayIdx, char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) { UNUSED(pageIdx); @@ -96,29 +102,57 @@ parser_error_t parser_getItem(const parser_context_t *ctx, uint8_t displayIdx, c CHECK_ERROR(checkSanity(numItems, displayIdx)); cleanOutput(outKey, outKeyLen, outVal, outValLen); - switch (displayIdx) { + uint64_t total_out_elements = ctx->tx_obj->outputs.elements * ELEMENTS_PER_OUTPUT; + uint8_t tmp_idx = displayIdx; + + if (tmp_idx > 0 && tmp_idx <= total_out_elements) { + tmp_idx = (displayIdx % ELEMENTS_PER_OUTPUT); + out_idx = (displayIdx / ELEMENTS_PER_OUTPUT); + if (tmp_idx == 0) { + tmp_idx = ELEMENTS_PER_OUTPUT; + out_idx--; + if (out_idx > ctx->tx_obj->outputs.elements - 1) { + return parser_display_idx_out_of_range; + } + } + if (tmp_idx == 1) { + const uint8_t *output = ctx->tx_obj->outputs.data.ptr + (out_idx * (192 + 328)); + if (pageIdx == 0) { + CHECK_ERROR(crypto_decrypt_merkle_note(ctx->tx_obj, output + 192, ctx->tx_obj->ovk)); + } + } + } else if (tmp_idx > total_out_elements) { + tmp_idx -= total_out_elements - ELEMENTS_PER_OUTPUT; + } + + char buf[70] = {0}; + switch (tmp_idx) { case 0: - snprintf(outKey, outKeyLen, "Spends"); - snprintf(outVal, outValLen, "%d", (uint8_t)ctx->tx_obj->spends.elements); + snprintf(outKey, outKeyLen, "Tx Version"); + snprintf(outVal, outValLen, "V%d", (uint8_t)ctx->tx_obj->transactionVersion); return parser_ok; case 1: - snprintf(outKey, outKeyLen, "Outputs"); - snprintf(outVal, outValLen, "%d", (uint8_t)ctx->tx_obj->outputs.elements); + snprintf(outKey, outKeyLen, "Owner %d", out_idx + 1); + array_to_hexstr(buf, sizeof(buf), ctx->tx_obj->outputs.decrypted_note.owner, 32); + pageString(outVal, outValLen, buf, pageIdx, pageCount); return parser_ok; case 2: - snprintf(outKey, outKeyLen, "Mints"); - snprintf(outVal, outValLen, "%d", (uint8_t)ctx->tx_obj->mints.elements); + snprintf(outKey, outKeyLen, "Amount %d", out_idx + 1); + snprintf(outVal, outValLen, "%d", (uint8_t)ctx->tx_obj->outputs.decrypted_note.value); return parser_ok; case 3: - snprintf(outKey, outKeyLen, "Burns"); - snprintf(outVal, outValLen, "%d", (uint8_t)ctx->tx_obj->burns.elements); + snprintf(outKey, outKeyLen, "AssetID %d", out_idx + 1); + array_to_hexstr(buf, sizeof(buf), ctx->tx_obj->outputs.decrypted_note.asset_id, 32); + pageString(outVal, outValLen, buf, pageIdx, pageCount); return parser_ok; - case 4: { - snprintf(outKey, outKeyLen, "TxnHash"); - pageStringHex(outVal, outValLen, (const char *)ctx->tx_obj->transactionHash, - sizeof(ctx->tx_obj->transactionHash), pageIdx, pageCount); + case 4: + snprintf(outKey, outKeyLen, "Fee"); + snprintf(outVal, outValLen, "%d", (uint8_t)ctx->tx_obj->fee); + return parser_ok; + case 5: + snprintf(outKey, outKeyLen, "Expiration"); + snprintf(outVal, outValLen, "%d", ctx->tx_obj->expiration); return parser_ok; - } default: break; } diff --git a/app/src/parser_impl.c b/app/src/parser_impl.c index d55dc78..84fd1b5 100644 --- a/app/src/parser_impl.c +++ b/app/src/parser_impl.c @@ -139,5 +139,15 @@ parser_error_t _read(parser_context_t *ctx, parser_tx_t *v) { } CHECK_ERROR(transaction_signature_hash(v, v->transactionHash)); + +#if defined(APP_TESTING) || !defined(LEDGER_SPECIFIC) + // Testing OVK + uint8_t buffer[32] = {0x49, 0xba, 0xd8, 0x39, 0x5e, 0xf4, 0x48, 0xeb, 0x00, 0x48, 0xaf, 0x13, 0x2b, 0x5c, 0x94, 0x25, + 0x79, 0x02, 0x47, 0x36, 0xd4, 0xc3, 0xcf, 0xd6, 0x85, 0xb2, 0x41, 0xb9, 0x94, 0xf8, 0xf8, 0xe5}; + memcpy(v->ovk, buffer, sizeof(buffer)); +#else + CHECK_ERROR(crypto_get_ovk(v->ovk)); +#endif + return parser_ok; } diff --git a/app/src/parser_impl.h b/app/src/parser_impl.h index 3fcf711..09f0bd8 100644 --- a/app/src/parser_impl.h +++ b/app/src/parser_impl.h @@ -25,6 +25,8 @@ extern "C" { #endif +#define ELEMENTS_PER_OUTPUT 3 +#define OUTPUT_ELEMENT_OFFSET 1 /** * @brief Checks that there are at least SIZE bytes available in the buffer. * @param CTX Context diff --git a/app/src/parser_txdef.h b/app/src/parser_txdef.h index ba06b19..4a82abe 100644 --- a/app/src/parser_txdef.h +++ b/app/src/parser_txdef.h @@ -28,6 +28,42 @@ extern "C" { #define NAME_LENGTH 32 #define METADATA_LENGTH 96 +// Decrypted Note is composed of: +// -scaler: 32 bytes +// -memo: 32 bytes +// -amount: 8 bytes +// -asset_id: 32 bytes +// -public_address (sender): 32 bytes +#define ENCRYPTED_NOTE_SIZE (SCALAR_SIZE + MEMO_SIZE + AMOUNT_VALUE_SIZE + ASSET_ID_LENGTH + PUBLIC_ADDRESS_SIZE) +#define SCALAR_SIZE 32 +#define MEMO_SIZE 32 +#define AMOUNT_VALUE_SIZE 8 +#define ASSET_ID_LENGTH 32 +#define PUBLIC_ADDRESS_SIZE 32 + +// Merkel Note is composed of: +// - value commitment: 32 bytes +// - note commitment: 32 bytes +// - ephemeral public key: 32 bytes +// - encrypted note: encrypted note size (136) + mac (16) bytes +// - note encryption keys: encrypted shared key size (64) + mac (16) bytes +#define VALUE_COMMITMENT_SIZE 32 +#define NOTE_COMMITMENT_SIZE 32 +#define EPHEMERAL_PUBLIC_KEY_SIZE 32 +#define ENCRYPTED_SHARED_KEY_SIZE 64 +#define MAC_SIZE 16 +#define ENCRYPTED_NOTE_OFFSET (VALUE_COMMITMENT_SIZE + NOTE_COMMITMENT_SIZE + EPHEMERAL_PUBLIC_KEY_SIZE) +#define NOTE_ENCRYPTION_KEYS_OFFSET \ + (VALUE_COMMITMENT_SIZE + NOTE_COMMITMENT_SIZE + EPHEMERAL_PUBLIC_KEY_SIZE + ENCRYPTED_NOTE_SIZE + MAC_SIZE) + +#define NOTE_ENCRYPTION_KEYS_SIZE (ENCRYPTED_SHARED_KEY_SIZE + MAC_SIZE) + +#define MERKLE_NOTE_LEN \ + (VALUE_COMMITMENT_SIZE + NOTE_COMMITMENT_SIZE + EPHEMERAL_PUBLIC_KEY_SIZE + ENCRYPTED_NOTE_SIZE + MAC_SIZE + \ + NOTE_ENCRYPTION_KEYS_SIZE) + +#define SECRET_KEY_SIZE 32 +#define CHACHA_NONCE_SIZE 12 typedef enum { V1 = 1, V2 = 2, @@ -87,9 +123,16 @@ typedef struct { bytes_t data; } vec_burn_description_t; +typedef struct { + uint8_t asset_id[32]; + uint8_t owner[32]; + uint64_t value; +} note_t; + typedef struct { uint64_t elements; bytes_t data; + note_t decrypted_note; } vec_output_description_t; typedef struct { @@ -124,6 +167,7 @@ typedef struct { bytes_t randomizedPublicKey; // redjubjub::PublicKey, bytes_t publicKeyRandomness; + uint8_t ovk[32]; bytes_t bindingSignature; // Not part of the incoming txn but it's used to compute signatures