Exemplo n.º 1
0
        private RespondToChallenge CommitToNonces(Transcript transcript, WasabiRandom random)
        {
            // With all the statements committed, generate a vector of random secret
            // nonces for every equation in underlying proof system. In order to
            // ensure that nonces are never reused (e.g. due to an insecure RNG) with
            // different challenges which would leak the witness, these are generated
            // as synthetic nonces that also depend on the witness data.
            var secretNonceProvider = transcript.CreateSyntheticSecretNonceProvider(Knowledge.Witness, random);

            // Actually generate all of the required nonces and save them in an array
            // because if the enumerable is evaluated several times the results will
            // be different.
            // Note, ToArray() is needed to make sure that secretNonces is captured
            // once and shared between the phases.
            var equations    = Knowledge.Statement.Equations;
            var secretNonces = secretNonceProvider.Sequence.Take(equations.Count()).ToArray();

            // The prover then commits to these, adding the corresponding public
            // points to the transcript.
            var publicNonces = new GroupElementVector(equations.Zip(secretNonces, (equation, pointSecretNonces) => pointSecretNonces * equation.Generators));

            transcript.CommitPublicNonces(publicNonces);

            return(() => Respond(transcript, publicNonces, secretNonces));
        }
Exemplo n.º 2
0
        public void SyntheticNoncesThrows()
        {
            var protocol = Encoding.UTF8.GetBytes("empty witness not allowed");

            var rnd = new SecureRandom();

            var transcript = new Transcript(protocol);

            Assert.ThrowsAny <ArgumentException>(() => transcript.CreateSyntheticSecretNonceProvider(new Scalar[0], rnd));
        }
Exemplo n.º 3
0
        public void SyntheticNoncesSecretDependenceTest()
        {
            var protocol = Encoding.UTF8.GetBytes("test TranscriptRng collisions");

            // if all synthetic nonce provider get the same randomness, nonce sequences
            // with different witnesses or commitments should still diverge
            var rnd = new MockRandom();

            rnd.GetBytesResults.Add(new byte[32]);
            rnd.GetBytesResults.Add(new byte[32]);
            rnd.GetBytesResults.Add(new byte[32]);
            rnd.GetBytesResults.Add(new byte[32]);

            var commitment1 = new[] { Generators.Gx0 };
            var commitment2 = new[] { Generators.Gx1 };
            var witness1    = new[] { Scalar.One };
            var witness2    = new[] { Scalar.Zero };

            var transcript1 = new Transcript(protocol);
            var transcript2 = new Transcript(protocol);
            var transcript3 = new Transcript(protocol);
            var transcript4 = new Transcript(protocol);

            transcript1.CommitPublicNonces(commitment1);
            transcript2.CommitPublicNonces(commitment2);
            transcript3.CommitPublicNonces(commitment2);
            transcript4.CommitPublicNonces(commitment2);

            var secretNonceGenerator1 = transcript1.CreateSyntheticSecretNonceProvider(witness1, rnd);
            var secretNonceGenerator2 = transcript2.CreateSyntheticSecretNonceProvider(witness1, rnd);
            var secretNonceGenerator3 = transcript3.CreateSyntheticSecretNonceProvider(witness2, rnd);
            var secretNonceGenerator4 = transcript4.CreateSyntheticSecretNonceProvider(witness2, rnd);

            Assert.Empty(rnd.GetBytesResults);

            var secretNonce1 = secretNonceGenerator1.GetScalar();
            var secretNonce2 = secretNonceGenerator2.GetScalar();
            var secretNonce3 = secretNonceGenerator3.GetScalar();
            var secretNonce4 = secretNonceGenerator4.GetScalar();

            Assert.NotEqual(secretNonce1, secretNonce2);
            Assert.NotEqual(secretNonce1, secretNonce3);
            Assert.NotEqual(secretNonce1, secretNonce4);

            Assert.NotEqual(secretNonce2, secretNonce3);
            Assert.NotEqual(secretNonce2, secretNonce4);

            // Since transcript3 and transcript4 share the same public inputs and
            // witness, with no randomness they should be identical
            Assert.Equal(secretNonce3, secretNonce4);
        }
