From aff8cd478c6318dadf594acf9cfe408c869e108c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Apr 2016 16:57:58 -0400 Subject: [PATCH] optional elgamal precomputation for x64 --- Config.cpp | 12 ++++++++++ Crypto.cpp | 65 ++++++++++++++++++++++++++++++++++++------------------ Crypto.h | 2 +- Daemon.cpp | 3 ++- api.cpp | 6 ++++- 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/Config.cpp b/Config.cpp index 8d42895a..d5ff2a46 100644 --- a/Config.cpp +++ b/Config.cpp @@ -180,6 +180,17 @@ namespace config { ("i2pcontrol.key", value()->default_value("i2pcontrol.key.pem"), "I2PCP connection cerificate key") ; + options_description precomputation("Precomputation options"); + precomputation.add_options() + ("precomputation.elgamal", +#if defined(__x86_64__) + value()->default_value(false), +#else + value()->default_value(true), +#endif + "Enable or disable elgamal precomputation table") + ; + m_OptionsDesc .add(general) .add(httpserver) @@ -188,6 +199,7 @@ namespace config { .add(sam) .add(bob) .add(i2pcontrol) + .add(precomputation) ; } diff --git a/Crypto.cpp b/Crypto.cpp index fe6dfa8f..f7c00595 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -150,12 +150,11 @@ namespace crypto const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1; const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048; - + const int ELGAMAL_FULL_EXPONENT_NUM_BYTES = ELGAMAL_FULL_EXPONENT_NUM_BITS/8; + #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg -#if !defined(__x86_64__) // use precalculated table - static BN_MONT_CTX * g_MontCtx = nullptr; static void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums { @@ -226,9 +225,7 @@ namespace crypto return ret; } - BIGNUM * g_ElggTable[ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255]; - -#endif + static BIGNUM * (* g_ElggTable)[255] = nullptr; // DH @@ -253,12 +250,20 @@ namespace crypto #if !defined(__x86_64__) // use short exponent for non x64 m_DH->priv_key = BN_new (); BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); - auto ctx = BN_CTX_new (); - m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx); - BN_CTX_free (ctx); -#else - DH_generate_key (m_DH); #endif + if (g_ElggTable) + { +#if defined(__x86_64__) + m_DH->priv_key = BN_new (); + BN_rand (m_DH->priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1); +#endif + auto ctx = BN_CTX_new (); + m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx); + BN_CTX_free (ctx); + } + else + DH_generate_key (m_DH); + if (priv) bn2buf (m_DH->priv_key, priv, 256); if (pub) bn2buf (m_DH->pub_key, pub, 256); m_IsUpdated = true; @@ -291,14 +296,16 @@ namespace crypto BIGNUM * k = BN_new (); #if defined(__x86_64__) BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 - // calculate a - a = BN_new (); - BN_mod_exp (a, elgg, k, elgp, ctx); #else BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits +#endif // calculate a - a = ElggPow (k, g_ElggTable, ctx); -#endif + a = BN_new (); + if (g_ElggTable) + a = ElggPow (k, g_ElggTable, ctx); + else + BN_mod_exp (a, elgg, k, elgp, ctx); + BIGNUM * y = BN_new (); BN_bin2bn (key, 256, y); // calculate b1 @@ -792,23 +799,37 @@ namespace crypto } }*/ - void InitCrypto () + void InitCrypto (bool precomputation) { SSL_library_init (); /* auto numLocks = CRYPTO_num_locks(); for (int i = 0; i < numLocks; i++) m_OpenSSLMutexes.emplace_back (new std::mutex); CRYPTO_set_locking_callback (OpensslLockingCallback);*/ -#if !defined(__x86_64__) - PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); + if (precomputation) + { +#if defined(__x86_64__) + g_ElggTable = new BIGNUM * [ELGAMAL_FULL_EXPONENT_NUM_BYTES][255]; + PrecalculateElggTable (g_ElggTable, ELGAMAL_FULL_EXPONENT_NUM_BYTES); +#else + g_ElggTable = new BIGNUM * [ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255]; + PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); #endif + } } void TerminateCrypto () { -#if !defined(__x86_64__) - DestroyElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); -#endif + if (g_ElggTable) + { + DestroyElggTable (g_ElggTable, +#if defined(__x86_64__) + ELGAMAL_FULL_EXPONENT_NUM_BYTES +#else + ELGAMAL_SHORT_EXPONENT_NUM_BYTES +#endif + ); + } /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ } diff --git a/Crypto.h b/Crypto.h index e633f8bf..e333940e 100644 --- a/Crypto.h +++ b/Crypto.h @@ -273,7 +273,7 @@ namespace crypto #endif }; - void InitCrypto (); + void InitCrypto (bool precomputation); void TerminateCrypto (); } } diff --git a/Daemon.cpp b/Daemon.cpp index f15fe3e3..0924b236 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -117,7 +117,8 @@ namespace i2p LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); - i2p::crypto::InitCrypto (); + bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); + i2p::crypto::InitCrypto (precomputation); i2p::context.Init (); uint16_t port; i2p::config::GetOption("port", port); diff --git a/api.cpp b/api.cpp index 64648743..1828901b 100644 --- a/api.cpp +++ b/api.cpp @@ -28,7 +28,11 @@ namespace api i2p::fs::DetectDataDir(datadir, false); i2p::fs::Init(); - i2p::crypto::InitCrypto (); +#if defined(__x86_64__) + i2p::crypto::InitCrypto (false); +#else + i2p::crypto::InitCrypto (true); +#endif i2p::context.Init (); }