Unified SerialNumber proof and Show credential
MODIFY
WalletWasabi.Tests/UnitTests/Crypto/ProofSystemTests.cs
WalletWasabi.Tests/UnitTests/Crypto/ProofSystemTests.cs
@@ -56,38 +56,6 @@ namespace WalletWasabi.Tests.UnitTests.Crypto
Assert.False(isValidProof);
}
- [Fact]
- [Trait("UnitTest", "UnitTest")]
- public void CanProveAndVerifySerialNumbers()
- {
- var rnd = new SecureRandom();
- var z = rnd.GetScalar();
- var r = rnd.GetScalar();
- var a = rnd.GetScalar();
-
- {
- var witness = new ScalarVector(z, a, r);
- var (Ca, S) = ProofSystem.SerialNumberPublicPoints(z, a, r);
- var statement = ProofSystem.SerialNumber(Ca, S);
- var proofOfSerialNumber = ProofSystem.Prove(new Knowledge(statement, witness), rnd);
-
- var isValidProof = ProofSystem.Verify(statement, proofOfSerialNumber);
- Assert.True(isValidProof);
- }
-
- // Test zero amount
- a = Scalar.Zero;
- {
- var witness = new ScalarVector(z, a, r);
- var (Ca, S) = ProofSystem.SerialNumberPublicPoints(z, a, r);
- var statement = ProofSystem.SerialNumber(Ca, S);
- var proofOfSerialNumber = ProofSystem.Prove(new Knowledge(statement, witness), rnd);
-
- var isValidProof = ProofSystem.Verify(statement, proofOfSerialNumber);
- Assert.True(isValidProof);
- }
- }
-
[Fact]
[Trait("UnitTest", "UnitTest")]
public void CanProveAndVerifyMacShow()
@@ -112,15 +80,15 @@ namespace WalletWasabi.Tests.UnitTests.Crypto
// The client randomizes the commitments before presenting them to the coordinator proving to
// the coordinator that a credential is valid (prover knows a valid MAC on non-randomized attribute)
var z = rnd.GetScalar();
- var randomizedCommitments = RandomizedCommitments.RandomizeMAC(mac, z, Ma);
- var knowledge = ProofSystem.MacShow(coordinatorParameters, randomizedCommitments, z, mac.T);
+ var randomizedCommitments = RandomizedCommitments.RandomizeMAC(mac, z, amount, r);
+ var knowledge = ProofSystem.ShowCredential(coordinatorParameters, randomizedCommitments, z, mac.T, amount, r);
var proofOfMacShow = ProofSystem.Prove(knowledge, rnd);
// The coordinator must verify the received randomized credential is valid.
- var Z = ProofSystem.ComputeZ(randomizedCommitments, coordinatorKey);
+ var Z = randomizedCommitments.ComputeZ(coordinatorKey);
Assert.Equal(Z, z * coordinatorParameters.I);
- var statement = ProofSystem.MacShow(coordinatorParameters, Z, randomizedCommitments.Cx0, randomizedCommitments.Cx1);
+ var statement = ProofSystem.ShowCredential(coordinatorParameters, Z, randomizedCommitments);
var isValidProof = ProofSystem.Verify(statement, proofOfMacShow);
Assert.True(isValidProof);

