Make generator a parameter
MODIFY
WalletWasabi.Tests/UnitTests/Crypto/ZeroKnowledge/ZkExponentTests.cs
WalletWasabi.Tests/UnitTests/Crypto/ZeroKnowledge/ZkExponentTests.cs
@@ -23,45 +23,48 @@ namespace WalletWasabi.Tests.UnitTests.Crypto.ZeroKnowledge
public void VerifySimpleProof(uint scalarSeed)
{
var exponent = new Scalar(scalarSeed);
- var proof = ZkProver.CreateProof(exponent);
- Assert.True(ZkVerifier.Verify(proof));
+ var gen = new Scalar(2) * GroupElement.G;
+ var proof = ZkProver.CreateProof(exponent, gen);
+ Assert.True(ZkVerifier.Verify(proof, gen));
}
[Fact]
public void InvalidExponent()
{
var exponent = new Scalar(0);
- Assert.Throws<ArgumentOutOfRangeException>(() => ZkProver.CreateProof(exponent));
+ var gen = new Scalar(3) * GroupElement.G;
+ Assert.Throws<ArgumentOutOfRangeException>(() => ZkProver.CreateProof(exponent, gen));
exponent = Scalar.Zero;
- Assert.Throws<ArgumentOutOfRangeException>(() => ZkProver.CreateProof(exponent));
+ Assert.Throws<ArgumentOutOfRangeException>(() => ZkProver.CreateProof(exponent, gen));
exponent = EC.N;
- Assert.Throws<ArgumentOutOfRangeException>(() => ZkProver.CreateProof(exponent));
+ Assert.Throws<ArgumentOutOfRangeException>(() => ZkProver.CreateProof(exponent, gen));
exponent = LargestScalarOverflow;
- Assert.Throws<ArgumentOutOfRangeException>(() => ZkProver.CreateProof(exponent));
+ Assert.Throws<ArgumentOutOfRangeException>(() => ZkProver.CreateProof(exponent, gen));
}
[Fact]
public void VerifyLargeScalar()
{
uint val = int.MaxValue;
+ var gen = new Scalar(4) * GroupElement.G;
var exponent = new Scalar(val, val, val, val, val, val, val, val);
- var proof = ZkProver.CreateProof(exponent);
- Assert.True(ZkVerifier.Verify(proof));
+ var proof = ZkProver.CreateProof(exponent, gen);
+ Assert.True(ZkVerifier.Verify(proof, gen));
exponent = EC.N + (new Scalar(1)).Negate();
- proof = ZkProver.CreateProof(exponent);
- Assert.True(ZkVerifier.Verify(proof));
+ proof = ZkProver.CreateProof(exponent, gen);
+ Assert.True(ZkVerifier.Verify(proof, gen));
exponent = EC.NC;
- proof = ZkProver.CreateProof(exponent);
- Assert.True(ZkVerifier.Verify(proof));
+ proof = ZkProver.CreateProof(exponent, gen);
+ Assert.True(ZkVerifier.Verify(proof, gen));
exponent = EC.NC + new Scalar(1);
- proof = ZkProver.CreateProof(exponent);
- Assert.True(ZkVerifier.Verify(proof));
+ proof = ZkProver.CreateProof(exponent, gen);
+ Assert.True(ZkVerifier.Verify(proof, gen));
exponent = EC.NC + (new Scalar(1)).Negate();
- proof = ZkProver.CreateProof(exponent);
- Assert.True(ZkVerifier.Verify(proof));
+ proof = ZkProver.CreateProof(exponent, gen);
+ Assert.True(ZkVerifier.Verify(proof, gen));
}
[Fact]
@@ -119,7 +122,7 @@ namespace WalletWasabi.Tests.UnitTests.Crypto.ZeroKnowledge
var scalar = new Scalar(11);
var proof = new ZkExponentProof(point1, point2, scalar);
- Assert.False(ZkVerifier.Verify(proof));
+ Assert.False(ZkVerifier.Verify(proof, GroupElement.G));
Assert.Throws<ArgumentOutOfRangeException>(() => new ZkExponentProof(GroupElement.Infinity, point2, scalar));
Assert.Throws<ArgumentOutOfRangeException>(() => new ZkExponentProof(point1, GroupElement.Infinity, scalar));

MODIFY
WalletWasabi/Crypto/ZeroKnowledge/ZkProver.cs
WalletWasabi/Crypto/ZeroKnowledge/ZkProver.cs
@@ -9,19 +9,20 @@ namespace WalletWasabi.Crypto.ZeroKnowledge
{
public static class ZkProver
{
- public static ZkExponentProof CreateProof(Scalar exponent)
+ public static ZkExponentProof CreateProof(Scalar exponent, GroupElement generator)
{
Guard.False($"{nameof(exponent)}.{nameof(exponent.IsOverflow)}", exponent.IsOverflow);
Guard.False($"{nameof(exponent)}.{nameof(exponent.IsZero)}", exponent.IsZero);
+ Guard.False($"{nameof(generator)}.{nameof(generator.IsInfinity)}", generator.IsInfinity);
- var publicPoint = exponent * GroupElement.G;
+ var publicPoint = exponent * generator;
using var secureRandom = new SecureRandom();
Scalar randomScalar = Scalar.Zero;
while (randomScalar == Scalar.Zero)
{
randomScalar = secureRandom.GetScalar();
}
- var randomPoint = randomScalar * GroupElement.G;
+ var randomPoint = randomScalar * generator;
var challenge = ZkChallenge.Build(publicPoint, randomPoint);
var response = randomScalar + exponent * challenge;

MODIFY
WalletWasabi/Crypto/ZeroKnowledge/ZkVerifier.cs
WalletWasabi/Crypto/ZeroKnowledge/ZkVerifier.cs
@@ -7,14 +7,16 @@ namespace WalletWasabi.Crypto.ZeroKnowledge
{
public static class ZkVerifier
{
- public static bool Verify(ZkExponentProof proof)
+ public static bool Verify(ZkExponentProof proof, GroupElement generator)
{
+ Guard.False($"{nameof(generator)}.{nameof(generator.IsInfinity)}", generator.IsInfinity);
+
var publicPoint = proof.PublicPoint;
var randomPoint = proof.RandomPoint;
var challenge = ZkChallenge.Build(publicPoint, randomPoint);
var a = challenge * publicPoint + randomPoint;
- var b = proof.Response * GroupElement.G;
+ var b = proof.Response * generator;
return a == b;
}
}

Make generator a parameter