Beispiel #1
0
        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 static BorromeanSignatureType Generate(List <byte[]> x, List <Cryptography.ECC.ECPoint> P1, List <Cryptography.ECC.ECPoint> P2, List <int> indices)
        {
            List <byte[]> s1    = new List <byte[]>();
            List <byte[]> alpha = new List <byte[]>();

            List <ECPoint>[] L = new List <ECPoint> [2];
            L[0] = new List <ECPoint>();
            L[1] = new List <ECPoint>();

            BorromeanSignatureType boroSig = new BorromeanSignatureType();

            boroSig.InitSField();

            for (int i = 0; i < AMOUNT_SIZE; i++)
            {
                int naught = indices[i];
                int prime  = (naught + 1) % 2;

                byte[]  a  = SchnorrNonLinkable.GenerateRandomScalar();
                ECPoint L1 = Cryptography.ECC.ECCurve.Secp256r1.G * a;

                L[naught].Add(L1);
                alpha.Add(a);
                if (naught == 0)
                {
                    byte[]  s2 = SchnorrNonLinkable.GenerateRandomScalar();
                    byte[]  c2 = Crypto.Default.Hash256(L1.EncodePoint(true));
                    ECPoint L2 = Cryptography.ECC.ECCurve.Secp256r1.G * s2 + P2[i] * c2;
                    L[prime].Add(L2);
                    boroSig.s1.Add(s2);
                }
                else
                {
                    boroSig.s1.Add(new byte[32]);
                }

                boroSig.ee = ScalarFunctions.Add(boroSig.ee, Crypto.Default.Hash256(L[1][i].EncodePoint(true))); //Check This Part
            }

            for (int i = 0; i < AMOUNT_SIZE; i++)
            {
                if (indices[i] == 0)
                {
                    boroSig.s0.Add(ScalarFunctions.MulSub(boroSig.ee, x[i], alpha[i]));
                }
                else
                {
                    byte[]  s2 = SchnorrNonLinkable.GenerateRandomScalar();
                    ECPoint LL = Cryptography.ECC.ECCurve.Secp256r1.G * s2 + P1[i] * boroSig.ee;
                    byte[]  cc = Crypto.Default.Hash256(LL.EncodePoint(true));
                    boroSig.s1[i] = ScalarFunctions.MulSub(cc, x[i], alpha[i]);
                    boroSig.s0.Add(s2);
                }
            }

            return(boroSig.Exports());
        }
        /// <summary>
        /// Generate gives C, and mask such that \sumCi = C
        /// c.f. http://eprint.iacr.org/2015/1098 section 5.1
        /// and Ci is a commitment to either 0 or 2^i, i=0,...,63
        /// thus this proves that "amount" is in [0, 2^64]
        /// mask is a such that C = aG + bH, and b = amount
        /// </summary>
        /// <returns></returns>
        public static RangeProveType Generate(Fixed8 amount)
        {
            Initialize();

            byte[]  mask = new byte[32];
            ECPoint C    = new ECPoint();

            List <int>     binaryAmount = amount.ToBinaryFormat();
            List <byte[]>  ai           = new List <byte[]>();
            List <ECPoint> CiH          = new List <ECPoint>();

            RangeProveType rangeProver = new RangeProveType();

            for (int i = 0; i < ASNLRingSignature.AMOUNT_SIZE; i++)
            {
                byte[] ai_i = new byte[32];
                ai.Add(ai_i);

                if (binaryAmount[i] == 0)
                {
                    rangeProver.rangeSig.Ci.Add(ECCurve.Secp256r1.G * ai_i);
                }
                else if (binaryAmount[i] == 1)
                {
                    rangeProver.rangeSig.Ci.Add(ECCurve.Secp256r1.G * ai_i + H2[i]);
                }
                else
                {
                    throw new Exception("Range Prove => Binary Format Error!");
                }

                CiH.Add(rangeProver.rangeSig.Ci[i] - H2[i]);
                mask = ScalarFunctions.Add(mask, ai[i]);

                if (i == 0)
                {
                    C = rangeProver.rangeSig.Ci[i];
                }
                else
                {
                    C = C + rangeProver.rangeSig.Ci[i];
                }
            }

            rangeProver.C                = C;
            rangeProver.mask             = mask;
            rangeProver.rangeSig.AsnlSig = ASNLRingSignature.Generate(ai, rangeProver.rangeSig.Ci, CiH, binaryAmount);

            if (!ASNLRingSignature.Verify(rangeProver.rangeSig.Ci, CiH, rangeProver.rangeSig.AsnlSig))
            {
                throw new Exception("Range prove error => ASNL verify error!");
            }

            return(rangeProver.Export());
        }
        public static EcdhTuple EcdhDecode(this EcdhTuple mask, byte[] recieverSK)
        {
            EcdhTuple unmask = mask;

            byte[] sharedSec1 = Cryptography.Crypto.Default.Hash256(ScalarFunctions.MulWithPoint(mask.senderPK, recieverSK));
            byte[] sharedSec2 = Cryptography.Crypto.Default.Hash256(sharedSec1);

            unmask.mask   = ScalarFunctions.Sub(mask.mask, sharedSec1);
            unmask.amount = ScalarFunctions.Sub(mask.amount, sharedSec2);

            return(unmask);
        }
        public static EcdhTuple EcdhEncode(this EcdhTuple unmask, ECPoint receiverPk)
        {
            EcdhTuple ret = new EcdhTuple();

            byte[] esk = SchnorrNonLinkable.GenerateRandomScalar();
            ret.senderPK = ECCurve.Secp256r1.G * esk;

            byte[] sharedSec1 = Cryptography.Crypto.Default.Hash256(ScalarFunctions.MulWithPoint(receiverPk, esk));
            byte[] sharedSec2 = Cryptography.Crypto.Default.Hash256(sharedSec1);

            ret.mask   = ScalarFunctions.Add(unmask.mask, sharedSec1);
            ret.amount = ScalarFunctions.Add(unmask.amount, sharedSec2);
            return(ret);
        }
        public static bool Verify(List <ECPoint> P1, List <ECPoint> P2, BorromeanSignatureType sig)
        {
            byte[]  ee = new byte [32];
            ECPoint LHS;
            ECPoint RHS = ECCurve.Secp256r1.G * sig.ee;

            for (int i = 0; i < AMOUNT_SIZE; i++)
            {
                ECPoint L2 = ECCurve.Secp256r1.G * sig.s0[i] + P1[i] * sig.ee;
                byte[]  c1 = Crypto.Default.Hash256(L2.EncodePoint(true));
                ECPoint L1 = ECCurve.Secp256r1.G * sig.s1[i] + P2[i] * c1;
                ee = ScalarFunctions.Add(ee, Crypto.Default.Hash256(L1.EncodePoint(true)));
            }
            return(sig.ee.ToHexString().Equals(ee.ToHexString()));
        }
        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!");
            }
        }
Beispiel #8
0
        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());
        }
Beispiel #9
0
        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);
        }
        /// <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));
        }