public void MLSAG_Not_Allow_Test() { for (int Test_Count = 0; Test_Count < 1; Test_Count++) { List <byte[]> x = new List <byte[]>(); List <List <ECPoint> > PK = new List <List <ECPoint> >(); for (int i = 0; i < 2; i++) { List <ECPoint> subPK = new List <ECPoint>(); for (int j = 0; j < 2; j++) { byte[] privX = SchnorrNonLinkable.GenerateRandomScalar(); ECPoint pubKey = ECCurve.Secp256r1.G * privX; subPK.Add(pubKey); } PK.Add(subPK); } for (int i = 0; i < 2; i++) { x.Add(SchnorrNonLinkable.GenerateRandomScalar()); } MLSAGSignatureType sig = MLSAGSignature.Generate(PK, x, 1); MLSAGSignature.Verify(PK, sig).Should().Be(false); } }
public static bool Verify(List <List <ECPoint> > PK, MLSAGSignatureType sig) { int rows = PK[0].Count; int cols = PK.Count; if (cols < 2) { throw new Exception("Error! What is c if cols = 1!"); } int i = 0; byte[] c_old = new byte[32]; Buffer.BlockCopy(sig.cc, 0, c_old, 0, sig.cc.Length); List <ECPoint> Li = new List <ECPoint>(); List <byte[]> Ri = new List <byte[]>(); while (i < cols) { Li.Clear(); Ri.Clear(); for (int j = 0; j < rows; j++) { ECPoint L = ECCurve.Secp256r1.G * sig.ss[i][j] + PK[i][j] * c_old; byte[] Hi = Crypto.Default.Hash256(PK[i][j].ToString().HexToBytes()); byte[] R = ScalarFunctions.Add(ScalarFunctions.Mul(sig.ss[i][j], Hi), ScalarFunctions.Mul(c_old, sig.II[j])); Li.Add(L); Ri.Add(R); } c_old = MakeHash(PK[i], Li, Ri); i = i + 1; } return(sig.cc.ToHexString() == c_old.ToHexString()); }
public static bool VerRctMG(MLSAGSignatureType sig, List <List <CTKey> > pubs, List <CTKey> outPK, Fixed8 vPub) { int rows = pubs[0].Count; int cols = pubs.Count; List <List <ECPoint> > M = new List <List <ECPoint> >(); for (int i = 0; i < cols; i++) { List <ECPoint> M_i = new List <ECPoint>(); ECPoint M_row = new ECPoint(); for (int j = 0; j < rows; j++) { M_i.Add(pubs[i][j].dest); M_row = M_row + pubs[i][j].mask; } M_i.Add(M_row); M.Add(M_i); } for (int i = 0; i < cols; i++) { for (int j = 0; j < outPK.Count; j++) { M[i][rows] = M[i][rows] - outPK[j].mask; } if (vPub > Fixed8.Zero) { byte[] b_vPub = vPub.ToBinaryFormat().ToBinary(); M[i][rows] = M[i][rows] - RangeSignature.H * b_vPub; } else if (vPub < Fixed8.Zero) { byte[] b_vPub = (-vPub).ToBinaryFormat().ToBinary(); M[i][rows] = M[i][rows] + RangeSignature.H * b_vPub; } } return(MLSAGSignature.Verify(M, sig)); }
public void Test_ProveRctMG() { List <List <CTKey> > pubs = new List <List <CTKey> >(); List <CTCommitment> inSK = new List <CTCommitment>(); List <CTCommitment> outSK = new List <CTCommitment>(); List <CTKey> outPK = new List <CTKey>(); int index; List <CTKey> pub_index = new List <CTKey>(); byte[] out_amount = new byte[32]; byte[] out_mask = new byte[32]; for (int i = 0; i < 2; i++) { byte[] sk = SchnorrNonLinkable.GenerateRandomScalar(); ECPoint pk = ECCurve.Secp256r1.G * sk; byte[] mask = SchnorrNonLinkable.GenerateRandomScalar(); Fixed8 amount = Fixed8.One * 100; byte[] b_amount = amount.ToBinaryFormat().ToBinary(); ECPoint C_i_in = RingCTSignature.GetCommitment(mask, b_amount); out_amount = ScalarFunctions.Add(out_amount, b_amount); out_mask = ScalarFunctions.Add(out_mask, mask); CTKey key = new CTKey(pk, C_i_in); CTCommitment i_insk = new CTCommitment(sk, mask); inSK.Add(i_insk); pub_index.Add(key); } pubs.Add(pub_index); for (int i = 0; i < 2; i++) { List <CTKey> pub_i = new List <CTKey>(); for (int j = 0; j < 2; j++) { CTKey key = new CTKey(SchnorrNonLinkable.GenerateRandomPoint(), SchnorrNonLinkable.GenerateRandomPoint()); pub_i.Add(key); } pubs.Add(pub_i); } // Out PK, outSK byte[] out_secretKey = SchnorrNonLinkable.GenerateRandomScalar(); ECPoint out_publicKey = ECCurve.Secp256r1.G * out_secretKey; byte[] out_z = SchnorrNonLinkable.GenerateRandomScalar(); out_mask = ScalarFunctions.Sub(out_mask, out_z); ECPoint C_i_out = RingCTSignature.GetCommitment(out_mask, out_amount); CTCommitment i_outsk = new CTCommitment(new byte[32], out_mask); outSK.Add(i_outsk); CTKey out_key = new CTKey(out_publicKey, C_i_out); outPK.Add(out_key); MLSAGSignatureType sig = RingCTSignature.ProveRctMG(pubs, inSK, outSK, outPK, Fixed8.Zero, 0); RingCTSignature.VerRctMG(sig, pubs, outPK, Fixed8.Zero).Should().Be(true); }
public static MLSAGSignatureType Generate(List <List <ECPoint> > PK, List <byte[]> X, int index) { MLSAGSignatureType sig = new MLSAGSignatureType(); int rows = PK[0].Count; int cols = PK.Count; #region Initialize for (int j = 0; j < cols; j++) { sig.ss.Add(new List <byte[]>()); } #endregion if (cols < 2) { throw new Exception("Error! What is c if cols = 1!"); } List <byte[]> alpha = new List <byte[]>(); List <ECPoint> aG = new List <ECPoint>(); List <byte[]> aHP = new List <byte[]>(); List <ECPoint> Li = new List <ECPoint>(); List <byte[]> Ri = new List <byte[]>(); for (int j = 0; j < rows; j++) { byte[] a = SchnorrNonLinkable.GenerateRandomScalar(); alpha.Add(a); aG.Add(ECCurve.Secp256r1.G * a); byte[] Hi = Crypto.Default.Hash256(PK[index][j].ToString().HexToBytes()); aHP.Add(ScalarFunctions.Mul(a, Hi)); sig.II.Add(ScalarFunctions.Mul(X[j], Hi)); } byte[] c_old = MakeHash(PK[index], aG, aHP); int i = (index + 1) % cols; if (i == 0) { Buffer.BlockCopy(c_old, 0, sig.cc, 0, c_old.Length); } while (i != index) { for (int j = 0; j < rows; j++) { sig.ss[i].Add(SchnorrNonLinkable.GenerateRandomScalar()); } byte[] c = new byte[32]; Li.Clear(); Ri.Clear(); for (int j = 0; j < rows; j++) { ECPoint L = ECCurve.Secp256r1.G * sig.ss[i][j] + PK[i][j] * c_old; byte[] Hi = Crypto.Default.Hash256(PK[i][j].ToString().HexToBytes()); byte[] R = ScalarFunctions.Add(ScalarFunctions.Mul(sig.ss[i][j], Hi), ScalarFunctions.Mul(c_old, sig.II[j])); Li.Add(L); Ri.Add(R); } c_old = MakeHash(PK[i], Li, Ri); i = (i + 1) % cols; if (i == 0) { Buffer.BlockCopy(c_old, 0, sig.cc, 0, c_old.Length); } } for (int j = 0; j < rows; j++) { sig.ss[index].Add(ScalarFunctions.MulSub(c_old, X[j], alpha[j])); } return(sig); }