@ -148,11 +148,85 @@ namespace crypto
@@ -148,11 +148,85 @@ namespace crypto
// DH/ElGamal
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
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
{
if ( len < = 0 ) return ;
BN_CTX * ctx = BN_CTX_new ( ) ;
g_MontCtx = BN_MONT_CTX_new ( ) ;
BN_MONT_CTX_set ( g_MontCtx , elgp , ctx ) ;
auto montCtx = BN_MONT_CTX_new ( ) ;
BN_MONT_CTX_copy ( montCtx , g_MontCtx ) ;
for ( int i = 0 ; i < len ; i + + )
{
table [ i ] [ 0 ] = BN_new ( ) ;
if ( ! i )
BN_to_montgomery ( table [ 0 ] [ 0 ] , elgg , montCtx , ctx ) ;
else
BN_mod_mul_montgomery ( table [ i ] [ 0 ] , table [ i - 1 ] [ 254 ] , table [ i - 1 ] [ 0 ] , montCtx , ctx ) ;
for ( int j = 1 ; j < 255 ; j + + )
{
table [ i ] [ j ] = BN_new ( ) ;
BN_mod_mul_montgomery ( table [ i ] [ j ] , table [ i ] [ j - 1 ] , table [ i ] [ 0 ] , montCtx , ctx ) ;
}
}
BN_MONT_CTX_free ( montCtx ) ;
BN_CTX_free ( ctx ) ;
}
static void DestroyElggTable ( BIGNUM * table [ ] [ 255 ] , int len )
{
for ( int i = 0 ; i < len ; i + + )
for ( int j = 0 ; j < 255 ; j + + )
{
BN_free ( table [ i ] [ j ] ) ;
table [ i ] [ j ] = nullptr ;
}
BN_MONT_CTX_free ( g_MontCtx ) ;
}
static BIGNUM * ElggPow ( const uint8_t * exp , int len , BIGNUM * table [ ] [ 255 ] , BN_CTX * ctx )
// exp is in Big Endian
{
if ( len < = 0 ) return nullptr ;
auto montCtx = BN_MONT_CTX_new ( ) ;
BN_MONT_CTX_copy ( montCtx , g_MontCtx ) ;
BIGNUM * res = nullptr ;
for ( int i = 0 ; i < len ; i + + )
{
if ( res )
{
if ( exp [ i ] )
BN_mod_mul_montgomery ( res , res , table [ len - 1 - i ] [ exp [ i ] - 1 ] , montCtx , ctx ) ;
}
else if ( exp [ i ] )
res = BN_dup ( table [ len - i - 1 ] [ exp [ i ] - 1 ] ) ;
}
if ( res )
BN_from_montgomery ( res , res , montCtx , ctx ) ;
BN_MONT_CTX_free ( montCtx ) ;
return res ;
}
static BIGNUM * ElggPow ( const BIGNUM * exp , BIGNUM * table [ ] [ 255 ] , BN_CTX * ctx )
{
auto len = BN_num_bytes ( exp ) ;
uint8_t * buf = new uint8_t [ len ] ;
BN_bn2bin ( exp , buf ) ;
auto ret = ElggPow ( buf , len , table , ctx ) ;
delete [ ] buf ;
return ret ;
}
static BIGNUM * ( * g_ElggTable ) [ 255 ] = nullptr ;
// DH
DHKeys : : DHKeys ( ) : m_IsUpdated ( true )
@ -177,7 +251,19 @@ namespace crypto
@@ -177,7 +251,19 @@ namespace crypto
m_DH - > priv_key = BN_new ( ) ;
BN_rand ( m_DH - > priv_key , ELGAMAL_SHORT_EXPONENT_NUM_BITS , 0 , 1 ) ;
# endif
DH_generate_key ( m_DH ) ;
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 ;
@ -213,9 +299,13 @@ namespace crypto
@@ -213,9 +299,13 @@ namespace crypto
# else
BN_rand ( k , ELGAMAL_SHORT_EXPONENT_NUM_BITS , - 1 , 1 ) ; // short exponent of 226 bits
# endif
// cau lculate a
// calculate a
a = BN_new ( ) ;
BN_mod_exp ( a , elgg , k , elgp , ctx ) ;
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
@ -709,17 +799,38 @@ namespace crypto
@@ -709,17 +799,38 @@ 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 ( 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 ( g_ElggTable )
{
DestroyElggTable ( g_ElggTable ,
# if defined(__x86_64__)
ELGAMAL_FULL_EXPONENT_NUM_BYTES
# else
ELGAMAL_SHORT_EXPONENT_NUM_BYTES
# endif
) ;
delete [ ] g_ElggTable ; g_ElggTable = nullptr ;
}
/* CRYPTO_set_locking_callback (nullptr);
m_OpenSSLMutexes . clear ( ) ; */
}