public static ASNLSignatureType Generate(List <byte[]> x, List <Cryptography.ECC.ECPoint> P1, List <Cryptography.ECC.ECPoint> P2, List <int> indices) { List <byte[]> s1 = new List <byte[]>(); ASNLSignatureType asnlSig = new ASNLSignatureType(); asnlSig.InitSField(); for (int i = 0; i < AMOUNT_SIZE; i++) { SchnorrSignatureType schnorrSig = SchnorrNonLinkable.Generate(x[i], P1[i], P2[i], indices[i]); if (!SchnorrNonLinkable.Verify(P1[i], P2[i], schnorrSig)) { throw new Exception("Schnorr Sign Error!"); } asnlSig.L1.Add(schnorrSig.L1); s1.Add(schnorrSig.s1); asnlSig.s2.Add(schnorrSig.s2); asnlSig.s = ScalarFunctions.Add(asnlSig.s, s1[i]); } return(asnlSig.Exports()); }
public void SchnorrNonLinkableAllowTest() { for (int i = 0; i < 64; i++) { byte[] x1 = SchnorrNonLinkable.GenerateRandomScalar(); byte[] x2 = SchnorrNonLinkable.GenerateRandomScalar(); ECPoint P1 = ECCurve.Secp256r1.G * x1; ECPoint P2 = ECCurve.Secp256r1.G * x2; Random rnd = new Random(i); int iRand = rnd.Next(2); if (iRand == 0) { SchnorrSignatureType sig = SchnorrNonLinkable.Generate(x1, P1, P2, 0); SchnorrNonLinkable.Verify(P1, P2, sig).Should().Be(true); } else { SchnorrSignatureType sig = SchnorrNonLinkable.Generate(x2, P1, P2, 1); SchnorrNonLinkable.Verify(P1, P2, sig).Should().Be(true); } } }
public void SchnorrNonLinkableNotAllowTest01() { byte[] x1 = SchnorrNonLinkable.GenerateRandomScalar(); byte[] x2 = SchnorrNonLinkable.GenerateRandomScalar(); ECPoint P1 = ECCurve.Secp256r1.G * x1; ECPoint P2 = ECCurve.Secp256r1.G * x2; SchnorrSignatureType sig = SchnorrNonLinkable.Generate(x1, P1, P2, 1); SchnorrNonLinkable.Verify(P1, P2, sig).Should().Be(false); }
public static SchnorrSignatureType Generate(byte[] x, Cryptography.ECC.ECPoint P1, Cryptography.ECC.ECPoint P2, int index) { byte[] a = GenerateRandomScalar(); if (index == 0) { Cryptography.ECC.ECPoint L1 = Cryptography.ECC.ECCurve.Secp256r1.G * a; byte[] s2 = GenerateRandomScalar(); byte[] c2 = Crypto.Default.Hash256(L1.EncodePoint(true)); Cryptography.ECC.ECPoint L2 = Cryptography.ECC.ECCurve.Secp256r1.G * s2 + P2 * c2; byte[] c1 = Crypto.Default.Hash256(L2.EncodePoint(true)); byte[] s1 = ScalarFunctions.MulSub(c1, x, a); SchnorrSignatureType retSig = new SchnorrSignatureType(L1, s1, s2); return(retSig); } else if (index == 1) { Cryptography.ECC.ECPoint L2 = Cryptography.ECC.ECCurve.Secp256r1.G * a; byte[] s1 = GenerateRandomScalar(); byte[] c1 = Crypto.Default.Hash256(L2.EncodePoint(true)); Cryptography.ECC.ECPoint L1 = Cryptography.ECC.ECCurve.Secp256r1.G * s1 + P1 * c1; byte[] c2 = Crypto.Default.Hash256(L1.EncodePoint(true)); byte[] s2 = ScalarFunctions.MulSub(c2, x, a); SchnorrSignatureType retSig = new SchnorrSignatureType(L1, s1, s2); return(retSig); } else { throw new Exception("SchnorrNonLinkable Index Overload Error!"); } }
public static bool Verify(Cryptography.ECC.ECPoint P1, Cryptography.ECC.ECPoint P2, SchnorrSignatureType sig) { byte[] c2 = Crypto.Default.Hash256(sig.L1.EncodePoint(true)); Cryptography.ECC.ECPoint L2 = Cryptography.ECC.ECCurve.Secp256r1.G * sig.s2 + P2 * c2; byte[] c1 = Crypto.Default.Hash256(L2.EncodePoint(true)); Cryptography.ECC.ECPoint L1P = Cryptography.ECC.ECCurve.Secp256r1.G * sig.s1 + P1 * c1; return(sig.L1.ToString() == L1P.ToString()); }