mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 07:28:10 +00:00
BIP-32 without gaps, prepare non-ecdsa curves
* Split ecdsa_curve into curve_info and ecdsa_curve to support bip32 on curves that don't have a ecdsa_curve. * Don't fail in key derivation but retry with a new hash. * Adapted test case accordingly
This commit is contained in:
parent
de30ffbf9a
commit
698f40f385
177
bip32.c
177
bip32.c
@ -1,6 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
* Copyright (c) 2013-2016 Tomas Dzetkulic
|
||||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
* Copyright (c) 2013-2016 Pavol Rusnak
|
||||||
|
* Copyright (c) 2015-2016 Jochen Hoenicke
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the "Software"),
|
* a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -33,17 +34,18 @@
|
|||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "secp256k1.h"
|
#include "secp256k1.h"
|
||||||
|
#include "nist256p1.h"
|
||||||
|
|
||||||
int hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char* curve, HDNode *out)
|
int hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char* curve, HDNode *out)
|
||||||
{
|
{
|
||||||
const ecdsa_curve *curve_info = get_curve_by_name(curve);
|
const curve_info *info = get_curve_by_name(curve);
|
||||||
if (curve_info == 0) {
|
if (info == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (public_key[0] != 0x02 && public_key[0] != 0x03) { // invalid pubkey
|
if (public_key[0] != 0x02 && public_key[0] != 0x03) { // invalid pubkey
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
out->curve = curve_info;
|
out->curve = info;
|
||||||
out->depth = depth;
|
out->depth = depth;
|
||||||
out->fingerprint = fingerprint;
|
out->fingerprint = fingerprint;
|
||||||
out->child_num = child_num;
|
out->child_num = child_num;
|
||||||
@ -55,18 +57,19 @@ int hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, c
|
|||||||
|
|
||||||
int hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, const char* curve, HDNode *out)
|
int hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, const char* curve, HDNode *out)
|
||||||
{
|
{
|
||||||
bignum256 a;
|
|
||||||
bn_read_be(private_key, &a);
|
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
const ecdsa_curve *curve_info = get_curve_by_name(curve);
|
const curve_info *info = get_curve_by_name(curve);
|
||||||
if (curve_info == 0) {
|
if (info == 0) {
|
||||||
failed = true;
|
|
||||||
} else if (bn_is_zero(&a)) { // == 0
|
|
||||||
failed = true;
|
failed = true;
|
||||||
} else {
|
} else {
|
||||||
if (!bn_is_less(&a, &out->curve->order)) { // >= order
|
bignum256 a;
|
||||||
|
bn_read_be(private_key, &a);
|
||||||
|
if (bn_is_zero(&a)) { // == 0
|
||||||
failed = true;
|
failed = true;
|
||||||
|
} else {
|
||||||
|
if (!bn_is_less(&a, &info->params->order)) { // >= order
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MEMSET_BZERO(&a, sizeof(a));
|
MEMSET_BZERO(&a, sizeof(a));
|
||||||
}
|
}
|
||||||
@ -75,7 +78,7 @@ int hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, c
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->curve = curve_info;
|
out->curve = info;
|
||||||
out->depth = depth;
|
out->depth = depth;
|
||||||
out->fingerprint = fingerprint;
|
out->fingerprint = fingerprint;
|
||||||
out->child_num = child_num;
|
out->child_num = child_num;
|
||||||
@ -98,27 +101,27 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNod
|
|||||||
}
|
}
|
||||||
hmac_sha512((const uint8_t*) out->curve->bip32_name,
|
hmac_sha512((const uint8_t*) out->curve->bip32_name,
|
||||||
strlen(out->curve->bip32_name), seed, seed_len, I);
|
strlen(out->curve->bip32_name), seed, seed_len, I);
|
||||||
memcpy(out->private_key, I, 32);
|
|
||||||
bignum256 a;
|
|
||||||
bn_read_be(out->private_key, &a);
|
|
||||||
|
|
||||||
bool failed = false;
|
if (out->curve->params) {
|
||||||
if (bn_is_zero(&a)) { // == 0
|
bignum256 a;
|
||||||
failed = true;
|
while (true) {
|
||||||
} else {
|
bn_read_be(I, &a);
|
||||||
if (!bn_is_less(&a, &out->curve->order)) { // >= order
|
if (!bn_is_zero(&a) // != 0
|
||||||
failed = true;
|
&& bn_is_less(&a, &out->curve->params->order)) { // < order
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hmac_sha512((const uint8_t*) out->curve->bip32_name,
|
||||||
|
strlen(out->curve->bip32_name), I, sizeof(I), I);
|
||||||
}
|
}
|
||||||
MEMSET_BZERO(&a, sizeof(a));
|
MEMSET_BZERO(&a, sizeof(a));
|
||||||
}
|
}
|
||||||
|
memcpy(out->private_key, I, 32);
|
||||||
if (!failed) {
|
memcpy(out->chain_code, I + 32, 32);
|
||||||
memcpy(out->chain_code, I + 32, 32);
|
hdnode_fill_public_key(out);
|
||||||
hdnode_fill_public_key(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
MEMSET_BZERO(I, sizeof(I));
|
MEMSET_BZERO(I, sizeof(I));
|
||||||
return failed ? 0 : 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdnode_private_ckd(HDNode *inout, uint32_t i)
|
int hdnode_private_ckd(HDNode *inout, uint32_t i)
|
||||||
@ -132,6 +135,9 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i)
|
|||||||
data[0] = 0;
|
data[0] = 0;
|
||||||
memcpy(data + 1, inout->private_key, 32);
|
memcpy(data + 1, inout->private_key, 32);
|
||||||
} else { // public derivation
|
} else { // public derivation
|
||||||
|
if (!inout->curve->params) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
memcpy(data, inout->public_key, 33);
|
memcpy(data, inout->public_key, 33);
|
||||||
}
|
}
|
||||||
write_be(data + 33, i);
|
write_be(data + 33, i);
|
||||||
@ -143,29 +149,37 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i)
|
|||||||
bn_read_be(inout->private_key, &a);
|
bn_read_be(inout->private_key, &a);
|
||||||
|
|
||||||
hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
|
hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
|
||||||
memcpy(inout->chain_code, I + 32, 32);
|
if (inout->curve->params) {
|
||||||
memcpy(inout->private_key, I, 32);
|
while (true) {
|
||||||
|
bool failed = false;
|
||||||
|
bn_read_be(I, &b);
|
||||||
|
if (!bn_is_less(&b, &inout->curve->params->order)) { // >= order
|
||||||
|
failed = true;
|
||||||
|
} else {
|
||||||
|
bn_addmod(&b, &a, &inout->curve->params->order);
|
||||||
|
bn_mod(&b, &inout->curve->params->order);
|
||||||
|
if (bn_is_zero(&b)) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failed) {
|
||||||
|
bn_write_be(&b, inout->private_key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
bn_read_be(inout->private_key, &b);
|
data[0] = 1;
|
||||||
|
memcpy(data + 1, I + 32, 32);
|
||||||
bool failed = false;
|
hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
|
||||||
|
|
||||||
if (!bn_is_less(&b, &inout->curve->order)) { // >= order
|
|
||||||
failed = true;
|
|
||||||
}
|
|
||||||
if (!failed) {
|
|
||||||
bn_addmod(&a, &b, &inout->curve->order);
|
|
||||||
bn_mod(&a, &inout->curve->order);
|
|
||||||
if (bn_is_zero(&a)) {
|
|
||||||
failed = true;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(inout->private_key, I, 32);
|
||||||
}
|
}
|
||||||
if (!failed) {
|
|
||||||
inout->depth++;
|
memcpy(inout->chain_code, I + 32, 32);
|
||||||
inout->child_num = i;
|
inout->depth++;
|
||||||
bn_write_be(&a, inout->private_key);
|
inout->child_num = i;
|
||||||
hdnode_fill_public_key(inout);
|
hdnode_fill_public_key(inout);
|
||||||
}
|
|
||||||
|
|
||||||
// making sure to wipe our memory
|
// making sure to wipe our memory
|
||||||
MEMSET_BZERO(&a, sizeof(a));
|
MEMSET_BZERO(&a, sizeof(a));
|
||||||
@ -173,7 +187,7 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i)
|
|||||||
MEMSET_BZERO(I, sizeof(I));
|
MEMSET_BZERO(I, sizeof(I));
|
||||||
MEMSET_BZERO(fingerprint, sizeof(fingerprint));
|
MEMSET_BZERO(fingerprint, sizeof(fingerprint));
|
||||||
MEMSET_BZERO(data, sizeof(data));
|
MEMSET_BZERO(data, sizeof(data));
|
||||||
return failed ? 0 : 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdnode_public_ckd(HDNode *inout, uint32_t i)
|
int hdnode_public_ckd(HDNode *inout, uint32_t i)
|
||||||
@ -187,6 +201,9 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i)
|
|||||||
if (i & 0x80000000) { // private derivation
|
if (i & 0x80000000) { // private derivation
|
||||||
return 0;
|
return 0;
|
||||||
} else { // public derivation
|
} else { // public derivation
|
||||||
|
if (!inout->curve->params) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
memcpy(data, inout->public_key, 33);
|
memcpy(data, inout->public_key, 33);
|
||||||
}
|
}
|
||||||
write_be(data + 33, i);
|
write_be(data + 33, i);
|
||||||
@ -197,34 +214,37 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i)
|
|||||||
|
|
||||||
memset(inout->private_key, 0, 32);
|
memset(inout->private_key, 0, 32);
|
||||||
|
|
||||||
bool failed = false;
|
if (!ecdsa_read_pubkey(inout->curve->params, inout->public_key, &a)) {
|
||||||
if (!ecdsa_read_pubkey(inout->curve, inout->public_key, &a)) {
|
return 0;
|
||||||
failed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!failed) {
|
while (true) {
|
||||||
|
bool failed = false;
|
||||||
hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
|
hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
|
||||||
memcpy(inout->chain_code, I + 32, 32);
|
|
||||||
bn_read_be(I, &c);
|
bn_read_be(I, &c);
|
||||||
if (!bn_is_less(&c, &inout->curve->order)) { // >= order
|
if (!bn_is_less(&c, &inout->curve->params->order)) { // >= order
|
||||||
failed = true;
|
failed = true;
|
||||||
|
} else {
|
||||||
|
scalar_multiply(inout->curve->params, &c, &b); // b = c * G
|
||||||
|
point_add(inout->curve->params, &a, &b); // b = a + b
|
||||||
|
if (point_is_infinity(&b)) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!failed) {
|
||||||
|
inout->public_key[0] = 0x02 | (b.y.val[0] & 0x01);
|
||||||
|
bn_write_be(&b.x, inout->public_key + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[0] = 1;
|
||||||
|
memcpy(data + 1, I + 32, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!failed) {
|
inout->depth++;
|
||||||
scalar_multiply(inout->curve, &c, &b); // b = c * G
|
inout->child_num = i;
|
||||||
point_add(inout->curve, &a, &b); // b = a + b
|
memcpy(inout->chain_code, I + 32, 32);
|
||||||
if (!ecdsa_validate_pubkey(inout->curve, &b)) {
|
|
||||||
failed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!failed) {
|
|
||||||
inout->public_key[0] = 0x02 | (b.y.val[0] & 0x01);
|
|
||||||
bn_write_be(&b.x, inout->public_key + 1);
|
|
||||||
inout->depth++;
|
|
||||||
inout->child_num = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wipe all stack data.
|
// Wipe all stack data.
|
||||||
MEMSET_BZERO(data, sizeof(data));
|
MEMSET_BZERO(data, sizeof(data));
|
||||||
@ -234,7 +254,7 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i)
|
|||||||
MEMSET_BZERO(&b, sizeof(b));
|
MEMSET_BZERO(&b, sizeof(b));
|
||||||
MEMSET_BZERO(&c, sizeof(c));
|
MEMSET_BZERO(&c, sizeof(c));
|
||||||
|
|
||||||
return failed ? 0 : 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_BIP32_CACHE
|
#if USE_BIP32_CACHE
|
||||||
@ -308,7 +328,7 @@ int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count)
|
|||||||
|
|
||||||
void hdnode_fill_public_key(HDNode *node)
|
void hdnode_fill_public_key(HDNode *node)
|
||||||
{
|
{
|
||||||
ecdsa_get_public_key33(node->curve, node->private_key, node->public_key);
|
ecdsa_get_public_key33(node->curve->params, node->private_key, node->public_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdnode_serialize(const HDNode *node, uint32_t version, char use_public, char *str, int strsize)
|
void hdnode_serialize(const HDNode *node, uint32_t version, char use_public, char *str, int strsize)
|
||||||
@ -367,3 +387,16 @@ int hdnode_deserialize(const char *str, HDNode *node)
|
|||||||
memcpy(node->chain_code, node_data + 13, 32);
|
memcpy(node->chain_code, node_data + 13, 32);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const curve_info *get_curve_by_name(const char *curve_name) {
|
||||||
|
if (curve_name == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (strcmp(curve_name, SECP256K1_NAME) == 0) {
|
||||||
|
return &secp256k1_info;
|
||||||
|
}
|
||||||
|
if (strcmp(curve_name, NIST256P1_NAME) == 0) {
|
||||||
|
return &nist256p1_info;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
9
bip32.h
9
bip32.h
@ -29,6 +29,11 @@
|
|||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *bip32_name; // string for generating BIP32 xprv from seed
|
||||||
|
const ecdsa_curve *params; // ecdsa curve parameters, null for ed25519
|
||||||
|
} curve_info;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t depth;
|
uint32_t depth;
|
||||||
uint32_t fingerprint;
|
uint32_t fingerprint;
|
||||||
@ -36,7 +41,7 @@ typedef struct {
|
|||||||
uint8_t chain_code[32];
|
uint8_t chain_code[32];
|
||||||
uint8_t private_key[32];
|
uint8_t private_key[32];
|
||||||
uint8_t public_key[33];
|
uint8_t public_key[33];
|
||||||
const ecdsa_curve *curve;
|
const curve_info *curve;
|
||||||
} HDNode;
|
} HDNode;
|
||||||
|
|
||||||
int hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char *curve, HDNode *out);
|
int hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char *curve, HDNode *out);
|
||||||
@ -68,4 +73,6 @@ int hdnode_deserialize(const char *str, HDNode *node);
|
|||||||
// Private
|
// Private
|
||||||
void hdnode_serialize(const HDNode *node, uint32_t version, char use_public, char *str, int strsize);
|
void hdnode_serialize(const HDNode *node, uint32_t version, char use_public, char *str, int strsize);
|
||||||
|
|
||||||
|
const curve_info *get_curve_by_name(const char *curve_name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
17
ecdsa.c
17
ecdsa.c
@ -36,9 +36,6 @@
|
|||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|
||||||
#include "secp256k1.h"
|
|
||||||
#include "nist256p1.h"
|
|
||||||
|
|
||||||
// Set cp2 = cp1
|
// Set cp2 = cp1
|
||||||
void point_copy(const curve_point *cp1, curve_point *cp2)
|
void point_copy(const curve_point *cp1, curve_point *cp2)
|
||||||
{
|
{
|
||||||
@ -1044,17 +1041,3 @@ int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der)
|
|||||||
*len = *len1 + *len2 + 4;
|
*len = *len1 + *len2 + 4;
|
||||||
return *len + 2;
|
return *len + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ecdsa_curve *get_curve_by_name(const char *curve_name) {
|
|
||||||
if (curve_name == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (strcmp(curve_name, SECP256K1_NAME) == 0) {
|
|
||||||
return &secp256k1;
|
|
||||||
}
|
|
||||||
if (strcmp(curve_name, NIST256P1_NAME) == 0) {
|
|
||||||
return &nist256p1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
2
ecdsa.h
2
ecdsa.h
@ -41,7 +41,6 @@ typedef struct {
|
|||||||
bignum256 order_half; // order of G divided by 2
|
bignum256 order_half; // order of G divided by 2
|
||||||
int a; // coefficient 'a' of the elliptic curve
|
int a; // coefficient 'a' of the elliptic curve
|
||||||
bignum256 b; // coefficient 'b' of the elliptic curve
|
bignum256 b; // coefficient 'b' of the elliptic curve
|
||||||
const char *bip32_name;// string used for generating BIP32 xprv from seed
|
|
||||||
|
|
||||||
#if USE_PRECOMPUTED_CP
|
#if USE_PRECOMPUTED_CP
|
||||||
const curve_point cp[64][8];
|
const curve_point cp[64][8];
|
||||||
@ -77,7 +76,6 @@ int ecdsa_verify(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t
|
|||||||
int ecdsa_verify_double(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len);
|
int ecdsa_verify_double(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len);
|
||||||
int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest);
|
int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest);
|
||||||
int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der);
|
int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der);
|
||||||
const ecdsa_curve *get_curve_by_name(const char *curve_name);
|
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
int generate_k_rfc6979(const ecdsa_curve *curve, bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash);
|
int generate_k_rfc6979(const ecdsa_curve *curve, bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash);
|
||||||
|
11
nist256p1.c
11
nist256p1.c
@ -46,10 +46,7 @@ const ecdsa_curve nist256p1 = {
|
|||||||
|
|
||||||
/* b */ {
|
/* b */ {
|
||||||
/*.val =*/{0x27d2604b, 0x2f38f0f8, 0x53b0f63, 0x741ac33, 0x1886bc65, 0x2ef555da, 0x293e7b3e, 0xd762a8e, 0x5ac6}
|
/*.val =*/{0x27d2604b, 0x2f38f0f8, 0x53b0f63, 0x741ac33, 0x1886bc65, 0x2ef555da, 0x293e7b3e, 0xd762a8e, 0x5ac6}
|
||||||
},
|
}
|
||||||
|
|
||||||
/* bip32_name */
|
|
||||||
"Nist256p1 seed"
|
|
||||||
|
|
||||||
#if USE_PRECOMPUTED_CP
|
#if USE_PRECOMPUTED_CP
|
||||||
,
|
,
|
||||||
@ -58,3 +55,9 @@ const ecdsa_curve nist256p1 = {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const curve_info nist256p1_info = {
|
||||||
|
/* bip32_name */
|
||||||
|
"Nist256p1 seed",
|
||||||
|
&nist256p1
|
||||||
|
};
|
||||||
|
@ -27,8 +27,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
|
#include "bip32.h"
|
||||||
|
|
||||||
extern const char NIST256P1_NAME[];
|
extern const char NIST256P1_NAME[];
|
||||||
extern const ecdsa_curve nist256p1;
|
extern const ecdsa_curve nist256p1;
|
||||||
|
extern const curve_info nist256p1_info;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
11
secp256k1.c
11
secp256k1.c
@ -47,10 +47,7 @@ const ecdsa_curve secp256k1 = {
|
|||||||
|
|
||||||
/* b */ {
|
/* b */ {
|
||||||
/*.val =*/{7}
|
/*.val =*/{7}
|
||||||
},
|
}
|
||||||
|
|
||||||
/* bip32_name */
|
|
||||||
"Bitcoin seed"
|
|
||||||
|
|
||||||
#if USE_PRECOMPUTED_CP
|
#if USE_PRECOMPUTED_CP
|
||||||
,
|
,
|
||||||
@ -59,3 +56,9 @@ const ecdsa_curve secp256k1 = {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const curve_info secp256k1_info = {
|
||||||
|
/* bip32_name */
|
||||||
|
"Bitcoin seed",
|
||||||
|
&secp256k1
|
||||||
|
};
|
||||||
|
@ -27,8 +27,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
|
#include "bip32.h"
|
||||||
|
|
||||||
extern const char SECP256K1_NAME[];
|
extern const char SECP256K1_NAME[];
|
||||||
extern const ecdsa_curve secp256k1;
|
extern const ecdsa_curve secp256k1;
|
||||||
|
extern const curve_info secp256k1_info;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
15
tests.c
15
tests.c
@ -648,7 +648,7 @@ START_TEST(test_bip32_nist_compare)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST(test_bip32_nist_invalid)
|
START_TEST(test_bip32_nist_repeat)
|
||||||
{
|
{
|
||||||
HDNode node, node2;
|
HDNode node, node2;
|
||||||
int r;
|
int r;
|
||||||
@ -666,12 +666,19 @@ START_TEST(test_bip32_nist_invalid)
|
|||||||
|
|
||||||
memcpy(&node2, &node, sizeof(HDNode));
|
memcpy(&node2, &node, sizeof(HDNode));
|
||||||
r = hdnode_private_ckd(&node2, 33941);
|
r = hdnode_private_ckd(&node2, 33941);
|
||||||
ck_assert_int_eq(r, 0);
|
ck_assert_int_eq(r, 1);
|
||||||
|
ck_assert_int_eq(node2.fingerprint, 0x3e2b7bc6);
|
||||||
|
ck_assert_mem_eq(node2.chain_code, fromhex("9e87fe95031f14736774cd82f25fd885065cb7c358c1edf813c72af535e83071"), 32);
|
||||||
|
ck_assert_mem_eq(node2.private_key, fromhex("092154eed4af83e078ff9b84322015aefe5769e31270f62c3f66c33888335f3a"), 32);
|
||||||
|
ck_assert_mem_eq(node2.public_key, fromhex("0235bfee614c0d5b2cae260000bb1d0d84b270099ad790022c1ae0b2e782efe120"), 33);
|
||||||
|
|
||||||
memcpy(&node2, &node, sizeof(HDNode));
|
memcpy(&node2, &node, sizeof(HDNode));
|
||||||
memset(&node2.private_key, 0, 32);
|
memset(&node2.private_key, 0, 32);
|
||||||
r = hdnode_public_ckd(&node2, 33941);
|
r = hdnode_public_ckd(&node2, 33941);
|
||||||
ck_assert_int_eq(r, 0);
|
ck_assert_int_eq(r, 1);
|
||||||
|
ck_assert_int_eq(node2.fingerprint, 0x3e2b7bc6);
|
||||||
|
ck_assert_mem_eq(node2.chain_code, fromhex("9e87fe95031f14736774cd82f25fd885065cb7c358c1edf813c72af535e83071"), 32);
|
||||||
|
ck_assert_mem_eq(node2.public_key, fromhex("0235bfee614c0d5b2cae260000bb1d0d84b270099ad790022c1ae0b2e782efe120"), 33);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@ -1596,7 +1603,7 @@ Suite *test_suite(void)
|
|||||||
tcase_add_test(tc, test_bip32_nist_vector_1);
|
tcase_add_test(tc, test_bip32_nist_vector_1);
|
||||||
tcase_add_test(tc, test_bip32_nist_vector_2);
|
tcase_add_test(tc, test_bip32_nist_vector_2);
|
||||||
tcase_add_test(tc, test_bip32_nist_compare);
|
tcase_add_test(tc, test_bip32_nist_compare);
|
||||||
tcase_add_test(tc, test_bip32_nist_invalid);
|
tcase_add_test(tc, test_bip32_nist_repeat);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("rfc6979");
|
tc = tcase_create("rfc6979");
|
||||||
|
Loading…
Reference in New Issue
Block a user