/// <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)); }
/// <summary> /// Proving algorithm as specified in section 3.2.1 of the setup. /// </summary> /// <param name="privKey">The secret key</param> /// <param name="setup">The setup parameters</param> /// <returns>The PoupardStern proof</returns> public static PoupardSternProof ProvePoupardStern(this RsaPrivateCrtKeyParameters privKey, PoupardSternSetup 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 Modulus = privKey.Modulus; int k = setup.SecurityParameter; var psBytes = setup.PublicString; int keyLength = setup.KeySize; BigInteger Two = BigInteger.Two; // 2^{|N| - 1} BigInteger lowerLimit = Two.Pow(keyLength - 1); // Rounding up k to the closest multiple of 8 k = Utils.GetByteLength(k) * 8; // if N < 2^{KeySize-1} or N >= 2^{KeySize} if (Modulus.BitLength != keyLength) { throw new ArgumentOutOfRangeException("RSA modulus value is out of range"); } // if even if ((Modulus.IntValue & 1) == 0) { throw new ArgumentException("RSA modulus is even"); } // p and q don't produce a modulus N that has the expected bitLength if (!(Modulus.BitLength.Equals(keyLength))) { throw new ArgumentException("RSA P and Q are bad"); } // Calculating phi BigInteger pSub1 = p.Subtract(BigInteger.One); BigInteger qSub1 = q.Subtract(BigInteger.One); BigInteger phi = pSub1.Multiply(qSub1); // N - phi(N) BigInteger NsubPhi = Modulus.Subtract(phi); // if 2^{|N|-1}/{(N-phi)*2^k} <= 2^k var p11 = Two.Pow(k); var p1 = lowerLimit.Divide(NsubPhi.Multiply(p11)); if (p1.CompareTo(p11) <= 0) { throw new ArgumentOutOfRangeException(nameof(Modulus), "Bad RSA modulus N"); } // Generate K GetK(k, out int BigK); // Extract public key (N, e) from private key. var pubKey = privKey.ToPublicKey(); // Initialize and generate list of z values BigInteger[] zValues = new BigInteger[BigK]; for (int i = 0; i < BigK; i++) { zValues[i] = SampleFromZnStar(pubKey, psBytes, i, BigK, keyLength); } BigInteger y; for (; ;) { // Initialize list of x values. BigInteger[] xValues = new BigInteger[BigK]; // Get r GetR(keyLength, out BigInteger r); for (int i = 0; i < BigK; i++) { // Compute x_i xValues[i] = zValues[i].ModPow(r, Modulus); } // Compute w GetW(pubKey, psBytes, xValues, k, keyLength, out BigInteger w); // Compute y y = r.Add(NsubPhi.Multiply(w)); // if y >= 2^{ |N| - 1 } if (y.CompareTo(lowerLimit) >= 0) { continue; } // if y < 0 if (y.CompareTo(BigInteger.Zero) < 0) { continue; } return(new PoupardSternProof(new Tuple <BigInteger[], BigInteger>(xValues, y))); } }
/// <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)); }