/** * @exception InvalidCipherTextException if the decrypted block is not a valid ISO 9796 bit string */ private byte[] DecodeBlock( byte[] input, int inOff, int inLen) { byte[] block = engine.ProcessBlock(input, inOff, inLen); int r = 1; int t = (bitSize + 13) / 16; BigInteger iS = new BigInteger(1, block); BigInteger iR; if (iS.Mod(Sixteen).Equals(Six)) { iR = iS; } else { iR = modulus.Subtract(iS); if (!iR.Mod(Sixteen).Equals(Six)) throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16"); } block = iR.ToByteArrayUnsigned(); if ((block[block.Length - 1] & 0x0f) != 0x6) throw new InvalidCipherTextException("invalid forcing byte in block"); block[block.Length - 1] = (byte)(((ushort)(block[block.Length - 1] & 0xff) >> 4) | ((inverse[(block[block.Length - 2] & 0xff) >> 4]) << 4)); block[0] = (byte)((shadows[(uint) (block[1] & 0xff) >> 4] << 4) | shadows[block[1] & 0x0f]); bool boundaryFound = false; int boundary = 0; for (int i = block.Length - 1; i >= block.Length - 2 * t; i -= 2) { int val = ((shadows[(uint) (block[i] & 0xff) >> 4] << 4) | shadows[block[i] & 0x0f]); if (((block[i - 1] ^ val) & 0xff) != 0) { if (!boundaryFound) { boundaryFound = true; r = (block[i - 1] ^ val) & 0xff; boundary = i - 1; } else { throw new InvalidCipherTextException("invalid tsums in block"); } } } block[boundary] = 0; byte[] nblock = new byte[(block.Length - boundary) / 2]; for (int i = 0; i < nblock.Length; i++) { nblock[i] = block[2 * i + boundary + 1]; } padBits = r - 1; return nblock; }
/// <summary>Choose a random prime value for use with RSA</summary> /// <param name="bitlength">the bit-length of the returned prime</param> /// <param name="e">the RSA public exponent</param> /// <returns>a prime p, with (p-1) relatively prime to e</returns> protected virtual BigInteger ChooseRandomPrime(int bitlength, BigInteger e) { for (;;) { BigInteger p = new BigInteger(bitlength, 1, param.Random); if (p.Mod(e).Equals(BigInteger.One)) continue; if (!p.IsProbablePrime(param.Certainty)) continue; if (!e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One)) continue; return p; } }