public void StatementAndKnowledge()
        {
            var x = new Scalar(42);
            var a = x * Generators.Gg;
            var b = x * Generators.Gh;

            // Discrete log equality (Chaum-Pedersen proof)
            var statement = new Statement(new GroupElement[, ]
            {
                { a, Generators.Gg },
                { b, Generators.Gh },
            });

            var challenge = new Scalar(13);

            // Create transcripts using a witness to the relation
            var knowledge    = new Knowledge(statement, new ScalarVector(x));
            var secretNonces = new ScalarVector(new Scalar(7));
            var publicNonces = new GroupElementVector(statement.Equations.Select(equation => secretNonces * equation.Generators));
            var responses    = knowledge.RespondToChallenge(challenge, secretNonces);

            Assert.Single(responses);
            Assert.True(statement.CheckVerificationEquation(publicNonces, challenge, responses));

            // Ensure that verifier rejects invalid transcripts
            Assert.False(statement.CheckVerificationEquation(publicNonces, new Scalar(17), responses));

            // Ensure that verifier rejects when proofs have been altered but not
            // when they are valid (which are prevented using Fiat-Shamir transform)
            var modifiedNonces    = new GroupElementVector(publicNonces.First() + Generators.Gg, publicNonces.Last() + Generators.Gh);
            var modifiedResponses = new ScalarVector(responses.Select(x => x + Scalar.One));

            Assert.True(statement.CheckVerificationEquation(modifiedNonces, challenge, modifiedResponses));
            Assert.False(statement.CheckVerificationEquation(modifiedNonces, challenge, responses));
            Assert.False(statement.CheckVerificationEquation(publicNonces, challenge, modifiedResponses));
        }