File indexing completed on 2020-06-25 15:50:44
0001
0002
0003
0004
0005 #ifndef BITCOIN_KEY_H
0006 #define BITCOIN_KEY_H
0007
0008 #include <stdexcept>
0009 #include <vector>
0010
0011 #include <openssl/ec.h>
0012 #include <openssl/ecdsa.h>
0013 #include <openssl/obj_mac.h>
0014
0015 #include "serialize.h"
0016 #include "uint256.h"
0017 #include "base58.h"
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
0044 {
0045 int ok = 0;
0046 BN_CTX *ctx = NULL;
0047 EC_POINT *pub_key = NULL;
0048
0049 if (!eckey) return 0;
0050
0051 const EC_GROUP *group = EC_KEY_get0_group(eckey);
0052
0053 if ((ctx = BN_CTX_new()) == NULL)
0054 goto err;
0055
0056 pub_key = EC_POINT_new(group);
0057
0058 if (pub_key == NULL)
0059 goto err;
0060
0061 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
0062 goto err;
0063
0064 EC_KEY_set_private_key(eckey,priv_key);
0065 EC_KEY_set_public_key(eckey,pub_key);
0066
0067 ok = 1;
0068
0069 err:
0070
0071 if (pub_key)
0072 EC_POINT_free(pub_key);
0073 if (ctx != NULL)
0074 BN_CTX_free(ctx);
0075
0076 return(ok);
0077 }
0078
0079
0080
0081
0082 int static inline ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
0083 {
0084 if (!eckey) return 0;
0085
0086 int ret = 0;
0087 BN_CTX *ctx = NULL;
0088
0089 BIGNUM *x = NULL;
0090 BIGNUM *e = NULL;
0091 BIGNUM *order = NULL;
0092 BIGNUM *sor = NULL;
0093 BIGNUM *eor = NULL;
0094 BIGNUM *field = NULL;
0095 EC_POINT *R = NULL;
0096 EC_POINT *O = NULL;
0097 EC_POINT *Q = NULL;
0098 BIGNUM *rr = NULL;
0099 BIGNUM *zero = NULL;
0100 int n = 0;
0101 int i = recid / 2;
0102
0103 const EC_GROUP *group = EC_KEY_get0_group(eckey);
0104 if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
0105 BN_CTX_start(ctx);
0106 order = BN_CTX_get(ctx);
0107 if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
0108 x = BN_CTX_get(ctx);
0109 if (!BN_copy(x, order)) { ret=-1; goto err; }
0110 if (!BN_mul_word(x, i)) { ret=-1; goto err; }
0111 if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
0112 field = BN_CTX_get(ctx);
0113 if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
0114 if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
0115 if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
0116 if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
0117 if (check)
0118 {
0119 if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
0120 if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
0121 if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
0122 }
0123 if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
0124 n = EC_GROUP_get_degree(group);
0125 e = BN_CTX_get(ctx);
0126 if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
0127 if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
0128 zero = BN_CTX_get(ctx);
0129 if (!BN_zero(zero)) { ret=-1; goto err; }
0130 if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
0131 rr = BN_CTX_get(ctx);
0132 if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
0133 sor = BN_CTX_get(ctx);
0134 if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
0135 eor = BN_CTX_get(ctx);
0136 if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
0137 if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
0138 if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
0139
0140 ret = 1;
0141
0142 err:
0143 if (ctx) {
0144 BN_CTX_end(ctx);
0145 BN_CTX_free(ctx);
0146 }
0147 if (R != NULL) EC_POINT_free(R);
0148 if (O != NULL) EC_POINT_free(O);
0149 if (Q != NULL) EC_POINT_free(Q);
0150 return ret;
0151 }
0152
0153 class key_error : public std::runtime_error
0154 {
0155 public:
0156 explicit key_error(const std::string& str) : std::runtime_error(str) {}
0157 };
0158
0159
0160
0161
0162 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
0163
0164 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
0165
0166 class CKey
0167 {
0168 protected:
0169 EC_KEY* pkey;
0170 bool fSet;
0171
0172 public:
0173 CKey()
0174 {
0175 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
0176 if (pkey == NULL)
0177 throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
0178 fSet = false;
0179 }
0180
0181 CKey(const CKey& b)
0182 {
0183 pkey = EC_KEY_dup(b.pkey);
0184 if (pkey == NULL)
0185 throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
0186 fSet = b.fSet;
0187 }
0188
0189 CKey& operator=(const CKey& b)
0190 {
0191 if (!EC_KEY_copy(pkey, b.pkey))
0192 throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
0193 fSet = b.fSet;
0194 return (*this);
0195 }
0196
0197 ~CKey()
0198 {
0199 EC_KEY_free(pkey);
0200 }
0201
0202 bool IsNull() const
0203 {
0204 return !fSet;
0205 }
0206
0207 void MakeNewKey()
0208 {
0209 if (!EC_KEY_generate_key(pkey))
0210 throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
0211 fSet = true;
0212 }
0213
0214 bool SetPrivKey(const CPrivKey& vchPrivKey)
0215 {
0216 const unsigned char* pbegin = &vchPrivKey[0];
0217 if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
0218 return false;
0219 fSet = true;
0220 return true;
0221 }
0222
0223 bool SetSecret(const CSecret& vchSecret)
0224 {
0225 EC_KEY_free(pkey);
0226 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
0227 if (pkey == NULL)
0228 throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
0229 if (vchSecret.size() != 32)
0230 throw key_error("CKey::SetSecret() : secret must be 32 bytes");
0231 BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
0232 if (bn == NULL)
0233 throw key_error("CKey::SetSecret() : BN_bin2bn failed");
0234 if (!EC_KEY_regenerate_key(pkey,bn))
0235 {
0236 BN_clear_free(bn);
0237 throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
0238 }
0239 BN_clear_free(bn);
0240 fSet = true;
0241 return true;
0242 }
0243
0244 CSecret GetSecret() const
0245 {
0246 CSecret vchRet;
0247 vchRet.resize(32);
0248 const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
0249 int nBytes = BN_num_bytes(bn);
0250 if (bn == NULL)
0251 throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed");
0252 int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
0253 if (n != nBytes)
0254 throw key_error("CKey::GetSecret(): BN_bn2bin failed");
0255 return vchRet;
0256 }
0257
0258 CPrivKey GetPrivKey() const
0259 {
0260 unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
0261 if (!nSize)
0262 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
0263 CPrivKey vchPrivKey(nSize, 0);
0264 unsigned char* pbegin = &vchPrivKey[0];
0265 if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
0266 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
0267 return vchPrivKey;
0268 }
0269
0270 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
0271 {
0272 const unsigned char* pbegin = &vchPubKey[0];
0273 if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
0274 return false;
0275 fSet = true;
0276 return true;
0277 }
0278
0279 std::vector<unsigned char> GetPubKey() const
0280 {
0281 unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
0282 if (!nSize)
0283 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
0284 std::vector<unsigned char> vchPubKey(nSize, 0);
0285 unsigned char* pbegin = &vchPubKey[0];
0286 if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
0287 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
0288 return vchPubKey;
0289 }
0290
0291 bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
0292 {
0293 vchSig.clear();
0294 ECDSA_SIG *sig = ECDSA_do_sign((unsigned char *) &hash, sizeof(hash), pkey);
0295
0296 if (sig == NULL)
0297 {
0298 printf("ERROR, ECDSA_sign failed in key.h:Sign()\n");
0299 return false;
0300 }
0301
0302 BN_CTX *ctx = BN_CTX_new();
0303 BN_CTX_start(ctx);
0304 const EC_GROUP *group = EC_KEY_get0_group(pkey);
0305 BIGNUM *order = BN_CTX_get(ctx);
0306 BIGNUM *halforder = BN_CTX_get(ctx);
0307 EC_GROUP_get_order(group, order, ctx);
0308 BN_rshift1(halforder, order);
0309
0310 if (fHighS && (BN_cmp(sig->s, halforder) < 0))
0311 {
0312
0313 BN_sub(sig->s, order, sig->s);
0314 }
0315
0316 if (fLowS && (BN_cmp(sig->s, halforder) > 0))
0317 {
0318
0319 BN_sub(sig->s, order, sig->s);
0320 }
0321
0322 BN_CTX_end(ctx);
0323 BN_CTX_free(ctx);
0324 unsigned int nSize = ECDSA_size(pkey);
0325 vchSig.resize(nSize);
0326 unsigned char *pos = &vchSig[0];
0327 nSize = i2d_ECDSA_SIG(sig, &pos);
0328
0329
0330
0331
0332 ECDSA_SIG_free(sig);
0333 vchSig.resize(nSize);
0334 return true;
0335 }
0336
0337
0338
0339
0340
0341 bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig)
0342 {
0343 bool fOk = false;
0344 ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
0345 if (sig==NULL)
0346 return false;
0347 vchSig.clear();
0348 vchSig.resize(65,0);
0349 int nBitsR = BN_num_bits(sig->r);
0350 int nBitsS = BN_num_bits(sig->s);
0351 if (nBitsR <= 256 && nBitsS <= 256)
0352 {
0353 int nRecId = -1;
0354 for (int i=0; i<4; i++)
0355 {
0356 CKey keyRec;
0357 keyRec.fSet = true;
0358 if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1)
0359 if (keyRec.GetPubKey() == this->GetPubKey())
0360 {
0361 nRecId = i;
0362 break;
0363 }
0364 }
0365
0366 if (nRecId == -1)
0367 throw key_error("CKey::SignCompact() : unable to construct recoverable key");
0368
0369 vchSig[0] = nRecId+27;
0370 BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]);
0371 BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]);
0372 fOk = true;
0373 }
0374 ECDSA_SIG_free(sig);
0375 return fOk;
0376 }
0377
0378
0379
0380
0381
0382 bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
0383 {
0384 if (vchSig.size() != 65)
0385 return false;
0386 if (vchSig[0]<27 || vchSig[0]>=31)
0387 return false;
0388 ECDSA_SIG *sig = ECDSA_SIG_new();
0389 BN_bin2bn(&vchSig[1],32,sig->r);
0390 BN_bin2bn(&vchSig[33],32,sig->s);
0391
0392 EC_KEY_free(pkey);
0393 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
0394 if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), vchSig[0] - 27, 0) == 1)
0395 {
0396 fSet = true;
0397 ECDSA_SIG_free(sig);
0398 return true;
0399 }
0400 return false;
0401 }
0402
0403 bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
0404 {
0405
0406 if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
0407 return false;
0408 return true;
0409 }
0410
0411
0412 bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig)
0413 {
0414 CKey key;
0415 if (!key.SetCompactSignature(hash, vchSig))
0416 return false;
0417 if (GetPubKey() != key.GetPubKey())
0418 return false;
0419 return true;
0420 }
0421
0422
0423 CBitcoinAddress GetAddress() const
0424 {
0425 return CBitcoinAddress(GetPubKey());
0426 }
0427
0428 bool IsValid()
0429 {
0430 if (!fSet)
0431 return false;
0432
0433 CSecret secret = GetSecret();
0434 CKey key2;
0435 key2.SetSecret(secret);
0436 return GetPubKey() == key2.GetPubKey();
0437 }
0438 };
0439
0440 #endif