libbtc
bitcoinclibrary
Functions
bip32.c File Reference
#include "btc/bip32.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include "btc/base58.h"
#include "btc/ecc.h"
#include "ripemd160.h"
#include "sha2.h"
#include "utils.h"

Go to the source code of this file.

Functions

static void write_be (uint8_t *data, uint32_t x)
 
static uint32_t read_be (const uint8_t *data)
 
btc_bool btc_hdnode_from_seed (const uint8_t *seed, int seed_len, btc_hdnode *out)
 
btc_bool btc_hdnode_public_ckd (btc_hdnode *inout, uint32_t i)
 
btc_bool btc_hdnode_private_ckd (btc_hdnode *inout, uint32_t i)
 
void btc_hdnode_fill_public_key (btc_hdnode *node)
 
static void btc_hdnode_serialize (const btc_hdnode *node, uint32_t version, char use_public, char *str, int strsize)
 
void btc_hdnode_serialize_public (const btc_hdnode *node, const btc_chain *chain, char *str, int strsize)
 
void btc_hdnode_serialize_private (const btc_hdnode *node, const btc_chain *chain, char *str, int strsize)
 
btc_bool btc_hdnode_deserialize (const char *str, const btc_chain *chain, btc_hdnode *node)
 
btc_bool btc_hd_generate_key (btc_hdnode *node, const char *keypath, const uint8_t *privkeymaster, const uint8_t *chaincode)
 derive btc_hdnode including private key from master private key More...
 

Function Documentation

btc_bool btc_hd_generate_key ( btc_hdnode node,
const char *  keypath,
const uint8_t *  privkeymaster,
const uint8_t *  chaincode 
)

derive btc_hdnode including private key from master private key

Definition at line 245 of file bip32.c.

References BTC_BIP32_CHAINCODE_SIZE, BTC_ECKEY_PKEY_LENGTH, btc_hdnode_fill_public_key(), btc_hdnode_private_ckd(), btc_hdnode_private_ckd_prime, btc_hdnode::chain_code, btc_hdnode::child_num, btc_hdnode::depth, btc_hdnode::fingerprint, btc_hdnode::private_key, and strlens.

246 {
247  static char delim[] = "/";
248  static char prime[] = "phH\'";
249  static char digits[] = "0123456789";
250  uint64_t idx = 0;
251  assert(strlens(keypath) < 1024);
252  char* pch, *kp = malloc(strlens(keypath) + 1);
253 
254  if (!kp) {
255  return false;
256  }
257 
258  if (strlens(keypath) < strlens("m/")) {
259  goto err;
260  }
261 
262  memset(kp, 0, strlens(keypath) + 1);
263  memcpy(kp, keypath, strlens(keypath));
264 
265  if (kp[0] != 'm' || kp[1] != '/') {
266  goto err;
267  }
268 
269  node->depth = 0;
270  node->child_num = 0;
271  node->fingerprint = 0;
272  memcpy(node->chain_code, chaincode, BTC_BIP32_CHAINCODE_SIZE);
273  memcpy(node->private_key, privkeymaster, BTC_ECKEY_PKEY_LENGTH);
275 
276  pch = strtok(kp + 2, delim);
277  while (pch != NULL) {
278  size_t i = 0;
279  int prm = 0;
280  for (; i < strlens(pch); i++) {
281  if (strchr(prime, pch[i])) {
282  if (i != strlens(pch) - 1) {
283  goto err;
284  }
285  prm = 1;
286  } else if (!strchr(digits, pch[i])) {
287  goto err;
288  }
289  }
290 
291  idx = strtoull(pch, NULL, 10);
292  if (idx > UINT32_MAX) {
293  goto err;
294  }
295 
296  if (prm) {
297  if (btc_hdnode_private_ckd_prime(node, idx) != true) {
298  goto err;
299  }
300  } else {
301  if (btc_hdnode_private_ckd(node, idx) != true) {
302  goto err;
303  }
304  }
305  pch = strtok(NULL, delim);
306  }
307  free(kp);
308  return true;
309 
310 err:
311  free(kp);
312  return false;
313 }
btc_bool btc_hdnode_private_ckd(btc_hdnode *inout, uint32_t i)
Definition: bip32.c:124
uint8_t private_key[BTC_ECKEY_PKEY_LENGTH]
Definition: bip32.h:47
#define strlens(s)
Definition: utils.h:40
#define BTC_ECKEY_PKEY_LENGTH
Definition: btc.h:70
uint32_t child_num
Definition: bip32.h:45
uint32_t depth
Definition: bip32.h:43
void btc_hdnode_fill_public_key(btc_hdnode *node)
Definition: bip32.c:178
uint32_t fingerprint
Definition: bip32.h:44
uint8_t chain_code[BTC_BIP32_CHAINCODE_SIZE]
Definition: bip32.h:46
#define BTC_BIP32_CHAINCODE_SIZE
Definition: bip32.h:39
#define btc_hdnode_private_ckd_prime(X, I)
Definition: bip32.h:52
btc_bool btc_hdnode_deserialize ( const char *  str,
const btc_chain chain,
btc_hdnode node 
)

