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

📄 int_functions.c

📁 ECC的C++源码
💻 C
字号:
/*********************************************************************************																				**		The functions in this file use the basic large integer arithmetic sub-	**	routines to perform such things as greatest common divisor, modular 		**	inversion and modular exponentiation.  Note that many other math packages	**	do all these things much better, but this is very easy to follow.			**																				*********************************************************************************/#include <stdio.h>#include "bigint.h"/*  divide a large integer by 2.  A simple shift right operation.  */void int_div2( x)BIGINT *x;{	INDEX j;	ELEMENT mask;		INTLOOP(j)	{		if (j) mask = ( x->hw[j-1] & 1) ? CARRY : 0;		else mask = 0;		x->hw[j] = (x->hw[j] | mask) >> 1;	}}/* compute greatest common divisor using binary method.	See [DEK, pg 321] Algorithm B for theoretical details.	Enter with large integers u, v.  	Returns gcd(u, v) as large integer in w.*/void int_gcd(u, v, w)BIGINT *u, *v, *w;{	INDEX  k, i, flag;	ELEMENT check, carry_bit;	BIGINT t, U, V;		int_copy( u, &U);	int_copy( v, &V);	/*  find common powers of 2 and eliminate them */	k = 0;	/*  check that both u and v are even */	while ( !(U.hw[INTMAX] & 1 || V.hw[INTMAX] & 1))   	{	/*  increment power of 2 and divide both u and v by 2 */		k++;							int_div2( &U);		int_div2( &V);	}	/* Now both u and v have been divided by 2^k.  	If u is odd, set t = v and flag, otherwise t = u and clear flag  */	if (U.hw[INTMAX] & 1)	{		int_copy( &V, &t);		flag = -1;	}	else 	{		int_copy( &U, &t);		flag = 1;	}		check = 0;	INTLOOP (i) check |= t.hw[i];	while (check)	{	/* while t is even, divide by 2  */			while ( !(t.hw[INTMAX] & 1)) int_div2( &t);  /* reset u or v to t depending on sign of flag  */		if (flag > 0) int_copy( &t, &U);		else int_copy( &t, &V);/*		t = u - v;			  core reduction step, gcd remains unchanged  */		int_sub( &U, &V, &t);		if (t.hw[0] & MSB_HW)		{			flag = -1;			int_neg( &t);		}		else flag = 1;		check = 0;		INTLOOP (i) check |= t.hw[i];	}	/*  reapply common powers of 2. First do words, then do bits.*/		int_copy( &U, w);	while ( k > HALFSIZE )	{		for (i=0; i<INTMAX; i++) w->hw[i] = w->hw[i+1];		k -= HALFSIZE;		w->hw[INTMAX] = 0;	}	carry_bit = 0;	while ( k > 0 )	{		INTLOOP (i)		{			w->hw[i] = (w->hw[i] << 1) | carry_bit;			carry_bit = w->hw[i] & CARRY ? 1 : 0;			w->hw[i] &= LOMASK;		}		k--;	}}/*  Binary method for modular exponentiation.  Taken from [DEK,pg 442] Algorithm A.	Computes z = x^n mod q for x, n and q large integers.*/void mod_exp(x, n, q, z)BIGINT *x, *n, *q, *z;{	BIGINT  N, Y, Z, temp, dummy;	ELEMENT check;	INDEX   i;	/*  initialize variables  */	int_copy (n, &N);	int_null( &Y);	Y.hw[INTMAX] = 1;	int_copy (x, &Z);/*  Main loop divides N by 2 each step.  Repeat until N = 0, and return Y as result.  */	check = 0;	INTLOOP (i) check |= N.hw[i];	while (check)	{/*  if N is odd, multiply by extra factor of Y */		if (N.hw[INTMAX] & 1) 		{			/*  Y = (Y * Z) % q;  */			int_mul (&Y, &Z, &temp);			int_div (&temp, q, &dummy, &Y);		}		int_div2( &N);					/* divide N by 2 */	/*		Z = (Z * Z) % q;		  square Z  */		int_mul (&Z, &Z, &temp);		int_div( &temp, q, &dummy, &Z);		check = 0;		INTLOOP (i) check |= N.hw[i];	}	int_copy (&Y, z);}/*  Inversion of numbers in a prime field is similar to solving the linear congruence	ax = c mod b.  Replace c with 1 and x is the inverse of a mod b.  Taken from [HR,	pg 309].	Inputs are large integer a and modulus b.	Output is x, inverse of a mod b  (ax = 1 mod b).*/void mod_inv(a, b, x)BIGINT *a, *b, *x;{	BIGINT  m, n, p0, p1, p2, q, r, temp, dummy;	ELEMENT check;	INDEX   sw, i;	/*  initialize loop variables  	sw = 1;	m = b;	n = a;	p0 = 1;	p1 = m/n;	q = p1;	r = m % n;*/	sw = 1;	int_copy( b, &m);	int_copy( a, &n);	int_null ( &p0);	p0.hw[INTMAX] = 1;	int_div ( &m, &n, &p1, &r);	int_copy ( &p1, &q);	/*  main loop, compute continued fraction  intermediates  */	check = 0;	INTLOOP (i) check |= r.hw[i];	while (check)	{		sw = -sw;		int_copy( &n, &m);		int_copy( &r, &n);		int_div( &m, &n, &q, &r); /*		p2 = (q * p1 + p0) % b;   core operation of routine  */ 		int_mul( &q, &p1, &temp); 		int_add( &temp, &p0, &temp); 		int_div( &temp, b, &dummy, &p2); 		int_copy( &p1, &p0); 		int_copy( &p2, &p1);		check = 0;		INTLOOP (i) check |= r.hw[i];	}	/*  sw keeps track of sign.  If sw < 0, add modulus to result */	if (sw < 0) int_sub( b, &p0, x);	else int_copy( &p0, x);}main(){	BIGINT test1, test2, test3, test4;	INDEX i;	FIELD2N point_order;	char outstring[MAXSTRING];/*	char string1[MAXSTRING] = "19822884620916109459140767798279811163792081";*//*	char string1[MAXSTRING] = "91343852333181432387730573045979447452365303319";*/	char string1[MAXSTRING] = "5192296858534827627896703833467507";		int_null(&test1);	int_null(&test2);		test1.hw[INTMAX] = 10763;	test1.hw[INTMAX-1] = 45;	bigint_to_ascii(&test1, &outstring);	printf("%s\n",outstring);/*	int_copy( &test1, &test2);*//*	int_neg( &test2);*/	test2.hw[INTMAX] = 10335;	test2.hw[INTMAX-1] = 3537;	bigint_to_ascii(&test2, &outstring);	printf("%s\n",outstring);	mod_inv( &test1, &test2, &test3);/*	int_mul(&test1, &test2, &test3); */	bigint_to_ascii(&test3, &outstring);	printf("%s\n",outstring);	int_mul(&test3, &test1, &test4);		bigint_to_ascii( &test4, &outstring);	printf("%s\n",outstring);	int_div(&test4, &test2, &test1, &test2);	bigint_to_ascii( &test1, &outstring);	printf("%s\n",outstring);	bigint_to_ascii( &test2, &outstring);	printf("%s\n",outstring);	/*	ascii_to_bigint(&string1, &test3);	bigint_to_ascii(&test3, &outstring);	printf("%s",string1);	printf("%s\n",outstring);	for(i=0; i<=INTMAX; i++) printf("%x ",test3.hw[i]);*/	/*	int_to_field(&test3, &point_order); */	/*	int_div( &test2, &test1, &test3, &test4);*/}	

⌨️ 快捷键说明

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