예제 #1
0
 public static void ReadWriteC(this BitcoinStream bs, ref PermutationTestProof proof)
 {
     if (bs.Serializing)
     {
         if (proof == null)
         {
             uint o = 0;
             bs.ReadWriteAsVarInt(ref o);
             return;
         }
         var len = (uint)proof.Signatures.Length;
         bs.ReadWriteAsVarInt(ref len);
         for (int i = 0; i < len; i++)
         {
             var sig = proof.Signatures[i];
             bs.ReadWriteAsVarString(ref sig);
         }
     }
     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 signatures = new byte[len][];
         for (int i = 0; i < len; i++)
         {
             byte[] sig = null;
             bs.ReadWriteAsVarString(ref sig);
             signatures[i] = sig;
         }
         proof = new PermutationTestProof(signatures);
     }
 }
예제 #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));
        }
예제 #3
0
        /// <summary>
        /// Verifying algorithm as specified in section 2.6.3 of the setup
        /// </summary>
        /// <param name="pubKey">Public Key used to verify the proof</param>
        /// <param name="proof">Proof</param>
        /// <param name="setup">Setup parameters</param>
        /// <returns> true if the signatures verify, false otherwise</returns>
        public static bool VerifyPermutationTest(this RsaKeyParameters pubKey, PermutationTestProof proof, PermutationTestSetup setup)
        {
            if (setup == null)
            {
                throw new ArgumentNullException(nameof(setup));
            }
            if (proof == null)
            {
                throw new ArgumentNullException(nameof(proof));
            }

            byte[][] sigs      = proof.Signatures;
            int      alpha     = setup.Alpha;
            int      keyLength = setup.KeySize;

            byte[] psBytes = setup.PublicString;
            int    k       = setup.SecurityParameter;

            BigInteger Modulus  = pubKey.Modulus;
            BigInteger Exponent = pubKey.Exponent;

            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)
            {
                return(false);
            }

            // if N >= 2^{KeySize}
            if (Modulus.CompareTo(upperLimit) >= 0)
            {
                return(false);
            }

            // Generate m1 and m2
            Get_m1_m2((decimal)alpha, Exponent.IntValue, k, out int m1, out int m2);

            // Verifying m2
            if (!m2.Equals(sigs.Length))
            {
                return(false);
            }

            // Verify alpha and N
            if (!CheckAlphaN(alpha, Modulus))
            {
                return(false);
            }

            // Generate a "weird" public key
            var eN          = Modulus.Multiply(Exponent);
            var pubKeyPrime = new RsaKeyParameters(false, Modulus, eN);

            // Generate list of rho values
            GetRhos(m2, psBytes, pubKey, keyLength, out byte[][] rhoValues);

            // Verifying the signatures
            for (int i = 0; i < m2; i++)
            {
                if (i <= m1)
                {
                    var dec_sig = pubKeyPrime.Encrypt(sigs[i]);
                    if (!dec_sig.SequenceEqual(rhoValues[i]))
                    {
                        return(false);
                    }
                }
                else
                {
                    var dec_sig = pubKey.Encrypt(sigs[i]);
                    if (!dec_sig.SequenceEqual(rhoValues[i]))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }