/// <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; // 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.BitLength >= keyLength) { // TODO: Verify that this bit check is equivalent to the math check return(false); } // if y < 0 if (y.CompareTo(BigInteger.Zero) < 0) { return(false); } // if N < 2^{KeySize-1} or N >= 2^{KeySize} if (Modulus.BitLength != keyLength) { return(false); } // if even if ((Modulus.IntValue & 1) == 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 var isCorrect = new bool[BigK]; Parallel.ForEach(Enumerable.Range(0, isCorrect.Length), (i) => { var z_i = SampleFromZnStar(pubKey, setup.PublicString, i, BigK, keyLength); // Compute right side of the equality var rs = z_i.ModPow(rPrime, Modulus); // Compare values and set the result in the array isCorrect[i] = proof.XValues[i].Equals(rs); }); return(isCorrect.All(o => o)); }
/// <summary> /// Verifying Algorithm specified in (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 lowerLimit = BigInteger.Two.Pow(keyLength - 1); BigInteger upperLimit = BigInteger.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 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); }