X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fkey.cpp;h=53eea7152214738b99f0a116ae024a4099091008;hb=bc0753c369cbf499e990541e723f737c62559803;hp=c68fcda5fd748d1666560cd7eabffc97feb49a85;hpb=7218a68da35b3dddb228fd4647da831d249e6cd5;p=novacoin.git diff --git a/src/key.cpp b/src/key.cpp index c68fcda..53eea71 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -6,7 +6,6 @@ #include #include -#include #include "key.h" #include "base58.h" @@ -80,7 +79,12 @@ int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned ch x = BN_CTX_get(ctx); if (!BN_copy(x, order)) { ret=-1; goto err; } if (!BN_mul_word(x, i)) { ret=-1; goto err; } - if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; } + + // Get internal R and S pointers + const BIGNUM *ecsig_r, *ecsig_s; + ECDSA_SIG_get0(ecsig, &ecsig_r, &ecsig_s); + + if (!BN_add(x, x, ecsig_r)) { ret=-1; goto err; } field = BN_CTX_get(ctx); if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } if (BN_cmp(x, field) >= 0) { ret=0; goto err; } @@ -98,12 +102,12 @@ 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); - if (!BN_zero(zero)) { ret=-1; goto err; } + BN_zero(zero); 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; } + if (!BN_mod_inverse(rr, ecsig_r, order, ctx)) { ret=-1; goto err; } sor = BN_CTX_get(ctx); - if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; } + if (!BN_mod_mul(sor, ecsig_s, rr, order, ctx)) { ret=-1; goto err; } eor = BN_CTX_get(ctx); if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } @@ -326,17 +330,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,12 +368,20 @@ bool CKey::Sign(uint256 hash, std::vector& vchSig) return false; const EC_GROUP *group = EC_KEY_get0_group(pkey); CBigNum order, halforder; - EC_GROUP_get_order(group, &order, NULL); - BN_rshift1(&halforder, &order); + EC_GROUP_get_order(group, order.get(), NULL); + BN_rshift1(halforder.get(), order.get()); + + // Get internal R and S pointers + const BIGNUM *current_s = ECDSA_SIG_get0_s(sig); + // enforce low S values, by negating the value (modulo the order) if above order/2. - if (BN_cmp(sig->s, &halforder) > 0) { - BN_sub(sig->s, &order, sig->s); + if (BN_cmp(current_s, halforder.get()) > 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); } + unsigned int nSize = ECDSA_size(pkey); vchSig.resize(nSize); // Make sure it is big enough unsigned char *pos = &vchSig[0]; @@ -407,16 +408,24 @@ bool CKey::SignCompact(uint256 hash, std::vector& vchSig) return false; const EC_GROUP *group = EC_KEY_get0_group(pkey); CBigNum order, halforder; - EC_GROUP_get_order(group, &order, NULL); - BN_rshift1(&halforder, &order); + EC_GROUP_get_order(group, order.get(), NULL); + BN_rshift1(halforder.get(), order.get()); + + // Get internal R and S pointers + const BIGNUM *current_s = ECDSA_SIG_get0_s(sig); + // enforce low S values, by negating the value (modulo the order) if above order/2. - if (BN_cmp(sig->s, &halforder) > 0) { - BN_sub(sig->s, &order, sig->s); + if (BN_cmp(current_s, halforder.get()) > 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); } + vchSig.clear(); vchSig.resize(65,0); - int nBitsR = BN_num_bits(sig->r); - int nBitsS = BN_num_bits(sig->s); + int nBitsR = BN_num_bits(ECDSA_SIG_get0_r(sig)); + int nBitsS = BN_num_bits(ECDSA_SIG_get0_s(sig)); bool fCompressedPubKey = IsCompressed(); if (nBitsR <= 256 && nBitsS <= 256) { @@ -441,8 +450,8 @@ bool CKey::SignCompact(uint256 hash, std::vector& vchSig) } vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0); - BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]); - BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]); + BN_bn2bin(ECDSA_SIG_get0_r(sig),&vchSig[33-(nBitsR+7)/8]); + BN_bn2bin(ECDSA_SIG_get0_s(sig),&vchSig[65-(nBitsS+7)/8]); fOk = true; } ECDSA_SIG_free(sig); @@ -461,8 +470,10 @@ bool CPubKey::SetCompactSignature(uint256 hash, const std::vector if (nV<27 || nV>=35) return false; ECDSA_SIG *sig = ECDSA_SIG_new(); - BN_bin2bn(&vchSig[1],32,sig->r); - BN_bin2bn(&vchSig[33],32,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); bool fSuccessful = false; EC_KEY* pkey = EC_KEY_new_by_curve_name(NID_secp256k1); if (nV >= 31) @@ -521,7 +532,7 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector& vchS break; // -1 = error, 0 = bad sig, 1 = good - ret = ECDSA_verify(0, hash.begin(), hash.size(), norm_der, derlen, pkey) == 1; + ret = ECDSA_verify(0, (const unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1; OPENSSL_free(norm_der); } while(false); @@ -631,7 +642,7 @@ 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, NULL)) { + if (!EC_POINT_mul(group, point, NULL, point, bnMultiplier.get(), NULL)) { printf("CPoint::ECMUL() : EC_POINT_mul failed"); return false; } @@ -642,7 +653,7 @@ bool CPoint::ECMUL(const CBigNum &bnMultiplier) // Calculate G*m + q bool CPoint::ECMULGEN(const CBigNum &bnMultiplier, const CPoint &qPoint) { - if (!EC_POINT_mul(group, point, &bnMultiplier, qPoint.point, BN_value_one(), NULL)) { + if (!EC_POINT_mul(group, point, bnMultiplier.get(), qPoint.point, BN_value_one(), NULL)) { printf("CPoint::ECMULGEN() : EC_POINT_mul failed."); return false; } @@ -1193,65 +1204,3 @@ 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); - - memcpy(cryptogram_key_data(cryptogram), &encrypted[0], encrypted.size()); - - decrypted = ecies_decrypt(ctx, cryptogram, &length, error); - cryptogram_free(cryptogram); - delete ctx; - - if (decrypted == NULL) { - throw key_error(std::string("Error in decryption: %s") + error); - } - - data.resize(length); - memcpy(&data[0], decrypted, length); - free(decrypted); -}