Speed up DH with small generator.
This commit is contained in:
parent
208f3688e0
commit
6dad7bd69c
5
CHANGES
5
CHANGES
@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
|
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
|
||||||
|
|
||||||
|
*) New function BN_mod_exp_mont_word for small bases (roughly 20%
|
||||||
|
faster than BN_mod_exp_mont even though it does not use
|
||||||
|
windowing).
|
||||||
|
[Bodo Moeller]
|
||||||
|
|
||||||
*) CygWin32 support.
|
*) CygWin32 support.
|
||||||
[John Jarvie <jjarvie@newsguy.com>]
|
[John Jarvie <jjarvie@newsguy.com>]
|
||||||
|
|
||||||
|
@ -364,6 +364,8 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
|
|||||||
const BIGNUM *m,BN_CTX *ctx);
|
const BIGNUM *m,BN_CTX *ctx);
|
||||||
int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
|
int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
|
||||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
|
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
|
||||||
|
int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
|
||||||
|
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
|
||||||
int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2,
|
int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2,
|
||||||
BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx);
|
BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx);
|
||||||
int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p,
|
int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p,
|
||||||
@ -484,6 +486,7 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
|
|||||||
#define BN_F_BN_DIV 107
|
#define BN_F_BN_DIV 107
|
||||||
#define BN_F_BN_EXPAND2 108
|
#define BN_F_BN_EXPAND2 108
|
||||||
#define BN_F_BN_MOD_EXP_MONT 109
|
#define BN_F_BN_MOD_EXP_MONT 109
|
||||||
|
#define BN_F_BN_MOD_EXP_MONT_WORD 117
|
||||||
#define BN_F_BN_MOD_INVERSE 110
|
#define BN_F_BN_MOD_INVERSE 110
|
||||||
#define BN_F_BN_MOD_MUL_RECIPROCAL 111
|
#define BN_F_BN_MOD_MUL_RECIPROCAL 111
|
||||||
#define BN_F_BN_MPI2BN 112
|
#define BN_F_BN_MPI2BN 112
|
||||||
|
@ -77,6 +77,7 @@ static ERR_STRING_DATA BN_str_functs[]=
|
|||||||
{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"},
|
{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"},
|
||||||
{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"},
|
{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"},
|
||||||
{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0), "BN_mod_exp_mont"},
|
{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0), "BN_mod_exp_mont"},
|
||||||
|
{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT_WORD,0), "BN_MOD_EXP_MONT_WORD"},
|
||||||
{ERR_PACK(0,BN_F_BN_MOD_INVERSE,0), "BN_mod_inverse"},
|
{ERR_PACK(0,BN_F_BN_MOD_INVERSE,0), "BN_mod_inverse"},
|
||||||
{ERR_PACK(0,BN_F_BN_MOD_MUL_RECIPROCAL,0), "BN_mod_mul_reciprocal"},
|
{ERR_PACK(0,BN_F_BN_MOD_MUL_RECIPROCAL,0), "BN_mod_mul_reciprocal"},
|
||||||
{ERR_PACK(0,BN_F_BN_MPI2BN,0), "BN_mpi2bn"},
|
{ERR_PACK(0,BN_F_BN_MPI2BN,0), "BN_mpi2bn"},
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define TABLE_SIZE 16
|
#define TABLE_SIZE 16
|
||||||
|
|
||||||
/* slow but works */
|
/* slow but works */
|
||||||
@ -91,42 +92,6 @@ err:
|
|||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* this one works - simple but works */
|
|
||||||
int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx)
|
|
||||||
{
|
|
||||||
int i,bits,ret=0;
|
|
||||||
BIGNUM *v,*tmp;
|
|
||||||
|
|
||||||
BN_CTX_start(ctx);
|
|
||||||
v = BN_CTX_get(ctx);
|
|
||||||
tmp = BN_CTX_get(ctx);
|
|
||||||
if (v == NULL || tmp == NULL) goto err;
|
|
||||||
|
|
||||||
if (BN_copy(v,a) == NULL) goto err;
|
|
||||||
bits=BN_num_bits(p);
|
|
||||||
|
|
||||||
if (BN_is_odd(p))
|
|
||||||
{ if (BN_copy(r,a) == NULL) goto err; }
|
|
||||||
else { if (!BN_one(r)) goto err; }
|
|
||||||
|
|
||||||
for (i=1; i<bits; i++)
|
|
||||||
{
|
|
||||||
if (!BN_sqr(tmp,v,ctx)) goto err;
|
|
||||||
if (!BN_mod(v,tmp,m,ctx)) goto err;
|
|
||||||
if (BN_is_bit_set(p,i))
|
|
||||||
{
|
|
||||||
if (!BN_mul(tmp,r,v,ctx)) goto err;
|
|
||||||
if (!BN_mod(r,tmp,m,ctx)) goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret=1;
|
|
||||||
err:
|
|
||||||
BN_CTX_end(ctx);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* this one works - simple but works */
|
/* this one works - simple but works */
|
||||||
int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
|
int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
|
||||||
@ -163,6 +128,7 @@ err:
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef ATALLA
|
#ifdef ATALLA
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -330,6 +296,7 @@ int BN_mod_exp_atalla(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m)
|
|||||||
}
|
}
|
||||||
#endif /* def ATALLA */
|
#endif /* def ATALLA */
|
||||||
|
|
||||||
|
|
||||||
int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
|
int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
|
||||||
BN_CTX *ctx)
|
BN_CTX *ctx)
|
||||||
{
|
{
|
||||||
@ -354,7 +321,15 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
|
|||||||
/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
|
/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
|
||||||
|
|
||||||
if (BN_is_odd(m))
|
if (BN_is_odd(m))
|
||||||
{ ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); }
|
{
|
||||||
|
if (a->top == 1)
|
||||||
|
{
|
||||||
|
BN_ULONG A = a->d[0];
|
||||||
|
ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#ifdef RECP_MUL_MOD
|
#ifdef RECP_MUL_MOD
|
||||||
@ -370,7 +345,7 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #ifdef RECP_MUL_MOD */
|
|
||||||
int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||||
const BIGNUM *m, BN_CTX *ctx)
|
const BIGNUM *m, BN_CTX *ctx)
|
||||||
{
|
{
|
||||||
@ -485,9 +460,8 @@ err:
|
|||||||
BN_RECP_CTX_free(&recp);
|
BN_RECP_CTX_free(&recp);
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
/* #endif */
|
|
||||||
|
|
||||||
/* #ifdef MONT_MUL_MOD */
|
|
||||||
int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
|
int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
|
||||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
|
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
|
||||||
{
|
{
|
||||||
@ -527,11 +501,9 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
|
|||||||
/* If this is not done, things will break in the montgomery
|
/* If this is not done, things will break in the montgomery
|
||||||
* part */
|
* part */
|
||||||
|
|
||||||
#if 1
|
|
||||||
if (in_mont != NULL)
|
if (in_mont != NULL)
|
||||||
mont=in_mont;
|
mont=in_mont;
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
|
if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
|
||||||
if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
|
if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
|
||||||
@ -541,7 +513,8 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
|
|||||||
ts=1;
|
ts=1;
|
||||||
if (BN_ucmp(a,m) >= 0)
|
if (BN_ucmp(a,m) >= 0)
|
||||||
{
|
{
|
||||||
BN_mod(&(val[0]),a,m,ctx);
|
if (!BN_mod(&(val[0]),a,m,ctx))
|
||||||
|
goto err;
|
||||||
aa= &(val[0]);
|
aa= &(val[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -635,7 +608,82 @@ err:
|
|||||||
BN_clear_free(&(val[i]));
|
BN_clear_free(&(val[i]));
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
/* #endif */
|
|
||||||
|
int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
|
||||||
|
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
|
||||||
|
/* if we had BN_mod_exp_mont_2, we could even use windowing in it */
|
||||||
|
{
|
||||||
|
int b, bits, ret=0;
|
||||||
|
BIGNUM *d, *r, *t;
|
||||||
|
BN_MONT_CTX *mont = NULL;
|
||||||
|
|
||||||
|
bn_check_top(p);
|
||||||
|
bn_check_top(m);
|
||||||
|
|
||||||
|
if (!(m->d[0] & 1))
|
||||||
|
{
|
||||||
|
BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
bits = BN_num_bits(p);
|
||||||
|
if (bits == 0)
|
||||||
|
{
|
||||||
|
BN_one(rr);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
BN_CTX_start(ctx);
|
||||||
|
d = BN_CTX_get(ctx);
|
||||||
|
r = BN_CTX_get(ctx);
|
||||||
|
t = BN_CTX_get(ctx);
|
||||||
|
if (d == NULL || r == NULL || t == NULL) goto err;
|
||||||
|
|
||||||
|
#ifdef ATALLA
|
||||||
|
if (!tried_atalla)
|
||||||
|
{
|
||||||
|
BN_set_word(t, a);
|
||||||
|
if (BN_mod_exp_word_atalla(rr, t, p, m))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* If it fails, try the other methods */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (in_mont != NULL)
|
||||||
|
mont=in_mont;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((mont = BN_MONT_CTX_new()) == NULL) goto err;
|
||||||
|
if (!BN_MONT_CTX_set(mont, m, ctx)) goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) goto err;
|
||||||
|
for (b = bits-1; b >= 0; b--)
|
||||||
|
{
|
||||||
|
if (BN_is_bit_set(p, b))
|
||||||
|
{
|
||||||
|
if (!BN_mul_word(r, a))
|
||||||
|
goto err;
|
||||||
|
if (BN_ucmp(r, m) >= 0)
|
||||||
|
{
|
||||||
|
if (!BN_mod(t, r, m, ctx))
|
||||||
|
goto err;
|
||||||
|
{ BIGNUM *swap_tmp = r; r = t; t = swap_tmp; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b > 0)
|
||||||
|
{
|
||||||
|
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BN_from_montgomery(rr, r, mont, ctx);
|
||||||
|
ret = 1;
|
||||||
|
err:
|
||||||
|
if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
|
||||||
|
BN_CTX_end(ctx);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The old fallback, simple version :-) */
|
/* The old fallback, simple version :-) */
|
||||||
int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
|
int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
|
||||||
|
@ -193,19 +193,26 @@ err:
|
|||||||
static int dh_bn_mod_exp(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
|
static int dh_bn_mod_exp(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
|
||||||
const BIGNUM *m, BN_CTX *ctx,
|
const BIGNUM *m, BN_CTX *ctx,
|
||||||
BN_MONT_CTX *m_ctx)
|
BN_MONT_CTX *m_ctx)
|
||||||
{
|
{
|
||||||
return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
|
if (a->top == 1)
|
||||||
}
|
{
|
||||||
|
BN_ULONG A = a->d[0];
|
||||||
|
return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int dh_init(DH *dh)
|
static int dh_init(DH *dh)
|
||||||
{
|
{
|
||||||
dh->flags |= DH_FLAG_CACHE_MONT_P;
|
dh->flags |= DH_FLAG_CACHE_MONT_P;
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dh_finish(DH *dh)
|
static int dh_finish(DH *dh)
|
||||||
{
|
{
|
||||||
if(dh->method_mont_p)
|
if(dh->method_mont_p)
|
||||||
BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p);
|
BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user