Definition at line 216 of file bip32.c.

References btc_chain::b58prefix_bip32_privkey, btc_chain::b58prefix_bip32_pubkey, btc_base58_decode_check(), BTC_BIP32_CHAINCODE_SIZE, BTC_ECKEY_COMPRESSED_LENGTH, BTC_ECKEY_PKEY_LENGTH, btc_hdnode_fill_public_key(), btc_hdnode::chain_code, btc_hdnode::child_num, btc_hdnode::depth, btc_hdnode::fingerprint, btc_hdnode::private_key, btc_hdnode::public_key, and read_be().

217 {
218  uint8_t node_data[strlen(str)];
219  memset(node, 0, sizeof(btc_hdnode));
220  size_t outlen = 0;
221 
222  outlen = btc_base58_decode_check(str, node_data, sizeof(node_data));
223  if (!outlen) {
224  return false;
225  }
226  uint32_t version = read_be(node_data);
227  if (version == chain->b58prefix_bip32_pubkey) { // public node
228  memcpy(node->public_key, node_data + 45, BTC_ECKEY_COMPRESSED_LENGTH);
229  } else if (version == chain->b58prefix_bip32_privkey) { // private node
230  if (node_data[45]) { // invalid data
231  return false;
232  }
233  memcpy(node->private_key, node_data + 46, BTC_ECKEY_PKEY_LENGTH);
235  } else {
236  return false; // invalid version
237  }
238  node->depth = node_data[4];
239  node->fingerprint = read_be(node_data + 5);
240  node->child_num = read_be(node_data + 9);
241  memcpy(node->chain_code, node_data + 13, BTC_BIP32_CHAINCODE_SIZE);
242  return true;
243 }
uint8_t private_key[BTC_ECKEY_PKEY_LENGTH]
Definition: bip32.h:47
#define BTC_ECKEY_PKEY_LENGTH
Definition: btc.h:70
uint32_t b58prefix_bip32_pubkey
Definition: chain.h:46
uint32_t child_num
Definition: bip32.h:45
#define BTC_ECKEY_COMPRESSED_LENGTH
Definition: btc.h:68
uint32_t b58prefix_bip32_privkey
private key
Definition: chain.h:45
uint32_t depth
Definition: bip32.h:43
void btc_hdnode_fill_public_key(btc_hdnode *node)
Definition: bip32.c:178
int btc_base58_decode_check(const char *str, uint8_t *data, size_t datalen)
Definition: base58.c:219
uint32_t fingerprint
Definition: bip32.h:44
uint8_t chain_code[BTC_BIP32_CHAINCODE_SIZE]
Definition: bip32.h:46
static uint32_t read_be(const uint8_t *data)
Definition: bip32.c:52
uint8_t public_key[BTC_ECKEY_COMPRESSED_LENGTH]
Definition: bip32.h:48
#define BTC_BIP32_CHAINCODE_SIZE
Definition: bip32.h:39
void btc_hdnode_fill_public_key ( btc_hdnode node)

Definition at line 178 of file bip32.c.

References BTC_ECKEY_COMPRESSED_LENGTH, ecc_get_pubkey(), btc_hdnode::private_key, and btc_hdnode::public_key.

Referenced by btc_hd_generate_key(), btc_hdnode_deserialize(), btc_hdnode_from_seed(), and btc_hdnode_private_ckd().

179 {
180  size_t outsize = BTC_ECKEY_COMPRESSED_LENGTH;
181  ecc_get_pubkey(node->private_key, node->public_key, &outsize, true);
182 }
uint8_t private_key[BTC_ECKEY_PKEY_LENGTH]
Definition: bip32.h:47
void ecc_get_pubkey(const uint8_t *private_key, uint8_t *public_key, size_t *in_outlen, btc_bool compressed)
get public key from given private key
#define BTC_ECKEY_COMPRESSED_LENGTH
Definition: btc.h:68
uint8_t public_key[BTC_ECKEY_COMPRESSED_LENGTH]
Definition: bip32.h:48
btc_bool btc_hdnode_from_seed ( const uint8_t *  seed,
int  seed_len,
btc_hdnode out 
)

