public void _ProvingAndVerifyingTest2(BigInteger Exp, int keySize, int k, out double ProvingTime, out double VerifyingTime) { var setup = new PoupardSternSetup(ps, keySize, k); // PoupardStern Protocol var keyPair = TestUtils.GeneratePrivate(Exp, keySize); sw.Restart(); //Proving start var outputTuple = ((RsaPrivateCrtKeyParameters)keyPair.Private).ProvePoupardStern(setup); sw.Stop(); //Proving ends ProvingTime = sw.Elapsed.TotalSeconds; sw.Restart(); //Verifying start ((RsaKeyParameters)keyPair.Public).VerifyPoupardStern(outputTuple, setup); sw.Stop(); //Verifying stops VerifyingTime = sw.Elapsed.TotalSeconds; }
/// <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); // 2^{|N|} BigInteger upperLimit = Two.Pow(keyLength); // Rounding up k to the closest multiple of 8 k = Utils.GetByteLength(k) * 8; // Check if N < 2^{|N|-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"); } // 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> /// Verifying Algorithm as specified in section 3.3 of the setup. /// </summary> /// <param name="pubKey">Public key used</param> /// <param name="proof">The proof.</param> /// <param name="setup">Setup parameters.</param> /// <returns>true if the proof verifies, false otherwise</returns> public static bool VerifyPoupardStern(this RsaKeyParameters pubKey, PoupardSternProof proof, PoupardSternSetup setup) { if (pubKey == null) { throw new ArgumentNullException(nameof(pubKey)); } if (proof == null) { throw new ArgumentNullException(nameof(proof)); } if (setup == null) { throw new ArgumentNullException(nameof(setup)); } int keyLength = setup.KeySize; int k = setup.SecurityParameter; var y = proof.YValue; BigInteger rPrime; BigInteger Two = BigInteger.Two; // 2^{|N| - 1} BigInteger lowerLimit = Two.Pow(keyLength - 1); // 2^{|N|} BigInteger upperLimit = Two.Pow(keyLength); // Rounding up k to the closest multiple of 8 k = Utils.GetByteLength(k) * 8; var Modulus = pubKey.Modulus; var Exponent = pubKey.Exponent; // Checking that: // if y >= 2^{ |N| - 1 } if (y.CompareTo(lowerLimit) >= 0) { return(false); } // if y < 0 if (y.CompareTo(BigInteger.Zero) < 0) { return(false); } // if N < 2^{KeySize-1} if (Modulus.CompareTo(lowerLimit) < 0) { return(false); } // if even if ((Modulus.IntValue & 1) == 0) { return(false); } // if N >= 2^{KeySize} if (Modulus.CompareTo(upperLimit) >= 0) { return(false); } // Computing K GetK(k, out int BigK); // Check if the number of x_values is not equal to K if (proof.XValues.Length != BigK) { return(false); } // Get w GetW(pubKey, setup.PublicString, proof.XValues, k, keyLength, out BigInteger w); // Computing rPrime rPrime = y.Subtract(Modulus.Multiply(w)); // Verifying x values for (int i = 0; i < BigK; i++) { var z_i = SampleFromZnStar(pubKey, setup.PublicString, i, BigK, keyLength); // Compute right side of the equality var rs = z_i.ModPow(rPrime, Modulus); // If the two sides are not equal if (!(proof.XValues[i].Equals(rs))) { return(false); } } return(true); }