Anoncoin  0.9.4
P2P Digital Currency
key.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2013 The Bitcoin developers
2 // Copyright (c) 2013-2014 The Anoncoin Core developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "key.h"
7 
8 #include <openssl/bn.h>
9 #include <openssl/ecdsa.h>
10 #include <openssl/obj_mac.h>
11 #include <openssl/rand.h>
12 
13 // anonymous namespace with local implementation code (OpenSSL interaction)
14 namespace {
15 
16 // Generate a private key from just the secret parameter
17 int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
18 {
19  int ok = 0;
20  BN_CTX *ctx = NULL;
21  EC_POINT *pub_key = NULL;
22 
23  if (!eckey) return 0;
24 
25  const EC_GROUP *group = EC_KEY_get0_group(eckey);
26 
27  if ((ctx = BN_CTX_new()) == NULL)
28  goto err;
29 
30  pub_key = EC_POINT_new(group);
31 
32  if (pub_key == NULL)
33  goto err;
34 
35  if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
36  goto err;
37 
38  EC_KEY_set_private_key(eckey,priv_key);
39  EC_KEY_set_public_key(eckey,pub_key);
40 
41  ok = 1;
42 
43 err:
44 
45  if (pub_key)
46  EC_POINT_free(pub_key);
47  if (ctx != NULL)
48  BN_CTX_free(ctx);
49 
50  return(ok);
51 }
52 
53 // Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
54 // recid selects which key is recovered
55 // if check is non-zero, additional checks are performed
56 int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
57 {
58  if (!eckey) return 0;
59 
60  int ret = 0;
61  BN_CTX *ctx = NULL;
62 
63  BIGNUM *x = NULL;
64  BIGNUM *e = NULL;
65  BIGNUM *order = NULL;
66  BIGNUM *sor = NULL;
67  BIGNUM *eor = NULL;
68  BIGNUM *field = NULL;
69  EC_POINT *R = NULL;
70  EC_POINT *O = NULL;
71  EC_POINT *Q = NULL;
72  BIGNUM *rr = NULL;
73  BIGNUM *zero = NULL;
74  int n = 0;
75  int i = recid / 2;
76 
77  const EC_GROUP *group = EC_KEY_get0_group(eckey);
78  if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
79  BN_CTX_start(ctx);
80  order = BN_CTX_get(ctx);
81  if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
82  x = BN_CTX_get(ctx);
83  if (!BN_copy(x, order)) { ret=-1; goto err; }
84  if (!BN_mul_word(x, i)) { ret=-1; goto err; }
85  if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
86  field = BN_CTX_get(ctx);
87  if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
88  if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
89  if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
90  if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
91  if (check)
92  {
93  if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
94  if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
95  if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
96  }
97  if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
98  n = EC_GROUP_get_degree(group);
99  e = BN_CTX_get(ctx);
100  if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
101  if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
102  zero = BN_CTX_get(ctx);
103  if (!BN_zero(zero)) { ret=-1; goto err; }
104  if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
105  rr = BN_CTX_get(ctx);
106  if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
107  sor = BN_CTX_get(ctx);
108  if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
109  eor = BN_CTX_get(ctx);
110  if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
111  if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
112  if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
113 
114  ret = 1;
115 
116 err:
117  if (ctx) {
118  BN_CTX_end(ctx);
119  BN_CTX_free(ctx);
120  }
121  if (R != NULL) EC_POINT_free(R);
122  if (O != NULL) EC_POINT_free(O);
123  if (Q != NULL) EC_POINT_free(Q);
124  return ret;
125 }
126 
127 // RAII Wrapper around OpenSSL's EC_KEY
128 class CECKey {
129 private:
130  EC_KEY *pkey;
131 
132 public:
133  CECKey() {
134  pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
135  assert(pkey != NULL);
136  }
137 
138  ~CECKey() {
139  EC_KEY_free(pkey);
140  }
141 
142  void GetSecretBytes(unsigned char vch[32]) const {
143  const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
144  assert(bn);
145  int nBytes = BN_num_bytes(bn);
146  int n=BN_bn2bin(bn,&vch[32 - nBytes]);
147  assert(n == nBytes);
148  memset(vch, 0, 32 - nBytes);
149  }
150 
151  void SetSecretBytes(const unsigned char vch[32]) {
152  bool ret;
153  BIGNUM bn;
154  BN_init(&bn);
155  ret = BN_bin2bn(vch, 32, &bn);
156  assert(ret);
157  ret = EC_KEY_regenerate_key(pkey, &bn);
158  assert(ret);
159  BN_clear_free(&bn);
160  }
161 
162  void GetPrivKey(CPrivKey &privkey, bool fCompressed) {
163  EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
164  int nSize = i2d_ECPrivateKey(pkey, NULL);
165  assert(nSize);
166  privkey.resize(nSize);
167  unsigned char* pbegin = &privkey[0];
168  int nSize2 = i2d_ECPrivateKey(pkey, &pbegin);
169  assert(nSize == nSize2);
170  }
171 
172  bool SetPrivKey(const CPrivKey &privkey, bool fSkipCheck=false) {
173  const unsigned char* pbegin = &privkey[0];
174  if (d2i_ECPrivateKey(&pkey, &pbegin, privkey.size())) {
175  if(fSkipCheck)
176  return true;
177 
178  // d2i_ECPrivateKey returns true if parsing succeeds.
179  // This doesn't necessarily mean the key is valid.
180  if (EC_KEY_check_key(pkey))
181  return true;
182  }
183  return false;
184  }
185 
186  void GetPubKey(CPubKey &pubkey, bool fCompressed) {
187  EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
188  int nSize = i2o_ECPublicKey(pkey, NULL);
189  assert(nSize);
190  assert(nSize <= 65);
191  unsigned char c[65];
192  unsigned char *pbegin = c;
193  int nSize2 = i2o_ECPublicKey(pkey, &pbegin);
194  assert(nSize == nSize2);
195  pubkey.Set(&c[0], &c[nSize]);
196  }
197 
198  bool SetPubKey(const CPubKey &pubkey) {
199  const unsigned char* pbegin = pubkey.begin();
200  return o2i_ECPublicKey(&pkey, &pbegin, pubkey.size());
201  }
202 
203  bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) {
204  vchSig.clear();
205  ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
206  if (sig == NULL)
207  return false;
208  BN_CTX *ctx = BN_CTX_new();
209  BN_CTX_start(ctx);
210  const EC_GROUP *group = EC_KEY_get0_group(pkey);
211  BIGNUM *order = BN_CTX_get(ctx);
212  BIGNUM *halforder = BN_CTX_get(ctx);
213  EC_GROUP_get_order(group, order, ctx);
214  BN_rshift1(halforder, order);
215  if (BN_cmp(sig->s, halforder) > 0) {
216  // enforce low S values, by negating the value (modulo the order) if above order/2.
217  BN_sub(sig->s, order, sig->s);
218  }
219  BN_CTX_end(ctx);
220  BN_CTX_free(ctx);
221  unsigned int nSize = ECDSA_size(pkey);
222  vchSig.resize(nSize); // Make sure it is big enough
223  unsigned char *pos = &vchSig[0];
224  nSize = i2d_ECDSA_SIG(sig, &pos);
225  ECDSA_SIG_free(sig);
226  vchSig.resize(nSize); // Shrink to fit actual size
227  return true;
228  }
229 
230  bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
231  // -1 = error, 0 = bad sig, 1 = good
232  if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
233  return false;
234  return true;
235  }
236 
237  bool SignCompact(const uint256 &hash, unsigned char *p64, int &rec) {
238  bool fOk = false;
239  ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
240  if (sig==NULL)
241  return false;
242  memset(p64, 0, 64);
243  int nBitsR = BN_num_bits(sig->r);
244  int nBitsS = BN_num_bits(sig->s);
245  if (nBitsR <= 256 && nBitsS <= 256) {
246  CPubKey pubkey;
247  GetPubKey(pubkey, true);
248  for (int i=0; i<4; i++) {
249  CECKey keyRec;
250  if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1) {
251  CPubKey pubkeyRec;
252  keyRec.GetPubKey(pubkeyRec, true);
253  if (pubkeyRec == pubkey) {
254  rec = i;
255  fOk = true;
256  break;
257  }
258  }
259  }
260  assert(fOk);
261  BN_bn2bin(sig->r,&p64[32-(nBitsR+7)/8]);
262  BN_bn2bin(sig->s,&p64[64-(nBitsS+7)/8]);
263  }
264  ECDSA_SIG_free(sig);
265  return fOk;
266  }
267 
268  // reconstruct public key from a compact signature
269  // This is only slightly more CPU intensive than just verifying it.
270  // If this function succeeds, the recovered public key is guaranteed to be valid
271  // (the signature is a valid signature of the given data for that key)
272  bool Recover(const uint256 &hash, const unsigned char *p64, int rec)
273  {
274  if (rec<0 || rec>=3)
275  return false;
276  ECDSA_SIG *sig = ECDSA_SIG_new();
277  BN_bin2bn(&p64[0], 32, sig->r);
278  BN_bin2bn(&p64[32], 32, sig->s);
279  bool ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1;
280  ECDSA_SIG_free(sig);
281  return ret;
282  }
283 
284  static bool TweakSecret(unsigned char vchSecretOut[32], const unsigned char vchSecretIn[32], const unsigned char vchTweak[32])
285  {
286  bool ret = true;
287  BN_CTX *ctx = BN_CTX_new();
288  BN_CTX_start(ctx);
289  BIGNUM *bnSecret = BN_CTX_get(ctx);
290  BIGNUM *bnTweak = BN_CTX_get(ctx);
291  BIGNUM *bnOrder = BN_CTX_get(ctx);
292  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp256k1);
293  EC_GROUP_get_order(group, bnOrder, ctx); // what a grossly inefficient way to get the (constant) group order...
294  BN_bin2bn(vchTweak, 32, bnTweak);
295  if (BN_cmp(bnTweak, bnOrder) >= 0)
296  ret = false; // extremely unlikely
297  BN_bin2bn(vchSecretIn, 32, bnSecret);
298  BN_add(bnSecret, bnSecret, bnTweak);
299  BN_nnmod(bnSecret, bnSecret, bnOrder, ctx);
300  if (BN_is_zero(bnSecret))
301  ret = false; // ridiculously unlikely
302  int nBits = BN_num_bits(bnSecret);
303  memset(vchSecretOut, 0, 32);
304  BN_bn2bin(bnSecret, &vchSecretOut[32-(nBits+7)/8]);
305  EC_GROUP_free(group);
306  BN_CTX_end(ctx);
307  BN_CTX_free(ctx);
308  return ret;
309  }
310 
311  bool TweakPublic(const unsigned char vchTweak[32]) {
312  bool ret = true;
313  BN_CTX *ctx = BN_CTX_new();
314  BN_CTX_start(ctx);
315  BIGNUM *bnTweak = BN_CTX_get(ctx);
316  BIGNUM *bnOrder = BN_CTX_get(ctx);
317  BIGNUM *bnOne = BN_CTX_get(ctx);
318  const EC_GROUP *group = EC_KEY_get0_group(pkey);
319  EC_GROUP_get_order(group, bnOrder, ctx); // what a grossly inefficient way to get the (constant) group order...
320  BN_bin2bn(vchTweak, 32, bnTweak);
321  if (BN_cmp(bnTweak, bnOrder) >= 0)
322  ret = false; // extremely unlikely
323  EC_POINT *point = EC_POINT_dup(EC_KEY_get0_public_key(pkey), group);
324  BN_one(bnOne);
325  EC_POINT_mul(group, point, bnTweak, point, bnOne, ctx);
326  if (EC_POINT_is_at_infinity(group, point))
327  ret = false; // ridiculously unlikely
328  EC_KEY_set_public_key(pkey, point);
329  EC_POINT_free(point);
330  BN_CTX_end(ctx);
331  BN_CTX_free(ctx);
332  return ret;
333  }
334 };
335 
336 }; // end of anonymous namespace
337 
338 bool CKey::Check(const unsigned char *vch) {
339  // Do not convert to OpenSSL's data structures for range-checking keys,
340  // it's easy enough to do directly.
341  static const unsigned char vchMax[32] = {
342  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
343  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
344  0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
345  0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40
346  };
347  bool fIsZero = true;
348  for (int i=0; i<32 && fIsZero; i++)
349  if (vch[i] != 0)
350  fIsZero = false;
351  if (fIsZero)
352  return false;
353  for (int i=0; i<32; i++) {
354  if (vch[i] < vchMax[i])
355  return true;
356  if (vch[i] > vchMax[i])
357  return false;
358  }
359  return true;
360 }
361 
362 void CKey::MakeNewKey(bool fCompressedIn) {
363  do {
364  RAND_bytes(vch, sizeof(vch));
365  } while (!Check(vch));
366  fValid = true;
367  fCompressed = fCompressedIn;
368 }
369 
370 void CKey::SetSecret(const unsigned char vchIn[32], bool fCompressedIn) {
371  CECKey key;
372  key.SetSecretBytes(vchIn);
373  key.GetSecretBytes(vch);
374  fCompressed = fCompressedIn;
375  fValid = true;
376 }
377 
378 bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) {
379  CECKey key;
380  if (!key.SetPrivKey(privkey))
381  return false;
382  key.GetSecretBytes(vch);
383  fCompressed = fCompressedIn;
384  fValid = true;
385  return true;
386 }
387 
389  assert(fValid);
390  CECKey key;
391  key.SetSecretBytes(vch);
392  CPrivKey privkey;
393  key.GetPrivKey(privkey, fCompressed);
394  return privkey;
395 }
396 
398  assert(fValid);
399  CECKey key;
400  key.SetSecretBytes(vch);
401  CPubKey pubkey;
402  key.GetPubKey(pubkey, fCompressed);
403  return pubkey;
404 }
405 
406 bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
407  if (!fValid)
408  return false;
409  CECKey key;
410  key.SetSecretBytes(vch);
411  return key.Sign(hash, vchSig);
412 }
413 
414 bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
415  if (!fValid)
416  return false;
417  CECKey key;
418  key.SetSecretBytes(vch);
419  vchSig.resize(65);
420  int rec = -1;
421  if (!key.SignCompact(hash, &vchSig[1], rec))
422  return false;
423  assert(rec != -1);
424  vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
425  return true;
426 }
427 
428 bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) {
429  CECKey key;
430  if (!key.SetPrivKey(privkey, fSkipCheck))
431  return false;
432 
433  key.GetSecretBytes(vch);
434  fCompressed = vchPubKey.IsCompressed();
435  fValid = true;
436 
437  if (fSkipCheck)
438  return true;
439 
440  if (GetPubKey() != vchPubKey)
441  return false;
442 
443  return true;
444 }
445 
446 bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
447  if (!IsValid())
448  return false;
449  CECKey key;
450  if (!key.SetPubKey(*this))
451  return false;
452  if (!key.Verify(hash, vchSig))
453  return false;
454  return true;
455 }
456 
457 bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
458  if (vchSig.size() != 65)
459  return false;
460  CECKey key;
461  if (!key.Recover(hash, &vchSig[1], (vchSig[0] - 27) & ~4))
462  return false;
463  key.GetPubKey(*this, (vchSig[0] - 27) & 4);
464  return true;
465 }
466 
467 bool CPubKey::VerifyCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
468  if (!IsValid())
469  return false;
470  if (vchSig.size() != 65)
471  return false;
472  CECKey key;
473  if (!key.Recover(hash, &vchSig[1], (vchSig[0] - 27) & ~4))
474  return false;
475  CPubKey pubkeyRec;
476  key.GetPubKey(pubkeyRec, IsCompressed());
477  if (*this != pubkeyRec)
478  return false;
479  return true;
480 }
481 
482 bool CPubKey::IsFullyValid() const {
483  if (!IsValid())
484  return false;
485  CECKey key;
486  if (!key.SetPubKey(*this))
487  return false;
488  return true;
489 }
490 
492  if (!IsValid())
493  return false;
494  CECKey key;
495  if (!key.SetPubKey(*this))
496  return false;
497  key.GetPubKey(*this, false);
498  return true;
499 }
500 
501 void static BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]) {
502  unsigned char num[4];
503  num[0] = (nChild >> 24) & 0xFF;
504  num[1] = (nChild >> 16) & 0xFF;
505  num[2] = (nChild >> 8) & 0xFF;
506  num[3] = (nChild >> 0) & 0xFF;
507  HMAC_SHA512_CTX ctx;
508  HMAC_SHA512_Init(&ctx, chainCode, 32);
509  HMAC_SHA512_Update(&ctx, &header, 1);
510  HMAC_SHA512_Update(&ctx, data, 32);
511  HMAC_SHA512_Update(&ctx, num, 4);
512  HMAC_SHA512_Final(output, &ctx);
513 }
514 
515 bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const {
516  assert(IsValid());
517  assert(IsCompressed());
518  unsigned char out[64];
519  LockObject(out);
520  if ((nChild >> 31) == 0) {
521  CPubKey pubkey = GetPubKey();
522  assert(pubkey.begin() + 33 == pubkey.end());
523  BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin()+1, out);
524  } else {
525  assert(begin() + 32 == end());
526  BIP32Hash(cc, nChild, 0, begin(), out);
527  }
528  memcpy(ccChild, out+32, 32);
529  bool ret = CECKey::TweakSecret((unsigned char*)keyChild.begin(), begin(), out);
530  UnlockObject(out);
531  keyChild.fCompressed = true;
532  keyChild.fValid = ret;
533  return ret;
534 }
535 
536 bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const {
537  assert(IsValid());
538  assert((nChild >> 31) == 0);
539  assert(begin() + 33 == end());
540  unsigned char out[64];
541  BIP32Hash(cc, nChild, *begin(), begin()+1, out);
542  memcpy(ccChild, out+32, 32);
543  CECKey key;
544  bool ret = key.SetPubKey(*this);
545  ret &= key.TweakPublic(out);
546  key.GetPubKey(pubkeyChild, true);
547  return ret;
548 }
549 
550 bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const {
551  out.nDepth = nDepth + 1;
552  CKeyID id = key.GetPubKey().GetID();
553  memcpy(&out.vchFingerprint[0], &id, 4);
554  out.nChild = nChild;
555  return key.Derive(out.key, out.vchChainCode, nChild, vchChainCode);
556 }
557 
558 void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) {
559  static const char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
560  HMAC_SHA512_CTX ctx;
561  HMAC_SHA512_Init(&ctx, hashkey, sizeof(hashkey));
562  HMAC_SHA512_Update(&ctx, seed, nSeedLen);
563  unsigned char out[64];
564  LockObject(out);
565  HMAC_SHA512_Final(out, &ctx);
566  key.Set(&out[0], &out[32], true);
567  memcpy(vchChainCode, &out[32], 32);
568  UnlockObject(out);
569  nDepth = 0;
570  nChild = 0;
571  memset(vchFingerprint, 0, sizeof(vchFingerprint));
572 }
573 
575  CExtPubKey ret;
576  ret.nDepth = nDepth;
577  memcpy(&ret.vchFingerprint[0], &vchFingerprint[0], 4);
578  ret.nChild = nChild;
579  ret.pubkey = key.GetPubKey();
580  memcpy(&ret.vchChainCode[0], &vchChainCode[0], 32);
581  return ret;
582 }
583 
584 void CExtKey::Encode(unsigned char code[74]) const {
585  code[0] = nDepth;
586  memcpy(code+1, vchFingerprint, 4);
587  code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
588  code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
589  memcpy(code+9, vchChainCode, 32);
590  code[41] = 0;
591  assert(key.size() == 32);
592  memcpy(code+42, key.begin(), 32);
593 }
594 
595 void CExtKey::Decode(const unsigned char code[74]) {
596  nDepth = code[0];
597  memcpy(vchFingerprint, code+1, 4);
598  nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
599  memcpy(vchChainCode, code+9, 32);
600  key.Set(code+42, code+74, true);
601 }
602 
603 void CExtPubKey::Encode(unsigned char code[74]) const {
604  code[0] = nDepth;
605  memcpy(code+1, vchFingerprint, 4);
606  code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
607  code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
608  memcpy(code+9, vchChainCode, 32);
609  assert(pubkey.size() == 33);
610  memcpy(code+41, pubkey.begin(), 33);
611 }
612 
613 void CExtPubKey::Decode(const unsigned char code[74]) {
614  nDepth = code[0];
615  memcpy(vchFingerprint, code+1, 4);
616  nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
617  memcpy(vchChainCode, code+9, 32);
618  pubkey.Set(code+41, code+74);
619 }
620 
621 bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const {
622  out.nDepth = nDepth + 1;
623  CKeyID id = pubkey.GetID();
624  memcpy(&out.vchFingerprint[0], &id, 4);
625  out.nChild = nChild;
626  return pubkey.Derive(out.pubkey, out.vchChainCode, nChild, vchChainCode);
627 }
628 
630  EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
631  if(pkey == NULL)
632  return false;
633  EC_KEY_free(pkey);
634 
635  // TODO Is there more EC functionality that could be missing?
636  return true;
637 }
638 
639 
bool VerifyCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig) const
Definition: key.cpp:467
void UnlockObject(const T &t)
Definition: allocators.h:172
void Encode(unsigned char code[74]) const
Definition: key.cpp:584
unsigned char vchFingerprint[4]
Definition: key.h:280
const unsigned char * begin() const
Definition: key.h:235
unsigned char vchChainCode[32]
Definition: key.h:282
CExtPubKey Neuter() const
Definition: key.cpp:574
CKey key
Definition: key.h:300
const unsigned char * end() const
Definition: key.h:236
Definition: key.h:295
int HMAC_SHA512_Init(HMAC_SHA512_CTX *pctx, const void *pkey, size_t len)
Definition: hash.cpp:60
unsigned int size() const
Definition: key.h:91
void Set(const T pbegin, const T pend)
Definition: key.h:71
unsigned char vchFingerprint[4]
Definition: key.h:297
int HMAC_SHA512_Update(HMAC_SHA512_CTX *pctx, const void *pdata, size_t len)
Definition: hash.cpp:88
unsigned char nDepth
Definition: key.h:279
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Definition: key.cpp:406
void Decode(const unsigned char code[74])
Definition: key.cpp:595
bool fValid
Definition: key.h:184
unsigned int nChild
Definition: key.h:281
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: key.cpp:621
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:550
bool IsValid() const
Definition: key.h:239
void SetSecret(const unsigned char vchIn[32], bool fCompressed=false)
Definition: key.cpp:370
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
Definition: key.h:177
bool IsCompressed() const
Definition: key.h:242
void LockObject(const T &t)
Definition: allocators.h:168
CPubKey GetPubKey() const
Definition: key.cpp:397
CPrivKey GetPrivKey() const
Definition: key.cpp:388
bool Derive(CKey &keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const
Definition: key.cpp:515
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Definition: key.cpp:457
unsigned char nDepth
Definition: key.h:296
An encapsulated public key.
Definition: key.h:43
void MakeNewKey(bool fCompressed)
Definition: key.cpp:362
unsigned int nChild
Definition: key.h:298
unsigned char vchChainCode[32]
Definition: key.h:299
void Set(const T pbegin, const T pend, bool fCompressedIn)
Definition: key.h:219
int HMAC_SHA512_Final(unsigned char *pmd, HMAC_SHA512_CTX *pctx)
Definition: hash.cpp:93
const unsigned char * begin() const
Definition: key.h:92
bool Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck)
Definition: key.cpp:428
bool IsCompressed() const
Definition: key.h:152
void Decode(const unsigned char code[74])
Definition: key.cpp:613
256-bit unsigned integer
Definition: uint256.h:532
bool SetPrivKey(const CPrivKey &vchPrivKey, bool fCompressed)
Definition: key.cpp:378
bool SignCompact(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Definition: key.cpp:414
void * memcpy(void *a, const void *b, size_t c)
A reference to a CKey: the Hash160 of its serialized public key.
Definition: key.h:27
bool fCompressed
Definition: key.h:187
bool IsFullyValid() const
Definition: key.cpp:482
bool IsValid() const
Definition: key.h:144
void SetMaster(const unsigned char *seed, unsigned int nSeedLen)
Definition: key.cpp:558
CPubKey pubkey
Definition: key.h:283
static bool Check(const unsigned char *vch)
Definition: key.cpp:338
An encapsulated private key.
Definition: key.h:180
unsigned char vch[32]
Definition: key.h:190
bool ECC_InitSanityCheck()
Check that required EC support is available at runtime.
Definition: key.cpp:629
bool Verify(const uint256 &hash, const std::vector< unsigned char > &vchSig) const
Definition: key.cpp:446
void Encode(unsigned char code[74]) const
Definition: key.cpp:603
bool Derive(CPubKey &pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const
Definition: key.cpp:536
unsigned int size() const
Definition: key.h:234
CKeyID GetID() const
Definition: key.h:132
unsigned int size() const
Definition: uint256.h:366
const unsigned char * end() const
Definition: key.h:93
bool Decompress()
Definition: key.cpp:491