首先,我正在使用Visual Studio Community 2017和OpenSSL的预构建64位版本。我需要在secp256k1曲线上进行大量的EC乘法运算,并且在运行程序时发现内存使用量一直在上升。因此,我使用了堆概要分析来缩小它的范围,而无法从堆中释放的VAST大部分内容都来自EC_POINT_mul函数。这是我从私钥获取公钥并对其进行10,000次迭代测试的功能:
#include <openssl/ec.h>
#include <openssl/bn.h>
#include <stdint.h>
void getPubKey(uint8_t privKey[], uint8_t* out[])
{
EC_KEY* pkey = EC_KEY_new_by_curve_name(714); //set to secp256k1
const EC_GROUP *pgroup = EC_KEY_get0_group(pkey);
EC_POINT *pub_key = EC_POINT_new(pgroup);
BIGNUM* privKeyBN = BN_bin2bn(privKey, 32, NULL);
EC_KEY_set_private_key(pkey, privKeyBN);
BN_CTX* ctx = BN_CTX_new();
EC_POINT_mul(pgroup, pub_key, privKeyBN, NULL, NULL, ctx);
char* pubUnc = EC_POINT_point2hex(pgroup, pub_key, 6, ctx);
HexToBin(pubUnc, out, 65);
EC_POINT_free(pub_key);
BN_CTX_free(ctx);
BN_free(privKeyBN);
EC_KEY_free(pkey);
}
int main(int argc, char** argv)
{
for (int i = 0; i < 10000; i++)
{
uint8_t* finalPrivKey = malloc(32);
memset(finalPrivKey, 156, 32);
uint8_t* finalFullPubKey = malloc(65);
memset(finalFullPubKey, 0, 65);
getPubKey(finalPrivKey, finalFullPubKey);
free(finalPrivKey);
free(finalFullPubKey);
}
}
根据堆概要分析,当我第一次运行getPubKey时,当它命中EC_POINT_mul()时,会将33880个分配中的17,880字节添加到堆中。然后每次之后,它将以1个分配将132个字节添加到堆中。最后释放所有对象并不能解决问题,因此所有132个字节加起来。如果我必须运行1000万EC乘法,那就是1.25GB!有办法解决这个问题吗?