Пример #1
0
        /* Galbraith & Scott Method */
        public static BIG[] GS(BIG e)
        {
            BIG[] u = new BIG[4];
            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                int   i, j;
                BIG   t = new BIG(0);
                BIG   q = new BIG(ROM.CURVE_Order);
                BIG[] v = new BIG[4];
                for (i = 0; i < 4; i++)
                {
                    t.Copy(new BIG(ROM.CURVE_WB[i]));
                    DBIG d = BIG.Mul(t, e);
                    v[i] = new BIG(d.Div(q));
                    u[i] = new BIG(0);
                }

                u[0].Copy(e);
                for (i = 0; i < 4; i++)
                {
                    for (j = 0; j < 4; j++)
                    {
                        t.Copy(new BIG(ROM.CURVE_BB[j][i]));
                        t.Copy(BIG.ModMul(v[j], t, q));
                        u[i].Add(q);
                        u[i].Sub(t);
                        u[i].Mod(q);
                    }
                }
            }
            else
            {
                BIG q = new BIG(ROM.CURVE_Order);
                BIG x = new BIG(ROM.CURVE_Bnx);
                BIG w = new BIG(e);
                for (int i = 0; i < 3; i++)
                {
                    u[i] = new BIG(w);
                    u[i].Mod(x);
                    w.Div(x);
                }

                u[3] = new BIG(w);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    u[1].Copy(BIG.ModNeg(u[1], q));
                    u[3].Copy(BIG.ModNeg(u[3], q));
                }
            }

            return(u);
        }
Пример #2
0
        /* GLV method */
        public static BIG[] Glv(BIG e)
        {
            BIG[] u = new BIG[2];
            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                int i, j;
                BIG t = new BIG(0);
                BIG q = new BIG(ROM.CURVE_Order);

                BIG[] v = new BIG[2];
                for (i = 0; i < 2; i++)
                {
                    t.Copy(new BIG(ROM.CURVE_W[i])); // why not just t=new BIG(ROM.CURVE_W[i]);
                    DBIG d = BIG.Mul(t, e);
                    v[i] = new BIG(d.Div(q));
                    u[i] = new BIG(0);
                }

                u[0].Copy(e);
                for (i = 0; i < 2; i++)
                {
                    for (j = 0; j < 2; j++)
                    {
                        t.Copy(new BIG(ROM.CURVE_SB[j][i]));
                        t.Copy(BIG.ModMul(v[j], t, q));
                        u[i].Add(q);
                        u[i].Sub(t);
                        u[i].Mod(q);
                    }
                }
            }
            else
            {
                // -(x^2).P = (Beta.x,y)
                BIG q  = new BIG(ROM.CURVE_Order);
                BIG x  = new BIG(ROM.CURVE_Bnx);
                BIG x2 = BIG.SMul(x, x);
                u[0] = new BIG(e);
                u[0].Mod(x2);
                u[1] = new BIG(e);
                u[1].Div(x2);
                u[1].RSub(q);
            }

            return(u);
        }
