mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 20:38:10 +00:00
commit
bf34b4269c
2
bignum.c
2
bignum.c
@ -371,7 +371,7 @@ void bn_sqrt(bignum256 *x, const bignum256 *prime)
|
|||||||
bn_zero(&res); res.val[0] = 1;
|
bn_zero(&res); res.val[0] = 1;
|
||||||
// compute p = (prime+1)/4
|
// compute p = (prime+1)/4
|
||||||
memcpy(&p, prime, sizeof(bignum256));
|
memcpy(&p, prime, sizeof(bignum256));
|
||||||
p.val[0] += 1;
|
bn_addi(&p, 1);
|
||||||
bn_rshift(&p);
|
bn_rshift(&p);
|
||||||
bn_rshift(&p);
|
bn_rshift(&p);
|
||||||
for (i = 0; i < 9; i++) {
|
for (i = 0; i < 9; i++) {
|
||||||
|
40
bip32.c
40
bip32.c
@ -34,9 +34,7 @@
|
|||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "secp256k1.h"
|
#include "secp256k1.h"
|
||||||
|
|
||||||
static const ecdsa_curve *default_curve = &secp256k1;
|
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, HDNode *out)
|
|
||||||
{
|
{
|
||||||
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;
|
||||||
@ -47,19 +45,21 @@ int hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, c
|
|||||||
memcpy(out->chain_code, chain_code, 32);
|
memcpy(out->chain_code, chain_code, 32);
|
||||||
MEMSET_BZERO(out->private_key, 32);
|
MEMSET_BZERO(out->private_key, 32);
|
||||||
memcpy(out->public_key, public_key, 33);
|
memcpy(out->public_key, public_key, 33);
|
||||||
|
out->curve = get_curve_by_name(curve);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, 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;
|
bignum256 a;
|
||||||
bn_read_be(private_key, &a);
|
bn_read_be(private_key, &a);
|
||||||
|
out->curve = get_curve_by_name(curve);
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
if (bn_is_zero(&a)) { // == 0
|
if (bn_is_zero(&a)) { // == 0
|
||||||
failed = true;
|
failed = true;
|
||||||
} else {
|
} else {
|
||||||
if (!bn_is_less(&a, &default_curve->order)) { // >= order
|
if (!bn_is_less(&a, &out->curve->order)) { // >= order
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
MEMSET_BZERO(&a, sizeof(a));
|
MEMSET_BZERO(&a, sizeof(a));
|
||||||
@ -78,14 +78,16 @@ int hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, c
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdnode_from_seed(const uint8_t *seed, int seed_len, HDNode *out)
|
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNode *out)
|
||||||
{
|
{
|
||||||
uint8_t I[32 + 32];
|
uint8_t I[32 + 32];
|
||||||
memset(out, 0, sizeof(HDNode));
|
memset(out, 0, sizeof(HDNode));
|
||||||
out->depth = 0;
|
out->depth = 0;
|
||||||
out->fingerprint = 0x00000000;
|
out->fingerprint = 0x00000000;
|
||||||
out->child_num = 0;
|
out->child_num = 0;
|
||||||
hmac_sha512((uint8_t *)"Bitcoin seed", 12, seed, seed_len, I);
|
out->curve = get_curve_by_name(curve);
|
||||||
|
hmac_sha512((const uint8_t*) out->curve->bip32_name,
|
||||||
|
strlen(out->curve->bip32_name), seed, seed_len, I);
|
||||||
memcpy(out->private_key, I, 32);
|
memcpy(out->private_key, I, 32);
|
||||||
bignum256 a;
|
bignum256 a;
|
||||||
bn_read_be(out->private_key, &a);
|
bn_read_be(out->private_key, &a);
|
||||||
@ -94,7 +96,7 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, HDNode *out)
|
|||||||
if (bn_is_zero(&a)) { // == 0
|
if (bn_is_zero(&a)) { // == 0
|
||||||
failed = true;
|
failed = true;
|
||||||
} else {
|
} else {
|
||||||
if (!bn_is_less(&a, &default_curve->order)) { // >= order
|
if (!bn_is_less(&a, &out->curve->order)) { // >= order
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
MEMSET_BZERO(&a, sizeof(a));
|
MEMSET_BZERO(&a, sizeof(a));
|
||||||
@ -138,12 +140,12 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i)
|
|||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
|
|
||||||
if (!bn_is_less(&b, &default_curve->order)) { // >= order
|
if (!bn_is_less(&b, &inout->curve->order)) { // >= order
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
if (!failed) {
|
if (!failed) {
|
||||||
bn_addmod(&a, &b, &default_curve->order);
|
bn_addmod(&a, &b, &inout->curve->order);
|
||||||
bn_mod(&a, &default_curve->order);
|
bn_mod(&a, &inout->curve->order);
|
||||||
if (bn_is_zero(&a)) {
|
if (bn_is_zero(&a)) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
@ -186,7 +188,7 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i)
|
|||||||
memset(inout->private_key, 0, 32);
|
memset(inout->private_key, 0, 32);
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
if (!ecdsa_read_pubkey(default_curve, inout->public_key, &a)) {
|
if (!ecdsa_read_pubkey(inout->curve, inout->public_key, &a)) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,15 +196,15 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i)
|
|||||||
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);
|
memcpy(inout->chain_code, I + 32, 32);
|
||||||
bn_read_be(I, &c);
|
bn_read_be(I, &c);
|
||||||
if (!bn_is_less(&c, &default_curve->order)) { // >= order
|
if (!bn_is_less(&c, &inout->curve->order)) { // >= order
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!failed) {
|
if (!failed) {
|
||||||
scalar_multiply(default_curve, &c, &b); // b = c * G
|
scalar_multiply(inout->curve, &c, &b); // b = c * G
|
||||||
point_add(default_curve, &a, &b); // b = a + b
|
point_add(inout->curve, &a, &b); // b = a + b
|
||||||
if (!ecdsa_validate_pubkey(default_curve, &b)) {
|
if (!ecdsa_validate_pubkey(inout->curve, &b)) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,7 +265,8 @@ int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count)
|
|||||||
for (j = 0; j < BIP32_CACHE_SIZE; j++) {
|
for (j = 0; j < BIP32_CACHE_SIZE; j++) {
|
||||||
if (private_ckd_cache[j].set &&
|
if (private_ckd_cache[j].set &&
|
||||||
private_ckd_cache[j].depth == i_count - 1 &&
|
private_ckd_cache[j].depth == i_count - 1 &&
|
||||||
memcmp(private_ckd_cache[j].i, i, (i_count - 1) * sizeof(uint32_t)) == 0) {
|
memcmp(private_ckd_cache[j].i, i, (i_count - 1) * sizeof(uint32_t)) == 0 &&
|
||||||
|
private_ckd_cache[j].node.curve == inout->curve) {
|
||||||
memcpy(inout, &(private_ckd_cache[j].node), sizeof(HDNode));
|
memcpy(inout, &(private_ckd_cache[j].node), sizeof(HDNode));
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@ -295,7 +298,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(default_curve, node->private_key, node->public_key);
|
ecdsa_get_public_key33(node->curve, 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)
|
||||||
@ -335,6 +338,7 @@ int hdnode_deserialize(const char *str, HDNode *node)
|
|||||||
if (!base58_decode_check(str, node_data, sizeof(node_data))) {
|
if (!base58_decode_check(str, node_data, sizeof(node_data))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
node->curve = get_curve_by_name(SECP256K1_NAME);
|
||||||
uint32_t version = read_be(node_data);
|
uint32_t version = read_be(node_data);
|
||||||
if (version == 0x0488B21E) { // public node
|
if (version == 0x0488B21E) { // public node
|
||||||
memcpy(node->public_key, node_data + 45, 33);
|
memcpy(node->public_key, node_data + 45, 33);
|
||||||
|
7
bip32.h
7
bip32.h
@ -36,13 +36,14 @@ 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;
|
||||||
} 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, 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);
|
||||||
|
|
||||||
int hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, 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);
|
||||||
|
|
||||||
int hdnode_from_seed(const uint8_t *seed, int seed_len, HDNode *out);
|
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve, HDNode *out);
|
||||||
|
|
||||||
#define hdnode_private_ckd_prime(X, I) hdnode_private_ckd((X), ((I) | 0x80000000))
|
#define hdnode_private_ckd_prime(X, I) hdnode_private_ckd((X), ((I) | 0x80000000))
|
||||||
|
|
||||||
|
6
ecdsa.c
6
ecdsa.c
@ -862,7 +862,7 @@ int ecdsa_address_decode(const char *addr, uint8_t *out)
|
|||||||
|
|
||||||
void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, const bignum256 *x, bignum256 *y)
|
void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, const bignum256 *x, bignum256 *y)
|
||||||
{
|
{
|
||||||
// y^2 = x^3 + 0*x + 7
|
// y^2 = x^3 + a*x + b
|
||||||
memcpy(y, x, sizeof(bignum256)); // y is x
|
memcpy(y, x, sizeof(bignum256)); // y is x
|
||||||
bn_multiply(x, y, &curve->prime); // y is x^2
|
bn_multiply(x, y, &curve->prime); // y is x^2
|
||||||
bn_subi(y, -curve->a, &curve->prime); // y is x^2 + a
|
bn_subi(y, -curve->a, &curve->prime); // y is x^2 + a
|
||||||
@ -1050,10 +1050,10 @@ const ecdsa_curve *get_curve_by_name(const char *curve_name) {
|
|||||||
if (curve_name == 0) {
|
if (curve_name == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(curve_name, "secp256k1") == 0) {
|
if (strcmp(curve_name, SECP256K1_NAME) == 0) {
|
||||||
return &secp256k1;
|
return &secp256k1;
|
||||||
}
|
}
|
||||||
if (strcmp(curve_name, "nist256p1") == 0) {
|
if (strcmp(curve_name, NIST256P1_NAME) == 0) {
|
||||||
return &nist256p1;
|
return &nist256p1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
1
ecdsa.h
1
ecdsa.h
@ -41,6 +41,7 @@ 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];
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "nist256p1.h"
|
#include "nist256p1.h"
|
||||||
|
|
||||||
|
const char NIST256P1_NAME[] = "nist256p1";
|
||||||
const ecdsa_curve nist256p1 = {
|
const ecdsa_curve nist256p1 = {
|
||||||
/* .prime */ {
|
/* .prime */ {
|
||||||
/*.val =*/ {0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3f, 0x0, 0x0, 0x1000, 0x3fffc000, 0xffff}
|
/*.val =*/ {0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3f, 0x0, 0x0, 0x1000, 0x3fffc000, 0xffff}
|
||||||
@ -45,7 +46,11 @@ 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
|
||||||
,
|
,
|
||||||
/* cp */ {
|
/* cp */ {
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
|
|
||||||
|
extern const char NIST256P1_NAME[];
|
||||||
extern const ecdsa_curve nist256p1;
|
extern const ecdsa_curve nist256p1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include "secp256k1.h"
|
#include "secp256k1.h"
|
||||||
|
|
||||||
|
const char SECP256K1_NAME[] = "secp256k1";
|
||||||
|
|
||||||
const ecdsa_curve secp256k1 = {
|
const ecdsa_curve secp256k1 = {
|
||||||
/* .prime */ {
|
/* .prime */ {
|
||||||
/*.val =*/ {0x3ffffc2f, 0x3ffffffb, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff}
|
/*.val =*/ {0x3ffffc2f, 0x3ffffffb, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff}
|
||||||
@ -45,7 +47,11 @@ const ecdsa_curve secp256k1 = {
|
|||||||
|
|
||||||
/* b */ {
|
/* b */ {
|
||||||
/*.val =*/{7}
|
/*.val =*/{7}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
/* bip32_name */
|
||||||
|
"Bitcoin seed"
|
||||||
|
|
||||||
#if USE_PRECOMPUTED_CP
|
#if USE_PRECOMPUTED_CP
|
||||||
,
|
,
|
||||||
/* cp */ {
|
/* cp */ {
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
|
|
||||||
|
extern const char SECP256K1_NAME[];
|
||||||
extern const ecdsa_curve secp256k1;
|
extern const ecdsa_curve secp256k1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
178
tests.c
178
tests.c
@ -25,6 +25,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
@ -168,7 +169,7 @@ START_TEST(test_bip32_vector_1)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
// init m
|
// init m
|
||||||
hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, &node);
|
hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, SECP256K1_NAME, &node);
|
||||||
|
|
||||||
// [Chain m]
|
// [Chain m]
|
||||||
ck_assert_int_eq(node.fingerprint, 0x00000000);
|
ck_assert_int_eq(node.fingerprint, 0x00000000);
|
||||||
@ -281,7 +282,7 @@ START_TEST(test_bip32_vector_2)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
// init m
|
// init m
|
||||||
hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, &node);
|
hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, SECP256K1_NAME, &node);
|
||||||
|
|
||||||
// [Chain m]
|
// [Chain m]
|
||||||
ck_assert_int_eq(node.fingerprint, 0x00000000);
|
ck_assert_int_eq(node.fingerprint, 0x00000000);
|
||||||
@ -390,7 +391,7 @@ START_TEST(test_bip32_vector_2)
|
|||||||
ck_assert_mem_eq(&node2, &node3, sizeof(HDNode));
|
ck_assert_mem_eq(&node2, &node3, sizeof(HDNode));
|
||||||
|
|
||||||
// init m
|
// init m
|
||||||
hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, &node);
|
hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, SECP256K1_NAME, &node);
|
||||||
|
|
||||||
// test public derivation
|
// test public derivation
|
||||||
// [Chain m/0]
|
// [Chain m/0]
|
||||||
@ -407,8 +408,8 @@ START_TEST(test_bip32_compare)
|
|||||||
{
|
{
|
||||||
HDNode node1, node2, node3;
|
HDNode node1, node2, node3;
|
||||||
int i, r;
|
int i, r;
|
||||||
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &node1);
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node1);
|
||||||
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &node2);
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node2);
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
memcpy(&node3, &node1, sizeof(HDNode));
|
memcpy(&node3, &node1, sizeof(HDNode));
|
||||||
r = hdnode_private_ckd(&node1, i); ck_assert_int_eq(r, 1);
|
r = hdnode_private_ckd(&node1, i); ck_assert_int_eq(r, 1);
|
||||||
@ -436,8 +437,8 @@ START_TEST(test_bip32_cache_1)
|
|||||||
int i, r;
|
int i, r;
|
||||||
|
|
||||||
// test 1 .. 8
|
// test 1 .. 8
|
||||||
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &node1);
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node1);
|
||||||
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &node2);
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node2);
|
||||||
|
|
||||||
uint32_t ii[] = {0x80000001, 0x80000002, 0x80000003, 0x80000004, 0x80000005, 0x80000006, 0x80000007, 0x80000008};
|
uint32_t ii[] = {0x80000001, 0x80000002, 0x80000003, 0x80000004, 0x80000005, 0x80000006, 0x80000007, 0x80000008};
|
||||||
|
|
||||||
@ -447,8 +448,8 @@ START_TEST(test_bip32_cache_1)
|
|||||||
r = hdnode_private_ckd_cached(&node2, ii, 8); ck_assert_int_eq(r, 1);
|
r = hdnode_private_ckd_cached(&node2, ii, 8); ck_assert_int_eq(r, 1);
|
||||||
ck_assert_mem_eq(&node1, &node2, sizeof(HDNode));
|
ck_assert_mem_eq(&node1, &node2, sizeof(HDNode));
|
||||||
|
|
||||||
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &node1);
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node1);
|
||||||
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &node2);
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node2);
|
||||||
|
|
||||||
// test 1 .. 7, 20
|
// test 1 .. 7, 20
|
||||||
ii[7] = 20;
|
ii[7] = 20;
|
||||||
@ -459,8 +460,8 @@ START_TEST(test_bip32_cache_1)
|
|||||||
ck_assert_mem_eq(&node1, &node2, sizeof(HDNode));
|
ck_assert_mem_eq(&node1, &node2, sizeof(HDNode));
|
||||||
|
|
||||||
// test different root node
|
// test different root node
|
||||||
hdnode_from_seed(fromhex("000000002ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &node1);
|
hdnode_from_seed(fromhex("000000002ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node1);
|
||||||
hdnode_from_seed(fromhex("000000002ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &node2);
|
hdnode_from_seed(fromhex("000000002ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node2);
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
r = hdnode_private_ckd(&node1, ii[i]); ck_assert_int_eq(r, 1);
|
r = hdnode_private_ckd(&node1, ii[i]); ck_assert_int_eq(r, 1);
|
||||||
@ -476,8 +477,8 @@ START_TEST(test_bip32_cache_2)
|
|||||||
int i, j, r;
|
int i, j, r;
|
||||||
|
|
||||||
for (j = 0; j < 9; j++) {
|
for (j = 0; j < 9; j++) {
|
||||||
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &(nodea[j]));
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &(nodea[j]));
|
||||||
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, &(nodeb[j]));
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &(nodeb[j]));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ii[] = {0x80000001, 0x80000002, 0x80000003, 0x80000004, 0x80000005, 0x80000006, 0x80000007, 0x80000008};
|
uint32_t ii[] = {0x80000001, 0x80000002, 0x80000003, 0x80000004, 0x80000005, 0x80000006, 0x80000007, 0x80000008};
|
||||||
@ -502,6 +503,151 @@ START_TEST(test_bip32_cache_2)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_bip32_nist_vector_1)
|
||||||
|
{
|
||||||
|
HDNode node;
|
||||||
|
|
||||||
|
// init m
|
||||||
|
hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, NIST256P1_NAME, &node);
|
||||||
|
|
||||||
|
// [Chain m]
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x00000000);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("beeb672fe4621673f722f38529c07392fecaa61015c80c34f29ce8b41b3cb6ea"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("612091aaa12e22dd2abef664f8a01a82cae99ad7441b7ef8110424915c268bc2"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("0266874dc6ade47b3ecd096745ca09bcd29638dd52c2c12117b11ed3e458cfa9e8"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0']
|
||||||
|
hdnode_private_ckd_prime(&node, 0);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0xbe6105b5);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("3460cea53e6a6bb5fb391eeef3237ffd8724bf0a40e94943c98b83825342ee11"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("6939694369114c67917a182c59ddb8cafc3004e63ca5d3b84403ba8613debc0c"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("0384610f5ecffe8fda089363a41f56a5c7ffc1d81b59a612d0d649b2d22355590c"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0'/1]
|
||||||
|
hdnode_private_ckd(&node, 1);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x9b02312f);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("4187afff1aafa8445010097fb99d23aee9f599450c7bd140b6826ac22ba21d0c"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("284e9d38d07d21e4e281b645089a94f4cf5a5a81369acf151a1c3a57f18b2129"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("03526c63f8d0b4bbbf9c80df553fe66742df4676b241dabefdef67733e070f6844"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0'/1/2']
|
||||||
|
hdnode_private_ckd_prime(&node, 2);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0xb98005c1);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("98c7514f562e64e74170cc3cf304ee1ce54d6b6da4f880f313e8204c2a185318"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("694596e8a54f252c960eb771a3c41e7e32496d03b954aeb90f61635b8e092aa7"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("0359cf160040778a4b14c5f4d7b76e327ccc8c4a6086dd9451b7482b5a4972dda0"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0'/1/2'/2]
|
||||||
|
hdnode_private_ckd(&node, 2);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x0e9f3274);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("ba96f776a5c3907d7fd48bde5620ee374d4acfd540378476019eab70790c63a0"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("5996c37fd3dd2679039b23ed6f70b506c6b56b3cb5e424681fb0fa64caf82aaa"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("029f871f4cb9e1c97f9f4de9ccd0d4a2f2a171110c61178f84430062230833ff20"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0'/1/2'/2/1000000000]
|
||||||
|
hdnode_private_ckd(&node, 1000000000);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x8b2b5c4b);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("b9b7b82d326bb9cb5b5b121066feea4eb93d5241103c9e7a18aad40f1dde8059"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("21c4f269ef0a5fd1badf47eeacebeeaa3de22eb8e5b0adcd0f27dd99d34d0119"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("02216cd26d31147f72427a453c443ed2cde8a1e53c9cc44e5ddf739725413fe3f4"), 33);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_bip32_nist_vector_2)
|
||||||
|
{
|
||||||
|
HDNode node;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
// init m
|
||||||
|
hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, NIST256P1_NAME, &node);
|
||||||
|
|
||||||
|
// [Chain m]
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x00000000);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("96cd4465a9644e31528eda3592aa35eb39a9527769ce1855beafc1b81055e75d"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("eaa31c2e46ca2962227cf21d73a7ef0ce8b31c756897521eb6c7b39796633357"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("02c9e16154474b3ed5b38218bb0463e008f89ee03e62d22fdcc8014beab25b48fa"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0]
|
||||||
|
r = hdnode_private_ckd(&node, 0);
|
||||||
|
ck_assert_int_eq(r, 1);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x607f628f);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("84e9c258bb8557a40e0d041115b376dd55eda99c0042ce29e81ebe4efed9b86a"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("d7d065f63a62624888500cdb4f88b6d59c2927fee9e6d0cdff9cad555884df6e"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("039b6df4bece7b6c81e2adfeea4bcf5c8c8a6e40ea7ffa3cf6e8494c61a1fc82cc"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0/2147483647']
|
||||||
|
r = hdnode_private_ckd_prime(&node, 2147483647);
|
||||||
|
ck_assert_int_eq(r, 1);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x946d2a54);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("f235b2bc5c04606ca9c30027a84f353acf4e4683edbd11f635d0dcc1cd106ea6"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("96d2ec9316746a75e7793684ed01e3d51194d81a42a3276858a5b7376d4b94b9"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("02f89c5deb1cae4fedc9905f98ae6cbf6cbab120d8cb85d5bd9a91a72f4c068c76"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0/2147483647'/1]
|
||||||
|
r = hdnode_private_ckd(&node, 1);
|
||||||
|
ck_assert_int_eq(r, 1);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x218182d8);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("7c0b833106235e452eba79d2bdd58d4086e663bc8cc55e9773d2b5eeda313f3b"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("974f9096ea6873a915910e82b29d7c338542ccde39d2064d1cc228f371542bbc"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("03abe0ad54c97c1d654c1852dfdc32d6d3e487e75fa16f0fd6304b9ceae4220c64"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0/2147483647'/1/2147483646']
|
||||||
|
r = hdnode_private_ckd_prime(&node, 2147483646);
|
||||||
|
ck_assert_int_eq(r, 1);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x931223e4);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("5794e616eadaf33413aa309318a26ee0fd5163b70466de7a4512fd4b1a5c9e6a"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("da29649bbfaff095cd43819eda9a7be74236539a29094cd8336b07ed8d4eff63"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("03cb8cb067d248691808cd6b5a5a06b48e34ebac4d965cba33e6dc46fe13d9b933"), 33);
|
||||||
|
|
||||||
|
// [Chain m/0/2147483647'/1/2147483646'/2]
|
||||||
|
r = hdnode_private_ckd(&node, 2);
|
||||||
|
ck_assert_int_eq(r, 1);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x956c4629);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("3bfb29ee8ac4484f09db09c2079b520ea5616df7820f071a20320366fbe226a7"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("bb0a77ba01cc31d77205d51d08bd313b979a71ef4de9b062f8958297e746bd67"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("020ee02e18967237cf62672983b253ee62fa4dd431f8243bfeccdf39dbe181387f"), 33);
|
||||||
|
|
||||||
|
// init m
|
||||||
|
hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, NIST256P1_NAME, &node);
|
||||||
|
|
||||||
|
// test public derivation
|
||||||
|
// [Chain m/0]
|
||||||
|
r = hdnode_public_ckd(&node, 0);
|
||||||
|
ck_assert_int_eq(r, 1);
|
||||||
|
ck_assert_int_eq(node.fingerprint, 0x607f628f);
|
||||||
|
ck_assert_mem_eq(node.chain_code, fromhex("84e9c258bb8557a40e0d041115b376dd55eda99c0042ce29e81ebe4efed9b86a"), 32);
|
||||||
|
ck_assert_mem_eq(node.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32);
|
||||||
|
ck_assert_mem_eq(node.public_key, fromhex("039b6df4bece7b6c81e2adfeea4bcf5c8c8a6e40ea7ffa3cf6e8494c61a1fc82cc"), 33);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_bip32_nist_compare)
|
||||||
|
{
|
||||||
|
HDNode node1, node2, node3;
|
||||||
|
int i, r;
|
||||||
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, NIST256P1_NAME, &node1);
|
||||||
|
hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, NIST256P1_NAME, &node2);
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
memcpy(&node3, &node1, sizeof(HDNode));
|
||||||
|
r = hdnode_private_ckd(&node1, i); ck_assert_int_eq(r, 1);
|
||||||
|
r = hdnode_public_ckd(&node2, i); ck_assert_int_eq(r, 1);
|
||||||
|
r = hdnode_public_ckd(&node3, i); ck_assert_int_eq(r, 1);
|
||||||
|
ck_assert_int_eq(node1.depth, node2.depth);
|
||||||
|
ck_assert_int_eq(node1.depth, node3.depth);
|
||||||
|
ck_assert_int_eq(node1.fingerprint, node2.fingerprint);
|
||||||
|
ck_assert_int_eq(node1.fingerprint, node3.fingerprint);
|
||||||
|
ck_assert_int_eq(node1.child_num, node2.child_num);
|
||||||
|
ck_assert_int_eq(node1.child_num, node3.child_num);
|
||||||
|
ck_assert_mem_eq(node1.chain_code, node2.chain_code, 32);
|
||||||
|
ck_assert_mem_eq(node1.chain_code, node3.chain_code, 32);
|
||||||
|
ck_assert_mem_eq(node2.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32);
|
||||||
|
ck_assert_mem_eq(node3.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32);
|
||||||
|
ck_assert_mem_eq(node1.public_key, node2.public_key, 33);
|
||||||
|
ck_assert_mem_eq(node1.public_key, node3.public_key, 33);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
#define test_deterministic(KEY, MSG, K) do { \
|
#define test_deterministic(KEY, MSG, K) do { \
|
||||||
sha256_Raw((uint8_t *)MSG, strlen(MSG), buf); \
|
sha256_Raw((uint8_t *)MSG, strlen(MSG), buf); \
|
||||||
res = generate_k_rfc6979(curve, &k, fromhex(KEY), buf); \
|
res = generate_k_rfc6979(curve, &k, fromhex(KEY), buf); \
|
||||||
@ -1419,6 +1565,12 @@ Suite *test_suite(void)
|
|||||||
tcase_add_test(tc, test_bip32_cache_2);
|
tcase_add_test(tc, test_bip32_cache_2);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
tc = tcase_create("bip32-nist");
|
||||||
|
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_compare);
|
||||||
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("rfc6979");
|
tc = tcase_create("rfc6979");
|
||||||
tcase_add_test(tc, test_rfc6979);
|
tcase_add_test(tc, test_rfc6979);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
Loading…
Reference in New Issue
Block a user