Update CMakeLists.txt - play with openssl
[novacoin.git] / src / key.cpp
1 // Copyright (c) 2009-2012 The Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "key.h"
6 #include "base58.h"
7 #include "streams.h"
8 #include "hash.h"
9
10 #include <openssl/ecdsa.h>
11 #include <openssl/evp.h>
12
13
14 // Generate a private key from just the secret parameter
15 int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
16 {
17     if (!eckey) return 0;
18
19     int ok = 0;
20     BN_CTX *ctx = nullptr;
21     EC_POINT *pub_key = nullptr;
22
23     const EC_GROUP *group = EC_KEY_get0_group(eckey);
24
25     if ((ctx = BN_CTX_new()) == nullptr)
26         goto err;
27
28     pub_key = EC_POINT_new(group);
29
30     if (pub_key == nullptr)
31         goto err;
32
33     if (!EC_POINT_mul(group, pub_key, priv_key, nullptr, nullptr, ctx))
34         goto err;
35
36     if (!EC_KEY_set_private_key(eckey,priv_key))
37         goto err;
38     if (!EC_KEY_set_public_key(eckey,pub_key))
39         goto err;
40
41     ok = 1;
42
43 err:
44
45     if (pub_key)
46         EC_POINT_free(pub_key);
47     if (ctx != nullptr)
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
86     // Get internal R and S pointers
87     const BIGNUM *ecsig_r, *ecsig_s;
88     ECDSA_SIG_get0(ecsig, &ecsig_r, &ecsig_s);
89
90     if (!BN_add(x, x, ecsig_r)) { ret=-1; goto err; }
91     field = BN_CTX_get(ctx);
92     if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
93     if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
94     if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
95     if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
96     if (check)
97     {
98         if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
99         if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
100         if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
101     }
102     if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
103     n = EC_GROUP_get_degree(group);
104     e = BN_CTX_get(ctx);
105     if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
106     if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
107     zero = BN_CTX_get(ctx);
108     if (!BN_set_word(zero, 0)) { ret=-1; goto err; }
109     if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
110     rr = BN_CTX_get(ctx);
111     if (!BN_mod_inverse(rr, ecsig_r, order, ctx)) { ret=-1; goto err; }
112     sor = BN_CTX_get(ctx);
113     if (!BN_mod_mul(sor, ecsig_s, rr, order, ctx)) { ret=-1; goto err; }
114     eor = BN_CTX_get(ctx);
115     if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
116     if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
117     if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
118
119     ret = 1;
120
121 err:
122     if (ctx) {
123         BN_CTX_end(ctx);
124         BN_CTX_free(ctx);
125     }
126     if (R != NULL) EC_POINT_free(R);
127     if (O != NULL) EC_POINT_free(O);
128     if (Q != NULL) EC_POINT_free(Q);
129     return ret;
130 }
131
132 int CompareBigEndian(const unsigned char *c1, size_t c1len, const unsigned char *c2, size_t c2len) {
133     while (c1len > c2len) {
134         if (*c1)
135             return 1;
136         c1++;
137         c1len--;
138     }
139     while (c2len > c1len) {
140         if (*c2)
141             return -1;
142         c2++;
143         c2len--;
144     }
145     while (c1len > 0) {
146         if (*c1 > *c2)
147             return 1;
148         if (*c2 > *c1)
149             return -1;
150         c1++;
151         c2++;
152         c1len--;
153     }
154     return 0;
155 }
156
157 // Order of secp256k1's generator minus 1.
158 const unsigned char vchMaxModOrder[32] = {
159     0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
160     0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
161     0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
162     0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40
163 };
164
165 // Half of the order of secp256k1's generator minus 1.
166 const unsigned char vchMaxModHalfOrder[32] = {
167     0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
168     0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
169     0x5D,0x57,0x6E,0x73,0x57,0xA4,0x50,0x1D,
170     0xDF,0xE9,0x2F,0x46,0x68,0x1B,0x20,0xA0
171 };
172
173 const unsigned char *vchZero = NULL;
174
175 void CKey::SetCompressedPubKey(bool fCompressed)
176 {
177     EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
178 }
179
180 void CKey::Reset()
181 {
182     fSet = false;
183     if (pkey != NULL)
184         EC_KEY_free(pkey);
185     pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
186     if (pkey == NULL)
187         throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
188 }
189
190 CKey::CKey()
191 {
192     pkey = NULL;
193     Reset();
194 }
195
196 CKey::CKey(const CKey& b)
197 {
198     pkey = EC_KEY_dup(b.pkey);
199     if (pkey == NULL)
200         throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
201     fSet = b.fSet;
202 }
203
204 CKey::CKey(const CSecret& b, bool fCompressed)
205 {
206     pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
207     if (pkey == NULL)
208         throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
209     SetSecret(b, fCompressed);
210 }
211
212 CKey& CKey::operator=(const CKey& b)
213 {
214     if (!EC_KEY_copy(pkey, b.pkey))
215         throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
216     fSet = b.fSet;
217     return (*this);
218 }
219
220 CKey::~CKey()
221 {
222     if (pkey != NULL)
223         EC_KEY_free(pkey);
224 }
225
226 bool CKey::IsNull() const
227 {
228     return !fSet;
229 }
230
231 bool CKey::IsCompressed() const
232 {
233     return (EC_KEY_get_conv_form(pkey) == POINT_CONVERSION_COMPRESSED);
234 }
235
236 bool CKey::CheckSignatureElement(const unsigned char *vch, int len, bool half) {
237     return CompareBigEndian(vch, len, vchZero, 0) > 0 &&
238         CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0;
239 }
240
241 bool CPubKey::ReserealizeSignature(std::vector<unsigned char>& vchSig)
242 {
243     if (vchSig.empty())
244         return false;
245
246     unsigned char *pos = &vchSig[0];
247     ECDSA_SIG *sig = d2i_ECDSA_SIG(NULL, (const unsigned char **)&pos, vchSig.size());
248     if (sig == NULL)
249         return false;
250
251     bool ret = false;
252     int nSize = i2d_ECDSA_SIG(sig, NULL);
253     if (nSize > 0) {
254         vchSig.resize(nSize); // grow or shrink as needed
255
256         pos = &vchSig[0];
257         i2d_ECDSA_SIG(sig, &pos);
258
259         ret = true;
260     }
261
262     ECDSA_SIG_free(sig);
263
264     return ret;
265 }
266
267 void CKey::MakeNewKey(bool fCompressed)
268 {
269     if (!EC_KEY_generate_key(pkey))
270         throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
271     SetCompressedPubKey(fCompressed);
272     fSet = true;
273 }
274
275 bool CKey::SetPrivKey(const CPrivKey& vchPrivKey)
276 {
277     const unsigned char* pbegin = &vchPrivKey[0];
278     if (d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
279     {
280         // In testing, d2i_ECPrivateKey can return true
281         // but fill in pkey with a key that fails
282         // EC_KEY_check_key, so:
283         if (EC_KEY_check_key(pkey))
284         {
285             fSet = true;
286             return true;
287         }
288     }
289     // If vchPrivKey data is bad d2i_ECPrivateKey() can
290     // leave pkey in a state where calling EC_KEY_free()
291     // crashes. To avoid that, set pkey to NULL and
292     // leak the memory (a leak is better than a crash)
293     pkey = NULL;
294     Reset();
295     return false;
296 }
297
298 bool CKey::SetSecret(const CSecret& vchSecret, bool fCompressed)
299 {
300     EC_KEY_free(pkey);
301     pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
302     if (pkey == NULL)
303         throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
304
305     if (vchSecret.size() != 32)
306         throw key_error("CKey::SetSecret() : secret must be 32 bytes");
307     BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
308     if (bn == NULL)
309         throw key_error("CKey::SetSecret() : BN_bin2bn failed");
310     if (!EC_KEY_regenerate_key(pkey,bn))
311     {
312         BN_clear_free(bn);
313         throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
314     }
315     BN_clear_free(bn);
316     fSet = true;
317     SetCompressedPubKey(fCompressed);
318     return true;
319 }
320
321 CSecret CKey::GetSecret(bool &fCompressed) const
322 {
323     CSecret vchRet;
324     vchRet.resize(32);
325     const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
326     int nBytes = BN_num_bytes(bn);
327     if (bn == NULL)
328         throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed");
329     int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
330     if (n != nBytes)
331         throw key_error("CKey::GetSecret(): BN_bn2bin failed");
332     fCompressed = IsCompressed();
333     return vchRet;
334 }
335
336 CSecret CKey::GetSecret() const
337 {
338     bool fCompressed;
339     return GetSecret(fCompressed);
340 }
341
342 CPrivKey CKey::GetPrivKey() const
343 {
344     int nSize = i2d_ECPrivateKey(pkey, NULL);
345     if (!nSize)
346         throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
347     CPrivKey vchPrivKey(nSize, 0);
348     unsigned char* pbegin = &vchPrivKey[0];
349     if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
350         throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
351     return vchPrivKey;
352 }
353
354 CPubKey CKey::GetPubKey() const
355 {
356     int nSize = i2o_ECPublicKey(pkey, NULL);
357     if (!nSize)
358         throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
359     std::vector<unsigned char> vchPubKey(nSize, 0);
360     unsigned char* pbegin = &vchPubKey[0];
361     if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
362         throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
363     return CPubKey(vchPubKey);
364 }
365
366 bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig)
367 {
368     vchSig.clear();
369     ECDSA_SIG *sig = ECDSA_do_sign(hash.begin(), sizeof(hash), pkey);
370     if (sig==nullptr)
371         return false;
372     const EC_GROUP *group = EC_KEY_get0_group(pkey);
373
374     BIGNUM* order = BN_new(), *halforder = BN_new();
375     EC_GROUP_get_order(group, order, nullptr);
376     BN_rshift1(halforder, order);
377
378     // Get internal R and S pointers
379     const BIGNUM *current_s = ECDSA_SIG_get0_s(sig);
380     BIGNUM *current_r = BN_dup(ECDSA_SIG_get0_r(sig));
381
382     // enforce low S values, by negating the value (modulo the order) if above order/2.
383     if (BN_cmp(current_s, halforder) > 0) {
384         BIGNUM *updated_s = BN_new();
385         BN_copy(updated_s, current_s);
386         BN_sub(updated_s, order, updated_s);
387         ECDSA_SIG_set0(sig, current_r, updated_s);
388     }
389
390     BN_free(order);
391     BN_free(halforder);
392
393     unsigned int nSize = ECDSA_size(pkey);
394     vchSig.resize(nSize); // Make sure it is big enough
395     unsigned char *pos = &vchSig[0];
396     nSize = i2d_ECDSA_SIG(sig, &pos);
397     ECDSA_SIG_free(sig);
398     vchSig.resize(nSize); // Shrink to fit actual size
399     // Testing our new signature
400     if (ECDSA_verify(0, hash.begin(), sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) {
401         vchSig.clear();
402         return false;
403     }
404     return true;
405 }
406
407 // create a compact signature (65 bytes), which allows reconstructing the used public key
408 // The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
409 // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
410 //                  0x1D = second key with even y, 0x1E = second key with odd y
411 bool CKey::SignCompact(uint256 hash, std::vector<unsigned char>& vchSig)
412 {
413     bool fOk = false;
414     ECDSA_SIG *sig = ECDSA_do_sign(hash.begin(), sizeof(hash), pkey);
415     if (sig==nullptr)
416         return false;
417     const EC_GROUP *group = EC_KEY_get0_group(pkey);
418     BIGNUM* order = BN_new(), *halforder = BN_new();
419     EC_GROUP_get_order(group, order, nullptr);
420     BN_rshift1(halforder, order);
421
422     // Get internal R and S pointers
423     const BIGNUM *current_s = ECDSA_SIG_get0_s(sig);
424     BIGNUM *current_r = BN_dup(ECDSA_SIG_get0_r(sig));
425
426     // enforce low S values, by negating the value (modulo the order) if above order/2.
427     if (BN_cmp(current_s, halforder) > 0) {
428         BIGNUM *updated_s = BN_new();
429         BN_copy(updated_s, current_s);
430         BN_sub(updated_s, order, updated_s);
431         ECDSA_SIG_set0(sig, current_r, updated_s);
432     }
433
434     BN_free(order);
435     BN_free(halforder);
436
437     vchSig.clear();
438     vchSig.resize(65,0);
439     int nBitsR = BN_num_bits(ECDSA_SIG_get0_r(sig));
440     int nBitsS = BN_num_bits(ECDSA_SIG_get0_s(sig));
441     bool fCompressedPubKey = IsCompressed();
442     if (nBitsR <= 256 && nBitsS <= 256)
443     {
444         int8_t nRecId = -1;
445         for (int8_t i=0; i<4; i++)
446         {
447             CKey keyRec;
448             keyRec.fSet = true;
449             keyRec.SetCompressedPubKey(fCompressedPubKey);
450             if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, hash.begin(), sizeof(hash), i, 1) == 1)
451                 if (keyRec.GetPubKey() == this->GetPubKey())
452                 {
453                     nRecId = i;
454                     break;
455                 }
456         }
457
458         if (nRecId == -1)
459         {
460             ECDSA_SIG_free(sig);
461             throw key_error("CKey::SignCompact() : unable to construct recoverable key");
462         }
463
464         vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0);
465         BN_bn2bin(ECDSA_SIG_get0_r(sig),&vchSig[33-(nBitsR+7)/8]);
466         BN_bn2bin(ECDSA_SIG_get0_s(sig),&vchSig[65-(nBitsS+7)/8]);
467         fOk = true;
468     }
469
470     ECDSA_SIG_free(sig);
471     return fOk;
472 }
473
474 // reconstruct public key from a compact signature
475 // This is only slightly more CPU intensive than just verifying it.
476 // If this function succeeds, the recovered public key is guaranteed to be valid
477 // (the signature is a valid signature of the given data for that key)
478 bool CPubKey::SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
479 {
480     if (vchSig.size() != 65)
481         return false;
482     int nV = vchSig[0];
483     if (nV<27 || nV>=35)
484         return false;
485     ECDSA_SIG *sig = ECDSA_SIG_new();
486     BIGNUM *sig_r = BN_new(), *sig_s = BN_new();
487     BN_bin2bn(&vchSig[1],32,sig_r);
488     BN_bin2bn(&vchSig[33],32,sig_s);
489     ECDSA_SIG_set0(sig, sig_r, sig_s);
490     bool fSuccessful = false;
491     EC_KEY* pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
492     if (nV >= 31)
493     {
494         nV -= 4;
495         EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
496     }
497     do
498     {
499         if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) != 1)
500             break;
501         int nSize = i2o_ECPublicKey(pkey, NULL);
502         if (!nSize)
503             break;
504         std::vector<unsigned char> vchPubKey(nSize, 0);
505         unsigned char* pbegin = &vchPubKey[0];
506         if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
507             break;
508         Set(vchPubKey.begin(), vchPubKey.end());
509         fSuccessful = IsValid();
510
511     } while (false);
512     ECDSA_SIG_free(sig);
513     EC_KEY_free(pkey);
514     if (!fSuccessful)
515         Invalidate();
516     return fSuccessful;
517 }
518
519 CKeyID CPubKey::GetID() const
520 {
521     return CKeyID(Hash160(vbytes, vbytes + size()));
522 }
523
524 uint256 CPubKey::GetHash() const
525 {
526     return Hash(vbytes, vbytes + size());
527 }
528
529 bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const
530 {
531     if (vchSig.empty() || !IsValid())
532         return false;
533
534     EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
535     ECDSA_SIG *norm_sig = ECDSA_SIG_new();
536
537     assert(norm_sig);
538     assert(pkey);
539
540     bool ret = false;
541     do
542     {
543         int derlen;
544         uint8_t *norm_der = NULL;
545         const uint8_t* pbegin = &vbytes[0];
546         const uint8_t* sigptr = &vchSig[0];
547
548         // Trying to parse public key
549         if (!o2i_ECPublicKey(&pkey, &pbegin, size()))
550             break;
551         // New versions of OpenSSL are rejecting a non-canonical DER signatures, de/re-serialize first.
552         if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
553             break;
554         if ((derlen = i2d_ECDSA_SIG(norm_sig, &norm_der)) <= 0)
555             break;
556
557         // -1 = error, 0 = bad sig, 1 = good
558         ret = ECDSA_verify(0, (const unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
559         OPENSSL_free(norm_der);
560     } while(false);
561
562     ECDSA_SIG_free(norm_sig);
563     EC_KEY_free(pkey);
564
565     return ret;
566 }
567
568 bool CPubKey::VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig)
569 {
570     CPubKey key;
571     if (!key.SetCompactSignature(hash, vchSig))
572         return false;
573     return true;
574 }
575
576 bool CKey::IsValid()
577 {
578     if (!fSet)
579         return false;
580
581     if (!EC_KEY_check_key(pkey))
582         return false;
583
584     bool fCompr;
585     CSecret secret = GetSecret(fCompr);
586     CKey key2;
587     key2.SetSecret(secret, fCompr);
588
589     return GetPubKey() == key2.GetPubKey();
590 }
591
592 CPoint::CPoint()
593 {
594     std::string err;
595     group = NULL;
596     point = NULL;
597     ctx   = NULL;
598
599     group = EC_GROUP_new_by_curve_name(NID_secp256k1);
600     if (!group) {
601         err = "EC_KEY_new_by_curve_name failed.";
602         goto finish;
603     }
604
605     point = EC_POINT_new(group);
606     if (!point) {
607         err = "EC_POINT_new failed.";
608         goto finish;
609     }
610
611     ctx = BN_CTX_new();
612     if (!ctx) {
613         err = "BN_CTX_new failed.";
614         goto finish;
615     }
616
617     return;
618
619 finish:
620     if (group) EC_GROUP_free(group);
621     if (point) EC_POINT_free(point);
622     throw std::runtime_error(std::string("CPoint::CPoint() :  - ") + err);
623 }
624
625 bool CPoint::operator!=(const CPoint &a)
626 {
627     if (EC_POINT_cmp(group, point, a.point, ctx) != 0)
628         return true;
629     return false;
630 }
631 CPoint::~CPoint()
632 {
633     if (point) EC_POINT_free(point);
634     if (group) EC_GROUP_free(group);
635     if (ctx)   BN_CTX_free(ctx);
636 }
637
638 // Initialize from octets stream
639 bool CPoint::setBytes(const std::vector<unsigned char> &vchBytes)
640 {
641     if (!EC_POINT_oct2point(group, point, &vchBytes[0], vchBytes.size(), ctx)) {
642         return false;
643     }
644     return true;
645 }
646
647 // Initialize from octets stream
648 bool CPoint::setPubKey(const CPubKey &key)
649 {
650     std::vector<uint8_t> vchPubKey(key.begin(), key.end());
651     return setBytes(vchPubKey);
652 }
653
654 // Serialize to octets stream
655 bool CPoint::getBytes(std::vector<unsigned char> &vchBytes)
656 {
657     size_t nSize = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, ctx);
658     vchBytes.resize(nSize);
659     if (!(nSize == EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, &vchBytes[0], nSize, ctx))) {
660         return false;
661     }
662     return true;
663 }
664
665 // ECC multiplication by specified multiplier
666 bool CPoint::ECMUL(const CBigNum &bnMultiplier)
667 {
668     BIGNUM* bnMul = bnMultiplier.get();
669     bool ok = EC_POINT_mul(group, point, NULL, point, bnMul, NULL);
670     if (!ok) printf("CPoint::ECMUL() : EC_POINT_mul failed");
671     BN_free(bnMul);
672     return ok;
673 }
674
675 // Calculate G*m + q
676 bool CPoint::ECMULGEN(const CBigNum &bnMultiplier, const CPoint &qPoint)
677 {
678     BIGNUM* bnMul = bnMultiplier.get();
679     bool ok = EC_POINT_mul(group, point, bnMul, qPoint.point, BN_value_one(), NULL);
680     if (!ok) printf("CPoint::ECMULGEN() : EC_POINT_mul failed.");
681     BN_free(bnMul);
682     return ok;
683 }
684
685 // CMalleablePubKey
686
687 void CMalleablePubKey::GetVariant(CPubKey &R, CPubKey &vchPubKeyVariant)
688 {
689     EC_KEY *eckey = NULL;
690     eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
691     if (eckey == NULL) {
692         throw key_error("CMalleablePubKey::GetVariant() : EC_KEY_new_by_curve_name failed");
693     }
694
695     // Use standard key generation function to get r and R values.
696     //
697     // r will be presented by private key;
698     // R is ECDSA public key which calculated as G*r
699     if (!EC_KEY_generate_key(eckey)) {
700         throw key_error("CMalleablePubKey::GetVariant() : EC_KEY_generate_key failed");
701     }
702
703     EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
704
705     int nSize = i2o_ECPublicKey(eckey, NULL);
706     if (!nSize) {
707         throw key_error("CMalleablePubKey::GetVariant() : i2o_ECPublicKey failed");
708     }
709
710     std::vector<unsigned char> vchPubKey(nSize, 0);
711     unsigned char* pbegin_R = &vchPubKey[0];
712
713     if (i2o_ECPublicKey(eckey, &pbegin_R) != nSize) {
714         throw key_error("CMalleablePubKey::GetVariant() : i2o_ECPublicKey returned unexpected size");
715     }
716
717     // R = G*r
718     R = CPubKey(vchPubKey);
719
720     // OpenSSL BIGNUM representation of r value
721     CBigNum bnr(EC_KEY_get0_private_key(eckey));
722     EC_KEY_free(eckey);
723
724     CPoint point;
725     if (!point.setPubKey(pubKeyL)) {
726         throw key_error("CMalleablePubKey::GetVariant() : Unable to decode L value");
727     }
728
729     // Calculate L*r
730     point.ECMUL(bnr);
731
732     std::vector<unsigned char> vchLr;
733     if (!point.getBytes(vchLr)) {
734         throw key_error("CMalleablePubKey::GetVariant() : Unable to convert Lr value");
735     }
736
737     // Calculate Hash(L*r) and then get a BIGNUM representation of hash value.
738     CBigNum bnHash;
739     bnHash.setuint160(Hash160(vchLr));
740
741     CPoint pointH;
742     pointH.setPubKey(pubKeyH);
743
744     CPoint P;
745     // Calculate P = Hash(L*r)*G + H
746     P.ECMULGEN(bnHash, pointH);
747
748     if (P.IsInfinity()) {
749         throw key_error("CMalleablePubKey::GetVariant() : P is infinity");
750     }
751
752     std::vector<unsigned char> vchResult;
753     P.getBytes(vchResult);
754
755     vchPubKeyVariant = CPubKey(vchResult);
756 }
757
758 std::string CMalleablePubKey::ToString() const
759 {
760     CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
761     ssKey << *this;
762     std::vector<unsigned char> vch(ssKey.begin(), ssKey.end());
763
764     return EncodeBase58Check(vch);
765 }
766
767 bool CMalleablePubKey::setvch(const std::vector<unsigned char> &vchPubKeyPair)
768 {
769     CDataStream ssKey(vchPubKeyPair, SER_NETWORK, PROTOCOL_VERSION);
770     ssKey >> *this;
771
772     return IsValid();
773 }
774
775 std::vector<unsigned char> CMalleablePubKey::Raw() const
776 {
777     CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
778     ssKey << *this;
779     std::vector<unsigned char> vch(ssKey.begin(), ssKey.end());
780
781     return vch;
782 }
783
784 bool CMalleablePubKey::SetString(const std::string& strMalleablePubKey)
785 {
786     std::vector<unsigned char> vchTemp;
787     if (!DecodeBase58Check(strMalleablePubKey, vchTemp)) {
788         throw key_error("CMalleablePubKey::SetString() : Provided key data seems corrupted.");
789     }
790     if (vchTemp.size() != 68)
791         return false;
792
793     CDataStream ssKey(vchTemp, SER_NETWORK, PROTOCOL_VERSION);
794     ssKey >> *this;
795
796     return IsValid();
797 }
798
799 bool CMalleablePubKey::operator==(const CMalleablePubKey &b)
800 {
801     return pubKeyL == b.pubKeyL && pubKeyH == b.pubKeyH;
802 }
803
804
805 // CMalleableKey
806
807 void CMalleableKey::Reset()
808 {
809     vchSecretL.clear();
810     vchSecretH.clear();
811 }
812
813 void CMalleableKey::MakeNewKeys()
814 {
815     Reset();
816
817     CKey keyL, keyH;
818     keyL.MakeNewKey();
819     keyH.MakeNewKey();
820
821     vchSecretL = keyL.GetSecret();
822     vchSecretH = keyH.GetSecret();
823 }
824
825 CMalleableKey::CMalleableKey()
826 {
827     Reset();
828 }
829
830 CMalleableKey::CMalleableKey(const CMalleableKey &b)
831 {
832     SetSecrets(b.vchSecretL, b.vchSecretH);
833 }
834
835 CMalleableKey::CMalleableKey(const CSecret &L, const CSecret &H)
836 {
837     SetSecrets(L, H);
838 }
839
840 CMalleableKey::~CMalleableKey()
841 {
842 }
843
844 bool CMalleableKey::IsNull() const
845 {
846     return vchSecretL.size() != 32 || vchSecretH.size() != 32;
847 }
848
849 bool CMalleableKey::SetSecrets(const CSecret &pvchSecretL, const CSecret &pvchSecretH)
850 {
851     Reset();
852
853     CKey keyL(pvchSecretL);
854     CKey keyH(pvchSecretH);
855
856     if (!keyL.IsValid() || !keyH.IsValid())
857         return false;
858
859     vchSecretL = pvchSecretL;
860     vchSecretH = pvchSecretH;
861
862     return true;
863 }
864
865 CMalleablePubKey CMalleableKey::GetMalleablePubKey() const
866 {
867     CKey L(vchSecretL), H(vchSecretH);
868     return CMalleablePubKey(L.GetPubKey(), H.GetPubKey());
869 }
870
871 // Check ownership
872 bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const
873 {
874     if (IsNull()) {
875         throw key_error("CMalleableKey::CheckKeyVariant() : Attempting to run on NULL key object.");
876     }
877
878     if (!R.IsValid()) {
879         printf("CMalleableKey::CheckKeyVariant() : R is invalid");
880         return false;
881     }
882
883     if (!vchPubKeyVariant.IsValid()) {
884         printf("CMalleableKey::CheckKeyVariant() : public key variant is invalid");
885         return false;
886     }
887
888     CPoint point_R;
889     if (!point_R.setPubKey(R)) {
890         printf("CMalleableKey::CheckKeyVariant() : Unable to decode R value");
891         return false;
892     }
893
894     CKey H(vchSecretH);
895     CPubKey vchPubKeyH = H.GetPubKey();
896
897     CPoint point_H;
898     if (!point_H.setPubKey(vchPubKeyH)) {
899         printf("CMalleableKey::CheckKeyVariant() : Unable to decode H value");
900         return false;
901     }
902
903     CPoint point_P;
904     if (!point_P.setPubKey(vchPubKeyVariant)) {
905         printf("CMalleableKey::CheckKeyVariant() : Unable to decode P value");
906         return false;
907     }
908
909     // Infinity points are senseless
910     if (point_P.IsInfinity()) {
911         printf("CMalleableKey::CheckKeyVariant() : P is infinity");
912         return false;
913     }
914
915     CBigNum bnl;
916     bnl.setBytes(std::vector<unsigned char>(vchSecretL.begin(), vchSecretL.end()));
917
918     point_R.ECMUL(bnl);
919
920     std::vector<unsigned char> vchRl;
921     if (!point_R.getBytes(vchRl)) {
922         printf("CMalleableKey::CheckKeyVariant() : Unable to convert Rl value");
923         return false;
924     }
925
926     // Calculate Hash(R*l)
927     CBigNum bnHash;
928     bnHash.setuint160(Hash160(vchRl));
929
930     CPoint point_Ps;
931     // Calculate Ps = Hash(L*r)*G + H
932     point_Ps.ECMULGEN(bnHash, point_H);
933
934     // Infinity points are senseless
935     if (point_Ps.IsInfinity()) {
936         printf("CMalleableKey::CheckKeyVariant() : Ps is infinity");
937         return false;
938     }
939
940     // Check ownership
941     if (point_Ps != point_P) {
942         return false;
943     }
944
945     return true;
946 }
947
948 // Check ownership and restore private key
949 bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant) const
950 {
951     if (IsNull()) {
952         throw key_error("CMalleableKey::CheckKeyVariant() : Attempting to run on NULL key object.");
953     }
954
955     if (!R.IsValid()) {
956         printf("CMalleableKey::CheckKeyVariant() : R is invalid");
957         return false;
958     }
959
960     if (!vchPubKeyVariant.IsValid()) {
961         printf("CMalleableKey::CheckKeyVariant() : public key variant is invalid");
962         return false;
963     }
964
965     CPoint point_R;
966     if (!point_R.setPubKey(R)) {
967         printf("CMalleableKey::CheckKeyVariant() : Unable to decode R value");
968         return false;
969     }
970
971     CKey H(vchSecretH);
972     CPubKey vchPubKeyH = H.GetPubKey();
973
974     CPoint point_H;
975     if (!point_H.setPubKey(vchPubKeyH)) {
976         printf("CMalleableKey::CheckKeyVariant() : Unable to decode H value");
977         return false;
978     }
979
980     CPoint point_P;
981     if (!point_P.setPubKey(vchPubKeyVariant)) {
982         printf("CMalleableKey::CheckKeyVariant() : Unable to decode P value");
983         return false;
984     }
985
986     // Infinity points are senseless
987     if (point_P.IsInfinity()) {
988         printf("CMalleableKey::CheckKeyVariant() : P is infinity");
989         return false;
990     }
991
992     CBigNum bnl;
993     bnl.setBytes(std::vector<unsigned char>(vchSecretL.begin(), vchSecretL.end()));
994
995     point_R.ECMUL(bnl);
996
997     std::vector<unsigned char> vchRl;
998     if (!point_R.getBytes(vchRl)) {
999         printf("CMalleableKey::CheckKeyVariant() : Unable to convert Rl value");
1000         return false;
1001     }
1002
1003     // Calculate Hash(R*l)
1004     CBigNum bnHash;
1005     bnHash.setuint160(Hash160(vchRl));
1006
1007     CPoint point_Ps;
1008     // Calculate Ps = Hash(L*r)*G + H
1009     point_Ps.ECMULGEN(bnHash, point_H);
1010
1011     // Infinity points are senseless
1012     if (point_Ps.IsInfinity()) {
1013         printf("CMalleableKey::CheckKeyVariant() : Ps is infinity");
1014         return false;
1015     }
1016
1017     // Check ownership
1018     if (point_Ps != point_P) {
1019         return false;
1020     }
1021
1022     // OpenSSL BIGNUM representation of the second private key from (l, h) pair
1023     CBigNum bnh;
1024     bnh.setBytes(std::vector<unsigned char>(vchSecretH.begin(), vchSecretH.end()));
1025
1026     // Calculate p = Hash(R*l) + h
1027     CBigNum bnp = bnHash + bnh;
1028
1029     std::vector<unsigned char> vchp = bnp.getBytes();
1030     privKeyVariant.SetSecret(CSecret(vchp.begin(), vchp.end()));
1031
1032     return true;
1033 }
1034
1035 std::string CMalleableKey::ToString() const
1036 {
1037     CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
1038     ssKey << *this;
1039     std::vector<unsigned char> vch(ssKey.begin(), ssKey.end());
1040
1041     return EncodeBase58Check(vch);
1042 }
1043
1044 std::vector<unsigned char> CMalleableKey::Raw() const
1045 {
1046     CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
1047     ssKey << *this;
1048     std::vector<unsigned char> vch(ssKey.begin(), ssKey.end());
1049
1050     return vch;
1051 }
1052
1053 bool CMalleableKey::SetString(const std::string& strMutableKey)
1054 {
1055     std::vector<unsigned char> vchTemp;
1056     if (!DecodeBase58Check(strMutableKey, vchTemp)) {
1057         throw key_error("CMalleableKey::SetString() : Provided key data seems corrupted.");
1058     }
1059     if (vchTemp.size() != 66)
1060         return false;
1061     CDataStream ssKey(vchTemp, SER_NETWORK, PROTOCOL_VERSION);
1062     ssKey >> *this;
1063
1064     return IsValid();
1065 }
1066
1067 // CMalleableKeyView
1068
1069 CMalleableKeyView::CMalleableKeyView(const std::string &strMalleableKey)
1070 {
1071     SetString(strMalleableKey);
1072 }
1073
1074 CMalleableKeyView::CMalleableKeyView(const CMalleableKey &b)
1075 {
1076     if (b.vchSecretL.size() != 32)
1077         throw key_error("CMalleableKeyView::CMalleableKeyView() : L size must be 32 bytes");
1078
1079     if (b.vchSecretH.size() != 32)
1080         throw key_error("CMalleableKeyView::CMalleableKeyView() : H size must be 32 bytes");
1081
1082     vchSecretL = b.vchSecretL;
1083
1084     CKey H(b.vchSecretH);
1085     vchPubKeyH = H.GetPubKey();
1086 }
1087
1088 CMalleableKeyView::CMalleableKeyView(const CMalleableKeyView &b)
1089 {
1090     vchSecretL = b.vchSecretL;
1091     vchPubKeyH = b.vchPubKeyH;
1092 }
1093
1094 CMalleableKeyView& CMalleableKeyView::operator=(const CMalleableKey &b)
1095 {
1096     vchSecretL = b.vchSecretL;
1097
1098     CKey H(b.vchSecretH);
1099     vchPubKeyH = H.GetPubKey();
1100
1101     return (*this);
1102 }
1103
1104 CMalleableKeyView::~CMalleableKeyView()
1105 {
1106 }
1107
1108 CMalleablePubKey CMalleableKeyView::GetMalleablePubKey() const
1109 {
1110     CKey keyL(vchSecretL);
1111     return CMalleablePubKey(keyL.GetPubKey(), vchPubKeyH);
1112 }
1113
1114 // Check ownership
1115 bool CMalleableKeyView::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const
1116 {
1117     if (!IsValid()) {
1118         throw key_error("CMalleableKeyView::CheckKeyVariant() : Attempting to run on invalid view object.");
1119     }
1120
1121     if (!R.IsValid()) {
1122         printf("CMalleableKeyView::CheckKeyVariant() : R is invalid");
1123         return false;
1124     }
1125
1126     if (!vchPubKeyVariant.IsValid()) {
1127         printf("CMalleableKeyView::CheckKeyVariant() : public key variant is invalid");
1128         return false;
1129     }
1130
1131     CPoint point_R;
1132     if (!point_R.setPubKey(R)) {
1133         printf("CMalleableKeyView::CheckKeyVariant() : Unable to decode R value");
1134         return false;
1135     }
1136
1137     CPoint point_H;
1138     if (!point_H.setPubKey(vchPubKeyH)) {
1139         printf("CMalleableKeyView::CheckKeyVariant() : Unable to decode H value");
1140         return false;
1141     }
1142
1143     CPoint point_P;
1144     if (!point_P.setPubKey(vchPubKeyVariant)) {
1145         printf("CMalleableKeyView::CheckKeyVariant() : Unable to decode P value");
1146         return false;
1147     }
1148
1149     // Infinity points are senseless
1150     if (point_P.IsInfinity()) {
1151         printf("CMalleableKeyView::CheckKeyVariant() : P is infinity");
1152         return false;
1153     }
1154
1155     CBigNum bnl;
1156     bnl.setBytes(std::vector<unsigned char>(vchSecretL.begin(), vchSecretL.end()));
1157
1158     point_R.ECMUL(bnl);
1159
1160     std::vector<unsigned char> vchRl;
1161     if (!point_R.getBytes(vchRl)) {
1162         printf("CMalleableKeyView::CheckKeyVariant() : Unable to convert Rl value");
1163         return false;
1164     }
1165
1166     // Calculate Hash(R*l)
1167     CBigNum bnHash;
1168     bnHash.setuint160(Hash160(vchRl));
1169
1170     CPoint point_Ps;
1171     // Calculate Ps = Hash(L*r)*G + H
1172     point_Ps.ECMULGEN(bnHash, point_H);
1173
1174     // Infinity points are senseless
1175     if (point_Ps.IsInfinity()) {
1176         printf("CMalleableKeyView::CheckKeyVariant() : Ps is infinity");
1177         return false;
1178     }
1179
1180     // Check ownership
1181     if (point_Ps != point_P) {
1182         return false;
1183     }
1184
1185     return true;
1186 }
1187
1188 bool CMalleableKeyView::operator <(const CMalleableKeyView &kv) const { return vchPubKeyH.GetID() < kv.vchPubKeyH.GetID(); }
1189
1190 std::string CMalleableKeyView::ToString() const
1191 {
1192     CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
1193     ssKey << *this;
1194     std::vector<unsigned char> vch(ssKey.begin(), ssKey.end());
1195
1196     return EncodeBase58Check(vch);
1197 }
1198
1199 bool CMalleableKeyView::SetString(const std::string& strMutableKey)
1200 {
1201     std::vector<unsigned char> vchTemp;
1202     if (!DecodeBase58Check(strMutableKey, vchTemp)) {
1203         throw key_error("CMalleableKeyView::SetString() : Provided key data seems corrupted.");
1204     }
1205
1206     if (vchTemp.size() != 67)
1207         return false;
1208
1209     CDataStream ssKey(vchTemp, SER_NETWORK, PROTOCOL_VERSION);
1210     ssKey >> *this;
1211
1212     return IsValid();
1213 }
1214
1215 std::vector<unsigned char> CMalleableKeyView::Raw() const
1216 {
1217     CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
1218     ssKey << *this;
1219     std::vector<unsigned char> vch(ssKey.begin(), ssKey.end());
1220
1221     return vch;
1222 }
1223
1224
1225 bool CMalleableKeyView::IsValid() const
1226 {
1227     return vchSecretL.size() == 32 && GetMalleablePubKey().IsValid();
1228 }
1229
1230 CScriptID::CScriptID() : uint160(0) { }
1231
1232 CScriptID::CScriptID(const uint160 &in) : uint160(in) { }
1233
1234 CKeyID::CKeyID() : uint160(0) { }
1235
1236 CKeyID::CKeyID(const uint160 &in) : uint160(in) { }