coins: Use curve_info instead of HasherType
This commit is contained in:
parent
268e7de109
commit
6e25e0b363
|
@ -29,7 +29,7 @@ def get_fields(coin):
|
||||||
'%d' % coin['forkid'] if coin['forkid'] else '0',
|
'%d' % coin['forkid'] if coin['forkid'] else '0',
|
||||||
'"%s"' % coin['bech32_prefix'] if coin.get('bech32_prefix') is not None else 'NULL',
|
'"%s"' % coin['bech32_prefix'] if coin.get('bech32_prefix') is not None else 'NULL',
|
||||||
'0x%08x' % (0x80000000 + coin['bip44']),
|
'0x%08x' % (0x80000000 + coin['bip44']),
|
||||||
'HASHER_SHA2',
|
'&%s_info' % 'secp256k1',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "address.h"
|
#include "address.h"
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
|
#include "secp256k1.h"
|
||||||
|
|
||||||
// filled CoinInfo structure defined in coins.h
|
// filled CoinInfo structure defined in coins.h
|
||||||
const CoinInfo coins[COINS_COUNT] = {
|
const CoinInfo coins[COINS_COUNT] = {
|
||||||
|
@ -63,7 +64,7 @@ bool coinExtractAddressType(const CoinInfo *coin, const char *addr, uint32_t *ad
|
||||||
{
|
{
|
||||||
if (!addr) return false;
|
if (!addr) return false;
|
||||||
uint8_t addr_raw[MAX_ADDR_RAW_SIZE];
|
uint8_t addr_raw[MAX_ADDR_RAW_SIZE];
|
||||||
int len = base58_decode_check(addr, coin->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
int len = base58_decode_check(addr, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
||||||
if (len >= 21) {
|
if (len >= 21) {
|
||||||
return coinExtractAddressTypeRaw(coin, addr_raw, address_type);
|
return coinExtractAddressTypeRaw(coin, addr_raw, address_type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "bip32.h"
|
||||||
#include "coins_count.h"
|
#include "coins_count.h"
|
||||||
#include "hasher.h"
|
#include "hasher.h"
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ typedef struct _CoinInfo {
|
||||||
uint32_t forkid;
|
uint32_t forkid;
|
||||||
const char *bech32_prefix;
|
const char *bech32_prefix;
|
||||||
uint32_t coin_type;
|
uint32_t coin_type;
|
||||||
HasherType hasher_type;
|
const curve_info *curve;
|
||||||
} CoinInfo;
|
} CoinInfo;
|
||||||
|
|
||||||
extern const CoinInfo coins[COINS_COUNT];
|
extern const CoinInfo coins[COINS_COUNT];
|
||||||
|
|
|
@ -114,7 +114,7 @@ int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uin
|
||||||
|
|
||||||
static void cryptoMessageHash(const CoinInfo *coin, const uint8_t *message, size_t message_len, uint8_t hash[HASHER_DIGEST_LENGTH]) {
|
static void cryptoMessageHash(const CoinInfo *coin, const uint8_t *message, size_t message_len, uint8_t hash[HASHER_DIGEST_LENGTH]) {
|
||||||
Hasher hasher;
|
Hasher hasher;
|
||||||
hasher_Init(&hasher, coin->hasher_type);
|
hasher_Init(&hasher, coin->curve->hasher_type);
|
||||||
hasher_Update(&hasher, (const uint8_t *)coin->signed_message_header, strlen(coin->signed_message_header));
|
hasher_Update(&hasher, (const uint8_t *)coin->signed_message_header, strlen(coin->signed_message_header));
|
||||||
uint8_t varint[5];
|
uint8_t varint[5];
|
||||||
uint32_t l = ser_length(message_len, varint);
|
uint32_t l = ser_length(message_len, varint);
|
||||||
|
@ -178,8 +178,8 @@ int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t mes
|
||||||
|
|
||||||
// p2pkh
|
// p2pkh
|
||||||
if (signature[0] >= 27 && signature[0] <= 34) {
|
if (signature[0] >= 27 && signature[0] <= 34) {
|
||||||
size_t len = base58_decode_check(address, coin->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
size_t len = base58_decode_check(address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
||||||
ecdsa_get_address_raw(pubkey, coin->address_type, coin->hasher_type, recovered_raw);
|
ecdsa_get_address_raw(pubkey, coin->address_type, coin->curve->hasher_type, recovered_raw);
|
||||||
if (memcmp(recovered_raw, addr_raw, len) != 0
|
if (memcmp(recovered_raw, addr_raw, len) != 0
|
||||||
|| len != address_prefix_bytes_len(coin->address_type) + 20) {
|
|| len != address_prefix_bytes_len(coin->address_type) + 20) {
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -187,8 +187,8 @@ int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t mes
|
||||||
} else
|
} else
|
||||||
// segwit-in-p2sh
|
// segwit-in-p2sh
|
||||||
if (signature[0] >= 35 && signature[0] <= 38) {
|
if (signature[0] >= 35 && signature[0] <= 38) {
|
||||||
size_t len = base58_decode_check(address, coin->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
size_t len = base58_decode_check(address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
||||||
ecdsa_get_address_segwit_p2sh_raw(pubkey, coin->address_type_p2sh, coin->hasher_type, recovered_raw);
|
ecdsa_get_address_segwit_p2sh_raw(pubkey, coin->address_type_p2sh, coin->curve->hasher_type, recovered_raw);
|
||||||
if (memcmp(recovered_raw, addr_raw, len) != 0
|
if (memcmp(recovered_raw, addr_raw, len) != 0
|
||||||
|| len != address_prefix_bytes_len(coin->address_type_p2sh) + 20) {
|
|| len != address_prefix_bytes_len(coin->address_type_p2sh) + 20) {
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -202,7 +202,7 @@ int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t mes
|
||||||
|| !segwit_addr_decode(&witver, recovered_raw, &len, coin->bech32_prefix, address)) {
|
|| !segwit_addr_decode(&witver, recovered_raw, &len, coin->bech32_prefix, address)) {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
ecdsa_get_pubkeyhash(pubkey, coin->hasher_type, addr_raw);
|
ecdsa_get_pubkeyhash(pubkey, coin->curve->hasher_type, addr_raw);
|
||||||
if (memcmp(recovered_raw, addr_raw, len) != 0
|
if (memcmp(recovered_raw, addr_raw, len) != 0
|
||||||
|| witver != 0 || len != 20) {
|
|| witver != 0 || len != 20) {
|
||||||
return 2;
|
return 2;
|
||||||
|
|
|
@ -424,7 +424,7 @@ bool compile_input_script_sig(TxInputType *tinput)
|
||||||
tinput->script_sig.size = compile_script_multisig(&(tinput->multisig), tinput->script_sig.bytes);
|
tinput->script_sig.size = compile_script_multisig(&(tinput->multisig), tinput->script_sig.bytes);
|
||||||
} else { // SPENDADDRESS
|
} else { // SPENDADDRESS
|
||||||
uint8_t hash[20];
|
uint8_t hash[20];
|
||||||
ecdsa_get_pubkeyhash(node.public_key, coin->hasher_type, hash);
|
ecdsa_get_pubkeyhash(node.public_key, coin->curve->hasher_type, hash);
|
||||||
tinput->script_sig.size = compile_script_sig(coin->address_type, hash, tinput->script_sig.bytes);
|
tinput->script_sig.size = compile_script_sig(coin->address_type, hash, tinput->script_sig.bytes);
|
||||||
}
|
}
|
||||||
return tinput->script_sig.size > 0;
|
return tinput->script_sig.size > 0;
|
||||||
|
@ -463,11 +463,11 @@ void signing_init(uint32_t _inputs_count, uint32_t _outputs_count, const CoinInf
|
||||||
multisig_fp_mismatch = false;
|
multisig_fp_mismatch = false;
|
||||||
next_nonsegwit_input = 0xffffffff;
|
next_nonsegwit_input = 0xffffffff;
|
||||||
|
|
||||||
tx_init(&to, inputs_count, outputs_count, version, lock_time, 0, coin->hasher_type);
|
tx_init(&to, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type);
|
||||||
// segwit hashes for hashPrevouts and hashSequence
|
// segwit hashes for hashPrevouts and hashSequence
|
||||||
hasher_Init(&hashers[0], coin->hasher_type);
|
hasher_Init(&hashers[0], coin->curve->hasher_type);
|
||||||
hasher_Init(&hashers[1], coin->hasher_type);
|
hasher_Init(&hashers[1], coin->curve->hasher_type);
|
||||||
hasher_Init(&hashers[2], coin->hasher_type);
|
hasher_Init(&hashers[2], coin->curve->hasher_type);
|
||||||
|
|
||||||
layoutProgressSwipe(_("Signing transaction"), 0);
|
layoutProgressSwipe(_("Signing transaction"), 0);
|
||||||
|
|
||||||
|
@ -883,7 +883,7 @@ void signing_txack(TransactionType *tx)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case STAGE_REQUEST_2_PREV_META:
|
case STAGE_REQUEST_2_PREV_META:
|
||||||
tx_init(&tp, tx->inputs_cnt, tx->outputs_cnt, tx->version, tx->lock_time, tx->extra_data_len, coin->hasher_type);
|
tx_init(&tp, tx->inputs_cnt, tx->outputs_cnt, tx->version, tx->lock_time, tx->extra_data_len, coin->curve->hasher_type);
|
||||||
progress_meta_step = progress_step / (tp.inputs_len + tp.outputs_len);
|
progress_meta_step = progress_step / (tp.inputs_len + tp.outputs_len);
|
||||||
idx2 = 0;
|
idx2 = 0;
|
||||||
if (tp.inputs_len > 0) {
|
if (tp.inputs_len > 0) {
|
||||||
|
@ -957,7 +957,7 @@ void signing_txack(TransactionType *tx)
|
||||||
case STAGE_REQUEST_4_INPUT:
|
case STAGE_REQUEST_4_INPUT:
|
||||||
progress = 500 + ((signatures * progress_step + idx2 * progress_meta_step) >> PROGRESS_PRECISION);
|
progress = 500 + ((signatures * progress_step + idx2 * progress_meta_step) >> PROGRESS_PRECISION);
|
||||||
if (idx2 == 0) {
|
if (idx2 == 0) {
|
||||||
tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, coin->hasher_type);
|
tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type);
|
||||||
hasher_Reset(&hashers[0]);
|
hasher_Reset(&hashers[0]);
|
||||||
}
|
}
|
||||||
// check prevouts and script type
|
// check prevouts and script type
|
||||||
|
@ -1091,7 +1091,7 @@ void signing_txack(TransactionType *tx)
|
||||||
tx->inputs[0].script_sig.bytes[1] = 0x00; // witness 0 script
|
tx->inputs[0].script_sig.bytes[1] = 0x00; // witness 0 script
|
||||||
tx->inputs[0].script_sig.bytes[2] = 0x20; // push 32 bytes (digest)
|
tx->inputs[0].script_sig.bytes[2] = 0x20; // push 32 bytes (digest)
|
||||||
// compute digest of multisig script
|
// compute digest of multisig script
|
||||||
if (!compile_script_multisig_hash(&tx->inputs[0].multisig, coin->hasher_type, tx->inputs[0].script_sig.bytes + 3)) {
|
if (!compile_script_multisig_hash(&tx->inputs[0].multisig, coin->curve->hasher_type, tx->inputs[0].script_sig.bytes + 3)) {
|
||||||
fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input"));
|
fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input"));
|
||||||
signing_abort();
|
signing_abort();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -97,7 +97,7 @@ bool compute_address(const CoinInfo *coin,
|
||||||
if (cryptoMultisigPubkeyIndex(multisig, node->public_key) < 0) {
|
if (cryptoMultisigPubkeyIndex(multisig, node->public_key) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (compile_script_multisig_hash(multisig, coin->hasher_type, digest) == 0) {
|
if (compile_script_multisig_hash(multisig, coin->curve->hasher_type, digest) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (script_type == InputScriptType_SPENDWITNESS) {
|
if (script_type == InputScriptType_SPENDWITNESS) {
|
||||||
|
@ -119,11 +119,11 @@ bool compute_address(const CoinInfo *coin,
|
||||||
raw[0] = 0; // push version
|
raw[0] = 0; // push version
|
||||||
raw[1] = 32; // push 32 bytes
|
raw[1] = 32; // push 32 bytes
|
||||||
memcpy(raw+2, digest, 32); // push hash
|
memcpy(raw+2, digest, 32); // push hash
|
||||||
hasher_Raw(coin->hasher_type, raw, 34, digest);
|
hasher_Raw(coin->curve->hasher_type, raw, 34, digest);
|
||||||
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
|
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
|
||||||
address_write_prefix_bytes(coin->address_type_p2sh, raw);
|
address_write_prefix_bytes(coin->address_type_p2sh, raw);
|
||||||
ripemd160(digest, 32, raw + prelen);
|
ripemd160(digest, 32, raw + prelen);
|
||||||
if (!base58_encode_check(raw, prelen + 20, coin->hasher_type, address, MAX_ADDR_SIZE)) {
|
if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_type, address, MAX_ADDR_SIZE)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -131,7 +131,7 @@ bool compute_address(const CoinInfo *coin,
|
||||||
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
|
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
|
||||||
address_write_prefix_bytes(coin->address_type_p2sh, raw);
|
address_write_prefix_bytes(coin->address_type_p2sh, raw);
|
||||||
ripemd160(digest, 32, raw + prelen);
|
ripemd160(digest, 32, raw + prelen);
|
||||||
if (!base58_encode_check(raw, prelen + 20, coin->hasher_type, address, MAX_ADDR_SIZE)) {
|
if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_type, address, MAX_ADDR_SIZE)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ bool compute_address(const CoinInfo *coin,
|
||||||
if (!coin->has_segwit || !coin->bech32_prefix) {
|
if (!coin->has_segwit || !coin->bech32_prefix) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ecdsa_get_pubkeyhash(node->public_key, coin->hasher_type, digest);
|
ecdsa_get_pubkeyhash(node->public_key, coin->curve->hasher_type, digest);
|
||||||
if (!segwit_addr_encode(address, coin->bech32_prefix, SEGWIT_VERSION_0, digest, 20)) {
|
if (!segwit_addr_encode(address, coin->bech32_prefix, SEGWIT_VERSION_0, digest, 20)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -152,9 +152,9 @@ bool compute_address(const CoinInfo *coin,
|
||||||
if (!coin->has_address_type_p2sh) {
|
if (!coin->has_address_type_p2sh) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ecdsa_get_address_segwit_p2sh(node->public_key, coin->address_type_p2sh, coin->hasher_type, address, MAX_ADDR_SIZE);
|
ecdsa_get_address_segwit_p2sh(node->public_key, coin->address_type_p2sh, coin->curve->hasher_type, address, MAX_ADDR_SIZE);
|
||||||
} else {
|
} else {
|
||||||
ecdsa_get_address(node->public_key, coin->address_type, coin->hasher_type, address, MAX_ADDR_SIZE);
|
ecdsa_get_address(node->public_key, coin->address_type, coin->curve->hasher_type, address, MAX_ADDR_SIZE);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ int compile_output(const CoinInfo *coin, const HDNode *root, TxOutputType *in, T
|
||||||
return 0; // failed to compile output
|
return 0; // failed to compile output
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_raw_len = base58_decode_check(in->address, coin->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
addr_raw_len = base58_decode_check(in->address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
||||||
size_t prefix_len;
|
size_t prefix_len;
|
||||||
if (coin->has_address_type // p2pkh
|
if (coin->has_address_type // p2pkh
|
||||||
&& address_check_prefix(addr_raw, coin->address_type)
|
&& address_check_prefix(addr_raw, coin->address_type)
|
||||||
|
@ -639,7 +639,7 @@ uint32_t tx_output_weight(const CoinInfo *coin, const TxOutputType *txoutput) {
|
||||||
&& segwit_addr_decode(&witver, addr_raw, &addr_raw_len, coin->bech32_prefix, txoutput->address)) {
|
&& segwit_addr_decode(&witver, addr_raw, &addr_raw_len, coin->bech32_prefix, txoutput->address)) {
|
||||||
output_script_size = 2 + addr_raw_len;
|
output_script_size = 2 + addr_raw_len;
|
||||||
} else {
|
} else {
|
||||||
addr_raw_len = base58_decode_check(txoutput->address, coin->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
addr_raw_len = base58_decode_check(txoutput->address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE);
|
||||||
if (coin->has_address_type
|
if (coin->has_address_type
|
||||||
&& address_check_prefix(addr_raw, coin->address_type)) {
|
&& address_check_prefix(addr_raw, coin->address_type)) {
|
||||||
output_script_size = TXSIZE_P2PKHASH;
|
output_script_size = TXSIZE_P2PKHASH;
|
||||||
|
|
Loading…
Reference in New Issue