Definition at line 61 of file bip32.c.

References BTC_BIP32_CHAINCODE_SIZE, BTC_ECKEY_PKEY_LENGTH, btc_hdnode_fill_public_key(), btc_hdnode::chain_code, btc_hdnode::child_num, btc_hdnode::depth, ecc_verify_privatekey(), btc_hdnode::fingerprint, hmac_sha512(), and btc_hdnode::private_key.

62 {
64  memset(out, 0, sizeof(btc_hdnode));
65  out->depth = 0;
66  out->fingerprint = 0x00000000;
67  out->child_num = 0;
68  hmac_sha512((const uint8_t*)"Bitcoin seed", 12, seed, seed_len, I);
69  memcpy(out->private_key, I, BTC_ECKEY_PKEY_LENGTH);
70 
72  memset(I, 0, sizeof(I));
73  return false;
74  }
75 
78  memset(I, 0, sizeof(I));
79  return true;
80 }
uint8_t private_key[BTC_ECKEY_PKEY_LENGTH]
Definition: bip32.h:47
#define BTC_ECKEY_PKEY_LENGTH
Definition: btc.h:70
uint32_t child_num
Definition: bip32.h:45
uint32_t depth
Definition: bip32.h:43
void btc_hdnode_fill_public_key(btc_hdnode *node)
Definition: bip32.c:178
uint32_t fingerprint
Definition: bip32.h:44
uint8_t chain_code[BTC_BIP32_CHAINCODE_SIZE]
Definition: bip32.h:46
#define BTC_BIP32_CHAINCODE_SIZE
Definition: bip32.h:39
void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac)
Definition: sha2.c:996
btc_bool ecc_verify_privatekey(const uint8_t *private_key)
verifies a given 32byte key
btc_bool btc_hdnode_private_ckd ( btc_hdnode inout,
uint32_t  i 
)

Definition at line 124 of file bip32.c.

References BTC_BIP32_CHAINCODE_SIZE, BTC_ECKEY_COMPRESSED_LENGTH, BTC_ECKEY_PKEY_LENGTH, btc_hdnode_fill_public_key(), btc_hdnode::chain_code, btc_hdnode::child_num, btc_hdnode::depth, ecc_private_key_tweak_add(), ecc_verify_privatekey(), btc_hdnode::fingerprint, hmac_sha512(), btc_hdnode::private_key, btc_hdnode::public_key, ripemd160(), sha256_Raw(), and write_be().

Referenced by btc_hd_generate_key().

125 {
126  uint8_t data[1 + BTC_ECKEY_PKEY_LENGTH + 4];
128  uint8_t fingerprint[BTC_BIP32_CHAINCODE_SIZE];
130 
131  if (i & 0x80000000) { // private derivation
132  data[0] = 0;
133  memcpy(data + 1, inout->private_key, BTC_ECKEY_PKEY_LENGTH);
134  } else { // public derivation
135  memcpy(data, inout->public_key, BTC_ECKEY_COMPRESSED_LENGTH);
136  }
138 
139  sha256_Raw(inout->public_key, BTC_ECKEY_COMPRESSED_LENGTH, fingerprint);
140  ripemd160(fingerprint, 32, fingerprint);
141  inout->fingerprint = (fingerprint[0] << 24) + (fingerprint[1] << 16) +
142  (fingerprint[2] << 8) + fingerprint[3];
143 
144  memset(fingerprint, 0, sizeof(fingerprint));
145  memcpy(p, inout->private_key, BTC_ECKEY_PKEY_LENGTH);
146 
147  hmac_sha512(inout->chain_code, BTC_BIP32_CHAINCODE_SIZE, data, sizeof(data), I);
149  memcpy(inout->private_key, I, BTC_ECKEY_PKEY_LENGTH);
150 
151  memcpy(z, inout->private_key, BTC_ECKEY_PKEY_LENGTH);
152 
153  int failed = 0;
154  if (!ecc_verify_privatekey(z)) {
155  failed = 1;
156  return false;
157  }
158 
159  memcpy(inout->private_key, p, BTC_ECKEY_PKEY_LENGTH);
160  if (!ecc_private_key_tweak_add(inout->private_key, z)) {
161  failed = 1;
162  }
163 
164  if (!failed) {
165  inout->depth++;
166  inout->child_num = i;
168  }
169 
170  memset(data, 0, sizeof(data));
171  memset(I, 0, sizeof(I));
172  memset(p, 0, sizeof(p));
173  memset(z, 0, sizeof(z));
174  return true;
175 }
uint8_t private_key[BTC_ECKEY_PKEY_LENGTH]
Definition: bip32.h:47
#define BTC_ECKEY_PKEY_LENGTH
Definition: btc.h:70
uint32_t child_num
Definition: bip32.h:45
#define BTC_ECKEY_COMPRESSED_LENGTH
Definition: btc.h:68
void sha256_Raw(const sha2_byte *data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH])
Definition: sha2.c:652
uint32_t depth
Definition: bip32.h:43
void btc_hdnode_fill_public_key(btc_hdnode *node)
Definition: bip32.c:178
const void * p
Definition: buffer.h:21
uint32_t fingerprint
Definition: bip32.h:44
uint8_t chain_code[BTC_BIP32_CHAINCODE_SIZE]
Definition: bip32.h:46
uint8_t public_key[BTC_ECKEY_COMPRESSED_LENGTH]
Definition: bip32.h:48
void ripemd160(const uint8_t *msg, uint32_t msg_len, uint8_t *hash)
Definition: ripemd160.c:292
static void write_be(uint8_t *data, uint32_t x)
Definition: bip32.c:42
btc_bool ecc_private_key_tweak_add(uint8_t *private_key, const uint8_t *tweak)
ec mul tweak on given private key
#define BTC_BIP32_CHAINCODE_SIZE
Definition: bip32.h:39
void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac)
Definition: sha2.c:996
btc_bool ecc_verify_privatekey(const uint8_t *private_key)
verifies a given 32byte key
btc_bool btc_hdnode_public_ckd ( btc_hdnode inout,
uint32_t  i 
)

