📄 rsa.c
字号:
typedef struct { unsigned int bytesNeeded; /* seed bytes required */ unsigned char state[16]; /* state of object */ unsigned int outputAvailable; /* number byte available */ unsigned char output[16]; /* output bytes */} R_RANDOM_STRUCT;/* RSA public and private key. */typedef struct { unsigned short int bits; /* length in bits of modulus */ unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */} R_RSA_PUBLIC_KEY;typedef struct { unsigned short int bits; /* length in bits of modulus */ unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ unsigned char publicExponent[MAX_RSA_MODULUS_LEN]; /* public exponent */ unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */ unsigned char prime[2][MAX_RSA_PRIME_LEN]; /* prime factors */ unsigned char primeExponent[2][MAX_RSA_PRIME_LEN]; /* exponents for CRT */ unsigned char coefficient[MAX_RSA_PRIME_LEN]; /* CRT coefficient */} R_RSA_PRIVATE_KEY;/* RSA prototype key. */typedef struct { unsigned int bits; /* length in bits of modulus */ int useFermat4; /* public exponent (1 = F4, 0 = 3) */} R_RSA_PROTO_KEY;/* Diffie-Hellman parameters. */typedef struct { unsigned char *prime; /* prime */ unsigned int primeLen; /* length of prime */ unsigned char *generator; /* generator */ unsigned int generatorLen; /* length of generator */} R_DH_PARAMS;/* digest algorithm context */typedef struct { int digestAlgorithm; /* digest type */ union { /* digest sub-context */ MD2_CTX md2; MD4_CTX md4; MD5_CTX md5; SHS_CTX shs; } context;} R_DIGEST_CTX;/* signature context */typedef struct { R_DIGEST_CTX digestContext;} R_SIGNATURE_CTX;/* envelope context */typedef struct { int encryptionAlgorithm; /* encryption type */ union { /* encryption sub-context */ DES_CBC_CTX des; DES3_CBC_CTX des3; DESX_CBC_CTX desx; } cipherContext; unsigned char buffer[8]; /* data buffer */ unsigned int bufferLen; /* buffer length */} R_ENVELOPE_CTX;/* Cryptographic procedures. */int R_OpenInit PROTO_LIST ((R_ENVELOPE_CTX *, int, unsigned char *, unsigned int, unsigned char [8], R_RSA_PRIVATE_KEY *));int R_OpenUpdate PROTO_LIST ((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *, unsigned int));int R_OpenFinal PROTO_LIST ((R_ENVELOPE_CTX *, unsigned char *, unsigned int *));/* Cryptographic enhancements. */int R_SignBlock PROTO_LIST ((unsigned char *, unsigned int *, unsigned char *, unsigned int, int, R_RSA_PRIVATE_KEY *));int R_VerifyPEMSignature PROTO_LIST ((unsigned char *, unsigned int *, unsigned char *, unsigned int, unsigned char *, unsigned int, int, int, R_RSA_PUBLIC_KEY *));int R_VerifyBlockSignature PROTO_LIST ((unsigned char *, unsigned int, unsigned char *, unsigned int, int, R_RSA_PUBLIC_KEY *));/* Standard library routines. */#ifdef USE_ANSI#define R_memset(x, y, z) memset(x, y, z)#define R_memcpy(x, y, z) memcpy(x, y, z)#define R_memcmp(x, y, z) memcmp(x, y, z)#elsevoid R_memset PROTO_LIST ((POINTER, int, unsigned int));void R_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));int R_memcmp PROTO_LIST ((POINTER, POINTER, unsigned int));#endif/***************************************************************************** ********************************************************* #include "rsa.h" */int RSAPublicDecrypt PROTO_LIST ((unsigned char *, unsigned int *, unsigned char *, unsigned int, R_RSA_PUBLIC_KEY *));/***************************************************************************** ******************************************************************* nn.c ***//* 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 (NN_DIGIT *a, unsigned int digits, unsigned char * b, unsigned int len){ NN_DIGIT t; unsigned int i, u; int j; 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 (unsigned char *a, unsigned int len, NN_DIGIT *b, unsigned int digits){ NN_DIGIT t; unsigned int i, u; int j; 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;}void NN_AssignZero (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 (NN_DIGIT *a, unsigned int b, unsigned int 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 (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits){ NN_DIGIT temp, borrow = 0; if(digits) do { 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 (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *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 (NN_DIGIT * a, NN_DIGIT * b, unsigned int c, unsigned int 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 (NN_DIGIT *a, NN_DIGIT *b, unsigned int c, unsigned int 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; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -