void RSASetE(BYTE* data, BYTE len, RSA_DATA_FORMAT format) { BYTE size; BigIntZero(&E); size = (E.ptrMSBMax - E.ptrLSB + 1) * sizeof(BIGINT_DATA_TYPE); // Make sure we don't copy too much if(len > size) len = size; // For little-endian data, copy as is to the front if(format == RSA_LITTLE_ENDIAN) { memcpy((void*)eData, (void*)data, len); } // For big-endian data, copy to end, then swap else { memcpy((void*)&eData[size - len], (void*)data, len); BigIntSwapEndianness(&E); } E.bMSBValid = 0; }
inline Primality MillerRabinSequence( const BigInt& n, Int numReps ) { const BigInt& zero = BigIntZero(); const BigInt& one = BigIntOne(); const BigInt& two = BigIntTwo(); EL_DEBUG_ONLY( if( n <= one ) LogicError("Miller-Rabin is invalid for n <= 1"); ) if( n == two )
void BigIntSquare(BIGINT *a, BIGINT *res) { BigIntZero(res); _iA = a->ptrLSB; _xA = BigIntMSB(a); _iR = res->ptrLSB; sqrBI(); // Invalidate the MSB ptr res->bMSBValid = 0; }
void BigIntMultiplyROM(BIGINT *a, BIGINT_ROM *b, BIGINT *res) { //clear out the result BigIntZero(res); // Load the start and stop pointers _iA = a->ptrLSB; _xA = BigIntMSB(a); _iBr = b->ptrLSB; _xBr = b->ptrMSB; _iR = res->ptrLSB; // Perform the multiplication mulBIROM(); // Invalidate the MSB ptr res->bMSBValid = 0; }
static BOOL _RSAModExpROM(BIGINT* y, BIGINT* x, BIGINT_ROM* e, BIGINT_ROM* n) { static ROM BYTE *pe = NULL, *pend = NULL; static BYTE startBit; // This macro processes a single bit, either with or without debug output. // The C preprocessor will optimize this without the overhead of a function call. #if RSAEXP_DEBUG #define doBitROM(a) putrsUART("\r\n\r\n * y = "); \ BigIntPrint(y); \ BigIntSquare(y, &tmp); \ putrsUART("\r\nnow t = "); \ BigIntPrint(&tmp); \ putrsUART("\r\n % n = "); \ BigIntPrintROM(n); \ BigIntModROM(&tmp, n); \ BigIntCopy(y, &tmp); \ putrsUART("\r\nnow y = "); \ BigIntPrint(y); \ if(*pe & a) \ { \ putrsUART("\r\n\r\n!!* x = "); \ BigIntPrint(x); \ BigIntMultiply(y, x, &tmp); \ putrsUART("\r\nnow t = "); \ BigIntPrint(&tmp); \ putrsUART("\r\n % n = "); \ BigIntPrintROM(n); \ BigIntModROM(&tmp, n); \ BigIntCopy(y, &tmp); \ putrsUART("\r\nnow y = "); \ BigIntPrint(y); \ } #else #define doBitROM(a) BigIntSquare(y, &tmp); \ BigIntModROM(&tmp, n); \ BigIntCopy(y, &tmp); \ if(*pe & a) \ { \ BigIntMultiply(y, x, &tmp); \ BigIntModROM(&tmp, n); \ BigIntCopy(y, &tmp); \ } #endif // Determine if this is a new computation if(pe == pend) {// Yes, so set up the calculation // Set up *pe to point to the MSB in e, *pend to stop byte pe = (ROM BYTE*)e->ptrMSB; pend = ((ROM BYTE*)e->ptrLSB) - 1; while(*pe == 0x00u) { pe--; // Handle special case where e is zero and n >= 2 (result y should be 1). // If n = 1, then y should be zero, but this really special case isn't // normally useful, so we shall not implement it and will return 1 // instead. if(pe == pend) { BigIntZero(y); *(y->ptrLSB) = 0x01; return TRUE; } } // Start at the bit following the MSbit startBit = *pe; if(startBit & 0x80) startBit = 0x40; else if(startBit & 0x40) startBit = 0x20; else if(startBit & 0x20) startBit = 0x10; else if(startBit & 0x10) startBit = 0x08; else if(startBit & 0x08) startBit = 0x04; else if(startBit & 0x04) startBit = 0x02; else if(startBit & 0x02) startBit = 0x01; else { pe--; startBit = 0x80; } // Process that second bit now to save memory in Y // (first round squares the message (X). Subsequent rounds square Y, // which is at most half that size when running the CRT.) BigIntSquare(x, &tmp); BigIntModROM(&tmp, n); BigIntCopy(y, &tmp); if(*pe & startBit) {// If bit is '1' BigIntMultiply(y, x, &tmp); BigIntModROM(&tmp, n); BigIntCopy(y, &tmp); } // Move to the next bit as the startBit startBit >>= 1; if(!startBit) { pe--; startBit = 0x80; } // We are finished if e has only one or two set bits total, ex: e = 3 if(pe == pend) return TRUE; }