/// <summary>
        /// Proving algorithm as specified in section 2.6.2 of the setup
        /// </summary>
        /// <param name="privKey">The secret key</param>
        /// <param name="setup">The setup parameters</param>
        /// <returns>List of signatures</returns>
        public static PermutationTestProof ProvePermutationTest(this RsaPrivateCrtKeyParameters privKey, PermutationTestSetup setup)
        {
            if (privKey == null)
            {
                throw new ArgumentNullException(nameof(privKey));
            }
            if (setup == null)
            {
                throw new ArgumentNullException(nameof(setup));
            }

            BigInteger p       = privKey.P;
            BigInteger q       = privKey.Q;
            BigInteger e       = privKey.PublicExponent;
            BigInteger Modulus = privKey.Modulus;

            var keyLength = Modulus.BitLength;
            var alpha     = setup.Alpha;

            var psBytes = setup.PublicString;
            var k       = setup.SecurityParameter;

            byte[][] sigs;

            // Generate m1 and m2
            Get_m1_m2((decimal)alpha, e.IntValue, k, out int m1, out int m2);

            // Calculate eN
            var eN = Modulus.Multiply(e);

            // Generate a pair (pub, sec) of keys with eN as e.
            var PrivatekeyPrime = Utils.GeneratePrivate(p, q, eN);

            // Extract public key (N, e) from private key.
            var pubKey = privKey.ToPublicKey();

            // Generate list of rho values
            GetRhos(m2, psBytes, pubKey, keyLength, out byte[][] rhoValues);

            // Signing the Rho values
            sigs = new byte[m2][];
            for (int i = 0; i < m2; i++)
            {
                if (i < m1)
                {
                    sigs[i] = PrivatekeyPrime.Decrypt(rhoValues[i]);
                }
                else
                {
                    sigs[i] = privKey.Decrypt(rhoValues[i]);
                }
            }
            return(new PermutationTestProof(sigs));
        }
