From 93e3fd925bd51981213a28c2ab8419ac289b77e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Vejpustek?= Date: Fri, 22 Nov 2024 17:54:51 +0100 Subject: [PATCH] refactor(legacy): introduce cryptoMultisigPubkeys --- legacy/firmware/crypto.c | 19 +++++++++++++++++++ legacy/firmware/crypto.h | 5 +++++ legacy/firmware/transaction.c | 20 ++++++++++++++------ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/legacy/firmware/crypto.c b/legacy/firmware/crypto.c index 5d1f4ae907..60b1f69013 100644 --- a/legacy/firmware/crypto.c +++ b/legacy/firmware/crypto.c @@ -368,6 +368,25 @@ uint32_t cryptoMultisigPubkeyCount(const MultisigRedeemScriptType *multisig) { : multisig->pubkeys_count; } +uint32_t cryptoMultisigPubkeys(const CoinInfo *coin, + const MultisigRedeemScriptType *multisig, + uint8_t *pubkeys) { + const uint32_t n = cryptoMultisigPubkeyCount(multisig); + if (n < 1 || n > 15) { + return 0; + } + + for (uint32_t i = 0; i < n; i++) { + const HDNode *pubnode = cryptoMultisigPubkey(coin, multisig, i); + if (!pubnode) { + return 0; + } + memcpy(pubkeys + i * 33, pubnode->public_key, 33); + } + + return n; +} + int cryptoMultisigPubkeyIndex(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, const uint8_t *pubkey) { diff --git a/legacy/firmware/crypto.h b/legacy/firmware/crypto.h index 8df938fc26..98c81fbd8e 100644 --- a/legacy/firmware/crypto.h +++ b/legacy/firmware/crypto.h @@ -88,6 +88,10 @@ int cryptoMultisigPubkeyIndex(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, const uint8_t *pubkey); +uint32_t cryptoMultisigPubkeys(const CoinInfo *coin, + const MultisigRedeemScriptType *multisig, + uint8_t *pubkeys); + int cryptoMultisigFingerprint(const MultisigRedeemScriptType *multisig, uint8_t *hash); @@ -115,5 +119,6 @@ void slip21_from_seed(const uint8_t *seed, int seed_len, Slip21Node *out); void slip21_derive_path(Slip21Node *inout, const uint8_t *label, size_t label_len); const uint8_t *slip21_key(const Slip21Node *node); +bool multisig_uses_single_path(const MultisigRedeemScriptType *multisig); #endif diff --git a/legacy/firmware/transaction.c b/legacy/firmware/transaction.c index 8659dbf4b9..77ae1f7726 100644 --- a/legacy/firmware/transaction.c +++ b/legacy/firmware/transaction.c @@ -373,6 +373,12 @@ uint32_t compile_script_multisig(const CoinInfo *coin, const uint32_t n = cryptoMultisigPubkeyCount(multisig); if (m < 1 || m > 15) return 0; if (n < 1 || n > 15) return 0; + + uint8_t pubkeys[33 * n]; + if (!cryptoMultisigPubkeys(coin, multisig, pubkeys)) { + return 0; + } + uint32_t r = 0; if (out) { out[r] = 0x50 + m; @@ -380,9 +386,7 @@ uint32_t compile_script_multisig(const CoinInfo *coin, for (uint32_t i = 0; i < n; i++) { out[r] = 33; r++; // OP_PUSH 33 - const HDNode *pubnode = cryptoMultisigPubkey(coin, multisig, i); - if (!pubnode) return 0; - memcpy(out + r, pubnode->public_key, 33); + memcpy(out + r, pubkeys + 33 * i, 33); r += 33; } out[r] = 0x50 + n; @@ -409,6 +413,12 @@ uint32_t compile_script_multisig_hash(const CoinInfo *coin, if (m < 1 || m > 15) return 0; if (n < 1 || n > 15) return 0; + // allocate on stack instead of heap + uint8_t pubkeys[33 * n]; + if (!cryptoMultisigPubkeys(coin, multisig, pubkeys)) { + return 0; + } + Hasher hasher = {0}; hasher_Init(&hasher, coin->curve->hasher_script); @@ -418,9 +428,7 @@ uint32_t compile_script_multisig_hash(const CoinInfo *coin, for (uint32_t i = 0; i < n; i++) { d[0] = 33; hasher_Update(&hasher, d, 1); // OP_PUSH 33 - const HDNode *pubnode = cryptoMultisigPubkey(coin, multisig, i); - if (!pubnode) return 0; - hasher_Update(&hasher, pubnode->public_key, 33); + hasher_Update(&hasher, pubkeys + 33 * i, 33); } d[0] = 0x50 + n; d[1] = 0xAE;