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

📄 bn_knuth.c

📁 openssl是ssl的开源项目
💻 C
字号:
/* crypto/bn/bn_knuth.c */#include <stdio.h>#include "cryptlib.h"#include "bn.h"/* This is just a test implementation, it has not been modified for * speed and it still has memory leaks. */int BN_mask_bits(BIGNUM *a,int n);#undef DEBUG#define MAIN/* r must be different to a and b * Toom-Cook multiplication algorithm, taken from * The Art Of Computer Programming, Volume 2, Donald Knuth */#define	CODE1		((BIGNUM *)0x01)#define	CODE2		((BIGNUM *)0x02)#define	CODE3		((BIGNUM *)0x03)#define MAXK		(30+1)#define C3	3#define C4	4#define C5	5#define C6	6#define C7	7#define C8	8#define C9	9#define C10	10#define DONE	11int new_total=0;int Free_total=0;int max=0,max_total=0;BIGNUM *LBN_new(void );BIGNUM *LBN_dup(BIGNUM *a);void LBN_free(BIGNUM *a);int BN_mul_knuth(w, a, b)BIGNUM *w;BIGNUM *a;BIGNUM *b;	{	int ret=1;	int i,j,n,an,bn,y,z;	BIGNUM *U[MAXK],*V[MAXK],*T[MAXK];	BIGNUM *C[(MAXK*2*3)];	BIGNUM *W[(MAXK*2)],*t1,*t2,*t3,*t4;	int Utos,Vtos,Ctos,Wtos,Ttos;	unsigned int k,Q,R;	unsigned int q[MAXK];	unsigned int r[MAXK];	int state;	/* C1 */	Utos=Vtos=Ctos=Wtos=Ttos=0;	k=1;	q[0]=q[1]=64;	r[0]=r[1]=4;	Q=6;	R=2;	if (!bn_expand(w,BN_BITS2*2)) goto err;	an=BN_num_bits(a);	bn=BN_num_bits(b);	n=(an > bn)?an:bn;	while ((q[k-1]+q[k]) < n)		{		k++;		Q+=R;		i=R+1;		if ((i*i) <= Q) R=i;		q[k]=(1<<Q);		r[k]=(1<<R);		}#ifdef DEBUG	printf("k   =");	for (i=0; i<=k; i++) printf("%7d",i);	printf("\nq[k]=");	for (i=0; i<=k; i++) printf("%7d",q[i]);	printf("\nr[k]=");	for (i=0; i<=k; i++) printf("%7d",r[i]);	printf("\n");#endif	/* C2 */	C[Ctos++]=CODE1;	if ((t1=LBN_dup(a)) == NULL) goto err;	C[Ctos++]=t1;	if ((t1=LBN_dup(b)) == NULL) goto err;	C[Ctos++]=t1;	state=C3;	for (;;)		{#ifdef DEBUG		printf("state=C%d, Ctos=%d Wtos=%d\n",state,Ctos,Wtos);#endif		switch (state)			{			int lr,lq,lp;		case C3:			k--;			if (k == 0)				{				t1=C[--Ctos];				t2=C[--Ctos];#ifdef DEBUG				printf("Ctos=%d poped %d\n",Ctos,2);#endif				if ((t2->top == 0) || (t1->top == 0))					w->top=0;				else					BN_mul(w,t1,t2);				LBN_free(t1); /* FREE */				LBN_free(t2); /* FREE */				state=C10;				}			else				{				lr=r[k];				lq=q[k];				lp=q[k-1]+q[k];				state=C4;				}			break;		case C4:			for (z=0; z<2; z++) /* do for u and v */				{				/* break the item at C[Ctos-1] 				 * into lr+1 parts of lq bits each				 * for j=0; j<=2r; j++				 */				t1=C[--Ctos]; /* pop off u */#ifdef DEBUG				printf("Ctos=%d poped %d\n",Ctos,1);#endif				if ((t2=LBN_dup(t1)) == NULL) goto err;				BN_mask_bits(t2,lq);				T[Ttos++]=t2;#ifdef DEBUG				printf("C4 r=0 bits=%d\n",BN_num_bits(t2));#endif				for (i=1; i<=lr; i++)					{					if (!BN_rshift(t1,t1,lq)) goto err;					if ((t2=LBN_dup(t1)) == NULL) goto err;					BN_mask_bits(t2,lq);					T[Ttos++]=t2;#ifdef DEBUG					printf("C4 r=%d bits=%d\n",i,						BN_num_bits(t2));#endif					}				LBN_free(t1);				if ((t2=LBN_new()) == NULL) goto err;				if ((t3=LBN_new()) == NULL) goto err;				for (j=0; j<=2*lr; j++)					{					if ((t1=LBN_new()) == NULL) goto err;					if (!BN_set_word(t3,j)) goto err;					for (i=lr; i>=0; i--)						{						if (!BN_mul(t2,t1,t3)) goto err;						if (!BN_add(t1,t2,T[i])) goto err;						}					/* t1 is U(j) */					if (z == 0)						U[Utos++]=t1;					else						V[Vtos++]=t1;					}				LBN_free(t2);				LBN_free(t3);				while (Ttos) LBN_free(T[--Ttos]);				}#ifdef DEBUG			for (i=0; i<Utos; i++)				printf("U[%2d]=%4d bits\n",i,BN_num_bits(U[i]));			for (i=0; i<Vtos; i++)				printf("V[%2d]=%4d bits\n",i,BN_num_bits(V[i]));#endif			/* C5 */#ifdef DEBUG			printf("PUSH CODE2 and %d CODE3 onto stack\n",2*lr);#endif			C[Ctos++]=CODE2;			for (i=2*lr; i>0; i--)				{				C[Ctos++]=V[i];				C[Ctos++]=U[i];				C[Ctos++]=CODE3;				}			C[Ctos++]=V[0];			C[Ctos++]=U[0];#ifdef DEBUG				printf("Ctos=%d pushed %d\n",Ctos,2*lr*3+3);#endif			Vtos=Utos=0;			state=C3;			break;		case C6:			if ((t1=LBN_dup(w)) == NULL) goto err;			W[Wtos++]=t1;#ifdef DEBUG			printf("put %d bit number onto w\n",BN_num_bits(t1));#endif			state=C3;			break;		case C7:			lr=r[k];			lq=q[k];			lp=q[k]+q[k-1];			z=Wtos-2*lr-1;			for (j=1; j<=2*lr; j++)				{				for (i=2*lr; i>=j; i--)					{					if (!BN_sub(W[z+i],W[z+i],W[z+i-1])) goto err;					BN_div_word(W[z+i],j);					}				}			state=C8;			break;		case C8:			y=2*lr-1;			if ((t1=LBN_new()) == NULL) goto err;			if ((t3=LBN_new()) == NULL) goto err;			for (j=y; j>0; j--)				{				if (!BN_set_word(t3,j)) goto err;				for (i=j; i<=y; i++)					{					if (!BN_mul(t1,W[z+i+1],t3)) goto err;					if (!BN_sub(W[z+i],W[z+i],t1)) goto err;					}				}			LBN_free(t1);			LBN_free(t3);			state=C9;			break;		case C9:			BN_zero(w);#ifdef DEBUG			printf("lq=%d\n",lq);#endif			for (i=lr*2; i>=0; i--)				{				BN_lshift(w,w,lq);				BN_add(w,w,W[z+i]);				}			for (i=0; i<=lr*2; i++)				LBN_free(W[--Wtos]);			state=C10;			break;		case C10:			k++;			t1=C[--Ctos];#ifdef DEBUG			printf("Ctos=%d poped %d\n",Ctos,1);			printf("code= CODE%d\n",t1);#endif			if (t1 == CODE3)				state=C6;			else if (t1 == CODE2)				{				if ((t2=LBN_dup(w)) == NULL) goto err;				W[Wtos++]=t2;				state=C7;				}			else if (t1 == CODE1)				{				state=DONE;				}			else				{				printf("BAD ERROR\n");				goto err;				}			break;		default:			printf("bad state\n");			goto err;			break;			}		if (state == DONE) break;		}	ret=1;err:	if (ret == 0) printf("ERROR\n");	return(ret);	}#ifdef MAINmain()	{	BIGNUM *a,*b,*r;	int i;	if ((a=LBN_new()) == NULL) goto err;	if ((b=LBN_new()) == NULL) goto err;	if ((r=LBN_new()) == NULL) goto err;	if (!BN_rand(a,1024*2,0,0)) goto err;	if (!BN_rand(b,1024*2,0,0)) goto err;	for (i=0; i<10; i++)		{		if (!BN_mul_knuth(r,a,b)) goto err; /**/		/*if (!BN_mul(r,a,b)) goto err; /**/		}BN_print(stdout,a); printf(" * ");BN_print(stdout,b); printf(" =\n");BN_print(stdout,r); printf("\n");printf("BN_new() =%d\nBN_free()=%d max=%d\n",new_total,Free_total,max);	exit(0);err:	ERR_load_crypto_strings();	ERR_print_errors(stderr);	exit(1);	}#endifint BN_mask_bits(a,n)BIGNUM *a;int n;	{	int b,w;	w=n/BN_BITS2;	b=n%BN_BITS2;	if (w >= a->top) return(0);	if (b == 0)		a->top=w;	else		{		a->top=w+1;		a->d[w]&= ~(BN_MASK2<<b);		}	return(1);	}BIGNUM *LBN_dup(a)BIGNUM *a;	{	new_total++;	max_total++;	if (max_total > max) max=max_total;	return(BN_dup(a));	}BIGNUM *LBN_new()	{	new_total++;	max_total++;	if (max_total > max) max=max_total;	return(BN_new());	}void LBN_free(a)BIGNUM *a;	{	max_total--;	if (max_total > max) max=max_total;	Free_total++;	BN_free(a);	}

⌨️ 快捷键说明

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