Пример #3
0
        /**
         * Constructor
         *
         * @param sk          the secret key of the user
         * @param issuerNonce a nonce
         * @param ipk         the issuer public key
         */
        public IdemixCredRequest(BIG sk, BIG issuerNonce, IdemixIssuerPublicKey ipk)
        {
            if (sk == null)
            {
                throw new ArgumentException("Cannot create idemix credrequest from null Secret Key input");
            }

            if (issuerNonce == null)
            {
                throw new ArgumentException("Cannot create idemix credrequest from null issuer nonce input");
            }

            if (ipk == null)
            {
                throw new ArgumentException("Cannot create idemix credrequest from null Issuer Public Key input");
            }

            RAND rng = IdemixUtils.GetRand();

            Nym = ipk.Hsk.Mul(sk);
            this.issuerNonce = new BIG(issuerNonce);

            // Create Zero Knowledge Proof
            BIG rsk = rng.RandModOrder();
            ECP t   = ipk.Hsk.Mul(rsk);

            // Make proofData: total 3 elements of G1, each 2*FIELD_BYTES+1 (ECP),
            // plus length of String array,
            // plus one BIG
            byte[] proofData = new byte[0];
            proofData = proofData.Append(CREDREQUEST_LABEL.ToBytes());
            proofData = proofData.Append(t.ToBytes());
            proofData = proofData.Append(ipk.Hsk.ToBytes());
            proofData = proofData.Append(Nym.ToBytes());
            proofData = proofData.Append(issuerNonce.ToBytes());
            proofData = proofData.Append(ipk.Hash);

            proofC = proofData.HashModOrder();

            // Compute proofS = ...
            proofS = BIG.ModMul(proofC, sk, IdemixUtils.GROUP_ORDER).Plus(rsk);
            proofS.Mod(IdemixUtils.GROUP_ORDER);
        }
        /**
         * Constructor
         *
         * @param sk        the secret key
         * @param pseudonym the pseudonym with respect to which this signature can be verified
         * @param ipk       the issuer public key
         * @param msg       the message to be signed
         */
        public IdemixPseudonymSignature(BIG sk, IdemixPseudonym pseudonym, IdemixIssuerPublicKey ipk, byte[] msg)
        {
            if (sk == null || pseudonym == null || pseudonym.Nym == null || pseudonym.RandNym == null || ipk == null || msg == null)
            {
                throw new ArgumentException("Cannot create IdemixPseudonymSignature from null input");
            }

            RAND rng = IdemixUtils.GetRand();

            nonce = rng.RandModOrder();

            //Construct Zero Knowledge Proof
            BIG rsk   = rng.RandModOrder();
            BIG rRNym = rng.RandModOrder();
            ECP t     = ipk.Hsk.Mul2(rsk, ipk.HRand, rRNym);

            // create array for proof data that will contain the sign label, 2 ECPs (each of length 2* FIELD_BYTES + 1), the ipk hash and the message
            byte[] proofData = new byte[0];
            proofData = proofData.Append(NYM_SIGN_LABEL.ToBytes());
            proofData = proofData.Append(t.ToBytes());
            proofData = proofData.Append(pseudonym.Nym.ToBytes());
            proofData = proofData.Append(ipk.Hash);
            proofData = proofData.Append(msg);

            BIG cvalue = proofData.HashModOrder();

            byte[] finalProofData = new byte[0];
            finalProofData = finalProofData.Append(cvalue.ToBytes());
            finalProofData = finalProofData.Append(nonce.ToBytes());
            proofC         = finalProofData.HashModOrder();

            proofSSk = new BIG(rsk);
            proofSSk.Add(BIG.ModMul(proofC, sk, IdemixUtils.GROUP_ORDER));
            proofSSk.Mod(IdemixUtils.GROUP_ORDER);

            proofSRNym = new BIG(rRNym);
            proofSRNym.Add(BIG.ModMul(proofC, pseudonym.RandNym, IdemixUtils.GROUP_ORDER));
            proofSRNym.Mod(IdemixUtils.GROUP_ORDER);
        }
