diff options
Diffstat (limited to 'src/key.cpp')
| -rw-r--r-- | src/key.cpp | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/key.cpp b/src/key.cpp index 8ed787654..079e2c654 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -179,19 +179,17 @@ public: BN_clear_free(&bn); } - void GetPrivKey(CPrivKey &privkey, bool fCompressed) { + int GetPrivKeySize(bool fCompressed) { EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED); - int nSize = i2d_ECPrivateKey(pkey, NULL); - assert(nSize); - privkey.resize(nSize); - unsigned char* pbegin = &privkey[0]; - int nSize2 = i2d_ECPrivateKey(pkey, &pbegin); - assert(nSize == nSize2); + return i2d_ECPrivateKey(pkey, NULL); + } + int GetPrivKey(unsigned char* privkey, bool fCompressed) { + EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED); + return i2d_ECPrivateKey(pkey, &privkey); } - bool SetPrivKey(const CPrivKey &privkey, bool fSkipCheck=false) { - const unsigned char* pbegin = &privkey[0]; - if (d2i_ECPrivateKey(&pkey, &pbegin, privkey.size())) { + bool SetPrivKey(const unsigned char* privkey, size_t size, bool fSkipCheck=false) { + if (d2i_ECPrivateKey(&pkey, &privkey, size)) { if(fSkipCheck) return true; @@ -220,7 +218,7 @@ public: return o2i_ECPublicKey(&pkey, &pbegin, pubkey.size()) != NULL; } - bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) { + bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lowS) { vchSig.clear(); ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); if (sig == NULL) @@ -232,7 +230,7 @@ public: BIGNUM *halforder = BN_CTX_get(ctx); EC_GROUP_get_order(group, order, ctx); BN_rshift1(halforder, order); - if (BN_cmp(sig->s, halforder) > 0) { + if (lowS && BN_cmp(sig->s, halforder) > 0) { // enforce low S values, by negating the value (modulo the order) if above order/2. BN_sub(sig->s, order, sig->s); } @@ -424,7 +422,7 @@ bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { return false; #else CECKey key; - if (!key.SetPrivKey(privkey)) + if (!key.SetPrivKey(&privkey[0], privkey.size())) return false; key.GetSecretBytes(vch); #endif @@ -436,16 +434,21 @@ bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { CPrivKey CKey::GetPrivKey() const { assert(fValid); CPrivKey privkey; + int privkeylen, ret; #ifdef USE_SECP256K1 privkey.resize(279); - int privkeylen = 279; - int ret = secp256k1_ecdsa_privkey_export(begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed); + privkeylen = 279; + ret = secp256k1_ecdsa_privkey_export(begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed); assert(ret); privkey.resize(privkeylen); #else CECKey key; key.SetSecretBytes(vch); - key.GetPrivKey(privkey, fCompressed); + privkeylen = key.GetPrivKeySize(fCompressed); + assert(privkeylen); + privkey.resize(privkeylen); + ret = key.GetPrivKey(&privkey[0], fCompressed); + assert(ret == (int)privkey.size()); #endif return privkey; } @@ -467,7 +470,7 @@ CPubKey CKey::GetPubKey() const { return pubkey; } -bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const { +bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lowS) const { if (!fValid) return false; #ifdef USE_SECP256K1 @@ -484,7 +487,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const { #else CECKey key; key.SetSecretBytes(vch); - return key.Sign(hash, vchSig); + return key.Sign(hash, vchSig, lowS); #endif } @@ -517,7 +520,7 @@ bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) { return false; #else CECKey key; - if (!key.SetPrivKey(privkey, fSkipCheck)) + if (!key.SetPrivKey(&privkey[0], privkey.size(), fSkipCheck)) return false; key.GetSecretBytes(vch); #endif |