public static RingCTSignatureType Generate(List <CTCommitment> inSK, List <MixRingCTKey> inPK, List <ECPoint> destinations, List <Fixed8> amounts, Fixed8 vPub, int mixin, UInt256 assetID, Fixed8 vPubOld) { RingCTSignatureType rctSig = new RingCTSignatureType(); List <CTCommitment> outSK = new List <CTCommitment>(); for (int i = 0; i < destinations.Count; i++) { rctSig.outPK.Add(new CTKey()); rctSig.rangeSigs.Add(new RangeProveType()); rctSig.ecdhInfo.Add(new EcdhTuple()); } for (int i = 0; i < destinations.Count; i++) { rctSig.outPK[i].dest = destinations[i]; rctSig.rangeSigs[i] = RangeSignature.Generate(amounts[i]); rctSig.outPK[i].mask = rctSig.rangeSigs[i].C; CTCommitment outSK_i = new CTCommitment(new byte[32], rctSig.rangeSigs[i].mask); outSK.Add(outSK_i); rctSig.ecdhInfo[i].mask = rctSig.rangeSigs[i].mask; rctSig.ecdhInfo[i].amount = amounts[i].ToBinaryFormat().ToBinary(); bool isEncoded = true; if (rctSig.ecdhInfo.Count > 1) { isEncoded = false; } for (int j = 0; j < inSK.Count; j++) { byte[] dest_cmp = new byte[32]; if (inSK[j].dest.ToHexString() == dest_cmp.ToHexString() && inSK[j].mask.ToHexString() == dest_cmp.ToHexString()) { isEncoded = false; } } if (isEncoded) { rctSig.ecdhInfo[i] = rctSig.ecdhInfo[i].EcdhEncode(destinations[i]); } } RingInfo ringInfo = PopulateFromBlockchain(inPK, mixin, assetID, vPubOld); rctSig.mixRing = ringInfo.mixRingIndex; rctSig.MG = ProveRctMG(ringInfo.mixRing, inSK, outSK, rctSig.outPK, vPub, ringInfo.index); rctSig.vPub = vPub; return(rctSig); }
public static bool Verify(RingCTSignatureType sig, Fixed8 vPubOld) { bool result = true; if (sig.rangeSigs.Count <= 0 || sig.ecdhInfo.Count <= 0 || sig.mixRing.Count <= 0) { return(false); } for (int i = 0; i < sig.outPK.Count; i++) { bool rangeVerify = RangeSignature.Verify(sig.outPK[i].mask, sig.rangeSigs[i].rangeSig); result = result && rangeVerify; } List <List <CTKey> > mixRing = GetRingKeyFromIndex(sig.mixRing, vPubOld); bool mgVer = VerRctMG(sig.MG, mixRing, sig.outPK, sig.vPub); return(result && mgVer); }