X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fkey.cpp;h=1ed4e25087db9e8786db0a40170f5aef19efe1ae;hb=HEAD;hp=1f4253365a36d2ba6f02ee5804e051f57f05ca7f;hpb=d9a9ab764d542fe29e177ff600eff108269d0a57;p=novacoin.git diff --git a/src/key.cpp b/src/key.cpp index 1f42533..82c8b34 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -2,39 +2,41 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include "key.h" +#include "base58.h" +#include "streams.h" +#include "hash.h" #include #include -#include -#include "key.h" -#include "base58.h" // Generate a private key from just the secret parameter int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) { - int ok = 0; - BN_CTX *ctx = NULL; - EC_POINT *pub_key = NULL; - if (!eckey) return 0; + int ok = 0; + BN_CTX *ctx = nullptr; + EC_POINT *pub_key = nullptr; + const EC_GROUP *group = EC_KEY_get0_group(eckey); - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new()) == nullptr) goto err; pub_key = EC_POINT_new(group); - if (pub_key == NULL) + if (pub_key == nullptr) goto err; - if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) + if (!EC_POINT_mul(group, pub_key, priv_key, nullptr, nullptr, ctx)) goto err; - EC_KEY_set_private_key(eckey,priv_key); - EC_KEY_set_public_key(eckey,pub_key); + if (!EC_KEY_set_private_key(eckey,priv_key)) + goto err; + if (!EC_KEY_set_public_key(eckey,pub_key)) + goto err; ok = 1; @@ -42,7 +44,7 @@ err: if (pub_key) EC_POINT_free(pub_key); - if (ctx != NULL) + if (ctx != nullptr) BN_CTX_free(ctx); return(ok); @@ -103,7 +105,7 @@ int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned ch if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); zero = BN_CTX_get(ctx); - BN_zero(zero); + if (!BN_set_word(zero, 0)) { ret=-1; goto err; } if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } rr = BN_CTX_get(ctx); if (!BN_mod_inverse(rr, ecsig_r, order, ctx)) { ret=-1; goto err; } @@ -331,17 +333,6 @@ CSecret CKey::GetSecret(bool &fCompressed) const return vchRet; } -bool CKey::WritePEM(BIO *streamObj, const SecureString &strPassKey) const // dumppem 4KJLA99FyqMMhjjDe7KnRXK4sjtv9cCtNS /tmp/test.pem 123 -{ - EVP_PKEY *evpKey = EVP_PKEY_new(); - if (!EVP_PKEY_assign_EC_KEY(evpKey, pkey)) - return error("CKey::WritePEM() : Error initializing EVP_PKEY instance."); - if(!PEM_write_bio_PKCS8PrivateKey(streamObj, evpKey, EVP_aes_256_cbc(), (char *)&strPassKey[0], strPassKey.size(), NULL, NULL)) - return error("CKey::WritePEM() : Error writing private key data to stream object"); - - return true; -} - CSecret CKey::GetSecret() const { bool fCompressed; @@ -375,25 +366,30 @@ CPubKey CKey::GetPubKey() const bool CKey::Sign(uint256 hash, std::vector& vchSig) { vchSig.clear(); - ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); - if (sig==NULL) + ECDSA_SIG *sig = ECDSA_do_sign(hash.begin(), sizeof(hash), pkey); + if (sig==nullptr) return false; const EC_GROUP *group = EC_KEY_get0_group(pkey); - CBigNum order, halforder; - EC_GROUP_get_order(group, order.get(), NULL); - BN_rshift1(halforder.get(), order.get()); + + BIGNUM* order = BN_new(), *halforder = BN_new(); + EC_GROUP_get_order(group, order, nullptr); + BN_rshift1(halforder, order); // Get internal R and S pointers const BIGNUM *current_s = ECDSA_SIG_get0_s(sig); + BIGNUM *current_r = BN_dup(ECDSA_SIG_get0_r(sig)); // enforce low S values, by negating the value (modulo the order) if above order/2. - if (BN_cmp(current_s, halforder.get()) > 0) { + if (BN_cmp(current_s, halforder) > 0) { BIGNUM *updated_s = BN_new(); BN_copy(updated_s, current_s); - BN_sub(updated_s, order.get(), updated_s); - ECDSA_SIG_set0(sig, NULL, updated_s); + BN_sub(updated_s, order, updated_s); + ECDSA_SIG_set0(sig, current_r, updated_s); } + BN_free(order); + BN_free(halforder); + unsigned int nSize = ECDSA_size(pkey); vchSig.resize(nSize); // Make sure it is big enough unsigned char *pos = &vchSig[0]; @@ -401,7 +397,7 @@ bool CKey::Sign(uint256 hash, std::vector& vchSig) ECDSA_SIG_free(sig); vchSig.resize(nSize); // Shrink to fit actual size // Testing our new signature - if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) { + if (ECDSA_verify(0, hash.begin(), sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) { vchSig.clear(); return false; } @@ -415,25 +411,29 @@ bool CKey::Sign(uint256 hash, std::vector& vchSig) bool CKey::SignCompact(uint256 hash, std::vector& vchSig) { bool fOk = false; - ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); - if (sig==NULL) + ECDSA_SIG *sig = ECDSA_do_sign(hash.begin(), sizeof(hash), pkey); + if (sig==nullptr) return false; const EC_GROUP *group = EC_KEY_get0_group(pkey); - CBigNum order, halforder; - EC_GROUP_get_order(group, order.get(), NULL); - BN_rshift1(halforder.get(), order.get()); + BIGNUM* order = BN_new(), *halforder = BN_new(); + EC_GROUP_get_order(group, order, nullptr); + BN_rshift1(halforder, order); // Get internal R and S pointers const BIGNUM *current_s = ECDSA_SIG_get0_s(sig); + BIGNUM *current_r = BN_dup(ECDSA_SIG_get0_r(sig)); // enforce low S values, by negating the value (modulo the order) if above order/2. - if (BN_cmp(current_s, halforder.get()) > 0) { + if (BN_cmp(current_s, halforder) > 0) { BIGNUM *updated_s = BN_new(); BN_copy(updated_s, current_s); - BN_sub(updated_s, order.get(), updated_s); - ECDSA_SIG_set0(sig, NULL, updated_s); + BN_sub(updated_s, order, updated_s); + ECDSA_SIG_set0(sig, current_r, updated_s); } + BN_free(order); + BN_free(halforder); + vchSig.clear(); vchSig.resize(65,0); int nBitsR = BN_num_bits(ECDSA_SIG_get0_r(sig)); @@ -447,7 +447,7 @@ bool CKey::SignCompact(uint256 hash, std::vector& vchSig) CKey keyRec; keyRec.fSet = true; keyRec.SetCompressedPubKey(fCompressedPubKey); - if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1) + if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, hash.begin(), sizeof(hash), i, 1) == 1) if (keyRec.GetPubKey() == this->GetPubKey()) { nRecId = i; @@ -466,6 +466,7 @@ bool CKey::SignCompact(uint256 hash, std::vector& vchSig) BN_bn2bin(ECDSA_SIG_get0_s(sig),&vchSig[65-(nBitsS+7)/8]); fOk = true; } + ECDSA_SIG_free(sig); return fOk; } @@ -482,7 +483,7 @@ bool CPubKey::SetCompactSignature(uint256 hash, const std::vector if (nV<27 || nV>=35) return false; ECDSA_SIG *sig = ECDSA_SIG_new(); - BIGNUM *sig_r, *sig_s; + BIGNUM *sig_r = BN_new(), *sig_s = BN_new(); BN_bin2bn(&vchSig[1],32,sig_r); BN_bin2bn(&vchSig[33],32,sig_s); ECDSA_SIG_set0(sig, sig_r, sig_s); @@ -515,6 +516,16 @@ bool CPubKey::SetCompactSignature(uint256 hash, const std::vector return fSuccessful; } +CKeyID CPubKey::GetID() const +{ + return CKeyID(Hash160(vbytes, vbytes + size())); +} + +uint256 CPubKey::GetHash() const +{ + return Hash(vbytes, vbytes + size()); +} + bool CPubKey::Verify(const uint256 &hash, const std::vector& vchSig) const { if (vchSig.empty() || !IsValid()) @@ -654,23 +665,21 @@ bool CPoint::getBytes(std::vector &vchBytes) // ECC multiplication by specified multiplier bool CPoint::ECMUL(const CBigNum &bnMultiplier) { - if (!EC_POINT_mul(group, point, NULL, point, bnMultiplier.get(), NULL)) { - printf("CPoint::ECMUL() : EC_POINT_mul failed"); - return false; - } - - return true; + BIGNUM* bnMul = bnMultiplier.get(); + bool ok = EC_POINT_mul(group, point, NULL, point, bnMul, NULL); + if (!ok) printf("CPoint::ECMUL() : EC_POINT_mul failed"); + BN_free(bnMul); + return ok; } // Calculate G*m + q bool CPoint::ECMULGEN(const CBigNum &bnMultiplier, const CPoint &qPoint) { - if (!EC_POINT_mul(group, point, bnMultiplier.get(), qPoint.point, BN_value_one(), NULL)) { - printf("CPoint::ECMULGEN() : EC_POINT_mul failed."); - return false; - } - - return true; + BIGNUM* bnMul = bnMultiplier.get(); + bool ok = EC_POINT_mul(group, point, bnMul, qPoint.point, BN_value_one(), NULL); + if (!ok) printf("CPoint::ECMULGEN() : EC_POINT_mul failed."); + BN_free(bnMul); + return ok; } // CMalleablePubKey @@ -709,8 +718,7 @@ void CMalleablePubKey::GetVariant(CPubKey &R, CPubKey &vchPubKeyVariant) R = CPubKey(vchPubKey); // OpenSSL BIGNUM representation of r value - CBigNum bnr; - bnr = *(CBigNum*) EC_KEY_get0_private_key(eckey); + CBigNum bnr(EC_KEY_get0_private_key(eckey)); EC_KEY_free(eckey); CPoint point; @@ -1177,6 +1185,8 @@ bool CMalleableKeyView::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubK return true; } +bool CMalleableKeyView::operator <(const CMalleableKeyView &kv) const { return vchPubKeyH.GetID() < kv.vchPubKeyH.GetID(); } + std::string CMalleableKeyView::ToString() const { CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION); @@ -1217,64 +1227,10 @@ bool CMalleableKeyView::IsValid() const return vchSecretL.size() == 32 && GetMalleablePubKey().IsValid(); } -//// Asymmetric encryption - -void CPubKey::EncryptData(const std::vector& data, std::vector& encrypted) -{ - ies_ctx_t *ctx; - char error[1024] = "Unknown error"; - cryptogram_t *cryptogram; - - const unsigned char* pbegin = &vbytes[0]; - EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1); - if (!o2i_ECPublicKey(&pkey, &pbegin, size())) - throw key_error("Unable to parse EC key"); - - ctx = create_context(pkey); - if (!EC_KEY_get0_public_key(ctx->user_key)) - throw key_error("Given EC key is not public key"); - - cryptogram = ecies_encrypt(ctx, (unsigned char*)&data[0], data.size(), error); - if (cryptogram == NULL) { - delete ctx; - ctx = NULL; - throw key_error(std::string("Error in encryption: %s") + error); - } - - encrypted.resize(cryptogram_data_sum_length(cryptogram)); - unsigned char *key_data = cryptogram_key_data(cryptogram); - memcpy(&encrypted[0], key_data, encrypted.size()); - cryptogram_free(cryptogram); - delete ctx; -} - -void CKey::DecryptData(const std::vector& encrypted, std::vector& data) -{ - ies_ctx_t *ctx; - char error[1024] = "Unknown error"; - cryptogram_t *cryptogram; - size_t length; - unsigned char *decrypted; - - ctx = create_context(pkey); - if (!EC_KEY_get0_private_key(ctx->user_key)) - throw key_error("Given EC key is not private key"); - - size_t key_length = ctx->stored_key_length; - size_t mac_length = EVP_MD_size(ctx->md); - cryptogram = cryptogram_alloc(key_length, mac_length, encrypted.size() - key_length - mac_length); +CScriptID::CScriptID() : uint160(0) { } - memcpy(cryptogram_key_data(cryptogram), &encrypted[0], encrypted.size()); +CScriptID::CScriptID(const uint160 &in) : uint160(in) { } - decrypted = ecies_decrypt(ctx, cryptogram, &length, error); - cryptogram_free(cryptogram); - delete ctx; +CKeyID::CKeyID() : uint160(0) { } - if (decrypted == NULL) { - throw key_error(std::string("Error in decryption: %s") + error); - } - - data.resize(length); - memcpy(&data[0], decrypted, length); - free(decrypted); -} +CKeyID::CKeyID(const uint160 &in) : uint160(in) { }