private BigInteger[] Decrypt(BigInteger FirstPrime, BigInteger SecondPrime, BigInteger cipherText) { var publicKey = CalculatePublicKey(FirstPrime, SecondPrime); if (cipherText > publicKey) { throw new ArgumentException("c", "Ciphertext is larger than public key"); } BigInteger r = NumericAlgorithms.FastExp(cipherText, (FirstPrime + 1) / 4, FirstPrime); BigInteger s = NumericAlgorithms.FastExp(cipherText, (SecondPrime + 1) / 4, SecondPrime); BigInteger a, b; NumericAlgorithms.ExtendedGCD(FirstPrime, SecondPrime, out a, out b); //(a*p*r + b*q*s) % n BigInteger m1 = (a * FirstPrime * s + b * SecondPrime * r) % publicKey; if (m1 < 0) { m1 += publicKey; } BigInteger m2 = publicKey - m1; BigInteger m3 = (a * FirstPrime * s - b * SecondPrime * r) % publicKey; if (m3 < 0) { m3 += publicKey; } BigInteger m4 = publicKey - m3; return(new BigInteger[] { m1, m2, m3, m4 }); }
/// <summary> /// Hash "image" used in RSA digital signature algorithm /// </summary> /// <param name="message"></param> /// <param name="key"></param> /// <returns></returns> protected virtual BigInteger HashImage(BigInteger message, BigInteger key) { if (((message > 0) ? message : -message) >= Modulus) { throw new ArgumentException("Modulus p * q was too small."); } return(NumericAlgorithms.FastExp(message, key, Modulus)); }
private BigInteger GenerateHash(byte[] message) { var returnValue = startHashValue; for (int i = 0; i < message.Length; ++i) { returnValue = NumericAlgorithms.FastExp(returnValue + (BigInteger)message[i], 2, modulus); var x = returnValue.ToString(); } return(returnValue); }
private int[] Decrypt(int FirstPrime, int SecondPrime, int b, int cipherText) { var publicKey = CalculatePublicKey(FirstPrime, SecondPrime); if (cipherText > publicKey) { throw new ArgumentException("cipherText", "Ciphertext is larger then public key"); } var D = (b * b + (4 * cipherText)) % publicKey; int mp = NumericAlgorithms.FastExp(D, (FirstPrime + 1) / 4, FirstPrime); int mq = NumericAlgorithms.FastExp(D, (SecondPrime + 1) / 4, SecondPrime); NumericAlgorithms.ExtendedGCD(FirstPrime, SecondPrime, out int yp, out int yq); int d1, d2, d3, d4; d1 = (yp * FirstPrime * mq + yq * SecondPrime * mp) % publicKey; d1 = (d1 >= 0) ? d1 : NumericAlgorithms.NegativeMod(yp * FirstPrime * mq + yq * SecondPrime * mp, publicKey); // do { d1 += publicKey; } while (d1 <= 0); d2 = publicKey - d1; d3 = (yp * FirstPrime * mq - yq * SecondPrime * mp) % publicKey; d3 = (d3 >= 0) ? d3 : NumericAlgorithms.NegativeMod(yp * FirstPrime * mq - yq * SecondPrime * mp, publicKey); //do { d3 += publicKey; } while (d3 <= 0); d4 = publicKey - d3; d1 = Math.Abs(CalculateRoot(b, d1, publicKey)); d2 = Math.Abs(CalculateRoot(b, d2, publicKey)); d3 = Math.Abs(CalculateRoot(b, d3, publicKey)); d4 = Math.Abs(CalculateRoot(b, d4, publicKey)); return(new int[] { d1, d2, d3, d4 }); }
/// <summary> /// Encrypts a message /// </summary> /// <param name="FirstPrime"> First prime (part of secret key)</param> /// <param name="SecondPrime">Second prime (part of secret key)</param> /// <param name="Message">Message to encrypt</param> /// <returns></returns> private byte[] Encrypt(BigInteger FirstPrime, BigInteger SecondPrime, byte[] plainText) { return(NumericAlgorithms.FastExp(new BigInteger(plainText), 2, CalculatePublicKey(FirstPrime, SecondPrime)).ToByteArray()); }