Definition at line 83 of file bip32.c.

References BTC_BIP32_CHAINCODE_SIZE, BTC_ECKEY_COMPRESSED_LENGTH, btc_hdnode::chain_code, btc_hdnode::child_num, btc_hdnode::depth, ecc_public_key_tweak_add(), btc_hdnode::fingerprint, hmac_sha512(), btc_hdnode::private_key, btc_hdnode::public_key, ripemd160(), sha256_Raw(), and write_be().

84 {
85  uint8_t data[1 + 32 + 4];
86  uint8_t I[32 + BTC_BIP32_CHAINCODE_SIZE];
87  uint8_t fingerprint[32];
88 
89  if (i & 0x80000000) { // private derivation
90  return false;
91  } else { // public derivation
92  memcpy(data, inout->public_key, BTC_ECKEY_COMPRESSED_LENGTH);
93  }
95 
97  ripemd160(fingerprint, 32, fingerprint);
98  inout->fingerprint = (fingerprint[0] << 24) + (fingerprint[1] << 16) + (fingerprint[2] << 8) + fingerprint[3];
99 
100  memset(inout->private_key, 0, 32);
101 
102  int failed = 0;
103  hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
104  memcpy(inout->chain_code, I + 32, BTC_BIP32_CHAINCODE_SIZE);
105 
106 
107  if (!ecc_public_key_tweak_add(inout->public_key, I))
108  failed = false;
109 
110  if (!failed) {
111  inout->depth++;
112  inout->child_num = i;
113  }
114 
115  // Wipe all stack data.
116  memset(data, 0, sizeof(data));
117  memset(I, 0, sizeof(I));
118  memset(fingerprint, 0, sizeof(fingerprint));
119 
120  return failed ? false : true;
121 }
uint8_t private_key[BTC_ECKEY_PKEY_LENGTH]
Definition: bip32.h:47
uint32_t child_num
Definition: bip32.h:45
#define BTC_ECKEY_COMPRESSED_LENGTH
Definition: btc.h:68
void sha256_Raw(const sha2_byte *data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH])
Definition: sha2.c:652
uint32_t depth
Definition: bip32.h:43
uint32_t fingerprint
Definition: bip32.h:44
uint8_t chain_code[BTC_BIP32_CHAINCODE_SIZE]
Definition: bip32.h:46
btc_bool ecc_public_key_tweak_add(uint8_t *public_key_inout, const uint8_t *tweak)
ec mul tweak on given public key
uint8_t public_key[BTC_ECKEY_COMPRESSED_LENGTH]
Definition: bip32.h:48
void ripemd160(const uint8_t *msg, uint32_t msg_len, uint8_t *hash)
Definition: ripemd160.c:292
static void write_be(uint8_t *data, uint32_t x)
Definition: bip32.c:42
#define BTC_BIP32_CHAINCODE_SIZE
Definition: bip32.h:39
void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac)
Definition: sha2.c:996
static void btc_hdnode_serialize ( const btc_hdnode node,
uint32_t  version,
char  use_public,
char *  str,
int  strsize 
)
static

