diff --git a/app/src/common/actions.h b/app/src/common/actions.h index 313341b..77628f5 100644 --- a/app/src/common/actions.h +++ b/app/src/common/actions.h @@ -71,8 +71,8 @@ __Z_INLINE void app_sign_hash() { } __Z_INLINE void app_sign_json_template() { - const uint8_t *message = (uint8_t *)tx_get_json_template_buffer(); - const uint16_t messageLength = tx_get_json_template_buffer_len(); + const uint8_t *message = (uint8_t *)tx_get_json_template_hash(); + const uint16_t messageLength = tx_get_json_template_hash_len(); const zxerr_t err = crypto_sign(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, message, messageLength, tx_type_transaction); diff --git a/app/src/common/parser.h b/app/src/common/parser.h index 0fbbc0c..131483e 100644 --- a/app/src/common/parser.h +++ b/app/src/common/parser.h @@ -22,8 +22,8 @@ extern "C" { #include "parser_impl.h" -char *parser_get_json_template_buffer(); -uint16_t parser_get_json_template_buffer_len(); +char *parser_get_json_inc_hash(); +uint16_t parser_get_json_inc_hash_len(); const char *parser_getErrorDescription(parser_error_t err); const char *parser_getMsgPackTypeDescription(uint8_t type); diff --git a/app/src/common/tx.c b/app/src/common/tx.c index a7a955f..27c3daf 100644 --- a/app/src/common/tx.c +++ b/app/src/common/tx.c @@ -54,9 +54,9 @@ void tx_reset() { buffering_reset(); } uint32_t tx_append(unsigned char *buffer, uint32_t length) { return buffering_append(buffer, length); } -char *tx_get_json_template_buffer() { return parser_get_json_template_buffer(); } +char *tx_get_json_template_hash() { return parser_get_json_inc_hash(); } -uint16_t tx_get_json_template_buffer_len() { return parser_get_json_template_buffer_len(); } +uint16_t tx_get_json_template_hash_len() { return parser_get_json_inc_hash_len(); } uint32_t tx_get_buffer_length() { return buffering_get_buffer()->pos; } diff --git a/app/src/common/tx.h b/app/src/common/tx.h index b85579f..f7b8e5d 100644 --- a/app/src/common/tx.h +++ b/app/src/common/tx.h @@ -34,11 +34,11 @@ uint32_t tx_append(unsigned char *buffer, uint32_t length); /// Returns a pointer to the JSON template buffer /// \return Pointer to the JSON template buffer -char *tx_get_json_template_buffer(); +char *tx_get_json_template_hash(); /// Returns the length of the JSON template buffer /// \return Length of the JSON template buffer -uint16_t tx_get_json_template_buffer_len(); +uint16_t tx_get_json_template_hash_len(); /// Returns size of the raw json transaction buffer /// \return diff --git a/app/src/crypto.c b/app/src/crypto.c index 5d71170..96a2847 100644 --- a/app/src/crypto.c +++ b/app/src/crypto.c @@ -73,7 +73,7 @@ zxerr_t crypto_sign(uint8_t *signature, uint16_t signatureMaxlen, const uint8_t uint8_t privateKeyData[SK_LEN_25519] = {0}; uint8_t hash[BLAKE2B_HASH_SIZE] = {0}; - if (tx_type == tx_type_hash) { + if (tx_type == tx_type_hash || tx_type == tx_type_transaction) { memcpy(hash, message, BLAKE2B_HASH_SIZE); } else { if (blake2b_hash((uint8_t *)message, messageLen, hash) != zxerr_ok) { diff --git a/app/src/crypto_helper.c b/app/src/crypto_helper.c index 76b61dd..cc093b8 100644 --- a/app/src/crypto_helper.c +++ b/app/src/crypto_helper.c @@ -18,7 +18,6 @@ #if defined(TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) || defined(TARGET_STAX) || defined(TARGET_FLEX) #include "cx.h" - zxerr_t blake2b_hash(const unsigned char *in, unsigned int inLen, unsigned char *out) { cx_blake2b_t ctx; if (cx_blake2b_init2_no_throw(&ctx, BLAKE2B_OUTPUT_LEN, NULL, 0, NULL, 0) != CX_OK || @@ -29,6 +28,29 @@ zxerr_t blake2b_hash(const unsigned char *in, unsigned int inLen, unsigned char return zxerr_ok; } +zxerr_t blake2b_incremental(const unsigned char *in, unsigned int inLen, unsigned char *out, bool isNew, bool isLast) { + zemu_log("blake2b_incremental\n"); + static cx_blake2b_t ctx; + + if (isNew) { + if (cx_blake2b_init2_no_throw(&ctx, BLAKE2B_OUTPUT_LEN, NULL, 0, NULL, 0) != CX_OK) { + return zxerr_invalid_crypto_settings; + } + } + + if (cx_hash_update(&ctx.header, in, inLen) != CX_OK) { + return zxerr_invalid_crypto_settings; + } + + if (isLast) { + if (cx_hash_final(&ctx.header, out) != CX_OK) { + return zxerr_invalid_crypto_settings; + } + } + + return zxerr_ok; +} + #else #include "blake2.h" diff --git a/app/src/crypto_helper.h b/app/src/crypto_helper.h index 3768f94..6dfca59 100644 --- a/app/src/crypto_helper.h +++ b/app/src/crypto_helper.h @@ -37,7 +37,7 @@ extern "C" { #define BLAKE2B_HASH_SIZE 32 zxerr_t blake2b_hash(const unsigned char *in, unsigned int inLen, unsigned char *out); - +zxerr_t blake2b_incremental(const unsigned char *in, unsigned int inLen, unsigned char *out, bool isNew, bool isLast); #ifdef __cplusplus } #endif diff --git a/app/src/items.c b/app/src/items.c index 880b7be..b904aef 100644 --- a/app/src/items.c +++ b/app/src/items.c @@ -73,6 +73,7 @@ items_error_t items_initItems() { item_array_t *items_getItemArray() { return &item_array; } items_error_t items_storeItems(tx_type_t tx_type) { + zemu_log("items_storeItems\n"); if (tx_type != tx_type_hash) { CHECK_ITEMS_ERROR(items_storeSigningTransaction()); @@ -82,21 +83,41 @@ items_error_t items_storeItems(tx_type_t tx_type) { CHECK_ITEMS_ERROR(items_storeKey()); - CHECK_ITEMS_ERROR(items_validateSigners()); + if (tx_type == tx_type_json) { + CHECK_ITEMS_ERROR(items_validateSigners()); - CHECK_ITEMS_ERROR(items_storePayingGas()); + CHECK_ITEMS_ERROR(items_storePayingGas()); - CHECK_ITEMS_ERROR(items_storeAllTransfers()); + CHECK_ITEMS_ERROR(items_storeAllTransfers()); - if (parser_validateMetaField() != parser_ok) { - CHECK_ITEMS_ERROR(items_storeCaution()); + if (parser_validateMetaField() != parser_ok) { + CHECK_ITEMS_ERROR(items_storeCaution()); + } else { + CHECK_ITEMS_ERROR(items_storeChainId()); + + CHECK_ITEMS_ERROR(items_storeUsingGas()); + } + + CHECK_ITEMS_ERROR(items_checkTxLengths()); } else { + CHECK_ITEMS_ERROR(items_storeGasItem(0)); + + switch (parser_getChunks()[0].data[0]) { + // TODO: Unknown transfers when namespace/module are custom + uint8_t num_of_transfers = 1; + case TX_TYPE_TRANSFER: + items_storeTxItem(0, &num_of_transfers); + break; + case TX_TYPE_TRANSFER_CROSSCHAIN: + items_storeTxCrossItem(0, &num_of_transfers); + break; + } + CHECK_ITEMS_ERROR(items_storeChainId()); CHECK_ITEMS_ERROR(items_storeUsingGas()); } - CHECK_ITEMS_ERROR(items_checkTxLengths()); } else { CHECK_ITEMS_ERROR(items_storeHashWarning()); } @@ -123,18 +144,24 @@ static items_error_t items_storeSigningTransaction() { } static items_error_t items_storeNetwork() { - uint16_t *curr_token_idx = &item_array.items[item_array.numOfItems].json_token_index; item_t *item = &item_array.items[item_array.numOfItems]; - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, *curr_token_idx, JSON_NETWORK_ID, curr_token_idx)); + if (!parser_usingChunks()) { + uint16_t *curr_token_idx = &item_array.items[item_array.numOfItems].json_token_index; + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - if (!items_isNullField(*curr_token_idx)) { - strcpy(item->key, "On Network"); - item_array.toString[item_array.numOfItems] = items_stdToDisplayString; - INCREMENT_NUM_ITEMS() + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, *curr_token_idx, JSON_NETWORK_ID, curr_token_idx)); + + if (items_isNullField(*curr_token_idx)) { + // Network not found in JSON or found but null. + return items_ok; + } } + strcpy(item->key, "On Network"); + item_array.toString[item_array.numOfItems] = items_stdToDisplayString; + INCREMENT_NUM_ITEMS() + return items_ok; } @@ -148,22 +175,30 @@ static items_error_t items_storeRequiringCapabilities() { } static items_error_t items_storeKey() { - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - uint16_t *curr_token_idx = &item_array.items[item_array.numOfItems].json_token_index; item_t *item = &item_array.items[item_array.numOfItems]; - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, *curr_token_idx, JSON_SIGNERS, curr_token_idx)); + if (!parser_usingChunks()) { + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); + uint16_t *curr_token_idx = &item_array.items[item_array.numOfItems].json_token_index; + + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, *curr_token_idx, JSON_SIGNERS, curr_token_idx)); + + if (items_isNullField(*curr_token_idx)) { + return items_ok; + } - if (!items_isNullField(*curr_token_idx)) { PARSER_TO_ITEMS_ERROR(array_get_nth_element(json_all, *curr_token_idx, 0, curr_token_idx)); PARSER_TO_ITEMS_ERROR(object_get_value(json_all, *curr_token_idx, JSON_PUBKEY, curr_token_idx)); - if (!items_isNullField(*curr_token_idx)) { - strcpy(item->key, "Of Key"); - item_array.toString[item_array.numOfItems] = items_stdToDisplayString; - INCREMENT_NUM_ITEMS() + + if (items_isNullField(*curr_token_idx)) { + return items_ok; } } + strcpy(item->key, "Of Key"); + item_array.toString[item_array.numOfItems] = items_stdToDisplayString; + INCREMENT_NUM_ITEMS() + return items_ok; } @@ -210,31 +245,19 @@ static items_error_t items_storePayingGas() { uint16_t token_index = 0; uint16_t name_token_index = 0; jsmntok_t *token; + uint16_t clist_element_count = 0; - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, *curr_token_idx, JSON_SIGNERS, curr_token_idx)); - - if (!items_isNullField(*curr_token_idx)) { - PARSER_TO_ITEMS_ERROR(array_get_nth_element(json_all, *curr_token_idx, 0, curr_token_idx)); - - if (object_get_value(json_all, *curr_token_idx, JSON_CLIST, curr_token_idx) == parser_no_data) { - return items_ok; - } - - if (!items_isNullField(*curr_token_idx)) { - uint16_t clist_element_count = 0; - PARSER_TO_ITEMS_ERROR(array_get_element_count(json_all, *curr_token_idx, &clist_element_count)); - - for (uint16_t i = 0; i < (uint8_t)clist_element_count; i++) { - PARSER_TO_ITEMS_ERROR(array_get_nth_element(json_all, *curr_token_idx, i, &token_index)); + if (parser_getValidClist(curr_token_idx, &clist_element_count) == parser_ok) { + for (uint16_t i = 0; i < (uint8_t)clist_element_count; i++) { + PARSER_TO_ITEMS_ERROR(array_get_nth_element(json_all, *curr_token_idx, i, &token_index)); - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, token_index, JSON_NAME, &name_token_index)); - token = &(json_all->tokens[name_token_index]); + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, token_index, JSON_NAME, &name_token_index)); + token = &(json_all->tokens[name_token_index]); - if (MEMCMP("coin.GAS", json_all->buffer + token->start, token->end - token->start) == 0) { - *curr_token_idx = token_index; - items_storeGasItem(*curr_token_idx); - return items_ok; - } + if (MEMCMP("coin.GAS", json_all->buffer + token->start, token->end - token->start) == 0) { + *curr_token_idx = token_index; + items_storeGasItem(*curr_token_idx); + return items_ok; } } } @@ -313,39 +336,51 @@ static items_error_t items_storeCaution() { } static items_error_t items_storeChainId() { - uint16_t *curr_token_idx = &item_array.items[item_array.numOfItems].json_token_index; item_t *item = &item_array.items[item_array.numOfItems]; - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, 0, JSON_META, curr_token_idx)); + if (!parser_usingChunks()) { + uint16_t *curr_token_idx = &item_array.items[item_array.numOfItems].json_token_index; + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); + + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, 0, JSON_META, curr_token_idx)); + + if (items_isNullField(*curr_token_idx)) { + return items_ok; + } - if (!items_isNullField(*curr_token_idx)) { PARSER_TO_ITEMS_ERROR(object_get_value(json_all, *curr_token_idx, JSON_CHAIN_ID, curr_token_idx)); - if (!items_isNullField(*curr_token_idx)) { - strcpy(item->key, "On Chain"); - item_array.toString[item_array.numOfItems] = items_stdToDisplayString; - INCREMENT_NUM_ITEMS() + + if (items_isNullField(*curr_token_idx)) { + return items_ok; } } + strcpy(item->key, "On Chain"); + item_array.toString[item_array.numOfItems] = items_stdToDisplayString; + INCREMENT_NUM_ITEMS() + return items_ok; } static items_error_t items_storeUsingGas() { - uint16_t *curr_token_idx = &item_array.items[item_array.numOfItems].json_token_index; item_t *item = &item_array.items[item_array.numOfItems]; - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, 0, JSON_META, curr_token_idx)); + if (!parser_usingChunks()) { + uint16_t *curr_token_idx = &item_array.items[item_array.numOfItems].json_token_index; + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - if (!items_isNullField(*curr_token_idx)) { - strcpy(item->key, "Using Gas"); - item_array.toString[item_array.numOfItems] = items_gasToDisplayString; - INCREMENT_NUM_ITEMS() - } else { - *curr_token_idx = 0; + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, 0, JSON_META, curr_token_idx)); + + if (items_isNullField(*curr_token_idx)) { + *curr_token_idx = 0; + return items_ok; + } } + strcpy(item->key, "Using Gas"); + item_array.toString[item_array.numOfItems] = items_gasToDisplayString; + INCREMENT_NUM_ITEMS() + return items_ok; } @@ -365,7 +400,7 @@ static items_error_t items_checkTxLengths() { } static items_error_t items_computeHash(tx_type_t tx_type) { - if (tx_type == tx_type_hash) { + if (tx_type == tx_type_hash || tx_type == tx_type_transaction) { tx_hash_t *hash_obj = parser_getParserHashObj(); base64_encode(base64_hash, 44, (uint8_t *)hash_obj->tx, hash_obj->hash_len); } else { @@ -412,66 +447,77 @@ static items_error_t items_storeSignForAddr() { } static items_error_t items_storeGasItem(uint16_t json_token_index) { - uint16_t token_index = 0; - uint16_t args_count = 0; - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); item_t *item = &item_array.items[item_array.numOfItems]; - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, json_token_index, "args", &token_index)); - PARSER_TO_ITEMS_ERROR(array_get_element_count(json_all, token_index, &args_count)); + if (!parser_usingChunks()) { + uint16_t token_index = 0; + uint16_t args_count = 0; + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - if (args_count > 0) { - items_storeUnknownItem(args_count, token_index); - } else { - strcpy(item->key, "Paying Gas"); - item_array.toString[item_array.numOfItems] = items_nothingToDisplayString; - INCREMENT_NUM_ITEMS() + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, json_token_index, "args", &token_index)); + PARSER_TO_ITEMS_ERROR(array_get_element_count(json_all, token_index, &args_count)); + + if (args_count > 0) { + items_storeUnknownItem(args_count, token_index); + return items_ok; + } } + strcpy(item->key, "Paying Gas"); + item_array.toString[item_array.numOfItems] = items_nothingToDisplayString; + INCREMENT_NUM_ITEMS() + return items_ok; } static items_error_t items_storeTxItem(uint16_t transfer_token_index, uint8_t *num_of_transfers) { - uint16_t token_index = 0; - uint16_t num_of_args = 0; item_t *item = &item_array.items[item_array.numOfItems]; - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, transfer_token_index, "args", &token_index)); + if (!parser_usingChunks()) { + uint16_t token_index = 0; + uint16_t num_of_args = 0; + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - PARSER_TO_ITEMS_ERROR(array_get_element_count(json_all, token_index, &num_of_args)); + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, transfer_token_index, "args", &token_index)); - if (num_of_args == 3) { - snprintf(item->key, sizeof(item->key), "Transfer %d", *num_of_transfers); - (*num_of_transfers)++; - item_array.toString[item_array.numOfItems] = items_transferToDisplayString; - INCREMENT_NUM_ITEMS() - } else { - items_storeUnknownItem(num_of_args, token_index); + PARSER_TO_ITEMS_ERROR(array_get_element_count(json_all, token_index, &num_of_args)); + + if (num_of_args != 3) { + items_storeUnknownItem(num_of_args, token_index); + return items_ok; + } } + snprintf(item->key, sizeof(item->key), "Transfer %d", *num_of_transfers); + (*num_of_transfers)++; + item_array.toString[item_array.numOfItems] = items_transferToDisplayString; + INCREMENT_NUM_ITEMS() + return items_ok; } static items_error_t items_storeTxCrossItem(uint16_t transfer_token_index, uint8_t *num_of_transfers) { - uint16_t token_index = 0; - uint16_t num_of_args = 0; item_t *item = &item_array.items[item_array.numOfItems]; - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, transfer_token_index, "args", &token_index)); + if (!parser_usingChunks()) { + uint16_t token_index = 0; + uint16_t num_of_args = 0; + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - PARSER_TO_ITEMS_ERROR(array_get_element_count(json_all, token_index, &num_of_args)); + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, transfer_token_index, "args", &token_index)); - if (num_of_args == 4) { - snprintf(item->key, sizeof(item->key), "Transfer %d", *num_of_transfers); - (*num_of_transfers)++; - item_array.toString[item_array.numOfItems] = items_crossTransferToDisplayString; - INCREMENT_NUM_ITEMS() - } else { - items_storeUnknownItem(num_of_args, token_index); + PARSER_TO_ITEMS_ERROR(array_get_element_count(json_all, token_index, &num_of_args)); + + if (num_of_args != 4) { + items_storeUnknownItem(num_of_args, token_index); + } } + snprintf(item->key, sizeof(item->key), "Transfer %d", *num_of_transfers); + (*num_of_transfers)++; + item_array.toString[item_array.numOfItems] = items_crossTransferToDisplayString; + INCREMENT_NUM_ITEMS() + return items_ok; } diff --git a/app/src/items_format.c b/app/src/items_format.c index 1bcfd03..f8ef120 100644 --- a/app/src/items_format.c +++ b/app/src/items_format.c @@ -20,21 +20,36 @@ #include "crypto.h" #include "parser.h" +#include "parser_impl.h" + +static items_error_t items_findChunkIndex(const char *key, uint8_t *outPos); extern char base64_hash[45]; items_error_t items_stdToDisplayString(item_t item, char *outVal, uint16_t outValLen) { - const parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - const jsmntok_t *token = &(json_all->tokens[item.json_token_index]); - const uint16_t len = token->end - token->start; + uint8_t *buffer = NULL; + uint16_t len = 0; - if (len == 0) return items_length_zero; + if (parser_usingChunks()) { + uint8_t chunk_index; + CHECK_ITEMS_ERROR(items_findChunkIndex(item.key, &chunk_index)); + len = parser_getChunks()[chunk_index].len; + buffer = (uint8_t *)parser_getChunks()[chunk_index].data; + } else { + const parsed_json_t *json_all = &(parser_getParserJsonObj()->json); + const jsmntok_t *token = &(json_all->tokens[item.json_token_index]); + len = token->end - token->start; - if (len >= outValLen) { - return items_data_too_large; + if (len == 0) return items_length_zero; + + if (len >= outValLen) { + return items_data_too_large; + } + + buffer = (uint8_t *)json_all->buffer + token->start; } - snprintf(outVal, outValLen, "%.*s", len, json_all->buffer + token->start); + snprintf(outVal, outValLen, "%.*s", len, buffer); return items_ok; } @@ -110,16 +125,28 @@ items_error_t items_transferToDisplayString(item_t item, char *outVal, uint16_t uint8_t amount_len = 0; uint8_t to_len = 0; uint8_t from_len = 0; - uint16_t token_index = 0; - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - uint16_t item_token_index = item.json_token_index; - - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, item_token_index, "args", &token_index)); - PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 0, &from, &from_len)); - PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 1, &to, &to_len)); - PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 2, &amount, &amount_len)); + + if (parser_usingChunks()) { + chunk_t *chunks = parser_getChunks(); + amount = chunks[AMOUNT_POS].data; + amount_len = chunks[AMOUNT_POS].len; + to = chunks[RECIPIENT_POS].data; + to_len = chunks[RECIPIENT_POS].len; + from = chunks[PUBKEY_POS].data; + from_len = chunks[PUBKEY_POS].len; + } else { + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); + uint16_t item_token_index = item.json_token_index; + uint16_t token_index = 0; + + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, item_token_index, "args", &token_index)); + PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 0, &from, &from_len)); + PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 1, &to, &to_len)); + PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 2, &amount, &amount_len)); + } uint16_t required_len = amount_len + from_len + to_len + strlen(" from ") + strlen(" to ") + 4 * sizeof("\""); + if (required_len > outValLen) { return items_data_too_large; } @@ -138,18 +165,32 @@ items_error_t items_crossTransferToDisplayString(item_t item, char *outVal, uint uint8_t to_len = 0; uint8_t from_len = 0; uint8_t chain_len = 0; - uint16_t token_index = 0; - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - uint16_t item_token_index = item.json_token_index; - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, item_token_index, "args", &token_index)); - PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 0, &from, &from_len)); - PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 1, &to, &to_len)); - PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 2, &amount, &amount_len)); - PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 3, &chain, &chain_len)); + if (parser_usingChunks()) { + chunk_t *chunks = parser_getChunks(); + amount = chunks[AMOUNT_POS].data; + amount_len = chunks[AMOUNT_POS].len; + to = chunks[RECIPIENT_POS].data; + to_len = chunks[RECIPIENT_POS].len; + from = chunks[PUBKEY_POS].data; + from_len = chunks[PUBKEY_POS].len; + chain = chunks[CHAIN_ID_POS].data; + chain_len = chunks[CHAIN_ID_POS].len; + } else { + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); + uint16_t item_token_index = item.json_token_index; + uint16_t token_index = 0; + + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, item_token_index, "args", &token_index)); + PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 0, &from, &from_len)); + PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 1, &to, &to_len)); + PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 2, &amount, &amount_len)); + PARSER_TO_ITEMS_ERROR(parser_arrayElementToString(token_index, 3, &chain, &chain_len)); + } uint16_t required_len = amount_len + from_len + to_len + chain_len + strlen("Cross-chain ") + strlen(" from ") + strlen(" to ") + 6 * strlen("\"") + strlen(" to chain "); + if (required_len > outValLen) { return items_data_too_large; } @@ -181,22 +222,31 @@ items_error_t items_gasToDisplayString(__Z_UNUSED item_t item, char *outVal, uin const char *gasPrice; uint8_t gasLimit_len; uint8_t gasPrice_len; - parsed_json_t *json_all = &(parser_getParserJsonObj()->json); - uint16_t item_token_index = item.json_token_index; - uint16_t meta_token_index = item.json_token_index; - jsmntok_t *token; - - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, item_token_index, JSON_GAS_LIMIT, &item_token_index)); - token = &(json_all->tokens[item_token_index]); - gasLimit = json_all->buffer + token->start; - gasLimit_len = token->end - token->start; - - item_token_index = meta_token_index; - - PARSER_TO_ITEMS_ERROR(object_get_value(json_all, item_token_index, JSON_GAS_PRICE, &item_token_index)); - token = &(json_all->tokens[item_token_index]); - gasPrice = json_all->buffer + token->start; - gasPrice_len = token->end - token->start; + + if (parser_usingChunks()) { + chunk_t *chunks = parser_getChunks(); + gasLimit = chunks[GAS_LIMIT_POS].data; + gasLimit_len = chunks[GAS_LIMIT_POS].len; + gasPrice = chunks[GAS_PRICE_POS].data; + gasPrice_len = chunks[GAS_PRICE_POS].len; + } else { + parsed_json_t *json_all = &(parser_getParserJsonObj()->json); + uint16_t item_token_index = item.json_token_index; + uint16_t meta_token_index = item.json_token_index; + jsmntok_t *token; + + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, item_token_index, JSON_GAS_LIMIT, &item_token_index)); + token = &(json_all->tokens[item_token_index]); + gasLimit = json_all->buffer + token->start; + gasLimit_len = token->end - token->start; + + item_token_index = meta_token_index; + + PARSER_TO_ITEMS_ERROR(object_get_value(json_all, item_token_index, JSON_GAS_PRICE, &item_token_index)); + token = &(json_all->tokens[item_token_index]); + gasPrice = json_all->buffer + token->start; + gasPrice_len = token->end - token->start; + } uint16_t required_len = gasLimit_len + gasPrice_len + strlen("at most ") + strlen(" at price "); if (required_len > outValLen) { @@ -309,4 +359,19 @@ items_error_t items_signForAddrToDisplayString(__Z_UNUSED item_t item, char *out return items_ok; } -#endif \ No newline at end of file +#endif + +static items_error_t items_findChunkIndex(const char *key, uint8_t *outPos) { + if (MEMCMP(key, "On Network", strlen("On Network")) == 0) { + *outPos = NETWORK_POS; + return items_ok; + } else if (MEMCMP(key, "Of Key", strlen("Of Key")) == 0) { + *outPos = PUBKEY_POS; + return items_ok; + } else if (MEMCMP(key, "On Chain", strlen("On Chain")) == 0) { + *outPos = CHAIN_ID_POS; + return items_ok; + } else { + return items_error; + } +} \ No newline at end of file diff --git a/app/src/parser.c b/app/src/parser.c index dea94fe..8a1af4a 100644 --- a/app/src/parser.c +++ b/app/src/parser.c @@ -33,17 +33,12 @@ tx_json_t tx_obj_json; tx_hash_t tx_obj_hash; -char -#if defined(TARGET_NANOS) - // For nanos, jsonTemplate does not fit in RAM. - __attribute__((section(".text"))) -#endif - jsonTemplate[1200] = {0}; +char incrementalHash[BLAKE2B_HASH_SIZE] = {0}; uint16_t jsonTemplateLen; -char *parser_get_json_template_buffer() { return jsonTemplate; } +char *parser_get_json_inc_hash() { return incrementalHash; } -uint16_t parser_get_json_template_buffer_len() { return jsonTemplateLen; } +uint16_t parser_get_json_inc_hash_len() { return BLAKE2B_HASH_SIZE; } parser_error_t parser_init_context(parser_context_t *ctx, const uint8_t *buffer, uint16_t bufferSize) { ctx->offset = 0; @@ -74,12 +69,12 @@ parser_error_t parser_parse(parser_context_t *ctx, const uint8_t *data, size_t d ctx->hash = &tx_obj_hash; CHECK_ERROR(_read_hash_tx(ctx)); } else if (tx_type == tx_type_transaction) { - parser_createJsonTemplate(ctx, jsonTemplate, sizeof(jsonTemplate), &jsonTemplateLen); - ctx->json = &tx_obj_json; - ctx->buffer = (const uint8_t *)jsonTemplate; - ctx->bufferLen = jsonTemplateLen; - - CHECK_ERROR(_read_json_tx(ctx)); + parser_readChunks(ctx); + parser_computeIncrementalHash(incrementalHash); + ctx->buffer = (const uint8_t *)incrementalHash; + ctx->bufferLen = BLAKE2B_HASH_SIZE; + ctx->hash = &tx_obj_hash; + CHECK_ERROR(_read_hash_tx(ctx)); } ITEMS_TO_PARSER_ERROR(items_initItems()) diff --git a/app/src/parser_impl.c b/app/src/parser_impl.c index e33da6d..a71ecbb 100644 --- a/app/src/parser_impl.c +++ b/app/src/parser_impl.c @@ -50,37 +50,22 @@ #if defined(TARGET_NANOS) #define INCREMENT_POINTER_NVM(inc) \ { \ - if (ptr + inc > jsonTemplate + jsonTemplateSize) return parser_unexpected_buffer_end; \ + if (ptr + inc > incrementalHash + jsonTemplateSize) return parser_unexpected_buffer_end; \ ptr += inc; \ } #endif -#define RECIPIENT_POS 0 -#define RECIPIENT_CHAIN_POS 1 -#define NETWORK_POS 2 -#define AMOUNT_POS 3 -#define NAMESPACE_POS 4 -#define MODULE_POS 5 -#define GAS_PRICE_POS 6 -#define GAS_LIMIT_POS 7 -#define CREATION_TIME_POS 8 -#define CHAIN_ID_POS 9 -#define NONCE_POS 10 -#define TTL_POS 11 - -static parser_error_t parser_readSingleByte(parser_context_t *ctx, uint8_t *byte); +static parser_error_t parser_readSingleByte(parser_context_t *ctx, uint8_t **byte); static parser_error_t parser_readBytes(parser_context_t *ctx, uint8_t **bytes, uint16_t len); -static parser_error_t parser_formatTxTransfer(char *jsonTemplate, uint16_t jsonTemplateSize, uint16_t *jsonTemplateLen, - uint16_t address_len, char *address, chunk_t *chunks); -static parser_error_t parser_formatTxTransferCreate(char *jsonTemplate, uint16_t jsonTemplateSize, uint16_t *jsonTemplateLen, - uint16_t address_len, char *address, chunk_t *chunks); -static parser_error_t parser_formatTxTransferCrosschain(char *jsonTemplate, uint16_t jsonTemplateSize, - uint16_t *jsonTemplateLen, uint16_t address_len, char *address, - chunk_t *chunks); +static parser_error_t parser_hashTxTransfer(char *incrementalHash); +static parser_error_t parser_hashTxTransferCreate(char *incrementalHash); +static parser_error_t parser_hashTxTransferCrosschain(char *incrementalHash); tx_json_t *parser_json_obj; tx_hash_t *parser_hash_obj; +chunk_t chunks[14]; + parser_error_t _read_json_tx(parser_context_t *c) { parser_json_obj = c->json; @@ -94,6 +79,7 @@ parser_error_t _read_json_tx(parser_context_t *c) { } parser_error_t _read_hash_tx(parser_context_t *c) { + zemu_log("_read_hash_tx\n"); parser_hash_obj = c->hash; MEMZERO(parser_hash_obj, sizeof(tx_hash_t)); @@ -108,6 +94,12 @@ tx_json_t *parser_getParserJsonObj() { return parser_json_obj; } tx_hash_t *parser_getParserHashObj() { return parser_hash_obj; } +chunk_t *parser_getChunks() { return chunks; } + +bool parser_usingChunks() { + return chunks[0].data != NULL; +} + parser_error_t parser_findPubKeyInClist(uint16_t key_token_index) { parsed_json_t *json_all = &parser_json_obj->json; uint16_t token_index = 0; @@ -262,16 +254,13 @@ bool items_isNullField(uint16_t json_token_index) { return (MEMCMP("null", json_all->buffer + token->start, token->end - token->start) == 0); } -parser_error_t parser_createJsonTemplate(parser_context_t *ctx, char *jsonTemplate, uint16_t jsonTemplateSize, - uint16_t *jsonTemplateLen) { - // read tx_type - uint8_t tx_type = 0; - parser_readSingleByte(ctx, &tx_type); - - chunk_t chunks[12]; +parser_error_t parser_readChunks(parser_context_t *ctx) { + zemu_log("parser_readChunks\n"); + parser_readSingleByte(ctx, (uint8_t **)&chunks[0].data); - for (int i = 0; i < 12; i++) { - parser_readSingleByte(ctx, &chunks[i].len); + for (uint8_t i = 1; i < sizeof(chunks)/sizeof(chunk_t); i++) { + uint8_t *pLen = (uint8_t *)&chunks[i].len; + parser_readSingleByte(ctx, &pLen); if (chunks[i].len > 0) { parser_readBytes(ctx, (uint8_t **)&chunks[i].data, chunks[i].len); } else { @@ -279,6 +268,11 @@ parser_error_t parser_createJsonTemplate(parser_context_t *ctx, char *jsonTempla } } + return parser_ok; +} + +parser_error_t parser_computeIncrementalHash(char *incrementalHash) { + zemu_log("parser_computeIncrementalHash\n"); char address[65] = {0}; #if defined(TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) || defined(TARGET_STAX) || defined(TARGET_FLEX) uint8_t pubkey[PUB_KEY_LENGTH] = {0}; @@ -295,17 +289,22 @@ parser_error_t parser_createJsonTemplate(parser_context_t *ctx, char *jsonTempla snprintf(address, sizeof(address), "%s", "1234567890123456789012345678901234567890123456789012345678901234"); #endif + strcpy(chunks[PUBKEY_POS].data, address); + chunks[PUBKEY_POS].len = address_len; + + tx_type_t tx_type = (tx_type_t)chunks[TYPE_POS].data[0]; + switch (tx_type) { case TX_TYPE_TRANSFER: { - parser_formatTxTransfer(jsonTemplate, jsonTemplateSize, jsonTemplateLen, address_len, address, chunks); + parser_hashTxTransfer(incrementalHash); break; } case TX_TYPE_TRANSFER_CREATE: { - parser_formatTxTransferCreate(jsonTemplate, jsonTemplateSize, jsonTemplateLen, address_len, address, chunks); + parser_hashTxTransferCreate(incrementalHash); break; } case TX_TYPE_TRANSFER_CROSSCHAIN: { - parser_formatTxTransferCrosschain(jsonTemplate, jsonTemplateSize, jsonTemplateLen, address_len, address, chunks); + parser_hashTxTransferCrosschain(incrementalHash); break; } default: @@ -315,12 +314,12 @@ parser_error_t parser_createJsonTemplate(parser_context_t *ctx, char *jsonTempla return parser_ok; } -static parser_error_t parser_readSingleByte(parser_context_t *ctx, uint8_t *byte) { +static parser_error_t parser_readSingleByte(parser_context_t *ctx, uint8_t **byte) { if (ctx->offset >= ctx->bufferLen) { return parser_unexpected_buffer_end; } - *byte = ctx->buffer[ctx->offset]; + *byte = (uint8_t *)(ctx->buffer + ctx->offset); ctx->offset++; return parser_ok; } @@ -335,8 +334,7 @@ static parser_error_t parser_readBytes(parser_context_t *ctx, uint8_t **bytes, u return parser_ok; } -static parser_error_t parser_formatTxTransfer(char *jsonTemplate, uint16_t jsonTemplateSize, uint16_t *jsonTemplateLen, - uint16_t address_len, char *address, chunk_t *chunks) { +static parser_error_t parser_hashTxTransfer(char *incrementalHash) { char namespace_and_module[30] = {0}; if (chunks[NAMESPACE_POS].len > 0 && chunks[MODULE_POS].len > 0) { snprintf(namespace_and_module, sizeof(namespace_and_module), "%.*s.%.*s", chunks[NAMESPACE_POS].len, @@ -345,102 +343,47 @@ static parser_error_t parser_formatTxTransfer(char *jsonTemplate, uint16_t jsonT snprintf(namespace_and_module, sizeof(namespace_and_module), "%s", "coin"); } -#if !defined(TARGET_NANOS) - snprintf(jsonTemplate, jsonTemplateSize, TRANSFER_FORMAT, chunks[NETWORK_POS].len, chunks[NETWORK_POS].data, - (int)strlen(namespace_and_module), namespace_and_module, address_len, address, chunks[RECIPIENT_POS].len, - chunks[RECIPIENT_POS].data, chunks[AMOUNT_POS].len, chunks[AMOUNT_POS].data, address_len, address, address_len, - address, chunks[RECIPIENT_POS].len, chunks[RECIPIENT_POS].data, chunks[AMOUNT_POS].len, chunks[AMOUNT_POS].data, - (int)strlen(namespace_and_module), namespace_and_module, chunks[CREATION_TIME_POS].len, - chunks[CREATION_TIME_POS].data, chunks[TTL_POS].len, chunks[TTL_POS].data, chunks[GAS_LIMIT_POS].len, - chunks[GAS_LIMIT_POS].data, chunks[CHAIN_ID_POS].len, chunks[CHAIN_ID_POS].data, chunks[GAS_PRICE_POS].len, - chunks[GAS_PRICE_POS].data, address_len, address, chunks[NONCE_POS].len, chunks[NONCE_POS].data); - - *jsonTemplateLen = strlen(jsonTemplate); -#else - // For nanoS we need to use flash memory for the json template - char *ptr = jsonTemplate; - - MEMCPY_NV((void *)ptr, (void *)"{\"networkId\":\"", 14); - INCREMENT_POINTER_NVM(14) - MEMCPY_NV((void *)ptr, chunks[NETWORK_POS].data, chunks[NETWORK_POS].len); - INCREMENT_POINTER_NVM(chunks[NETWORK_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\",\"payload\":{\"exec\":{\"data\":{},\"code\":\"", 39); - INCREMENT_POINTER_NVM(39) - MEMCPY_NV((void *)ptr, (void *)"(", 1); - INCREMENT_POINTER_NVM(1) - MEMCPY_NV((void *)ptr, namespace_and_module, strlen(namespace_and_module)); - INCREMENT_POINTER_NVM(strlen(namespace_and_module)) - MEMCPY_NV((void *)ptr, (void *)".transfer \\\"k:", 14); - INCREMENT_POINTER_NVM(14) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\\\" \\\"k:", 7); - INCREMENT_POINTER_NVM(7) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\\\" ", 3); - INCREMENT_POINTER_NVM(3) - MEMCPY_NV((void *)ptr, chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len); - INCREMENT_POINTER_NVM(chunks[AMOUNT_POS].len) - MEMCPY_NV((void *)ptr, (void *)")\"}},\"signers\":[{\"pubKey\":\"", 27); - INCREMENT_POINTER_NVM(27) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\",\"clist\":[{\"args\":[\"k:", 23); - INCREMENT_POINTER_NVM(23) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\",\"k:", 5); - INCREMENT_POINTER_NVM(5) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\",", 2); - INCREMENT_POINTER_NVM(2) - MEMCPY_NV((void *)ptr, chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len); - INCREMENT_POINTER_NVM(chunks[AMOUNT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"],\"name\":\"", 10); - INCREMENT_POINTER_NVM(10) - MEMCPY_NV((void *)ptr, namespace_and_module, strlen(namespace_and_module)); - INCREMENT_POINTER_NVM(strlen(namespace_and_module)) - MEMCPY_NV((void *)ptr, (void *)".TRANSFER\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":", 68); - INCREMENT_POINTER_NVM(68) - MEMCPY_NV((void *)ptr, chunks[CREATION_TIME_POS].data, chunks[CREATION_TIME_POS].len); - INCREMENT_POINTER_NVM(chunks[CREATION_TIME_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"ttl\":", 7); - INCREMENT_POINTER_NVM(7) - MEMCPY_NV((void *)ptr, chunks[TTL_POS].data, chunks[TTL_POS].len); - INCREMENT_POINTER_NVM(chunks[TTL_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"gasLimit\":", 12); - INCREMENT_POINTER_NVM(12) - MEMCPY_NV((void *)ptr, chunks[GAS_LIMIT_POS].data, chunks[GAS_LIMIT_POS].len); - INCREMENT_POINTER_NVM(chunks[GAS_LIMIT_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"chainId\":\"", 12); - INCREMENT_POINTER_NVM(12) - MEMCPY_NV((void *)ptr, chunks[CHAIN_ID_POS].data, chunks[CHAIN_ID_POS].len); - INCREMENT_POINTER_NVM(chunks[CHAIN_ID_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\",\"gasPrice\":", 13); - INCREMENT_POINTER_NVM(13) - MEMCPY_NV((void *)ptr, chunks[GAS_PRICE_POS].data, chunks[GAS_PRICE_POS].len); - INCREMENT_POINTER_NVM(chunks[GAS_PRICE_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"sender\":\"k:", 13); - INCREMENT_POINTER_NVM(13) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\"},\"nonce\":\"", 12); - INCREMENT_POINTER_NVM(12) - MEMCPY_NV((void *)ptr, chunks[NONCE_POS].data, chunks[NONCE_POS].len); - INCREMENT_POINTER_NVM(chunks[NONCE_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\"}", 2); - INCREMENT_POINTER_NVM(2) - - *jsonTemplateLen = ptr - jsonTemplate; -#endif + blake2b_incremental((uint8_t *)"{\"networkId\":\"", 14, (uint8_t *)incrementalHash, true, false); + blake2b_incremental((uint8_t *)chunks[NETWORK_POS].data, chunks[NETWORK_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",\"payload\":{\"exec\":{\"data\":{},\"code\":\"", 39, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"(", 1, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)namespace_and_module, strlen(namespace_and_module), (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)".transfer \\\"k:", 14, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\\\" \\\"k:", 7, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\\\" ", 3, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)")\"}},\"signers\":[{\"pubKey\":\"", 27, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",\"clist\":[{\"args\":[\"k:", 23, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",\"k:", 5, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",", 2, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"],\"name\":\"", 10, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)namespace_and_module, strlen(namespace_and_module), (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)".TRANSFER\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":", 68, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[CREATION_TIME_POS].data, chunks[CREATION_TIME_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"ttl\":", 7, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[TTL_POS].data, chunks[TTL_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"gasLimit\":", 12, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[GAS_LIMIT_POS].data, chunks[GAS_LIMIT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"chainId\":\"", 12, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[CHAIN_ID_POS].data, chunks[CHAIN_ID_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"gasPrice\":", 13, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[GAS_PRICE_POS].data, chunks[GAS_PRICE_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"sender\":\"k:", 13, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\"},\"nonce\":\"", 12, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[NONCE_POS].data, chunks[NONCE_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\"}", 2, (uint8_t *)incrementalHash, false, true); return parser_ok; } -static parser_error_t parser_formatTxTransferCreate(char *jsonTemplate, uint16_t jsonTemplateSize, uint16_t *jsonTemplateLen, - uint16_t address_len, char *address, chunk_t *chunks) { +static parser_error_t parser_hashTxTransferCreate(char *incrementalHash) { char namespace_and_module[30] = {0}; if (chunks[NAMESPACE_POS].len > 0 && chunks[MODULE_POS].len > 0) { snprintf(namespace_and_module, sizeof(namespace_and_module), "%.*s.%.*s", chunks[NAMESPACE_POS].len, @@ -449,106 +392,48 @@ static parser_error_t parser_formatTxTransferCreate(char *jsonTemplate, uint16_t snprintf(namespace_and_module, sizeof(namespace_and_module), "%s", "coin"); } -#if !defined(TARGET_NANOS) - snprintf(jsonTemplate, jsonTemplateSize, TRANSFER_CREATE_FORMAT, chunks[NETWORK_POS].len, chunks[NETWORK_POS].data, - chunks[RECIPIENT_POS].len, chunks[RECIPIENT_POS].data, (int)strlen(namespace_and_module), namespace_and_module, - address_len, address, chunks[RECIPIENT_POS].len, chunks[RECIPIENT_POS].data, chunks[AMOUNT_POS].len, - chunks[AMOUNT_POS].data, address_len, address, address_len, address, chunks[RECIPIENT_POS].len, - chunks[RECIPIENT_POS].data, chunks[AMOUNT_POS].len, chunks[AMOUNT_POS].data, (int)strlen(namespace_and_module), - namespace_and_module, chunks[CREATION_TIME_POS].len, chunks[CREATION_TIME_POS].data, chunks[TTL_POS].len, - chunks[TTL_POS].data, chunks[GAS_LIMIT_POS].len, chunks[GAS_LIMIT_POS].data, chunks[CHAIN_ID_POS].len, - chunks[CHAIN_ID_POS].data, chunks[GAS_PRICE_POS].len, chunks[GAS_PRICE_POS].data, address_len, address, - chunks[NONCE_POS].len, chunks[NONCE_POS].data); - - *jsonTemplateLen = strlen(jsonTemplate); -#else - // For nanoS we need to use flash memory for the json template - char *ptr = jsonTemplate; - - MEMCPY_NV((void *)ptr, (void *)"{\"networkId\":\"", 14); - INCREMENT_POINTER_NVM(14) - MEMCPY_NV((void *)ptr, chunks[NETWORK_POS].data, chunks[NETWORK_POS].len); - INCREMENT_POINTER_NVM(chunks[NETWORK_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\",\"payload\":{\"exec\":{\"data\":{\"ks\":{\"pred\":\"keys-all\",\"keys\":[\"", 62); - INCREMENT_POINTER_NVM(62) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\"]}},\"code\":\"(", 14); - INCREMENT_POINTER_NVM(14) - MEMCPY_NV((void *)ptr, namespace_and_module, strlen(namespace_and_module)); - INCREMENT_POINTER_NVM(strlen(namespace_and_module)) - MEMCPY_NV((void *)ptr, (void *)".transfer-create \\\"k:", 21); - INCREMENT_POINTER_NVM(21) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\\\" \\\"k:", 7); - INCREMENT_POINTER_NVM(7) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\\\" (read-keyset \\\"ks\\\") ", 24); - INCREMENT_POINTER_NVM(24) - MEMCPY_NV((void *)ptr, chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len); - INCREMENT_POINTER_NVM(chunks[AMOUNT_POS].len) - MEMCPY_NV((void *)ptr, (void *)")\"}},\"signers\":[{\"pubKey\":\"", 27); - INCREMENT_POINTER_NVM(27) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\",\"clist\":[{\"args\":[\"k:", 23); - INCREMENT_POINTER_NVM(23) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\",\"k:", 5); - INCREMENT_POINTER_NVM(5) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\",", 2); - INCREMENT_POINTER_NVM(2) - MEMCPY_NV((void *)ptr, chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len); - INCREMENT_POINTER_NVM(chunks[AMOUNT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"],\"name\":\"", 10); - INCREMENT_POINTER_NVM(10) - MEMCPY_NV((void *)ptr, namespace_and_module, strlen(namespace_and_module)); - INCREMENT_POINTER_NVM(strlen(namespace_and_module)) - MEMCPY_NV((void *)ptr, (void *)".TRANSFER\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":", 68); - INCREMENT_POINTER_NVM(68) - MEMCPY_NV((void *)ptr, chunks[CREATION_TIME_POS].data, chunks[CREATION_TIME_POS].len); - INCREMENT_POINTER_NVM(chunks[CREATION_TIME_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"ttl\":", 7); - INCREMENT_POINTER_NVM(7) - MEMCPY_NV((void *)ptr, chunks[TTL_POS].data, chunks[TTL_POS].len); - INCREMENT_POINTER_NVM(chunks[TTL_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"gasLimit\":", 12); - INCREMENT_POINTER_NVM(12) - MEMCPY_NV((void *)ptr, chunks[GAS_LIMIT_POS].data, chunks[GAS_LIMIT_POS].len); - INCREMENT_POINTER_NVM(chunks[GAS_LIMIT_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"chainId\":\"", 12); - INCREMENT_POINTER_NVM(12) - MEMCPY_NV((void *)ptr, chunks[CHAIN_ID_POS].data, chunks[CHAIN_ID_POS].len); - INCREMENT_POINTER_NVM(chunks[CHAIN_ID_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\",\"gasPrice\":", 13); - INCREMENT_POINTER_NVM(13) - MEMCPY_NV((void *)ptr, chunks[GAS_PRICE_POS].data, chunks[GAS_PRICE_POS].len); - INCREMENT_POINTER_NVM(chunks[GAS_PRICE_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"sender\":\"k:", 13); - INCREMENT_POINTER_NVM(13) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\"},\"nonce\":\"", 12); - INCREMENT_POINTER_NVM(12) - MEMCPY_NV((void *)ptr, chunks[NONCE_POS].data, chunks[NONCE_POS].len); - INCREMENT_POINTER_NVM(chunks[NONCE_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\"}", 2); - INCREMENT_POINTER_NVM(2) - - *jsonTemplateLen = ptr - jsonTemplate; -#endif + blake2b_incremental((uint8_t *)"{\"networkId\":\"", 14, (uint8_t *)incrementalHash, true, false); + blake2b_incremental((uint8_t *)chunks[NETWORK_POS].data, chunks[NETWORK_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",\"payload\":{\"exec\":{\"data\":{\"ks\":{\"pred\":\"keys-all\",\"keys\":[\"", 62, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\"]}},\"code\":\"(", 14, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)namespace_and_module, strlen(namespace_and_module), (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)".transfer-create \\\"k:", 21, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\\\" \\\"k:", 7, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\\\" (read-keyset \\\"ks\\\") ", 24, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)")\"}},\"signers\":[{\"pubKey\":\"", 27, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",\"clist\":[{\"args\":[\"k:", 23, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",\"k:", 5, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",", 2, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"],\"name\":\"", 10, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)namespace_and_module, strlen(namespace_and_module), (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)".TRANSFER\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":", 68, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[CREATION_TIME_POS].data, chunks[CREATION_TIME_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"ttl\":", 7, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[TTL_POS].data, chunks[TTL_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"gasLimit\":", 12, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[GAS_LIMIT_POS].data, chunks[GAS_LIMIT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"chainId\":\"", 12, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[CHAIN_ID_POS].data, chunks[CHAIN_ID_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"gasPrice\":", 13, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[GAS_PRICE_POS].data, chunks[GAS_PRICE_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"sender\":\"k:", 13, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\"},\"nonce\":\"", 12, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[NONCE_POS].data, chunks[NONCE_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\"}", 2, (uint8_t *)incrementalHash, false, true); return parser_ok; } -static parser_error_t parser_formatTxTransferCrosschain(char *jsonTemplate, uint16_t jsonTemplateSize, - uint16_t *jsonTemplateLen, uint16_t address_len, char *address, - chunk_t *chunks) { +static parser_error_t parser_hashTxTransferCrosschain(char *incrementalHash) { char namespace_and_module[30] = {0}; if (chunks[NAMESPACE_POS].len > 0 && chunks[MODULE_POS].len > 0) { snprintf(namespace_and_module, sizeof(namespace_and_module), "%.*s.%.*s", chunks[NAMESPACE_POS].len, @@ -556,109 +441,48 @@ static parser_error_t parser_formatTxTransferCrosschain(char *jsonTemplate, uint } else { snprintf(namespace_and_module, sizeof(namespace_and_module), "%s", "coin"); } -#if !defined(TARGET_NANOS) - snprintf(jsonTemplate, jsonTemplateSize, TRANSFER_CROSSCHAIN_FORMAT, chunks[NETWORK_POS].len, chunks[NETWORK_POS].data, - chunks[RECIPIENT_POS].len, chunks[RECIPIENT_POS].data, (int)strlen(namespace_and_module), namespace_and_module, - address_len, address, chunks[RECIPIENT_POS].len, chunks[RECIPIENT_POS].data, chunks[RECIPIENT_CHAIN_POS].len, - chunks[RECIPIENT_CHAIN_POS].data, chunks[AMOUNT_POS].len, chunks[AMOUNT_POS].data, address_len, address, - address_len, address, chunks[RECIPIENT_POS].len, chunks[RECIPIENT_POS].data, chunks[AMOUNT_POS].len, - chunks[AMOUNT_POS].data, chunks[RECIPIENT_CHAIN_POS].len, chunks[RECIPIENT_CHAIN_POS].data, - (int)strlen(namespace_and_module), namespace_and_module, chunks[CREATION_TIME_POS].len, - chunks[CREATION_TIME_POS].data, chunks[TTL_POS].len, chunks[TTL_POS].data, chunks[GAS_LIMIT_POS].len, - chunks[GAS_LIMIT_POS].data, chunks[CHAIN_ID_POS].len, chunks[CHAIN_ID_POS].data, chunks[GAS_PRICE_POS].len, - chunks[GAS_PRICE_POS].data, address_len, address, chunks[NONCE_POS].len, chunks[NONCE_POS].data); - - *jsonTemplateLen = strlen(jsonTemplate); -#else - // For nanoS we need to use flash memory for the json template - char *ptr = jsonTemplate; - - MEMCPY_NV((void *)ptr, (void *)"{\"networkId\":\"", 14); - INCREMENT_POINTER_NVM(14) - MEMCPY_NV((void *)ptr, chunks[NETWORK_POS].data, chunks[NETWORK_POS].len); - INCREMENT_POINTER_NVM(chunks[NETWORK_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\",\"payload\":{\"exec\":{\"data\":{\"ks\":{\"pred\":\"keys-all\",\"keys\":[\"", 62); - INCREMENT_POINTER_NVM(62) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\"]}},\"code\":\"(", 14); - INCREMENT_POINTER_NVM(14) - MEMCPY_NV((void *)ptr, namespace_and_module, strlen(namespace_and_module)); - INCREMENT_POINTER_NVM(strlen(namespace_and_module)) - MEMCPY_NV((void *)ptr, (void *)".transfer-crosschain \\\"k:", 25); - INCREMENT_POINTER_NVM(25) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\\\" \\\"k:", 7); - INCREMENT_POINTER_NVM(7) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\\\" (read-keyset \\\"ks\\\") \\\"", 26); - INCREMENT_POINTER_NVM(26) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_CHAIN_POS].data, chunks[RECIPIENT_CHAIN_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_CHAIN_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\\\" ", 3); - INCREMENT_POINTER_NVM(3) - MEMCPY_NV((void *)ptr, chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len); - INCREMENT_POINTER_NVM(chunks[AMOUNT_POS].len) - MEMCPY_NV((void *)ptr, (void *)")\"}},\"signers\":[{\"pubKey\":\"", 27); - INCREMENT_POINTER_NVM(27) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\",\"clist\":[{\"args\":[\"k:", 23); - INCREMENT_POINTER_NVM(23) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\",\"k:", 5); - INCREMENT_POINTER_NVM(5) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\",", 2); - INCREMENT_POINTER_NVM(2) - MEMCPY_NV((void *)ptr, chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len); - INCREMENT_POINTER_NVM(chunks[AMOUNT_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"", 2); - INCREMENT_POINTER_NVM(2) - MEMCPY_NV((void *)ptr, chunks[RECIPIENT_CHAIN_POS].data, chunks[RECIPIENT_CHAIN_POS].len); - INCREMENT_POINTER_NVM(chunks[RECIPIENT_CHAIN_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\"],\"name\":\"", 11); - INCREMENT_POINTER_NVM(11) - MEMCPY_NV((void *)ptr, namespace_and_module, strlen(namespace_and_module)); - INCREMENT_POINTER_NVM(strlen(namespace_and_module)) - MEMCPY_NV((void *)ptr, - (void *)".TRANSFER_XCHAIN\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":", 75); - INCREMENT_POINTER_NVM(75) - MEMCPY_NV((void *)ptr, chunks[CREATION_TIME_POS].data, chunks[CREATION_TIME_POS].len); - INCREMENT_POINTER_NVM(chunks[CREATION_TIME_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"ttl\":", 7); - INCREMENT_POINTER_NVM(7) - MEMCPY_NV((void *)ptr, chunks[TTL_POS].data, chunks[TTL_POS].len); - INCREMENT_POINTER_NVM(chunks[TTL_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"gasLimit\":", 12); - INCREMENT_POINTER_NVM(12) - MEMCPY_NV((void *)ptr, chunks[GAS_LIMIT_POS].data, chunks[GAS_LIMIT_POS].len); - INCREMENT_POINTER_NVM(chunks[GAS_LIMIT_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"chainId\":\"", 12); - INCREMENT_POINTER_NVM(12) - MEMCPY_NV((void *)ptr, chunks[CHAIN_ID_POS].data, chunks[CHAIN_ID_POS].len); - INCREMENT_POINTER_NVM(chunks[CHAIN_ID_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\",\"gasPrice\":", 13); - INCREMENT_POINTER_NVM(13) - MEMCPY_NV((void *)ptr, chunks[GAS_PRICE_POS].data, chunks[GAS_PRICE_POS].len); - INCREMENT_POINTER_NVM(chunks[GAS_PRICE_POS].len) - MEMCPY_NV((void *)ptr, (void *)",\"sender\":\"k:", 13); - INCREMENT_POINTER_NVM(13) - MEMCPY_NV((void *)ptr, address, address_len); - INCREMENT_POINTER_NVM(address_len) - MEMCPY_NV((void *)ptr, (void *)"\"},\"nonce\":\"", 12); - INCREMENT_POINTER_NVM(12) - MEMCPY_NV((void *)ptr, chunks[NONCE_POS].data, chunks[NONCE_POS].len); - INCREMENT_POINTER_NVM(chunks[NONCE_POS].len) - MEMCPY_NV((void *)ptr, (void *)"\"}", 2); - INCREMENT_POINTER_NVM(2) - - *jsonTemplateLen = ptr - jsonTemplate; -#endif + + blake2b_incremental((uint8_t *)"{\"networkId\":\"", 14, (uint8_t *)incrementalHash, true, false); + blake2b_incremental((uint8_t *)chunks[NETWORK_POS].data, chunks[NETWORK_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",\"payload\":{\"exec\":{\"data\":{\"ks\":{\"pred\":\"keys-all\",\"keys\":[\"", 62, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\"]}},\"code\":\"(", 14, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)namespace_and_module, strlen(namespace_and_module), (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)".transfer-crosschain \\\"k:", 25, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\\\" \\\"k:", 7, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\\\" (read-keyset \\\"ks\\\") \\\"", 26, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_CHAIN_POS].data, chunks[RECIPIENT_CHAIN_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\\\" ", 3, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)")\"}},\"signers\":[{\"pubKey\":\"", 27, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",\"clist\":[{\"args\":[\"k:", 23, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\",\"k:", 5, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_POS].data, chunks[RECIPIENT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",", 2, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[AMOUNT_POS].data, chunks[AMOUNT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"", 2, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[RECIPIENT_CHAIN_POS].data, chunks[RECIPIENT_CHAIN_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\"],\"name\":\"", 11, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)namespace_and_module, strlen(namespace_and_module), (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)".TRANSFER_XCHAIN\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":", 75, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[CREATION_TIME_POS].data, chunks[CREATION_TIME_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"ttl\":", 7, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[TTL_POS].data, chunks[TTL_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"gasLimit\":", 12, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[GAS_LIMIT_POS].data, chunks[GAS_LIMIT_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"chainId\":\"", 12, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[CHAIN_ID_POS].data, chunks[CHAIN_ID_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"gasPrice\":", 13, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[GAS_PRICE_POS].data, chunks[GAS_PRICE_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)",\"sender\":\"k:", 13, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[PUBKEY_POS].data, chunks[PUBKEY_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\"},\"nonce\":\"", 12, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)chunks[NONCE_POS].data, chunks[NONCE_POS].len, (uint8_t *)incrementalHash, false, false); + blake2b_incremental((uint8_t *)"\"}", 2, (uint8_t *)incrementalHash, false, true); return parser_ok; } diff --git a/app/src/parser_impl.h b/app/src/parser_impl.h index 094071c..acb0c00 100644 --- a/app/src/parser_impl.h +++ b/app/src/parser_impl.h @@ -43,6 +43,21 @@ extern "C" { #define JSON_GAS_PRICE "gasPrice" #define JSON_SENDER "sender" +#define TYPE_POS 0 +#define RECIPIENT_POS 1 +#define RECIPIENT_CHAIN_POS 2 +#define NETWORK_POS 3 +#define AMOUNT_POS 4 +#define NAMESPACE_POS 5 +#define MODULE_POS 6 +#define GAS_PRICE_POS 7 +#define GAS_LIMIT_POS 8 +#define CREATION_TIME_POS 9 +#define CHAIN_ID_POS 10 +#define NONCE_POS 11 +#define TTL_POS 12 +#define PUBKEY_POS 13 + typedef struct { const uint8_t *buffer; uint16_t bufferLen; @@ -63,6 +78,8 @@ parser_error_t _read_json_tx(parser_context_t *c); parser_error_t _read_hash_tx(parser_context_t *c); tx_json_t *parser_getParserJsonObj(); tx_hash_t *parser_getParserHashObj(); +chunk_t *parser_getChunks(); +bool parser_usingChunks(); parser_error_t parser_findPubKeyInClist(uint16_t key_token_index); parser_error_t parser_arrayElementToString(uint16_t json_token_index, uint16_t element_idx, const char **outVal, uint8_t *outValLen); @@ -70,8 +87,8 @@ parser_error_t parser_validateMetaField(); parser_error_t parser_getTxName(uint16_t token_index); parser_error_t parser_getValidClist(uint16_t *clist_token_index, uint16_t *num_args); bool items_isNullField(uint16_t json_token_index); -parser_error_t parser_createJsonTemplate(parser_context_t *ctx, char *jsonTemplate, uint16_t jsonTemplateSize, - uint16_t *jsonTemplateLen); +parser_error_t parser_readChunks(parser_context_t *ctx); +parser_error_t parser_computeIncrementalHash(char *incrementalHash); #ifdef __cplusplus }