Exemple #2
0
        /// <summary>
        /// Verifying algorithm as specified in section 2.6.3 of the setup
        /// </summary>
        /// <param name="pubKey">Public Key used to verify the proof</param>
        /// <param name="proof">Proof</param>
        /// <param name="setup">Setup parameters</param>
        /// <returns> true if the signatures verify, false otherwise</returns>
        public static bool VerifyPermutationTest(this RsaKeyParameters pubKey, PermutationTestProof proof, PermutationTestSetup setup)
        {
            if (setup == null)
            {
                throw new ArgumentNullException(nameof(setup));
            }
            if (proof == null)
            {
                throw new ArgumentNullException(nameof(proof));
            }

            byte[][] sigs      = proof.Signatures;
            int      alpha     = setup.Alpha;
            int      keyLength = setup.KeySize;

            byte[] psBytes = setup.PublicString;
            int    k       = setup.SecurityParameter;

            BigInteger Modulus  = pubKey.Modulus;
            BigInteger Exponent = pubKey.Exponent;

            BigInteger Two = BigInteger.Two;
            // 2^{|N| - 1}
            BigInteger lowerLimit = Two.Pow(keyLength - 1);
            // 2^{|N|}
            BigInteger upperLimit = Two.Pow(keyLength);

            // if N < 2^{KeySize-1}
            if (Modulus.CompareTo(lowerLimit) < 0)
            {
                return(false);
            }

            // if N >= 2^{KeySize}
            if (Modulus.CompareTo(upperLimit) >= 0)
            {
                return(false);
            }

            // Generate m1 and m2
            Get_m1_m2((decimal)alpha, Exponent.IntValue, k, out int m1, out int m2);

            // Verifying m2
            if (!m2.Equals(sigs.Length))
            {
                return(false);
            }

            // Verify alpha and N
            if (!CheckAlphaN(alpha, Modulus))
            {
                return(false);
            }

            // Generate a "weird" public key
            var eN          = Modulus.Multiply(Exponent);
            var pubKeyPrime = new RsaKeyParameters(false, Modulus, eN);

            // Generate list of rho values
            GetRhos(m2, psBytes, pubKey, keyLength, out byte[][] rhoValues);

            // Verifying the signatures
            for (int i = 0; i < m2; i++)
            {
                if (i <= m1)
                {
                    var dec_sig = pubKeyPrime.Encrypt(sigs[i]);
                    if (!dec_sig.SequenceEqual(rhoValues[i]))
                    {
                        return(false);
                    }
                }
                else
                {
                    var dec_sig = pubKey.Encrypt(sigs[i]);
                    if (!dec_sig.SequenceEqual(rhoValues[i]))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Exemple #3
0
        /// <summary>
        /// Proving algorithm as specified in section 2.6.2 of the setup
        /// </summary>
        /// <param name="privKey">The secret key</param>
        /// <param name="setup">The setup parameters</param>
        /// <returns>List of signatures</returns>
        public static PermutationTestProof ProvePermutationTest(this RsaPrivateCrtKeyParameters privKey, PermutationTestSetup setup)
        {
            if (privKey == null)
            {
                throw new ArgumentNullException(nameof(privKey));
            }
            if (setup == null)
            {
                throw new ArgumentNullException(nameof(setup));
            }

            BigInteger p       = privKey.P;
            BigInteger q       = privKey.Q;
            BigInteger e       = privKey.PublicExponent;
            BigInteger Modulus = privKey.Modulus;

            var keyLength = Modulus.BitLength;
            var alpha     = setup.Alpha;

            BigInteger Two = BigInteger.Two;
            // 2^{|N| - 1}
            BigInteger lowerLimit = Two.Pow(keyLength - 1);
            // 2^{|N|}
            BigInteger upperLimit = Two.Pow(keyLength);

            // if N < 2^{KeySize-1}
            if (Modulus.CompareTo(lowerLimit) < 0)
            {
                throw new ArgumentOutOfRangeException("RSA modulus smaller than expected");
            }

            // if N >= 2^{KeySize}
            if (Modulus.CompareTo(upperLimit) >= 0)
            {
                throw new ArgumentOutOfRangeException("RSA modulus larger than expected");
            }

            // Verify alpha and N
            if (!CheckAlphaN(alpha, Modulus))
            {
                throw new ArgumentException("RSA modulus has a small prime factor");
            }

            var psBytes = setup.PublicString;
            var k       = setup.SecurityParameter;

            byte[][] sigs;

            // Generate m1 and m2
            Get_m1_m2((decimal)alpha, e.IntValue, k, out int m1, out int m2);

            // Calculate eN
            var eN = Modulus.Multiply(e);

            // Generate a pair (pub, sec) of keys with eN as e.
            var keyPrimePair = Utils.GeneratePrivate(p, q, eN);

            // Extract public key (N, e) from private key.
            var pubKey = privKey.ToPublicKey();

            // Generate list of rho values
            GetRhos(m2, psBytes, pubKey, keyLength, out byte[][] rhoValues);

            // Signing the Rho values
            sigs = new byte[m2][];
            for (int i = 0; i < m2; i++)
            {
                if (i <= m1)
                {
                    sigs[i] = ((RsaPrivateCrtKeyParameters)keyPrimePair.Private).Decrypt(rhoValues[i]);
                }
                else
                {
                    sigs[i] = privKey.Decrypt(rhoValues[i]);
                }
            }
            return(new PermutationTestProof(sigs));
        }
        /// <summary>
        /// Verifying algorithm as specified in section 2.6.3 of the setup
        /// </summary>
        /// <param name="pubKey">Public Key used to verify the proof</param>
        /// <param name="proof">Proof</param>
        /// <param name="setup">Setup parameters</param>
        /// <returns> true if the signatures verify, false otherwise</returns>
        public static bool VerifyPermutationTest(this RsaKeyParameters pubKey, PermutationTestProof proof, PermutationTestSetup setup)
        {
            if (setup == null)
            {
                throw new ArgumentNullException(nameof(setup));
            }
            if (proof == null)
            {
                throw new ArgumentNullException(nameof(proof));
            }

            byte[][] sigs      = proof.Signatures;
            int      alpha     = setup.Alpha;
            int      keyLength = setup.KeySize;

            byte[] psBytes = setup.PublicString;
            int    k       = setup.SecurityParameter;

            BigInteger Modulus  = pubKey.Modulus;
            BigInteger Exponent = pubKey.Exponent;

            // Check if exponent e is prime
            if (!Array.Exists(PermutationTestSetup.SPECIAL_E_VALUES, element => Exponent.IntValue == element))
            {
                if (!Exponent.IsProbablePrime(k))
                {
                    return(false);
                }
            }

            // if N < 2^{KeySize-1} or N >= 2^{KeySize}
            if (Modulus.BitLength != keyLength)
            {
                return(false);
            }

            // Generate m1 and m2
            Get_m1_m2((decimal)alpha, Exponent.IntValue, k, out int m1, out int m2);

            // Verifying m2
            if (!m2.Equals(sigs.Length))
            {
                return(false);
            }

            // Verify alpha and N
            if (!CheckAlphaN(alpha, Modulus))
            {
                return(false);
            }

            // Generate a "weird" public key
            var eN          = Modulus.Multiply(Exponent);
            var pubKeyPrime = new RsaKeyParameters(false, Modulus, eN);

            // Generate list of rho values
            GetRhos(m2, psBytes, pubKey, keyLength, out byte[][] rhoValues);

            // Verifying the signatures
            for (int i = 0; i < m2; i++)
            {
                if (i < m1)
                {
                    var dec_sig = pubKeyPrime.Encrypt(sigs[i]);
                    if (!dec_sig.SequenceEqual(rhoValues[i]))
                    {
                        return(false);
                    }
                }
                else
                {
                    var dec_sig = pubKey.Encrypt(sigs[i]);
                    if (!dec_sig.SequenceEqual(rhoValues[i]))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }