Пример #1
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="p">First prime number</param>
        /// <param name="q">Second prime number</param>
        /// <param name="privateKey">Private key d</param>
        /// <param name="hashFunction">hashfunction to use in algorithm</param>
        /// <param name="ChecksNeeded">check if data is right </param>
        public RsaSignature(BigInteger p, BigInteger q, BigInteger privateKey, HashFunction hashFunction, bool ChecksNeeded)
        {
            if (ChecksNeeded)
            {
                if ((!p.CheckIfPrime()) || (!q.CheckIfPrime()))
                {
                    throw new ArgumentException("p and q must be prime numbers!");
                }
                //if privatekey = 1 then signature == h
                //if privateKey == phi(n) - 1; then s == 1
                //if privateKey > phi(n) then there'll problem with multipl. inversion in equation d*e = 1 mod phi(n)
                if ((privateKey < 2) || (privateKey > (p - 1) * (q - 1) - 1))
                {
                    throw new ArgumentException("Private key should be 2 < < (p - 1) * (q - 1) - 1)!");
                }
                //We need private key to be prime with phi(n) to find open key later
                if (!NumericAlgorithms.GCD(privateKey, (p - 1) * (q - 1)).Equals(1))
                {
                    throw new ArgumentException("D should be mutually prime with (p - 1) * (q - 1)");
                }
            }

            Modulus = p * q;

            PublicExp = NumericAlgorithms.ExtendedGCD((p - 1) * (q - 1), privateKey);

            PrivateExp = privateKey;

            HashFunc = (hashFunction == HashFunction.MD5) ? null : new HashFunctionFactory().NewHashFunction(Modulus, hashFunction);
        }
Пример #2
0
        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 });
        }
Пример #3
0
        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 });
        }