public static KnowledgeOfRep CreateProof(KnowledgeOfRepParams parameters, WasabiRandom?random = null) { var nonce = GroupElement.Infinity; var randomScalars = new List <Scalar>(); foreach (var(secret, generator) in parameters.SecretGeneratorPairs) { var randomScalar = GetNonZeroRandomScalar(random); randomScalars.Add(randomScalar); var randomPoint = randomScalar * generator; nonce += randomPoint; } var statement = parameters.Statement; var challenge = Challenge.Build(nonce, statement); var responses = new List <Scalar>(); foreach (var(secret, randomScalar) in parameters.Secrets.ZipForceEqualLength(randomScalars)) { var response = randomScalar + secret * challenge; responses.Add(response); } var proof = new KnowledgeOfRep(nonce, responses); // Sanity check: if (!Verifier.Verify(proof, statement)) { throw new InvalidOperationException($"{nameof(CreateProof)} or {nameof(Verifier.Verify)} is incorrectly implemented. Proof was built, but verification failed."); } return(proof); }
public static bool Verify(KnowledgeOfRep proof, Statement statement) { var publicPoint = statement.PublicPoint; if (publicPoint == proof.Nonce) { throw new InvalidOperationException($"{nameof(publicPoint)} and {nameof(proof.Nonce)} should not be equal."); } var nonce = proof.Nonce; var responses = proof.Responses; var challenge = Challenge.Build(nonce, statement); var a = challenge * publicPoint + nonce; var b = GroupElement.Infinity; foreach (var(response, generator) in responses.ZipForceEqualLength(statement.Generators)) { b += response * generator; } return(a == b); }