Я поставил код вверх на GitHub. Я программист на более чем C ++; это показывает.
https://github.com/halfinney/bitcoin/tree/secp256k1Вот самодостаточная тестовая программа, которая сравнивает скорость. Стройте с -lcrypto.
#включают
#включают
#включают
#включают
#включают
#define Репс 1000
// Разделить secp256k1 показатель к в два меньших k1 и k2 такие, что для любой точки Y,
// к * Y = k1 * Y + k2 * Y 'где Y' = лямбда * Y очень быстро
статическая ИНТ
splitk (BIGNUM * bnk1, BIGNUM * bnk2, Const BIGNUM * БНК, Const BIGNUM * BNN, BN_CTX * CTX)
{
BIGNUM * BNC1 = BN_new ();
BIGNUM * BNC2 = BN_new ();
BIGNUM * bnt1 = BN_new ();
BIGNUM * bnt2 = BN_new ();
BIGNUM * bnn2 = BN_new ();
статический символ без знака A1B2 [] = {
0x30, 0x86, 0xd2, 0x21, 0xa7, 0xd4, 0x6b, 0xcd,
0xE8, 0x6c, 0x90, 0xe4, 0x92, 0x84, 0xeb, 0x15,
};
статический символ без знака B1M [] = {
0xe4, 0x43, 0x7e, 0xd6, 0x01, 0x0E, 0x88, 0x28,
0x6F, 0x54, 0x7F, 0xa9, 0x0a, 0xBF, 0xe4, 0xC3,
};
статический символ без знака а2 [] = {
0x01, 0x14, 0xca, 0x50, 0xf7, 0xa8, 0xe2, 0xf3,
0xf6, 0x57, 0xc1, 0x10, 0x8d, 0x9d, 0x44, 0xcf,
0xd8,
};
BIGNUM * bna1b2 = BN_bin2bn (A1B2, SizeOf (A1B2), NULL);
BIGNUM * bnb1m = BN_bin2bn (B1M, SizeOf (B1M), NULL);
BIGNUM * bna2 = BN_bin2bn (а2, SizeOf (а2), NULL);
BN_rshift1 (bnn2, BNN);
BN_mul (BNC1, БНК, bna1b2, CTX);
BN_add (BNC1, BNC1, bnn2);
BN_div (BNC1, NULL, BNC1, BNN, CTX);
BN_mul (BNC2, БНК, bnb1m, CTX);
BN_add (BNC2, BNC2, bnn2);
BN_div (BNC2, NULL, BNC2, BNN, CTX);
BN_mul (bnt1, BNC1, bna1b2, CTX);
BN_mul (bnt2, BNC2, bna2, CTX);
BN_add (bnt1, bnt1, bnt2);
BN_sub (bnk1, БНК, bnt1);
BN_mul (bnt1, BNC1, bnb1m, CTX);
BN_mul (bnt2, BNC2, bna1b2, CTX);
BN_sub (bnk2, bnt1, bnt2);
BN_free (BNC1);
BN_free (BNC2);
BN_free (bnt1);
BN_free (bnt2);
BN_free (bnn2);
BN_free (bna1b2);
BN_free (bnb1m);
BN_free (bna2);
возвращать 0;
}
статическая ИНТ
secp256k1Verify (Const символ без знака хэш [32], Const символ без знака * dersig, size_t sigsize, Const EC_KEY * PKey)
{
INT Rslt = 0 ;;
Const EC_GROUP * Группа = EC_KEY_get0_group (PKey);
Const EC_POINT * Y = EC_KEY_get0_public_key (PKey);
Const EC_POINT * G = EC_GROUP_get0_generator (группа);
EC_POINT * Глэм = EC_POINT_new (группа);
EC_POINT * Ylam = EC_POINT_new (группа);
EC_POINT * R = EC_POINT_new (группа);
Const EC_POINT * Пункты [3];
Const BIGNUM * bnexps [3];
BIGNUM * БНП = BN_new ();
BIGNUM * BNN = BN_new ();
BIGNUM * BNX = BN_new ();
BIGNUM * BNY = BN_new ();
BIGNUM * БНК = BN_new ();
BIGNUM * bnk1 = BN_new ();
BIGNUM * bnk2 = BN_new ();
BIGNUM * bnk1a = BN_new ();
BIGNUM * bnk2a = BN_new ();
BIGNUM * bnsinv = BN_new ();
BIGNUM * BNH = BN_bin2bn (хэш, 32, NULL);
статический символ без знака беты [] = {
0x7A, 0xe9, 0x6a, 0x2b, 0x65, 0x7c, 0x07, 0x10,
0x6e, 0x64, 0x47, 0x9e, 0xac, 0x34, 0x34, 0xe9,
0x9C, 0xf0, 0x49, 0x75, 0x12, 0xf5, 0x89, 0x95,
0xc1, 0x39, 0x6c, 0x28, 0x71, 0x95, 0x01, 0xEE,
};
BIGNUM * bnbeta = BN_bin2bn (бета, 32, NULL);
BN_CTX * CTX = BN_CTX_new ();
ECDSA_SIG * сиг = d2i_ECDSA_SIG (NULL, &dersig, sigsize);
если (Sig == NULL)
Гото сделано;
EC_GROUP_get_curve_GFp (группа, БНП, NULL, NULL, CTX);
EC_GROUP_get_order (группа, BNN, CTX);
если (BN_is_zero (SIG->г) || BN_is_negative (SIG->г) || BN_ucmp (SIG->г, BNN) >= 0
|| BN_is_zero (SIG->с) || BN_is_negative (SIG->с) || BN_ucmp (SIG->с, BNN) >= 0)
Гото сделано;
EC_POINT_get_affine_coordinates_GFp (группа, G BNX, BNY, CTX);
BN_mod_mul (BNX, BNX, bnbeta, БНП, CTX);
EC_POINT_set_affine_coordinates_GFp (группа, Глэм, BNX, BNY, CTX);
EC_POINT_get_affine_coordinates_GFp (группа, Y, BNX, BNY, CTX);
BN_mod_mul (BNX, BNX, bnbeta, БНП, CTX);
EC_POINT_set_affine_coordinates_GFp (группа, Ylam, BNX, BNY, CTX);
Очки [0] = Глая;
Очки [1] = Y;
Очки [2] = Ylam;
BN_mod_inverse (bnsinv, SIG->с, BNN, CTX);
BN_mod_mul (БНК, BNH, bnsinv, BNN, CTX);
splitk (bnk1, bnk2, БНК, BNN, CTX);
bnexps [0] = bnk2;
BN_mod_mul (БНК, SIG->г, bnsinv, BNN, CTX);
splitk (bnk1a, bnk2a, БНК, BNN, CTX);
bnexps [1] = bnk1a;
bnexps [2] = bnk2a;
EC_POINTs_mul (группа, R, bnk1, 3, очки, bnexps, CTX);
EC_POINT_get_affine_coordinates_GFp (группа, R, BNX, NULL, CTX);
BN_mod (BNX, BNX, BNN, CTX);
Rslt = (BN_cmp (BNX, SIG->г) == 0);
ECDSA_SIG_free (сиг);
сделанный:
EC_POINT_free (глэм);
EC_POINT_free (Ylam);
EC_POINT_free (R);
BN_free (НПБ);
BN_free (BNN);
BN_free (BNX);
BN_free (BNY);
BN_free (БНК);
BN_free (bnk1);
BN_free (bnk2);
BN_free (bnk1a);
BN_free (bnk2a);
BN_free (bnsinv);
BN_free (BNH);
BN_free (bnbeta);
BN_CTX_free (CTX);
вернуться Rslt;
}
главный()
{
EC_KEY * PKey;
EC_GROUP * группа;
Const EC_POINT * ecpub;
неподписанный символ сиг [100];
без знака siglen = SizeOf (Sig);
символ без знака хэш [32];
структура формата: первый формат TV1, TV2;
двойная time1, time2;
Int я;
INT Rslt;
ENGINE_load_builtin_engines ();
CRYPTO_malloc_init ();
группа = EC_GROUP_new_by_curve_name (NID_secp256k1);
PKey = EC_KEY_new ();
EC_KEY_set_group (PKey, группа);
EC_KEY_generate_key (PKey);
ecpub = EC_KEY_get0_public_key (PKey);
ECDSA_sign (0, хэш, 32, сиг, &siglen, PKey);
Rslt = ECDSA_verify (0, хэш, 32, сиг, siglen, PKey);
Е ("Rslt =% d \ п", Rslt);
Rslt = secp256k1Verify (хэш, сиг, siglen, PKey);
Е ("Rslt =% d \ п", Rslt);
хэш [0] ++;
Rslt = ECDSA_verify (0, хэш, 32, сиг, siglen, PKey);
Е ("Rslt =% d \ п", Rslt);
Rslt = secp256k1Verify (хэш, сиг, siglen, PKey);
Е ("Rslt =% d \ п", Rslt);
хэш [0] -;
gettimeofday (&TV1, NULL);
для (я = 0; я<ПРЕДСТАВИТЕЛИ; я ++) {
Rslt = ECDSA_verify (0, хэш, 32, сиг, siglen, PKey);
}
gettimeofday (&TV2, NULL);
Е ("Rslt =% d \ п", Rslt);
time1 = (tv2.tv_sec - tv1.tv_sec + (tv2.tv_usec - tv1.tv_usec) / 1000000.) / REPS;
Е ("Время:% г \ п", Time1);
gettimeofday (&TV1, NULL);
для (я = 0; я<ПРЕДСТАВИТЕЛИ; я ++) {
Rslt = secp256k1Verify (хэш, сиг, siglen, PKey);
}
gettimeofday (&TV2, NULL);
Е ("Rslt =% d \ п", Rslt);
time2 = (tv2.tv_sec - tv1.tv_sec + (tv2.tv_usec - tv1.tv_usec) / 1000000.) / REPS;
Е ("Время:% г \ п", Time2);
Е ("% Е %% убыстрение \ п", (Time1-time2) / time1);
Выход (0);
}