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

📄 nn.c

📁 des和rsa加密算法程序
💻 C
字号:
#include "rsa_incl.h"#include "nn.h"/* internal static functions */static NN_DIGIT subdigitmult PROTO_LIST	((NN_DIGIT *, NN_DIGIT *, NN_DIGIT, NN_DIGIT *, unsigned int));static void dmult PROTO_LIST ((NN_DIGIT, NN_DIGIT, NN_DIGIT *, NN_DIGIT *));static unsigned int NN_DigitBits PROTO_LIST ((NN_DIGIT));#ifndef USEASM/* Decodes character string b into a, where character string is ordered	 from most to least significant.	 Lengths: a[digits], b[len].	 Assumes b[i] = 0 for i < len - digits * NN_DIGIT_LEN. (Otherwise most	 significant bytes are truncated.) */void NN_Decode (a, digits, b, len)NN_DIGIT *a;unsigned char *b;unsigned int digits, len;{  NN_DIGIT t;  unsigned int i, u;  int j;              /* @##$ unsigned/signed bug fix added JSAK - Fri  31/05/96 18:09:11 */  for (i = 0, j = len - 1; i < digits && j >= 0; i++) {    t = 0;    for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)			t |= ((NN_DIGIT)b[j]) << u;		a[i] = t;  }    for (; i < digits; i++)    a[i] = 0;}/* Encodes b into character string a, where character string is ordered   from most to least significant.	 Lengths: a[len], b[digits].	 Assumes NN_Bits (b, digits) <= 8 * len. (Otherwise most significant	 digits are truncated.) */void NN_Encode (a, len, b, digits)NN_DIGIT *b;unsigned char *a;unsigned int digits, len;{	NN_DIGIT t;    unsigned int i, u;    int j;            /* @##$ unsigned/signed bug fix added JSAK - Fri  31/05/96 18:09:11 */    for (i = 0, j = len - 1; i < digits && j >= 0; i++) {		t = b[i];        for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)			a[j] = (unsigned char)(t >> u);	}    for (; j >= 0; j--)		a[j] = 0;}/* Assigns a = 0. */void NN_AssignZero (a, digits)NN_DIGIT *a;unsigned int digits;{	if(digits) {		do {			*a++ = 0;		}while(--digits);	}}#endif/* Assigns a = 2^b.   Lengths: a[digits].	 Requires b < digits * NN_DIGIT_BITS. */void NN_Assign2Exp (a, b, digits)NN_DIGIT *a;unsigned int b, digits;{  NN_AssignZero (a, digits);	if (b >= digits * NN_DIGIT_BITS)    return;  a[b / NN_DIGIT_BITS] = (NN_DIGIT)1 << (b % NN_DIGIT_BITS);}/* Computes a = b - c. Returns borrow.	 Lengths: a[digits], b[digits], c[digits]. */NN_DIGIT NN_Sub (a, b, c, digits)NN_DIGIT *a, *b, *c;unsigned int digits;{	NN_DIGIT temp, borrow = 0;	if(digits)		do {            /* Bug fix 16/10/95 - JSK, code below removed, caused bug with               Sun Compiler SC4.			if((temp = (*b++) - borrow) == MAX_NN_DIGIT)                temp = MAX_NN_DIGIT - *c++;            */            temp = *b - borrow;            b++;            if(temp == MAX_NN_DIGIT) {                temp = MAX_NN_DIGIT - *c;                c++;            }else {      /* Patch to prevent bug for Sun CC */                if((temp -= *c) > (MAX_NN_DIGIT - *c))					borrow = 1;				else					borrow = 0;                c++;            }			*a++ = temp;		}while(--digits);	return(borrow);}/* Computes a = b * c.	 Lengths: a[2*digits], b[digits], c[digits].	 Assumes digits < MAX_NN_DIGITS.*/void NN_Mult (a, b, c, digits)NN_DIGIT *a, *b, *c;unsigned int digits;{	NN_DIGIT t[2*MAX_NN_DIGITS];	NN_DIGIT dhigh, dlow, carry;	unsigned int bDigits, cDigits, i, j;	NN_AssignZero (t, 2 * digits);	bDigits = NN_Digits (b, digits);	cDigits = NN_Digits (c, digits);	for (i = 0; i < bDigits; i++) {		carry = 0;		if(*(b+i) != 0) {			for(j = 0; j < cDigits; j++) {				dmult(*(b+i), *(c+j), &dhigh, &dlow);				if((*(t+(i+j)) = *(t+(i+j)) + carry) < carry)					carry = 1;				else					carry = 0;				if((*(t+(i+j)) += dlow) < dlow)					carry++;				carry += dhigh;			}		}		*(t+(i+cDigits)) += carry;	}	NN_Assign(a, t, 2 * digits);}/* Computes a = b * 2^c (i.e., shifts left c bits), returning carry.	 Requires c < NN_DIGIT_BITS. */NN_DIGIT NN_LShift (a, b, c, digits)NN_DIGIT *a, *b;unsigned int c, digits;{	NN_DIGIT temp, carry = 0;	unsigned int t;	if(c < NN_DIGIT_BITS)		if(digits) {			t = NN_DIGIT_BITS - c;			do {				temp = *b++;				*a++ = (temp << c) | carry;				carry = c ? (temp >> t) : 0;			}while(--digits);		}	return (carry);}/* Computes a = c div 2^c (i.e., shifts right c bits), returning carry.	 Requires: c < NN_DIGIT_BITS. */NN_DIGIT NN_RShift (a, b, c, digits)NN_DIGIT *a, *b;unsigned int c, digits;{	NN_DIGIT temp, carry = 0;	unsigned int t;	if(c < NN_DIGIT_BITS)		if(digits) {			t = NN_DIGIT_BITS - c;			do {				digits--;				temp = *(b+digits);				*(a+digits) = (temp >> c) | carry;				carry = c ? (temp << t) : 0;			}while(digits);		}	return (carry);}/* Computes a = c div d and b = c mod d.	 Lengths: a[cDigits], b[dDigits], c[cDigits], d[dDigits].	 Assumes d > 0, cDigits < 2 * MAX_NN_DIGITS,					 dDigits < MAX_NN_DIGITS.*/void NN_Div (a, b, c, cDigits, d, dDigits)NN_DIGIT *a, *b, *c, *d;unsigned int cDigits, dDigits;{	NN_DIGIT ai, cc[2*MAX_NN_DIGITS+1], dd[MAX_NN_DIGITS], s;	NN_DIGIT t[2], u, v, *ccptr;	NN_HALF_DIGIT aHigh, aLow, cHigh, cLow;	int i;	unsigned int ddDigits, shift;	ddDigits = NN_Digits (d, dDigits);	if(ddDigits == 0)		return;	shift = NN_DIGIT_BITS - NN_DigitBits (d[ddDigits-1]);	NN_AssignZero (cc, ddDigits);	cc[cDigits] = NN_LShift (cc, c, shift, cDigits);	NN_LShift (dd, d, shift, ddDigits);	s = dd[ddDigits-1];	NN_AssignZero (a, cDigits);	for (i = cDigits-ddDigits; i >= 0; i--) {		if (s == MAX_NN_DIGIT)			ai = cc[i+ddDigits];		else {			ccptr = &cc[i+ddDigits-1];			s++;			cHigh = (NN_HALF_DIGIT)HIGH_HALF (s);			cLow = (NN_HALF_DIGIT)LOW_HALF (s);			*t = *ccptr;			*(t+1) = *(ccptr+1);			if (cHigh == MAX_NN_HALF_DIGIT)				aHigh = (NN_HALF_DIGIT)HIGH_HALF (*(t+1));			else				aHigh = (NN_HALF_DIGIT)(*(t+1) / (cHigh + 1));			u = (NN_DIGIT)aHigh * (NN_DIGIT)cLow;			v = (NN_DIGIT)aHigh * (NN_DIGIT)cHigh;			if ((*t -= TO_HIGH_HALF (u)) > (MAX_NN_DIGIT - TO_HIGH_HALF (u)))				t[1]--;			*(t+1) -= HIGH_HALF (u);			*(t+1) -= v;			while ((*(t+1) > cHigh) ||						 ((*(t+1) == cHigh) && (*t >= TO_HIGH_HALF (cLow)))) {				if ((*t -= TO_HIGH_HALF (cLow)) > MAX_NN_DIGIT - TO_HIGH_HALF (cLow))					t[1]--;				*(t+1) -= cHigh;				aHigh++;			}			if (cHigh == MAX_NN_HALF_DIGIT)				aLow = (NN_HALF_DIGIT)LOW_HALF (*(t+1));			else				aLow =			(NN_HALF_DIGIT)((TO_HIGH_HALF (*(t+1)) + HIGH_HALF (*t)) / (cHigh + 1));			u = (NN_DIGIT)aLow * (NN_DIGIT)cLow;			v = (NN_DIGIT)aLow * (NN_DIGIT)cHigh;			if ((*t -= u) > (MAX_NN_DIGIT - u))				t[1]--;			if ((*t -= TO_HIGH_HALF (v)) > (MAX_NN_DIGIT - TO_HIGH_HALF (v)))				t[1]--;			*(t+1) -= HIGH_HALF (v);			while ((*(t+1) > 0) || ((*(t+1) == 0) && *t >= s)) {				if ((*t -= s) > (MAX_NN_DIGIT - s))					t[1]--;				aLow++;			}			ai = TO_HIGH_HALF (aHigh) + aLow;			s--;		}		cc[i+ddDigits] -= subdigitmult(&cc[i], &cc[i], ai, dd, ddDigits);		while (cc[i+ddDigits] || (NN_Cmp (&cc[i], dd, ddDigits) >= 0)) {			ai++;			cc[i+ddDigits] -= NN_Sub (&cc[i], &cc[i], dd, ddDigits);		}		a[i] = ai;	}	NN_AssignZero (b, dDigits);	NN_RShift (b, cc, shift, ddDigits);}/* Computes a = b mod c.	 Lengths: a[cDigits], b[bDigits], c[cDigits].	 Assumes c > 0, bDigits < 2 * MAX_NN_DIGITS, cDigits < MAX_NN_DIGITS.*/void NN_Mod (a, b, bDigits, c, cDigits)NN_DIGIT *a, *b, *c;unsigned int bDigits, cDigits;{    NN_DIGIT t[2 * MAX_NN_DIGITS];  	NN_Div (t, a, b, bDigits, c, cDigits);}/* Computes a = b * c mod d.   Lengths: a[digits], b[digits], c[digits], d[digits].   Assumes d > 0, digits < MAX_NN_DIGITS. */void NN_ModMult (a, b, c, d, digits)NN_DIGIT *a, *b, *c, *d;unsigned int digits;{    NN_DIGIT t[2*MAX_NN_DIGITS];	NN_Mult (t, b, c, digits);    NN_Mod (a, t, 2 * digits, d, digits);}/* Computes a = b^c mod d.   Lengths: a[dDigits], b[dDigits], c[cDigits], d[dDigits].	 Assumes d > 0, cDigits > 0, dDigits < MAX_NN_DIGITS. */void NN_ModExp (a, b, c, cDigits, d, dDigits)NN_DIGIT *a, *b, *c, *d;unsigned int cDigits, dDigits;{    NN_DIGIT bPower[3][MAX_NN_DIGITS], ci, t[MAX_NN_DIGITS];    int i;	unsigned int ciBits, j, s;	/* Store b, b^2 mod d, and b^3 mod d.	 */	NN_Assign (bPower[0], b, dDigits);	NN_ModMult (bPower[1], bPower[0], b, d, dDigits);    NN_ModMult (bPower[2], bPower[1], b, d, dDigits);      NN_ASSIGN_DIGIT (t, 1, dDigits);	cDigits = NN_Digits (c, cDigits);    for (i = cDigits - 1; i >= 0; i--) {		ci = c[i];		ciBits = NN_DIGIT_BITS;		/* Scan past leading zero bits of most significant digit.		 */		if (i == (int)(cDigits - 1)) {			while (! DIGIT_2MSB (ci)) {				ci <<= 2;				ciBits -= 2;			}        }        for (j = 0; j < ciBits; j += 2, ci <<= 2) {        /* Compute t = t^4 * b^s mod d, where s = two MSB's of ci. */            NN_ModMult (t, t, t, d, dDigits);            NN_ModMult (t, t, t, d, dDigits);            if ((s = DIGIT_2MSB (ci)) != 0)            NN_ModMult (t, t, bPower[s-1], d, dDigits);        }    }  	NN_Assign (a, t, dDigits);}/* Compute a = 1/b mod c, assuming inverse exists.      Lengths: a[digits], b[digits], c[digits].	 Assumes gcd (b, c) = 1, digits < MAX_NN_DIGITS. */void NN_ModInv (a, b, c, digits)NN_DIGIT *a, *b, *c;unsigned int digits;{    NN_DIGIT q[MAX_NN_DIGITS], t1[MAX_NN_DIGITS], t3[MAX_NN_DIGITS],		u1[MAX_NN_DIGITS], u3[MAX_NN_DIGITS], v1[MAX_NN_DIGITS],		v3[MAX_NN_DIGITS], w[2*MAX_NN_DIGITS];    int u1Sign;    /* Apply extended Euclidean algorithm, modified to avoid negative       numbers.    */    NN_ASSIGN_DIGIT (u1, 1, digits);	NN_AssignZero (v1, digits);    NN_Assign (u3, b, digits);	NN_Assign (v3, c, digits);    u1Sign = 1;	while (! NN_Zero (v3, digits)) {        NN_Div (q, t3, u3, digits, v3, digits);        NN_Mult (w, q, v1, digits);		NN_Add (t1, u1, w, digits);        NN_Assign (u1, v1, digits);		NN_Assign (v1, t1, digits);		NN_Assign (u3, v3, digits);		NN_Assign (v3, t3, digits);		u1Sign = -u1Sign;	}    /* Negate result if sign is negative. */	if (u1Sign < 0)		NN_Sub (a, c, u1, digits);	else		NN_Assign (a, u1, digits);}/* Computes a = gcd(b, c).	 Assumes b > c, digits < MAX_NN_DIGITS.*/#define iplus1  ( i==2 ? 0 : i+1 )      /* used by Euclid algorithms */#define iminus1 ( i==0 ? 2 : i-1 )      /* used by Euclid algorithms */#define g(i) (  &(t[i][0])  )void NN_Gcd(a ,b ,c, digits)NN_DIGIT *a, *b, *c;unsigned int digits;{	short i;	NN_DIGIT t[3][MAX_NN_DIGITS];	NN_Assign(g(0), c, digits);	NN_Assign(g(1), b, digits);	i=1;	while(!NN_Zero(g(i),digits)) {		NN_Mod(g(iplus1), g(iminus1), digits, g(i), digits);		i = iplus1;	}	NN_Assign(a , g(iminus1), digits);}/* Returns the significant length of a in bits.	 Lengths: a[digits]. */unsigned int NN_Bits (a, digits)NN_DIGIT *a;unsigned int digits;{	if ((digits = NN_Digits (a, digits)) == 0)		return (0);	return ((digits - 1) * NN_DIGIT_BITS + NN_DigitBits (a[digits-1]));}#ifndef USEASM/* Returns sign of a - b. */int NN_Cmp (a, b, digits)NN_DIGIT *a, *b;unsigned int digits;{	if(digits) {		do {			digits--;			if(*(a+digits) > *(b+digits))				return(1);			if(*(a+digits) < *(b+digits))				return(-1);		}while(digits);	}	return (0);}/* Returns nonzero iff a is zero. */int NN_Zero (a, digits)NN_DIGIT *a;unsigned int digits;{	if(digits) {		do {			if(*a++)				return(0);		}while(--digits);	}	return (1);}/* Assigns a = b. */void NN_Assign (a, b, digits)NN_DIGIT *a, *b;unsigned int digits;{	if(digits) {		do {			*a++ = *b++;		}while(--digits);	}}/* Returns the significant length of a in digits. */unsigned int NN_Digits (a, digits)NN_DIGIT *a;unsigned int digits;{	if(digits) {		digits--;		do {			if(*(a+digits))				break;		}while(digits--);		return(digits + 1);	}	return(digits);}/* Computes a = b + c. Returns carry.	 Lengths: a[digits], b[digits], c[digits]. */NN_DIGIT NN_Add (a, b, c, digits)NN_DIGIT *a, *b, *c;unsigned int digits;{	NN_DIGIT temp, carry = 0;	if(digits)		do {			if((temp = (*b++) + carry) < carry)				temp = *c++;            else {      /* Patch to prevent bug for Sun CC */                if((temp += *c) < *c)					carry = 1;				else					carry = 0;                c++;            }			*a++ = temp;		}while(--digits);	return (carry);}#endifstatic NN_DIGIT subdigitmult(a, b, c, d, digits)NN_DIGIT *a, *b, c, *d;unsigned int digits;{	NN_DIGIT borrow, thigh, tlow;	unsigned int i;	borrow = 0;	if(c != 0) {		for(i = 0; i < digits; i++) {			dmult(c, d[i], &thigh, &tlow);			if((a[i] = b[i] - borrow) > (MAX_NN_DIGIT - borrow))				borrow = 1;			else				borrow = 0;			if((a[i] -= tlow) > (MAX_NN_DIGIT - tlow))				borrow++;			borrow += thigh;		}	}	return (borrow);}/* Returns the significant length of a in bits, where a is a digit. */static unsigned int NN_DigitBits (a)NN_DIGIT a;{	unsigned int i;	for (i = 0; i < NN_DIGIT_BITS; i++, a >>= 1)		if (a == 0)			break;	return (i);}/* Computes a * b, result stored in high and low. */ static void dmult( a, b, high, low)NN_DIGIT          a, b;NN_DIGIT         *high;NN_DIGIT         *low;{	NN_HALF_DIGIT al, ah, bl, bh;	NN_DIGIT m1, m2, m, ml, mh, carry = 0;	al = (NN_HALF_DIGIT)LOW_HALF(a);	ah = (NN_HALF_DIGIT)HIGH_HALF(a);	bl = (NN_HALF_DIGIT)LOW_HALF(b);	bh = (NN_HALF_DIGIT)HIGH_HALF(b);	*low = (NN_DIGIT) al*bl;	*high = (NN_DIGIT) ah*bh;	m1 = (NN_DIGIT) al*bh;	m2 = (NN_DIGIT) ah*bl;	m = m1 + m2;	if(m < m1)        carry = 1L << (NN_DIGIT_BITS / 2);	ml = (m & MAX_NN_HALF_DIGIT) << (NN_DIGIT_BITS / 2);	mh = m >> (NN_DIGIT_BITS / 2);	*low += ml;	if(*low < ml)		carry++;	*high += carry + mh;}

⌨️ 快捷键说明

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