mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-26 17:38:39 +00:00
implement GetAddress.multisig field
This commit is contained in:
parent
6561647d6b
commit
92cfcd1565
@ -251,3 +251,14 @@ int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, pb_size_t payload
|
||||
*msg_len = o;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey, uint32_t pubkey_len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < multisig->pubkeys_count; i++) {
|
||||
if (multisig->pubkeys[i].size == pubkey_len && memcmp(multisig->pubkeys[i].bytes, pubkey, pubkey_len) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <secp256k1.h>
|
||||
#include <pb.h>
|
||||
#include "types.pb.h"
|
||||
|
||||
uint32_t ser_length(uint32_t len, uint8_t *out);
|
||||
|
||||
@ -38,4 +39,6 @@ int cryptoMessageEncrypt(curve_point *pubkey, const uint8_t *msg, pb_size_t msg_
|
||||
|
||||
int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, pb_size_t payload_len, const uint8_t *hmac, pb_size_t hmac_len, const uint8_t *privkey, uint8_t *msg, pb_size_t *msg_len, bool *display_only, bool *signing, uint8_t *address_raw);
|
||||
|
||||
int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey, uint32_t pubkey_len);
|
||||
|
||||
#endif
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "crypto.h"
|
||||
#include "base58.h"
|
||||
#include "bip39.h"
|
||||
#include "ripemd160.h"
|
||||
|
||||
// message methods
|
||||
|
||||
@ -487,7 +488,24 @@ void fsm_msgGetAddress(GetAddress *msg)
|
||||
|
||||
fsm_deriveKey(node, msg->address_n, msg->address_n_count);
|
||||
|
||||
ecdsa_get_address(node->public_key, coin->address_type, resp->address);
|
||||
if (msg->has_multisig) {
|
||||
if (cryptoMultisigPubkeyIndex(&(msg->multisig), node->public_key, 33) < 0) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Pubkey not found in multisig script");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
uint8_t buf[32];
|
||||
if (compile_script_multisig_hash(&(msg->multisig), buf) == 0) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Invalid multisig script");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
ripemd160(buf, 32, buf + 1);
|
||||
buf[0] = 0x05; // multisig cointype
|
||||
base58_encode_check(buf, 21, resp->address);
|
||||
} else {
|
||||
ecdsa_get_address(node->public_key, coin->address_type, resp->address);
|
||||
}
|
||||
|
||||
if (msg->has_show_display && msg->show_display) {
|
||||
layoutAddress(resp->address);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "transaction.h"
|
||||
#include "ecdsa.h"
|
||||
#include "protect.h"
|
||||
#include "crypto.h"
|
||||
|
||||
static uint32_t inputs_count;
|
||||
static uint32_t outputs_count;
|
||||
@ -378,14 +379,8 @@ void signing_txack(TransactionType *tx)
|
||||
return;
|
||||
}
|
||||
// fill in the signature
|
||||
int i, pubkey_idx = -1;
|
||||
for (i = 0; i < input.multisig.pubkeys_count; i++) {
|
||||
if (input.multisig.pubkeys[i].size == 33 && memcmp(input.multisig.pubkeys[i].bytes, pubkey, 33) == 0) {
|
||||
pubkey_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pubkey_idx == -1) {
|
||||
int pubkey_idx = cryptoMultisigPubkeyIndex(&(input.multisig), pubkey, 33);
|
||||
if (pubkey_idx < 0) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Pubkey not found in multisig script");
|
||||
signing_abort();
|
||||
return;
|
||||
|
@ -149,8 +149,8 @@ uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8
|
||||
out[r] = 0xAE; r++; // OP_CHECKMULTISIG
|
||||
} else {
|
||||
r++;
|
||||
uint8_t dummy[8];
|
||||
for (i = 0; i < n; i++) {
|
||||
uint8_t dummy[8];
|
||||
r += op_push(multisig->pubkeys[i].size, dummy);
|
||||
r += multisig->pubkeys[i].size;
|
||||
}
|
||||
@ -160,6 +160,36 @@ uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig, uint8_t *hash)
|
||||
{
|
||||
if (!multisig->has_m) return 0;
|
||||
uint32_t m = multisig->m;
|
||||
uint32_t n = multisig->pubkeys_count;
|
||||
if (m < 2 || m > 3) return 0;
|
||||
if (n < 2 || n > 3) return 0;
|
||||
|
||||
SHA256_CTX ctx;
|
||||
sha256_Init(&ctx);
|
||||
|
||||
uint8_t d, dummy[8];
|
||||
d = 0x50 + m;
|
||||
sha256_Update(&ctx, &d, 1);
|
||||
uint32_t i, r;
|
||||
for (i = 0; i < n; i++) {
|
||||
r = op_push(multisig->pubkeys[i].size, dummy);
|
||||
sha256_Update(&ctx, dummy, r);
|
||||
sha256_Update(&ctx, multisig->pubkeys[i].bytes, multisig->pubkeys[i].size);
|
||||
}
|
||||
d = 0x50 + n;
|
||||
sha256_Update(&ctx, &d, 1);
|
||||
d = 0xAE;
|
||||
sha256_Update(&ctx, &d, 1);
|
||||
|
||||
sha256_Final(hash, &ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t serialize_script_sig(const uint8_t *signature, uint32_t signature_len, const uint8_t *pubkey, uint32_t pubkey_len, uint8_t *out)
|
||||
{
|
||||
uint32_t r = 0;
|
||||
|
@ -43,6 +43,7 @@ typedef struct {
|
||||
|
||||
uint32_t compile_script_sig(uint8_t address_type, const uint8_t *pubkeyhash, uint8_t *out);
|
||||
uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t *out);
|
||||
uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig, uint8_t *hash);
|
||||
uint32_t serialize_script_sig(const uint8_t *signature, uint32_t signature_len, const uint8_t *pubkey, uint32_t pubkey_len, uint8_t *out);
|
||||
uint32_t serialize_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t *out);
|
||||
int compile_output(const CoinType *coin, const HDNode *root, TxOutputType *in, TxOutputBinType *out, bool needs_confirm);
|
||||
|
Loading…
Reference in New Issue
Block a user