Во-первых, я использую Visual Studio Community 2017 и готовую 64-битную версию OpenSSL.Мне нужно сделать значительное количество умножений EC на кривой secp256k1, и во время работы моей программы я обнаружил, что использование памяти только увеличивалось и увеличивалось.Поэтому я использовал профилирование кучи, чтобы сузить его, и большинство вещей, которые не освобождаются из кучи, происходят из функции EC_POINT_mul.Вот моя функция для получения открытого ключа из закрытого ключа и проверки его на 10000 итераций:
#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 17 880 байт добавляются вкучи в 33 распределений, когда он попадает в EC_POINT_mul ().Затем каждый раз после этого он добавляет 132 байта в кучу за 1 выделение.Все освобождение объектов в конце не исправляет это, поэтому все эти 132 байта складываются.Если мне нужно выполнить 10 миллионов операций умножения EC, то это 1,25 ГБ!Есть ли способ это исправить?