Definition at line 185 of file bip32.c.

References btc_base58_encode_check(), BTC_BIP32_CHAINCODE_SIZE, BTC_ECKEY_COMPRESSED_LENGTH, BTC_ECKEY_PKEY_LENGTH, btc_hdnode::chain_code, btc_hdnode::child_num, btc_hdnode::depth, btc_hdnode::fingerprint, btc_hdnode::private_key, btc_hdnode::public_key, and write_be().

Referenced by btc_hdnode_serialize_private(), and btc_hdnode_serialize_public().

186 {
187  uint8_t node_data[78];
188  write_be(node_data, version);
189  node_data[4] = node->depth;
190  write_be(node_data + 5, node->fingerprint);
191  write_be(node_data + 9, node->child_num);
192  memcpy(node_data + 13, node->chain_code, BTC_BIP32_CHAINCODE_SIZE);
193  if (use_public) {
194  memcpy(node_data + 45, node->public_key, BTC_ECKEY_COMPRESSED_LENGTH);
195  } else {
196  node_data[45] = 0;
197  memcpy(node_data + 46, node->private_key, BTC_ECKEY_PKEY_LENGTH);
198  }
199  btc_base58_encode_check(node_data, 78, str, strsize);
200 }
uint8_t private_key[BTC_ECKEY_PKEY_LENGTH]
Definition: bip32.h:47
#define BTC_ECKEY_PKEY_LENGTH
Definition: btc.h:70
uint32_t child_num
Definition: bip32.h:45
#define BTC_ECKEY_COMPRESSED_LENGTH
Definition: btc.h:68
uint32_t depth
Definition: bip32.h:43
uint32_t fingerprint
Definition: bip32.h:44
uint8_t chain_code[BTC_BIP32_CHAINCODE_SIZE]
Definition: bip32.h:46
uint8_t public_key[BTC_ECKEY_COMPRESSED_LENGTH]
Definition: bip32.h:48
static void write_be(uint8_t *data, uint32_t x)
Definition: bip32.c:42
int btc_base58_encode_check(const uint8_t *data, int datalen, char *str, int strsize)
Definition: base58.c:198
#define BTC_BIP32_CHAINCODE_SIZE
Definition: bip32.h:39
void btc_hdnode_serialize_private ( const btc_hdnode node,
const btc_chain chain,
char *  str,
int  strsize 
)

Definition at line 209 of file bip32.c.

References btc_chain::b58prefix_bip32_privkey, and btc_hdnode_serialize().

210 {
211  btc_hdnode_serialize(node, chain->b58prefix_bip32_privkey, 0, str, strsize);
212 }
uint32_t b58prefix_bip32_privkey
private key
Definition: chain.h:45
static void btc_hdnode_serialize(const btc_hdnode *node, uint32_t version, char use_public, char *str, int strsize)
Definition: bip32.c:185
void btc_hdnode_serialize_public ( const btc_hdnode node,
const btc_chain chain,
char *  str,
int  strsize 
)

Definition at line 203 of file bip32.c.

References btc_chain::b58prefix_bip32_pubkey, and btc_hdnode_serialize().

204 {
205  btc_hdnode_serialize(node, chain->b58prefix_bip32_pubkey, 1, str, strsize);
206 }
uint32_t b58prefix_bip32_pubkey
Definition: chain.h:46
static void btc_hdnode_serialize(const btc_hdnode *node, uint32_t version, char use_public, char *str, int strsize)
Definition: bip32.c:185
static uint32_t read_be ( const uint8_t *  data)
static

Definition at line 52 of file bip32.c.

Referenced by btc_hdnode_deserialize().

53 {
54  return (((uint32_t)data[0]) << 24) |
55  (((uint32_t)data[1]) << 16) |
56  (((uint32_t)data[2]) << 8) |
57  (((uint32_t)data[3]));
58 }
static void write_be ( uint8_t *  data,
uint32_t  x 
)
static

Copyright (c) 2013-2014 Tomas Dzetkulic Copyright (c) 2013-2014 Pavol Rusnak Copyright (c) 2015 Douglas J. Bakkumk

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Definition at line 42 of file bip32.c.

Referenced by btc_hdnode_private_ckd(), btc_hdnode_public_ckd(), and btc_hdnode_serialize().

43 {
44  data[0] = x >> 24;
45  data[1] = x >> 16;
46  data[2] = x >> 8;
47  data[3] = x;
48 }