MODIFY
WalletWasabi/Crypto/ZeroKnowledge/ProofSystem.cs
WalletWasabi/Crypto/ZeroKnowledge/ProofSystem.cs
@@ -42,34 +42,18 @@ namespace WalletWasabi.Crypto.ZeroKnowledge
{ iparams.Cw, Generators.Gw, Generators.Gwp, O, O, O },
});
- public static Knowledge SerialNumber(GroupElement Ca, GroupElement S, Scalar z, Scalar a, Scalar r)
- => new Knowledge(SerialNumber(Ca, S), new ScalarVector(z, a, r));
+ public static Knowledge ShowCredential(CoordinatorParameters iparams, RandomizedCommitments c, Scalar z, Scalar t, Scalar a, Scalar r)
+ => new Knowledge(ShowCredential(iparams, z * iparams.I, c), new ScalarVector(z, (t * z).Negate(), t, a, r));
- public static Statement SerialNumber(GroupElement Ca, GroupElement S)
+ public static Statement ShowCredential(CoordinatorParameters iparams, GroupElement Z, RandomizedCommitments c)
=> new Statement(new GroupElement[,]
{
// public Witness terms:
- // point z a r
- { Ca, Generators.Ga, Generators.Gg, Generators.Gh },
- { S, O, O, Generators.Gs }
+ // point z z0 t a r
+ { Z, iparams.I, O, O, O, O },
+ { c.Cx1, Generators.Gx1, Generators.Gx0, c.Cx0, O, O },
+ { c.Ca, Generators.Ga, O, O, Generators.Gg, Generators.Gh },
+ { c.S, O, O, O, O, Generators.Gs }
});
-
- public static (GroupElement Ca, GroupElement S) SerialNumberPublicPoints(Scalar z, Scalar a, Scalar r)
- => (z * Generators.Ga + r * Generators.Gh + a * Generators.Gg, r * Generators.Gs);
-
- public static Knowledge MacShow(CoordinatorParameters iparams, RandomizedCommitments c, Scalar z, Scalar t)
- => new Knowledge(MacShow(iparams, z * iparams.I, c.Cx0, c.Cx1), new ScalarVector(z, (t * z).Negate(), t));
-
- public static Statement MacShow(CoordinatorParameters iparams, GroupElement Z, GroupElement Cx0, GroupElement Cx1)
- => new Statement(new GroupElement[,]
- {
- // public Witness terms:
- // point z z0 t
- { Z, iparams.I, O, O },
- { Cx1, Generators.Gx1, Generators.Gx0, Cx0 }, // Cx1 = z*Gx1 + t*U, z0 cancels t*z*Gx0 out of t*Cx0 leaving z*Gx1 + t*U
- });
-
- public static GroupElement ComputeZ(RandomizedCommitments rc, CoordinatorSecretKey sk)
- => rc.CV - (sk.W * Generators.Gw + sk.X0 * rc.Cx0 + sk.X1 * rc.Cx1 + sk.Ya * rc.Ca);
}
}

MODIFY
WalletWasabi/Crypto/ZeroKnowledge/RandomizedCommitments.cs
WalletWasabi/Crypto/ZeroKnowledge/RandomizedCommitments.cs
@@ -5,27 +5,33 @@ namespace WalletWasabi.Crypto.ZeroKnowledge
{
public class RandomizedCommitments
{
- public static RandomizedCommitments RandomizeMAC(MAC mac, Scalar z, GroupElement Ma)
- {
- GroupElement Randomize(GroupElement G, GroupElement M) => M + z * G;
- return new RandomizedCommitments(
- Ca: Randomize(Generators.Ga, Ma),
- Cx0: Randomize(Generators.Gx0, mac.U),
- Cx1: Randomize(Generators.Gx1, mac.T * mac.U),
- CV: Randomize(Generators.GV, mac.V));
- }
-
- private RandomizedCommitments(GroupElement Ca, GroupElement Cx0, GroupElement Cx1, GroupElement CV)
+ private RandomizedCommitments(GroupElement Ca, GroupElement Cx0, GroupElement Cx1, GroupElement CV, GroupElement S)
{
this.Ca = Ca;
this.Cx0 = Cx0;
this.Cx1 = Cx1;
this.CV = CV;
+ this.S = S;
}
public GroupElement Ca { get; }
public GroupElement Cx0 { get; }
public GroupElement Cx1 { get; }
public GroupElement CV { get; }
+ public GroupElement S { get; }
+
+ public static RandomizedCommitments RandomizeMAC(MAC mac, Scalar z, Scalar a, Scalar r)
+ {
+ GroupElement Randomize(GroupElement G, GroupElement M) => M + z * G;
+ return new RandomizedCommitments(
+ Ca: Randomize(Generators.Ga, a * Generators.Gg + r * Generators.Gh),
+ Cx0: Randomize(Generators.Gx0, mac.U),
+ Cx1: Randomize(Generators.Gx1, mac.T * mac.U),
+ CV: Randomize(Generators.GV, mac.V),
+ S: r * Generators.Gs);
+ }
+
+ public GroupElement ComputeZ(CoordinatorSecretKey sk)
+ => CV - (sk.W * Generators.Gw + sk.X0 * Cx0 + sk.X1 * Cx1 + sk.Ya * Ca);
}
}
\ No newline at end of file

Unified SerialNumber proof and Show credential