update to new multisig api

pull/25/head
Pavol Rusnak 10 years ago
parent 961566c9b7
commit 567537cd03

@ -24,6 +24,7 @@
#include "pbkdf2.h"
#include "aes.h"
#include "hmac.h"
#include "bip32.h"
uint32_t ser_length(uint32_t len, uint8_t *out)
{
@ -252,11 +253,22 @@ int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, pb_size_t payload
return 0;
}
int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey, uint32_t pubkey_len)
uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath)
{
static HDNode node;
hdnode_from_xpub(hdnodepath->node.depth, hdnodepath->node.fingerprint, hdnodepath->node.child_num, hdnodepath->node.chain_code.bytes, hdnodepath->node.public_key.bytes, &node);
uint32_t i;
for (i = 0; i < hdnodepath->address_n_count; i++) {
hdnode_public_ckd(&node, hdnodepath->address_n[i]);
}
return node.public_key;
}
int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey)
{
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) {
if (memcmp(cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])), pubkey, 33) == 0) {
return i;
}
}

@ -39,6 +39,9 @@ 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);
uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath);
int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey);
#endif

@ -503,7 +503,7 @@ void fsm_msgGetAddress(GetAddress *msg)
fsm_deriveKey(node, msg->address_n, msg->address_n_count);
if (msg->has_multisig) {
if (cryptoMultisigPubkeyIndex(&(msg->multisig), node->public_key, 33) < 0) {
if (cryptoMultisigPubkeyIndex(&(msg->multisig), node->public_key) < 0) {
fsm_sendFailure(FailureType_Failure_Other, "Pubkey not found in multisig script");
layoutHome();
return;

@ -2,6 +2,8 @@ HDNodeType.chain_code max_size:32
HDNodeType.private_key max_size:32
HDNodeType.public_key max_size:33
HDNodePathType.address_n max_count:8
CoinType.coin_name max_size:17
CoinType.coin_shortcut max_size:9
@ -23,5 +25,5 @@ TxRequestDetailsType.tx_hash max_size:32
TxRequestSerializedType.signature max_size:73
TxRequestSerializedType.serialized_tx max_size:2048
MultisigRedeemScriptType.pubkeys max_count:15 max_size:33
MultisigRedeemScriptType.pubkeys max_count:15
MultisigRedeemScriptType.signatures max_count:15 max_size:73

@ -21,6 +21,12 @@ const pb_field_t HDNodeType_fields[7] = {
PB_LAST_FIELD
};
const pb_field_t HDNodePathType_fields[3] = {
PB_FIELD( 1, MESSAGE , REQUIRED, STATIC , FIRST, HDNodePathType, node, node, &HDNodeType_fields),
PB_FIELD( 2, UINT32 , REPEATED, STATIC , OTHER, HDNodePathType, address_n, node, 0),
PB_LAST_FIELD
};
const pb_field_t CoinType_fields[5] = {
PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, CoinType, coin_name, coin_name, 0),
PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, CoinType, coin_shortcut, coin_name, 0),
@ -30,7 +36,7 @@ const pb_field_t CoinType_fields[5] = {
};
const pb_field_t MultisigRedeemScriptType_fields[4] = {
PB_FIELD( 1, BYTES , REPEATED, STATIC , FIRST, MultisigRedeemScriptType, pubkeys, pubkeys, 0),
PB_FIELD( 1, MESSAGE , REPEATED, STATIC , FIRST, MultisigRedeemScriptType, pubkeys, pubkeys, &HDNodePathType_fields),
PB_FIELD( 2, BYTES , REPEATED, STATIC , OTHER, MultisigRedeemScriptType, signatures, pubkeys, 0),
PB_FIELD( 3, UINT32 , OPTIONAL, STATIC , OTHER, MultisigRedeemScriptType, m, signatures, 0),
PB_LAST_FIELD
@ -47,11 +53,12 @@ const pb_field_t TxInputType_fields[8] = {
PB_LAST_FIELD
};
const pb_field_t TxOutputType_fields[5] = {
const pb_field_t TxOutputType_fields[6] = {
PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, TxOutputType, address, address, 0),
PB_FIELD( 2, UINT32 , REPEATED, STATIC , OTHER, TxOutputType, address_n, address, 0),
PB_FIELD( 3, UINT64 , REQUIRED, STATIC , OTHER, TxOutputType, amount, address_n, 0),
PB_FIELD( 4, ENUM , REQUIRED, STATIC , OTHER, TxOutputType, script_type, amount, 0),
PB_FIELD( 5, MESSAGE , OPTIONAL, STATIC , OTHER, TxOutputType, multisig, script_type, &MultisigRedeemScriptType_fields),
PB_LAST_FIELD
};
@ -147,7 +154,7 @@ const pb_extension_type_t wire_debug_out = {
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(TxInputType, multisig) < 65536 && pb_membersize(TransactionType, inputs[0]) < 65536 && pb_membersize(TransactionType, bin_outputs[0]) < 65536 && pb_membersize(TransactionType, outputs[0]) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_HDNodeType_CoinType_MultisigRedeemScriptType_TxInputType_TxOutputType_TxOutputBinType_TransactionType_TxRequestDetailsType_TxRequestSerializedType)
PB_STATIC_ASSERT((pb_membersize(HDNodePathType, node) < 65536 && pb_membersize(MultisigRedeemScriptType, pubkeys[0]) < 65536 && pb_membersize(TxInputType, multisig) < 65536 && pb_membersize(TxOutputType, multisig) < 65536 && pb_membersize(TransactionType, inputs[0]) < 65536 && pb_membersize(TransactionType, bin_outputs[0]) < 65536 && pb_membersize(TransactionType, outputs[0]) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_HDNodeType_HDNodePathType_CoinType_MultisigRedeemScriptType_TxInputType_TxOutputType_TxOutputBinType_TransactionType_TxRequestDetailsType_TxRequestSerializedType)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)

@ -30,7 +30,8 @@ typedef enum _FailureType {
typedef enum _OutputScriptType {
OutputScriptType_PAYTOADDRESS = 0,
OutputScriptType_PAYTOSCRIPTHASH = 1
OutputScriptType_PAYTOSCRIPTHASH = 1,
OutputScriptType_PAYTOMULTISIG = 2
} OutputScriptType;
typedef enum _InputScriptType {
@ -93,19 +94,6 @@ typedef struct _HDNodeType {
HDNodeType_public_key_t public_key;
} HDNodeType;
typedef PB_BYTES_ARRAY_T(33) MultisigRedeemScriptType_pubkeys_t;
typedef PB_BYTES_ARRAY_T(73) MultisigRedeemScriptType_signatures_t;
typedef struct _MultisigRedeemScriptType {
pb_size_t pubkeys_count;
MultisigRedeemScriptType_pubkeys_t pubkeys[15];
pb_size_t signatures_count;
MultisigRedeemScriptType_signatures_t signatures[15];
bool has_m;
uint32_t m;
} MultisigRedeemScriptType;
typedef PB_BYTES_ARRAY_T(520) TxOutputBinType_script_pubkey_t;
typedef struct _TxOutputBinType {
@ -113,15 +101,6 @@ typedef struct _TxOutputBinType {
TxOutputBinType_script_pubkey_t script_pubkey;
} TxOutputBinType;
typedef struct _TxOutputType {
bool has_address;
char address[35];
pb_size_t address_n_count;
uint32_t address_n[8];
uint64_t amount;
OutputScriptType script_type;
} TxOutputType;
typedef PB_BYTES_ARRAY_T(32) TxRequestDetailsType_tx_hash_t;
typedef struct _TxRequestDetailsType {
@ -144,6 +123,23 @@ typedef struct _TxRequestSerializedType {
TxRequestSerializedType_serialized_tx_t serialized_tx;
} TxRequestSerializedType;
typedef struct _HDNodePathType {
HDNodeType node;
pb_size_t address_n_count;
uint32_t address_n[8];
} HDNodePathType;
typedef PB_BYTES_ARRAY_T(73) MultisigRedeemScriptType_signatures_t;
typedef struct _MultisigRedeemScriptType {
pb_size_t pubkeys_count;
HDNodePathType pubkeys[15];
pb_size_t signatures_count;
MultisigRedeemScriptType_signatures_t signatures[15];
bool has_m;
uint32_t m;
} MultisigRedeemScriptType;
typedef PB_BYTES_ARRAY_T(32) TxInputType_prev_hash_t;
typedef PB_BYTES_ARRAY_T(1650) TxInputType_script_sig_t;
@ -163,6 +159,17 @@ typedef struct _TxInputType {
MultisigRedeemScriptType multisig;
} TxInputType;
typedef struct _TxOutputType {
bool has_address;
char address[35];
pb_size_t address_n_count;
uint32_t address_n[8];
uint64_t amount;
OutputScriptType script_type;
bool has_multisig;
MultisigRedeemScriptType multisig;
} TxOutputType;
typedef struct _TransactionType {
bool has_version;
uint32_t version;
@ -192,19 +199,21 @@ extern const InputScriptType TxInputType_script_type_default;
/* Initializer values for message structs */
#define HDNodeType_init_default {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
#define HDNodePathType_init_default {HDNodeType_init_default, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define CoinType_init_default {false, "", false, "", false, 0, false, 0}
#define MultisigRedeemScriptType_init_default {0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0}
#define MultisigRedeemScriptType_init_default {0, {HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0}
#define TxInputType_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 4294967295u, false, InputScriptType_SPENDADDRESS, false, MultisigRedeemScriptType_init_default}
#define TxOutputType_init_default {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0}
#define TxOutputType_init_default {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0, false, MultisigRedeemScriptType_init_default}
#define TxOutputBinType_init_default {0, {0, {0}}}
#define TransactionType_init_default {false, 0, 0, {TxInputType_init_default}, 0, {TxOutputBinType_init_default}, false, 0, 0, {TxOutputType_init_default}, false, 0, false, 0}
#define TxRequestDetailsType_init_default {false, 0, false, {0, {0}}}
#define TxRequestSerializedType_init_default {false, 0, false, {0, {0}}, false, {0, {0}}}
#define HDNodeType_init_zero {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
#define HDNodePathType_init_zero {HDNodeType_init_zero, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define CoinType_init_zero {false, "", false, "", false, 0, false, 0}
#define MultisigRedeemScriptType_init_zero {0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0}
#define MultisigRedeemScriptType_init_zero {0, {HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0}
#define TxInputType_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 0, false, (InputScriptType)0, false, MultisigRedeemScriptType_init_zero}
#define TxOutputType_init_zero {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0}
#define TxOutputType_init_zero {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0, false, MultisigRedeemScriptType_init_zero}
#define TxOutputBinType_init_zero {0, {0, {0}}}
#define TransactionType_init_zero {false, 0, 0, {TxInputType_init_zero}, 0, {TxOutputBinType_init_zero}, false, 0, 0, {TxOutputType_init_zero}, false, 0, false, 0}
#define TxRequestDetailsType_init_zero {false, 0, false, {0, {0}}}
@ -221,20 +230,18 @@ extern const InputScriptType TxInputType_script_type_default;
#define HDNodeType_chain_code_tag 4
#define HDNodeType_private_key_tag 5
#define HDNodeType_public_key_tag 6
#define MultisigRedeemScriptType_pubkeys_tag 1
#define MultisigRedeemScriptType_signatures_tag 2
#define MultisigRedeemScriptType_m_tag 3
#define TxOutputBinType_amount_tag 1
#define TxOutputBinType_script_pubkey_tag 2
#define TxOutputType_address_tag 1
#define TxOutputType_address_n_tag 2
#define TxOutputType_amount_tag 3
#define TxOutputType_script_type_tag 4
#define TxRequestDetailsType_request_index_tag 1
#define TxRequestDetailsType_tx_hash_tag 2
#define TxRequestSerializedType_signature_index_tag 1
#define TxRequestSerializedType_signature_tag 2
#define TxRequestSerializedType_serialized_tx_tag 3
#define HDNodePathType_node_tag 1
#define HDNodePathType_address_n_tag 2
#define MultisigRedeemScriptType_pubkeys_tag 1
#define MultisigRedeemScriptType_signatures_tag 2
#define MultisigRedeemScriptType_m_tag 3
#define TxInputType_address_n_tag 1
#define TxInputType_prev_hash_tag 2
#define TxInputType_prev_index_tag 3
@ -242,6 +249,11 @@ extern const InputScriptType TxInputType_script_type_default;
#define TxInputType_sequence_tag 5
#define TxInputType_script_type_tag 6
#define TxInputType_multisig_tag 7
#define TxOutputType_address_tag 1
#define TxOutputType_address_n_tag 2
#define TxOutputType_amount_tag 3
#define TxOutputType_script_type_tag 4
#define TxOutputType_multisig_tag 5
#define TransactionType_version_tag 1
#define TransactionType_inputs_tag 2
#define TransactionType_bin_outputs_tag 3
@ -256,10 +268,11 @@ extern const InputScriptType TxInputType_script_type_default;
/* Struct field encoding specification for nanopb */
extern const pb_field_t HDNodeType_fields[7];
extern const pb_field_t HDNodePathType_fields[3];
extern const pb_field_t CoinType_fields[5];
extern const pb_field_t MultisigRedeemScriptType_fields[4];
extern const pb_field_t TxInputType_fields[8];
extern const pb_field_t TxOutputType_fields[5];
extern const pb_field_t TxOutputType_fields[6];
extern const pb_field_t TxOutputBinType_fields[3];
extern const pb_field_t TransactionType_fields[8];
extern const pb_field_t TxRequestDetailsType_fields[3];
@ -267,12 +280,13 @@ extern const pb_field_t TxRequestSerializedType_fields[4];
/* Maximum encoded size of messages (where known) */
#define HDNodeType_size 121
#define HDNodePathType_size 171
#define CoinType_size 47
#define MultisigRedeemScriptType_size 1656
#define TxInputType_size 3412
#define TxOutputType_size 102
#define MultisigRedeemScriptType_size 3741
#define TxInputType_size 5497
#define TxOutputType_size 3846
#define TxOutputBinType_size 534
#define TransactionType_size 4080
#define TransactionType_size 9910
#define TxRequestDetailsType_size 40
#define TxRequestSerializedType_size 2132

@ -379,7 +379,7 @@ void signing_txack(TransactionType *tx)
return;
}
// fill in the signature
int pubkey_idx = cryptoMultisigPubkeyIndex(&(input.multisig), pubkey, 33);
int pubkey_idx = cryptoMultisigPubkeyIndex(&(input.multisig), pubkey);
if (pubkey_idx < 0) {
fsm_sendFailure(FailureType_Failure_Other, "Pubkey not found in multisig script");
signing_abort();

@ -142,20 +142,13 @@ uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8
if (out) {
out[r] = 0x50 + m; r++;
for (i = 0; i < n; i++) {
r += op_push(multisig->pubkeys[i].size, out + r);
memcpy(out + r, multisig->pubkeys[i].bytes, multisig->pubkeys[i].size); r += multisig->pubkeys[i].size;
out[r] = 33; r++; // OP_PUSH 33
memcpy(out + r, cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])), 33); r += 33;
}
out[r] = 0x50 + n; r++;
out[r] = 0xAE; r++; // OP_CHECKMULTISIG
} else {
r++;
uint8_t dummy[8];
for (i = 0; i < n; i++) {
r += op_push(multisig->pubkeys[i].size, dummy);
r += multisig->pubkeys[i].size;
}
r++;
r++;
r = 1 + 34 * n + 2;
}
return r;
}
@ -171,19 +164,15 @@ uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig,
SHA256_CTX ctx;
sha256_Init(&ctx);
uint8_t d, dummy[8];
d = 0x50 + m;
sha256_Update(&ctx, &d, 1);
uint32_t i, r;
uint8_t d;
d = 0x50 + m; sha256_Update(&ctx, &d, 1);
uint32_t i;
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 = 33; sha256_Update(&ctx, &d, 1); // OP_PUSH 33
sha256_Update(&ctx, cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])), 33);
}
d = 0x50 + n;
sha256_Update(&ctx, &d, 1);
d = 0xAE;
sha256_Update(&ctx, &d, 1);
d = 0x50 + n; sha256_Update(&ctx, &d, 1);
d = 0xAE; sha256_Update(&ctx, &d, 1);
sha256_Final(hash, &ctx);

@ -1 +1 @@
Subproject commit 40b3cb414864f970d627651f8be0669be95c5efc
Subproject commit 94d17ef8bc56d7c0e6ddfed39e84987543259e05

@ -1 +1 @@
Subproject commit b4cdba8489201e623b948469609a48495f2eeed2
Subproject commit 10a92c3c6276d5b1955331b7a33ebe9d6a32c37e
Loading…
Cancel
Save