Exemplo n.º 1
0
 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));
     }
 }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
        /// <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);
        }