Пример #5
0
        /**
         * Create a new IdemixSignature by proving knowledge of a credential
         *
         * @param c          the credential used to create an idemix signature
         * @param sk         the signer's secret key
         * @param pseudonym  a pseudonym of the signer
         * @param ipk        the issuer public key
         * @param disclosure a bool-array that steers the disclosure of attributes
         * @param msg        the message to be signed
         * @param rhIndex    the index of the attribute that represents the revocation handle
         * @param cri        the credential revocation information that allows the signer to prove non-revocation
         */
        public IdemixSignature(IdemixCredential c, BIG sk, IdemixPseudonym pseudonym, IdemixIssuerPublicKey ipk, bool[] disclosure, byte[] msg, int rhIndex, CredentialRevocationInformation cri)
        {
            if (c == null || sk == null || pseudonym == null || pseudonym.Nym == null || pseudonym.RandNym == null || ipk == null || disclosure == null || msg == null || cri == null)
            {
                throw new ArgumentException("Cannot construct idemix signature from null input");
            }

            if (disclosure.Length != c.Attrs.Length)
            {
                throw new ArgumentException("Disclosure length must be the same as the number of attributes");
            }

            if (cri.RevocationAlg >= Enum.GetValues(typeof(RevocationAlgorithm)).Length)
            {
                throw new ArgumentException("CRI specifies unknown revocation algorithm");
            }

            if (cri.RevocationAlg != (int)RevocationAlgorithm.ALG_NO_REVOCATION && disclosure[rhIndex])
            {
                throw new ArgumentException("Attribute " + rhIndex + " is disclosed but also used a revocation handle attribute, which should remain hidden");
            }

            RevocationAlgorithm revocationAlgorithm = (RevocationAlgorithm)cri.RevocationAlg;

            int[] hiddenIndices = HiddenIndices(disclosure);
            RAND  rng           = IdemixUtils.GetRand();
            // Start signature
            BIG r1 = rng.RandModOrder();
            BIG r2 = rng.RandModOrder();
            BIG r3 = new BIG(r1);

            r3.InvModp(IdemixUtils.GROUP_ORDER);

            nonce = rng.RandModOrder();

            aPrime = PAIR.G1Mul(c.A, r1);
            aBar   = PAIR.G1Mul(c.B, r1);
            aBar.Sub(PAIR.G1Mul(aPrime, c.E));

            bPrime = PAIR.G1Mul(c.B, r1);
            bPrime.Sub(PAIR.G1Mul(ipk.HRand, r2));
            BIG sPrime = new BIG(c.S);

            sPrime.Add(BIG.ModNeg(BIG.ModMul(r2, r3, IdemixUtils.GROUP_ORDER), IdemixUtils.GROUP_ORDER));
            sPrime.Mod(IdemixUtils.GROUP_ORDER);

            //Construct Zero Knowledge Proof
            BIG rsk     = rng.RandModOrder();
            BIG re      = rng.RandModOrder();
            BIG rR2     = rng.RandModOrder();
            BIG rR3     = rng.RandModOrder();
            BIG rSPrime = rng.RandModOrder();
            BIG rRNym   = rng.RandModOrder();

            BIG[] rAttrs = new BIG[hiddenIndices.Length];
            for (int i = 0; i < hiddenIndices.Length; i++)
            {
                rAttrs[i] = rng.RandModOrder();
            }

            // Compute non-revoked proof
            INonRevocationProver prover = NonRevocationProver.GetNonRevocationProver(revocationAlgorithm);
            int hiddenRHIndex           = Array.IndexOf(hiddenIndices, rhIndex);

            if (hiddenRHIndex < 0)
            {
                // rhIndex is not present, set to last index position
                hiddenRHIndex = hiddenIndices.Length;
            }

            byte[] nonRevokedProofHashData = prover.GetFSContribution(BIG.FromBytes(c.Attrs[rhIndex]), rAttrs[hiddenRHIndex], cri);
            if (nonRevokedProofHashData == null)
            {
                throw new Exception("Failed to compute non-revoked proof");
            }

            ECP t1 = aPrime.Mul2(re, ipk.HRand, rR2);
            ECP t2 = PAIR.G1Mul(ipk.HRand, rSPrime);

            t2.Add(bPrime.Mul2(rR3, ipk.Hsk, rsk));

            for (int i = 0; i < hiddenIndices.Length / 2; i++)
            {
                t2.Add(ipk.HAttrs[hiddenIndices[2 * i]].Mul2(rAttrs[2 * i], ipk.HAttrs[hiddenIndices[2 * i + 1]], rAttrs[2 * i + 1]));
            }

            if (hiddenIndices.Length % 2 != 0)
            {
                t2.Add(PAIR.G1Mul(ipk.HAttrs[hiddenIndices[hiddenIndices.Length - 1]], rAttrs[hiddenIndices.Length - 1]));
            }

            ECP t3 = ipk.Hsk.Mul2(rsk, ipk.HRand, rRNym);

            // create proofData such that it can contain the sign label, 7 elements in G1 (each of size 2*FIELD_BYTES+1),
            // the ipk hash, the disclosure array, and the message
            byte[] proofData = new byte[0];
            proofData = proofData.Append(SIGN_LABEL.ToBytes());
            proofData = proofData.Append(t1.ToBytes());
            proofData = proofData.Append(t2.ToBytes());
            proofData = proofData.Append(t3.ToBytes());
            proofData = proofData.Append(aPrime.ToBytes());
            proofData = proofData.Append(aBar.ToBytes());
            proofData = proofData.Append(bPrime.ToBytes());
            proofData = proofData.Append(pseudonym.Nym.ToBytes());
            proofData = proofData.Append(ipk.Hash);
            proofData = proofData.Append(disclosure);
            proofData = proofData.Append(msg);

            BIG cvalue = proofData.HashModOrder();

            byte[] finalProofData = new byte[0];
            finalProofData = finalProofData.Append(cvalue.ToBytes());
            finalProofData = finalProofData.Append(nonce.ToBytes());

            proofC = finalProofData.HashModOrder();

            proofSSk     = rsk.ModAdd(BIG.ModMul(proofC, sk, IdemixUtils.GROUP_ORDER), IdemixUtils.GROUP_ORDER);
            proofSE      = re.ModSub(BIG.ModMul(proofC, c.E, IdemixUtils.GROUP_ORDER), IdemixUtils.GROUP_ORDER);
            proofSR2     = rR2.ModAdd(BIG.ModMul(proofC, r2, IdemixUtils.GROUP_ORDER), IdemixUtils.GROUP_ORDER);
            proofSR3     = rR3.ModSub(BIG.ModMul(proofC, r3, IdemixUtils.GROUP_ORDER), IdemixUtils.GROUP_ORDER);
            proofSSPrime = rSPrime.ModAdd(BIG.ModMul(proofC, sPrime, IdemixUtils.GROUP_ORDER), IdemixUtils.GROUP_ORDER);
            proofSRNym   = rRNym.ModAdd(BIG.ModMul(proofC, pseudonym.RandNym, IdemixUtils.GROUP_ORDER), IdemixUtils.GROUP_ORDER);

            nym = new ECP();
            nym.Copy(pseudonym.Nym);

            proofSAttrs = new BIG[hiddenIndices.Length];
            for (int i = 0; i < hiddenIndices.Length; i++)
            {
                proofSAttrs[i] = new BIG(rAttrs[i]);
                proofSAttrs[i].Add(BIG.ModMul(proofC, BIG.FromBytes(c.Attrs[hiddenIndices[i]]), IdemixUtils.GROUP_ORDER));
                proofSAttrs[i].Mod(IdemixUtils.GROUP_ORDER);
            }

            // include non-revocation proof in signature
            revocationPk       = cri.EpochPk;
            revocationPKSig    = cri.EpochPkSig.ToByteArray();
            epoch              = cri.Epoch;
            nonRevocationProof = prover.GetNonRevocationProof(proofC);
        }
        /**
         * Constructor
         *
         * @param attributeNames the names of attributes as String array (must not contain duplicates)
         * @param isk            the issuer secret key
         */
        public IdemixIssuerPublicKey(string[] attributeNames, BIG isk)
        {
            // check null input
            if (attributeNames == null || isk == null)
            {
                throw new ArgumentException("Cannot create IdemixIssuerPublicKey from null input");
            }

            // Checking if attribute names are unique
            HashSet <string> map = new HashSet <string>();

            foreach (string item in attributeNames)
            {
                if (map.Contains(item))
                {
                    throw new ArgumentException("Attribute " + item + " appears multiple times in attributeNames");
                }
                map.Add(item);
            }

            RAND rng = IdemixUtils.GetRand();

            // Attaching Attribute Names array correctly
            AttributeNames = attributeNames;

            // Computing W value
            W = IdemixUtils.GenG2.Mul(isk);

            // Filling up HAttributes correctly in Issuer Public Key, length
            // preserving
            HAttrs = new ECP[attributeNames.Length];

            for (int i = 0; i < attributeNames.Length; i++)
            {
                HAttrs[i] = IdemixUtils.GenG1.Mul(rng.RandModOrder());
            }

            // Generating Hsk value
            Hsk = IdemixUtils.GenG1.Mul(rng.RandModOrder());

            // Generating HRand value
            HRand = IdemixUtils.GenG1.Mul(rng.RandModOrder());

            // Generating BarG1 value
            BarG1 = IdemixUtils.GenG1.Mul(rng.RandModOrder());

            // Generating BarG2 value
            BarG2 = BarG1.Mul(isk);

            // Zero Knowledge Proofs

            // Computing t1 and t2 values with random local variable r for later use
            BIG  r  = rng.RandModOrder();
            ECP2 t1 = IdemixUtils.GenG2.Mul(r);
            ECP  t2 = BarG1.Mul(r);

            // Generating proofData that will contain 3 elements in G1 (of size 2*FIELD_BYTES+1)and 3 elements in G2 (of size 4 * FIELD_BYTES)
            byte[] proofData = new byte[0];
            proofData = proofData.Append(t1.ToBytes());
            proofData = proofData.Append(t2.ToBytes());
            proofData = proofData.Append(IdemixUtils.GenG2.ToBytes());
            proofData = proofData.Append(BarG1.ToBytes());
            proofData = proofData.Append(W.ToBytes());
            proofData = proofData.Append(BarG2.ToBytes());

            // Hashing proofData to proofC
            ProofC = proofData.HashModOrder();

            // Computing ProofS = (ProofC*isk) + r mod GROUP_ORDER
            ProofS = BIG.ModMul(ProofC, isk, IdemixUtils.GROUP_ORDER).Plus(r);
            ProofS.Mod(IdemixUtils.GROUP_ORDER);

            // Compute Hash of IdemixIssuerPublicKey
            byte[] serializedIpk = ToProto().ToByteArray();
            Hash = serializedIpk.HashModOrder().ToBytes();
        }