public static BigInt ModPower(BigInt a, BigInt b, BigInt c) { // returns (a ^ b) mod c // eg 28 ^ 23 mod 55 = 7 // There's a trick to this. a ^ b is usually way too big to handle, so we break it // into pieces, using the fact that xy mod c = ( x mod c )( y mod c ) mod c. // Please see www.carljohansen.co.uk/rsa for a full explanation. a.EnsureInitialized(); b.EnsureInitialized(); c.EnsureInitialized(); int numBdigits = b.NumDigits; BigInt prevResult, finalProduct = 1; int i; BigInt[] arrResidues = new BigInt[numBdigits + 1]; BigInt accumulation2, accumulation4, accumulation8; arrResidues[0] = a; prevResult = arrResidues[0]; for (i = 1; i < numBdigits; i++) { //have to calculate (prevResult^10) mod c. This is (prevResult^2^2^2) mod c * (prevResult^2) mod c accumulation2 = (prevResult * prevResult) % c; accumulation4 = (accumulation2 * accumulation2) % c; accumulation8 = (accumulation4 * accumulation4) % c; arrResidues[i] = (accumulation2 * accumulation8) % c; prevResult = arrResidues[i]; } for (i = numBdigits - 1; i >= 0; i--) { int currChunk = b.GetChunkAbsolute(i / 3); int currDigit; if (i % 3 == 0) { currDigit = currChunk % 10; } else if (i % 3 == 1) { currDigit = (currChunk % 100) / 10; } else { currDigit = currChunk / 100; } for (int j = 0; j < currDigit; j++) { finalProduct *= arrResidues[i]; finalProduct %= c; } } return(finalProduct); }
/// <summary> /// Compares two BigInts /// </summary> /// <returns>1 if a > b, 0 if a == b, -1 if a is less than b</returns> public static short Compare(BigInt a, BigInt b) { a.EnsureInitialized(); b.EnsureInitialized(); if (a.IsZero() && b.IsZero()) { return(0); } if (a.Sign != b.Sign) { //a and b have different signs if (a.Sign == 1) { return(1); //every positive number is bigger than every negative number } else { return(-1); //and vice versa } } else if (a.NumDigits > b.NumDigits) { //a has more digits than b (a and b have same sign) return(a.Sign); // If both are positive then a > b. If both are negative then a < b } else if (a.NumDigits < b.NumDigits) { //a has fewer digits than b (a and b have same sign) return((short)-a.Sign); // If both are positive then a < b. If both are negative then a > b } else { short aChunk, bChunk; for (int i = a.NumChunks - 1; i >= 0; i--) { aChunk = a.GetChunk(i); bChunk = b.GetChunk(i); if (aChunk < bChunk) { return(-1); } else if (aChunk > bChunk) { return(1); } } //they must be equal return(0); } }
public static void DivAndMod(BigInt a, BigInt b, out BigInt remainder, out BigInt result) { a.EnsureInitialized(); b.EnsureInitialized(); DivAndMod(DivModOperationType.DivAndMod, a, b, out remainder, out result); }