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);
        }