Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: Use new standalone SDK hashing functions #231

Merged
merged 2 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 13 additions & 38 deletions src/common/merkle.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,54 +24,29 @@

#include "merkle.h"

#include "cx_ram.h"
#include "debug-helpers/debug.h"

#include "ledger_assert.h"

void merkle_compute_element_hash(const uint8_t *in, size_t in_len, uint8_t out[static 32]) {
cx_sha256_t hash;
cx_sha256_init(&hash);

void merkle_compute_element_hash(const uint8_t *in,
size_t in_len,
uint8_t out[static CX_SHA256_SIZE]) {
// H(0x00 | in)
crypto_hash_update_u8(&hash.header, 0x00);
crypto_hash_update(&hash.header, in, in_len);

crypto_hash_digest(&hash.header, out, 32);
uint8_t data = 0x00;
cx_iovec_t iovec[2] = {{.iov_base = &data, .iov_len = 1}, {.iov_base = in, .iov_len = in_len}};
cx_sha256_hash_iovec(iovec, 2, out);
}

// void merkle_combine_hashes(const uint8_t left[static 32],
// const uint8_t right[static 32],
// uint8_t out[static 32]) {
// PRINT_STACK_POINTER();

// cx_sha256_t hash;
// cx_sha256_init(&hash);

// // H(0x01 | left | right)
// crypto_hash_update_u8(&hash.header, 0x01);
// crypto_hash_update(&hash.header, left, 32);
// crypto_hash_update(&hash.header, right, 32);

// crypto_hash_digest(&hash.header, out, 32);
// }

// implementation using the cxram section, in order to save ram
void merkle_combine_hashes(const uint8_t left[static 32],
const uint8_t right[static 32],
uint8_t out[static 32]) {
void merkle_combine_hashes(const uint8_t left[static CX_SHA256_SIZE],
const uint8_t right[static CX_SHA256_SIZE],
uint8_t out[static CX_SHA256_SIZE]) {
PRINT_STACK_POINTER();

cx_sha256_init_no_throw(&G_cx.sha256);

uint8_t prefix = 0x01;
LEDGER_ASSERT(cx_sha256_update(&G_cx.sha256, &prefix, 1) == CX_OK, "It never fails");

LEDGER_ASSERT(cx_sha256_update(&G_cx.sha256, left, 32) == CX_OK, "It never fails");
LEDGER_ASSERT(cx_sha256_update(&G_cx.sha256, right, 32) == CX_OK, "It never fails");

cx_sha256_final(&G_cx.sha256, out);
explicit_bzero(&G_cx.sha256, sizeof(cx_sha256_t));
cx_iovec_t iovec[3] = {{.iov_base = &prefix, .iov_len = 1},
{.iov_base = left, .iov_len = CX_SHA256_SIZE},
{.iov_base = right, .iov_len = CX_SHA256_SIZE}};
cx_sha256_hash_iovec(iovec, 3, out);
}

// TODO: make this O(log n), or possibly O(1). Currently O(log^2 n).
Expand Down
54 changes: 20 additions & 34 deletions src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,25 +155,8 @@ int bip32_CKDpub(const serialized_extended_pubkey_t *parent,
return 0;
}

#ifndef _NR_cx_hash_ripemd160
/** Missing in some SDKs, we implement it using the cxram section if needed. */
static size_t cx_hash_ripemd160(const uint8_t *in, size_t in_len, uint8_t *out, size_t out_len) {
PRINT_STACK_POINTER();

if (out_len < CX_RIPEMD160_SIZE) {
return 0;
}
LEDGER_ASSERT(cx_ripemd160_init_no_throw((cx_ripemd160_t *) &G_cx) == CX_OK, "It never fails");
LEDGER_ASSERT(cx_ripemd160_update((cx_ripemd160_t *) &G_cx, in, in_len) == CX_OK,
"It never fails");
LEDGER_ASSERT(cx_ripemd160_final((cx_ripemd160_t *) &G_cx, out) == CX_OK, "It never fails");
explicit_bzero((cx_ripemd160_t *) &G_cx, sizeof(cx_sha256_t));
return CX_RIPEMD160_SIZE;
}
#endif // _NR_cx_hash_ripemd160

void crypto_ripemd160(const uint8_t *in, uint16_t inlen, uint8_t out[static 20]) {
cx_hash_ripemd160(in, inlen, out, 20);
cx_ripemd160_hash(in, inlen, out);
}

void crypto_hash160(const uint8_t *in, uint16_t inlen, uint8_t out[static 20]) {
Expand Down Expand Up @@ -473,22 +456,25 @@ static int crypto_tr_lift_x(const uint8_t x[static 32], uint8_t out[static 65])

// Computes a tagged hash according to BIP-340.
// If data2_len > 0, then data2 must be non-NULL and the `data` and `data2` arrays are concatenated.
// Somewhat weird signature, but this helps to optimize stack usage.
static void __attribute__((noinline)) crypto_tr_tagged_hash(const uint8_t *tag,
uint16_t tag_len,
const uint8_t *data,
uint16_t data_len,
const uint8_t *data2,
uint16_t data2_len,
uint8_t out[static 32]) {
cx_sha256_t hash_context;
cx_sha256_init(&hash_context);

crypto_tr_tagged_hash_init(&hash_context, tag, tag_len);

crypto_hash_update(&hash_context.header, data, data_len);
if (data2_len > 0) crypto_hash_update(&hash_context.header, data2, data2_len);
crypto_hash_digest(&hash_context.header, out, 32);
static void crypto_tr_tagged_hash(const uint8_t *tag,
uint16_t tag_len,
const uint8_t *data,
uint16_t data_len,
const uint8_t *data2,
uint16_t data2_len,
uint8_t out[static CX_SHA256_SIZE]) {
// First compute hashtag, reuse out buffer for that
cx_sha256_hash(tag, tag_len, out);

cx_iovec_t iovec[4] = {{.iov_base = out, .iov_len = CX_SHA256_SIZE},
{.iov_base = out, .iov_len = CX_SHA256_SIZE},
{.iov_base = data, .iov_len = data_len},
{.iov_base = data2, .iov_len = data2_len}};
if (data2_len > 0) {
cx_sha256_hash_iovec(iovec, 4, out);
} else {
cx_sha256_hash_iovec(iovec, 3, out);
}
}

void crypto_tr_combine_taptree_hashes(const uint8_t left_h[static 32],
Expand Down
3 changes: 1 addition & 2 deletions src/cxram_stash.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
#include "cxram_stash.h"
#include "cx_ram.h"

#ifdef USE_CXRAM_SECTION
#ifndef G_cx
// The G_cx symbol is only defined in the sdk if compiled with certain libs are included.
// This makes sure that the symbol exists nonetheless.
union cx_u G_cx;
#endif

#ifdef USE_CXRAM_SECTION

uint8_t *get_cxram_buffer() {
return (uint8_t *) &G_cx;
}
Expand Down
Loading