public static void ReadWriteC(this BitcoinStream bs, ref PoupardSternProof proof) { if (bs.Serializing) { if (proof == null) { uint o = 0; bs.ReadWriteAsVarInt(ref o); return; } var len = (uint)proof.XValues.Length; bs.ReadWriteAsVarInt(ref len); for (int i = 0; i < len; i++) { var n = proof.XValues[i]; bs.ReadWriteC(ref n); } var yvalue = proof.YValue; bs.ReadWriteC(ref yvalue); } else { uint len = 0; bs.ReadWriteAsVarInt(ref len); if (len == 0) { proof = null; return; } if (len > bs.MaxArraySize) { throw new ArgumentOutOfRangeException("Array is too big"); } var xValues = new NTumbleBit.BouncyCastle.Math.BigInteger[len]; for (int i = 0; i < len; i++) { NTumbleBit.BouncyCastle.Math.BigInteger b = null; bs.ReadWriteC(ref b); xValues[i] = b; } NTumbleBit.BouncyCastle.Math.BigInteger yValue = null; bs.ReadWriteC(ref yValue); proof = new PoupardSternProof(Tuple.Create(xValues, yValue)); } }
private static Tuple <RsaKey, RSAKeyData> LoadRSAKeyData(string dataDir, string keyName, bool noRSAProof) { RSAKeyData data = new RSAKeyData(); RsaKey key = null; { var rsaFile = Path.Combine(dataDir, keyName); if (!File.Exists(rsaFile)) { Logs.Configuration.LogWarning("RSA private key not found, please backup it. Creating..."); key = new RsaKey(); File.WriteAllBytes(rsaFile, key.ToBytes()); Logs.Configuration.LogInformation("RSA key saved (" + rsaFile + ")"); } else { Logs.Configuration.LogInformation("RSA private key found (" + rsaFile + ")"); key = new RsaKey(File.ReadAllBytes(rsaFile)); } } data.PublicKey = key.PubKey; if (!noRSAProof) { { var poupard = Path.Combine(dataDir, "ProofPoupard-" + keyName); PoupardSternProof poupardProof = null; if (!File.Exists(poupard)) { Logs.Configuration.LogInformation("Creating Poupard Stern proof..."); poupardProof = PoupardStern.ProvePoupardStern(key._Key, RSAKeyData.PoupardSetup); MemoryStream ms = new MemoryStream(); BitcoinStream bs = new BitcoinStream(ms, true); bs.ReadWriteC(ref poupardProof); File.WriteAllBytes(poupard, ms.ToArray()); Logs.Configuration.LogInformation("Poupard Stern proof created (" + poupard + ")"); } else { Logs.Configuration.LogInformation("Poupard Stern Proof found (" + poupard + ")"); var bytes = File.ReadAllBytes(poupard); MemoryStream ms = new MemoryStream(bytes); BitcoinStream bs = new BitcoinStream(ms, false); bs.ReadWriteC(ref poupardProof); } data.PoupardSternProof = poupardProof; } { var permutation = Path.Combine(dataDir, "ProofPermutation-" + keyName); PermutationTestProof permutationProof = null; if (!File.Exists(permutation)) { Logs.Configuration.LogInformation("Creating Permutation Test proof..."); permutationProof = PermutationTest.ProvePermutationTest(key._Key, RSAKeyData.PermutationSetup); MemoryStream ms = new MemoryStream(); BitcoinStream bs = new BitcoinStream(ms, true); bs.ReadWriteC(ref permutationProof); File.WriteAllBytes(permutation, ms.ToArray()); Logs.Configuration.LogInformation("Permutation Test proof created (" + permutation + ")"); } else { Logs.Configuration.LogInformation("Permutation Test Proof found (" + permutation + ")"); var bytes = File.ReadAllBytes(permutation); MemoryStream ms = new MemoryStream(bytes); BitcoinStream bs = new BitcoinStream(ms, false); bs.ReadWriteC(ref permutationProof); } data.PermutationTestProof = permutationProof; } } return(Tuple.Create(key, data)); }
/// <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); }