⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bn_exp2.c

📁 openssl是ssl的开源项目
💻 C
字号:
#include <stdio.h>#include "cryptlib.h"#include "bn_lcl.h"/* I've done some timing with different table sizes. * The main hassle is that even with bits set at 3, this requires * 63 BIGNUMs to store the pre-calculated values. *          512   1024  * bits=1  75.4%  79.4% * bits=2  61.2%  62.4% * bits=3  61.3%  59.3% * The lack of speed improvment is also a function of the pre-calculation * which could be removed. */#define EXP2_TABLE_BITS	2 /* 1  2  3  4  5  */#define EXP2_TABLE_SIZE	4 /* 2  4  8 16 32  */int BN_mod_exp2_mont(rr,a1,p1,a2,p2,m,ctx,in_mont)BIGNUM *rr;BIGNUM *a1;BIGNUM *p1;BIGNUM *a2;BIGNUM *p2;BIGNUM *m;BN_CTX *ctx;BN_MONT_CTX *in_mont;	{	int i,j,k,bits,bits1,bits2,ret=0,wstart,wend,window,xvalue,yvalue;	int start=1,ts=0,x,y;	BIGNUM *d,*aa1,*aa2,*r;	BIGNUM val[EXP2_TABLE_SIZE][EXP2_TABLE_SIZE];	BN_MONT_CTX *mont=NULL;	bn_check_top(a1);	bn_check_top(p1);	bn_check_top(a2);	bn_check_top(p2);	bn_check_top(m);	if (!(m->d[0] & 1))		{		BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);		return(0);		}	d= &(ctx->bn[ctx->tos++]);	r= &(ctx->bn[ctx->tos++]);	bits1=BN_num_bits(p1);	bits2=BN_num_bits(p2);	if ((bits1 == 0) && (bits2 == 0))		{		BN_one(r);		return(1);		}	bits=(bits1 > bits2)?bits1:bits2;	/* If this is not done, things will break in the montgomery	 * part */	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;		}	BN_init(&(val[0][0]));	BN_init(&(val[1][1]));	BN_init(&(val[0][1]));	BN_init(&(val[1][0]));	ts=1;	if (BN_ucmp(a1,m) >= 0)		{		BN_mod(&(val[1][0]),a1,m,ctx);		aa1= &(val[1][0]);		}	else		aa1=a1;	if (BN_ucmp(a2,m) >= 0)		{		BN_mod(&(val[0][1]),a2,m,ctx);		aa2= &(val[0][1]);		}	else		aa2=a2;	if (!BN_to_montgomery(&(val[1][0]),aa1,mont,ctx)) goto err;	if (!BN_to_montgomery(&(val[0][1]),aa2,mont,ctx)) goto err;	if (!BN_mod_mul_montgomery(&(val[1][1]),		&(val[1][0]),&(val[0][1]),mont,ctx))		goto err;#if 0	if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */		window=1;	else if (bits > 250)		window=5;	/* max size of window */	else if (bits >= 120)		window=4;	else		window=3;#else	window=EXP2_TABLE_BITS;#endif	k=1<<window;	for (x=0; x<k; x++)		{		if (x >= 2)			{			BN_init(&(val[x][0]));			BN_init(&(val[x][1]));			if (!BN_mod_mul_montgomery(&(val[x][0]),				&(val[1][0]),&(val[x-1][0]),mont,ctx)) goto err;			if (!BN_mod_mul_montgomery(&(val[x][1]),				&(val[1][0]),&(val[x-1][1]),mont,ctx)) goto err;			}		for (y=2; y<k; y++)			{			BN_init(&(val[x][y]));			if (!BN_mod_mul_montgomery(&(val[x][y]),				&(val[x][y-1]),&(val[0][1]),mont,ctx))				goto err;			}		}	ts=k;	start=1;	/* This is used to avoid multiplication etc			 * when there is only the value '1' in the			 * buffer. */	xvalue=0;	/* The 'x value' of the window */	yvalue=0;	/* The 'y value' of the window */	wstart=bits-1;	/* The top bit of the window */	wend=0;		/* The bottom bit of the window */        if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;	for (;;)		{		xvalue=BN_is_bit_set(p1,wstart);		yvalue=BN_is_bit_set(p2,wstart);		if (!(xvalue || yvalue))			{			if (!start)				{				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))					goto err;				}			wstart--;			if (wstart < 0) break;			continue;			}		/* We now have wstart on a 'set' bit, we now need to work out		 * how bit a window to do.  To do this we need to scan		 * forward until the last set bit before the end of the		 * window */		j=wstart;		/* xvalue=BN_is_bit_set(p1,wstart); already set */		/* yvalue=BN_is_bit_set(p1,wstart); already set */		wend=0;		for (i=1; i<window; i++)			{			if (wstart-i < 0) break;			xvalue+=xvalue;			xvalue|=BN_is_bit_set(p1,wstart-i);			yvalue+=yvalue;			yvalue|=BN_is_bit_set(p2,wstart-i);			}		/* i is the size of the current window */		/* add the 'bytes above' */		if (!start)			for (j=0; j<i; j++)				{				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))					goto err;				}				/* wvalue will be an odd number < 2^window */		if (xvalue || yvalue)			{			if (!BN_mod_mul_montgomery(r,r,&(val[xvalue][yvalue]),				mont,ctx)) goto err;			}		/* move the 'window' down further */		wstart-=i;		start=0;		if (wstart < 0) break;		}	BN_from_montgomery(rr,r,mont,ctx);	ret=1;err:	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);	ctx->tos-=2;	for (i=0; i<ts; i++)		{		for (j=0; j<ts; j++)			{			BN_clear_free(&(val[i][j]));			}		}	return(ret);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -