GroupElement[,] constructor for Statement
MODIFY
WalletWasabi.Tests/UnitTests/Crypto/ZeroKnowledge/LinearRelationTests.cs
WalletWasabi.Tests/UnitTests/Crypto/ZeroKnowledge/LinearRelationTests.cs
@@ -93,10 +93,11 @@ namespace WalletWasabi.Tests.UnitTests.Crypto.ZeroKnowledge
var b = x * Generators.Gh;
// Discrete log equality (Chaum-Pedersen proof)
- var statement = new Statement(
- new Equation(a, new GroupElementVector(Generators.Gg)),
- new Equation(b, new GroupElementVector(Generators.Gh))
- );
+ var statement = new Statement(new GroupElement [,]
+ {
+ { a, Generators.Gg },
+ { b, Generators.Gh },
+ });
var challenge = new Scalar(13);
@@ -115,17 +116,12 @@ namespace WalletWasabi.Tests.UnitTests.Crypto.ZeroKnowledge
[Fact]
public void StatementThrows()
{
- // Jagged equation matrices are not allowed
- Assert.ThrowsAny<ArgumentException>(() => new Statement(
- new Equation(GroupElement.Infinity, new GroupElementVector(Generators.Gg, Generators.Gh)),
- new Equation(GroupElement.Infinity, new GroupElementVector(Generators.G))
- ));
-
// Null generators are not allowed
- Assert.ThrowsAny<ArgumentException>(() => new Statement(
- new Equation(GroupElement.Infinity, new GroupElementVector(Generators.Gg, Generators.Gh)),
- new Equation(GroupElement.Infinity, new GroupElementVector(Generators.G, null!))
- ));
+ Assert.ThrowsAny<ArgumentException>(() => new Statement(new GroupElement[,]
+ {
+ { GroupElement.Infinity, Generators.Gg, Generators.Gh },
+ { GroupElement.Infinity, Generators.G, null! },
+ }));
}
[Fact]
@@ -135,10 +131,11 @@ namespace WalletWasabi.Tests.UnitTests.Crypto.ZeroKnowledge
var a = x * Generators.Gg;
var b = x * Generators.Gh;
- var statement = new Statement(
- new Equation(a, new GroupElementVector(Generators.Gg)),
- new Equation(b, new GroupElementVector(Generators.Gh))
- );
+ var statement = new Statement(new GroupElement[,]
+ {
+ { a, Generators.Gg },
+ { b, Generators.Gh },
+ });
// The witness should have the same number of components as the number of generators in the equations
var ex = Assert.ThrowsAny<ArgumentException>(() => new Knowledge(statement, new ScalarVector(Scalar.Zero, Scalar.Zero)));
@@ -149,10 +146,11 @@ namespace WalletWasabi.Tests.UnitTests.Crypto.ZeroKnowledge
Assert.Contains("witness is not solution of the equation", ex.Message);
// Incorrect statement generators (effectively incorrect witness)
- var badStatement = new Statement(
- new Equation(a, new GroupElementVector(Generators.Gh)),
- new Equation(b, new GroupElementVector(Generators.Gg))
- );
+ var badStatement = new Statement(new GroupElement [,]
+ {
+ { a, Generators.Gh },
+ { b, Generators.Gg },
+ });
ex = Assert.ThrowsAny<ArgumentException>(() => new Knowledge(badStatement, new ScalarVector(Scalar.One)));
Assert.Contains("witness is not solution of the equation", ex.Message);
}

MODIFY
WalletWasabi/Crypto/ZeroKnowledge/LinearRelation/Statement.cs
WalletWasabi/Crypto/ZeroKnowledge/LinearRelation/Statement.cs
@@ -28,6 +28,22 @@ namespace WalletWasabi.Crypto.ZeroKnowledge.LinearRelation
Equations = equations;
}
+ public Statement(GroupElement[,] equations)
+ {
+ // need to have at least one generator and one public point
+ var terms = equations.GetLength(1);
+ Guard.True(nameof(terms), terms >= 2);
+ foreach (var generator in equations)
+ {
+ Guard.NotNull(nameof(generator), generator);
+ }
+
+ // make an equation out of each row taking the first element of each row as the public point
+ var rows = Enumerable.Range(0, equations.GetLength(0));
+ var cols = Enumerable.Range(1, terms - 1);
+ Equations = rows.Select(i => new Equation(equations[i, 0], new GroupElementVector(cols.Select(j => equations[i, j]))));
+ }
+
public IEnumerable<Equation> Equations { get; }
public IEnumerable<GroupElement> PublicPoints =>

GroupElement[,] constructor for Statement