Exemplo n.º 4
0
        public void SyntheticNoncesVectorTest(int size)
        {
            var protocol = Encoding.UTF8.GetBytes("witness size");

            var rnd = new SecureRandom();

            var witness = new Scalar[size];

            var transcript          = new Transcript(protocol);
            var secretNonceProvider = transcript.CreateSyntheticSecretNonceProvider(witness, rnd);

            var secretNonce = secretNonceProvider.Sequence.First();

            Assert.Equal(secretNonce.Count(), witness.Length);
        }
Exemplo n.º 5
0
        public void SyntheticNoncesTest()
        {
            var protocol = Encoding.UTF8.GetBytes("test TranscriptRng collisions");

            using var rnd = new SecureRandom();

            var commitment1 = new[] { Generators.Gx0 };
            var commitment2 = new[] { Generators.Gx1 };
            var witness1    = new[] { rnd.GetScalar() };
            var witness2    = new[] { rnd.GetScalar() };

            var transcript1 = new Transcript(protocol);
            var transcript2 = new Transcript(protocol);
            var transcript3 = new Transcript(protocol);
            var transcript4 = new Transcript(protocol);

            transcript1.CommitPublicNonces(commitment1);
            transcript2.CommitPublicNonces(commitment2);
            transcript3.CommitPublicNonces(commitment2);
            transcript4.CommitPublicNonces(commitment2);

            var secretNonceProvider1 = transcript1.CreateSyntheticSecretNonceProvider(witness1, rnd);
            var secretNonceProvider2 = transcript2.CreateSyntheticSecretNonceProvider(witness1, rnd);
            var secretNonceProvider3 = transcript3.CreateSyntheticSecretNonceProvider(witness2, rnd);
            var secretNonceProvider4 = transcript4.CreateSyntheticSecretNonceProvider(witness2, rnd);

            var secretNonce1 = secretNonceProvider1.GetScalar();
            var secretNonce2 = secretNonceProvider2.GetScalar();
            var secretNonce3 = secretNonceProvider3.GetScalar();
            var secretNonce4 = secretNonceProvider4.GetScalar();

            Assert.NotEqual(secretNonce1, secretNonce2);
            Assert.NotEqual(secretNonce1, secretNonce3);
            Assert.NotEqual(secretNonce1, secretNonce4);

            Assert.NotEqual(secretNonce2, secretNonce3);
            Assert.NotEqual(secretNonce2, secretNonce4);

            Assert.NotEqual(secretNonce3, secretNonce4);
        }
Exemplo n.º 6
0
    public static IEnumerable <Proof> Prove(Transcript transcript, IEnumerable <Knowledge> knowledge, WasabiRandom random)
    {
        // Before anything else all components in a compound proof commit to the
        // individual sub-statement that will be proven, ensuring that the
        // challenges and therefore the responses depend on the statement as a
        // whole.
        foreach (var k in knowledge)
        {
            transcript.CommitStatement(k.Statement);
        }

        var deferredResponds = new List <DeferredProofCreator>();

        foreach (var k in knowledge)
        {
            // With all the statements committed, generate a vector of random secret
            // nonces for every equation in underlying proof system. In order to
            // ensure that nonces are never reused (e.g. due to an insecure RNG) with
            // different challenges which would leak the witness, these are generated
            // as synthetic nonces that also depend on the witness data.
            var          secretNonceProvider = transcript.CreateSyntheticSecretNonceProvider(k.Witness, random);
            ScalarVector secretNonces        = secretNonceProvider.GetScalarVector();

            // The prover then commits to these, adding the corresponding public
            // points to the transcript.
            var equations    = k.Statement.Equations;
            var publicNonces = new GroupElementVector(equations.Select(equation => secretNonces * equation.Generators));
            transcript.CommitPublicNonces(publicNonces);

            deferredResponds.Add((challenge) => new Proof(publicNonces, k.RespondToChallenge(challenge, secretNonces)));
        }

        // With the public nonces committed to the transcript the prover can then
        // derive a challenge that depend on the transcript state without needing
        // to interact with the verifier, but ensuring that they can't know the
        // challenge before the prover commitments are generated.
        Scalar challenge = transcript.GenerateChallenge();

        return(deferredResponds.Select(createProof => createProof(challenge)));
    }