Paul Sheer optimised the OpenSSL to/from libGMP conversions for the case
where they both use the same limb size. I've tweaked his patch slightly, so blame me if it breaks. Submitted by: Paul Sheer Reviewed by: Geoff Thorpe
This commit is contained in:
parent
dc634aff25
commit
5ee6f96cea
5
CHANGES
5
CHANGES
@ -681,6 +681,11 @@
|
||||
|
||||
Changes between 0.9.8g and 0.9.8h [xx XXX xxxx]
|
||||
|
||||
*) Update the GMP engine glue to do direct copies between BIGNUM and
|
||||
mpz_t when openssl and GMP use the same limb size. Otherwise the
|
||||
existing "conversion via a text string export" trick is still used.
|
||||
[Paul Sheer <paulsheer@gmail.com>, Geoff Thorpe]
|
||||
|
||||
*) Zlib compression BIO. This is a filter BIO which compressed and
|
||||
uncompresses any data passed through it.
|
||||
[Steve Henson]
|
||||
|
@ -85,6 +85,8 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifndef OPENSSL_NO_HW
|
||||
#ifndef OPENSSL_NO_GMP
|
||||
@ -251,27 +253,61 @@ static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
|
||||
return to_return;
|
||||
}
|
||||
|
||||
/* HACK - use text I/O functions in openssl and GMP to handle conversions. This
|
||||
* is vile. */
|
||||
|
||||
/* Most often limb sizes will be the same. If not, we use hex conversion
|
||||
* which is neat, but extremely inefficient. */
|
||||
static int bn2gmp(const BIGNUM *bn, mpz_t g)
|
||||
{
|
||||
int toret;
|
||||
char *tmpchar = BN_bn2hex(bn);
|
||||
if(!tmpchar) return 0;
|
||||
toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0);
|
||||
OPENSSL_free(tmpchar);
|
||||
return toret;
|
||||
bn_check_top(bn);
|
||||
if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
|
||||
(BN_BITS2 == GMP_NUMB_BITS))
|
||||
{
|
||||
/* The common case */
|
||||
if(!_mpz_realloc (g, bn->top))
|
||||
return 0;
|
||||
memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0]));
|
||||
g->_mp_size = bn->top;
|
||||
if(bn->neg)
|
||||
g->_mp_size = -g->_mp_size;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int toret;
|
||||
char *tmpchar = BN_bn2hex(bn);
|
||||
if(!tmpchar) return 0;
|
||||
toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0);
|
||||
OPENSSL_free(tmpchar);
|
||||
return toret;
|
||||
}
|
||||
}
|
||||
|
||||
static int gmp2bn(mpz_t g, BIGNUM *bn)
|
||||
{
|
||||
int toret;
|
||||
char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10);
|
||||
if(!tmpchar) return 0;
|
||||
mpz_get_str(tmpchar, 16, g);
|
||||
toret = BN_hex2bn(&bn, tmpchar);
|
||||
OPENSSL_free(tmpchar);
|
||||
return toret;
|
||||
if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
|
||||
(BN_BITS2 == GMP_NUMB_BITS))
|
||||
{
|
||||
/* The common case */
|
||||
int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size;
|
||||
BN_zero(bn);
|
||||
if(bn_expand2 (bn, s) == NULL)
|
||||
return 0;
|
||||
bn->top = s;
|
||||
memcpy(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0]));
|
||||
bn_correct_top(bn);
|
||||
bn->neg = g->_mp_size >= 0 ? 0 : 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int toret;
|
||||
char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10);
|
||||
if(!tmpchar) return 0;
|
||||
mpz_get_str(tmpchar, 16, g);
|
||||
toret = BN_hex2bn(&bn, tmpchar);
|
||||
OPENSSL_free(tmpchar);
|
||||
return toret;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
|
Loading…
Reference in New Issue
Block a user