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)); }
/// <summary> /// Tag-Linkable Ring-CT with Multiple Inputs and One-time Keys /// c.f. http://eprint.iacr.org/2015/1098 section 4. definition 10. /// This does the MG sig on the "dest" part of the given key matrix, and /// the last row is the sum of input commitments from that column - sum output commitments /// this shows that sum inputs = sum outputs /// </summary> /// <param name="pubs">Public keys using from Ring CT -> {P(i,j), C(i,j)}</param> /// <param name="inSK">Private keys for public keys</param> /// <param name="outSK">C_out sk</param> /// <param name="outPK">C_out PK</param> /// <param name="index">Signer's index</param> /// <returns></returns> public static MLSAGSignatureType ProveRctMG(List <List <CTKey> > pubs, List <CTCommitment> inSK, List <CTCommitment> outSK, List <CTKey> outPK, Fixed8 vPub, int index) { int rows = pubs[0].Count; int cols = pubs.Count; List <byte[]> sk = new List <byte[]>(); List <byte[]> tmp = new List <byte[]>(); for (int i = 0; i < rows + 1; i++) { byte[] sk_i = new byte[32]; sk.Add(sk_i); } 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; } } byte[] sk_row = inSK[0].mask; for (int i = 0; i < rows; i++) { sk[i] = inSK[i].dest; if (i > 0) { sk_row = ScalarFunctions.Add(sk_row, inSK[i].mask); } } sk[rows] = sk_row; for (int i = 0; i < outPK.Count; i++) { sk[rows] = ScalarFunctions.Sub(sk[rows], outSK[i].mask); } return(MLSAGSignature.Generate(M, sk, index)); }