public BigInteger ProcessBlock( BigInteger input) { if (key is RsaPrivateCrtKeyParameters) { // // we have the extra factors, use the Chinese Remainder Theorem - the author // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for // advice regarding the expression of this. // RsaPrivateCrtKeyParameters crtKey = (RsaPrivateCrtKeyParameters)key; BigInteger p = crtKey.P;; BigInteger q = crtKey.Q; BigInteger dP = crtKey.DP; BigInteger dQ = crtKey.DQ; BigInteger qInv = crtKey.QInv; BigInteger mP, mQ, h, m; // mP = ((input Mod p) ^ dP)) Mod p mP = (input.Remainder(p)).ModPow(dP, p); // mQ = ((input Mod q) ^ dQ)) Mod q mQ = (input.Remainder(q)).ModPow(dQ, q); // h = qInv * (mP - mQ) Mod p h = mP.Subtract(mQ); h = h.Multiply(qInv); h = h.Mod(p); // Mod (in Java) returns the positive residual // m = h * q + mQ m = h.Multiply(q); m = m.Add(mQ); return m; } return input.ModPow(key.Exponent, key.Modulus); }
internal bool RabinMillerTest( int certainty, Random random) { Debug.Assert(certainty > 0); Debug.Assert(BitLength > 2); Debug.Assert(TestBit(0)); // let n = 1 + d . 2^s BigInteger n = this; BigInteger nMinusOne = n.Subtract(One); int s = nMinusOne.GetLowestSetBit(); BigInteger r = nMinusOne.ShiftRight(s); Debug.Assert(s >= 1); do { // TODO Make a method for random BigIntegers in range 0 < x < n) // - Method can be optimized by only replacing examined bits at each trial BigInteger a; do { a = new BigInteger(n.BitLength, random); } while (a.CompareTo(One) <= 0 || a.CompareTo(nMinusOne) >= 0); BigInteger y = a.ModPow(r, n); if (!y.Equals(One)) { int j = 0; while (!y.Equals(nMinusOne)) { if (++j == s) return false; y = y.ModPow(Two, n); if (y.Equals(One)) return false; } } certainty -= 2; // composites pass for only 1/4 possible 'a' } while (certainty > 0); return true; }