/**
         * Construct a new signature from a serialized IdemixSignature
         *
         * @param proto a protobuf object representing an IdemixSignature
         */
        public IdemixSignature(Signature proto)
        {
            if (proto == null)
            {
                throw new ArgumentException("Cannot construct idemix signature from null input");
            }

            aBar         = proto.ABar.ToECP();
            aPrime       = proto.APrime.ToECP();
            bPrime       = proto.BPrime.ToECP();
            nym          = proto.Nym.ToECP();
            proofC       = BIG.FromBytes(proto.ProofC.ToByteArray());
            proofSSk     = BIG.FromBytes(proto.ProofSSk.ToByteArray());
            proofSE      = BIG.FromBytes(proto.ProofSE.ToByteArray());
            proofSR2     = BIG.FromBytes(proto.ProofSR2.ToByteArray());
            proofSR3     = BIG.FromBytes(proto.ProofSR3.ToByteArray());
            proofSSPrime = BIG.FromBytes(proto.ProofSSPrime.ToByteArray());
            proofSRNym   = BIG.FromBytes(proto.ProofSRNym.ToByteArray());
            nonce        = BIG.FromBytes(proto.Nonce.ToByteArray());
            proofSAttrs  = new BIG[proto.ProofSAttrs.Count];
            for (int i = 0; i < proto.ProofSAttrs.Count; i++)
            {
                proofSAttrs[i] = BIG.FromBytes(proto.ProofSAttrs[i].ToByteArray());
            }
            revocationPk       = proto.RevocationEpochPk;
            revocationPKSig    = proto.RevocationPkSig.ToByteArray();
            epoch              = proto.Epoch;
            nonRevocationProof = proto.NonRevocationProof;
        }
Beispiel #2
0
        /* constant time multiply by small integer of length bts - use ladder */
        public ECP PinMul(int e, int bts)
        {
            if (CURVETYPE == MONTGOMERY)
            {
                return(Mul(new BIG(e)));
            }
            else
            {
                int i, b;
                ECP P  = new ECP();
                ECP R0 = new ECP();
                ECP R1 = new ECP();
                R1.Copy(this);

                for (i = bts - 1; i >= 0; i--)
                {
                    b = (e >> i) & 1;
                    P.Copy(R1);
                    P.Add(R0);
                    R0.CSwap(R1, b);
                    R1.Copy(P);
                    R0.Dbl();
                    R0.CSwap(R1, b);
                }

                P.Copy(R0);
                P.Affine();
                return(P);
            }
        }
Beispiel #3
0
        /* Test P == Q */
        public bool Equals(ECP Q)
        {
            //		if (is_infinity() && Q.is_infinity()) return true;
            //		if (is_infinity() || Q.is_infinity()) return false;

            FP a = new FP(0); // Edits made
            FP b = new FP(0);

            a.Copy(x);
            a.Mul(Q.z);
            b.Copy(Q.x);
            b.Mul(z);
            if (!a.Equals(b))
            {
                return(false);
            }

            if (CURVETYPE != MONTGOMERY)
            {
                a.Copy(y);
                a.Mul(Q.z);
                b.Copy(Q.y);
                b.Mul(z);
                if (!a.Equals(b))
                {
                    return(false);
                }
            }

            return(true);
        }
        /**
         * check whether the issuer public key is correct
         *
         * @return true iff valid
         */
        public bool Check()
        {
            // check formalities of IdemixIssuerPublicKey
            if (AttributeNames == null || Hsk == null || HRand == null || HAttrs == null || BarG1 == null || BarG1.IsInfinity() || BarG2 == null || HAttrs.Length < AttributeNames.Length)
            {
                return(false);
            }

            for (int i = 0; i < AttributeNames.Length; i++)
            {
                if (HAttrs[i] == null)
                {
                    return(false);
                }
            }

            // check proofs
            ECP2 t1 = IdemixUtils.GenG2.Mul(ProofS);
            ECP  t2 = BarG1.Mul(ProofS);

            t1.Add(W.Mul(BIG.ModNeg(ProofC, IdemixUtils.GROUP_ORDER)));
            t2.Add(BarG2.Mul(BIG.ModNeg(ProofC, IdemixUtils.GROUP_ORDER)));

            // 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());

            // Hash proofData to hproofdata and compare with proofC
            return(Enumerable.SequenceEqual(proofData.HashModOrder().ToBytes(), ProofC.ToBytes()));
        }
        /**
         * Create Idemix Identity from a Serialized Identity
         *
         * @param proto
         */
        public IdemixIdentity(SerializedIdentity proto)
        {
            if (proto == null)
            {
                throw new ArgumentException("Input must not be null");
            }

            mspId = proto.Mspid;

            try
            {
                logger.Trace("Fetching Idemix Proto");
                SerializedIdemixIdentity idemixProto = SerializedIdemixIdentity.Parser.ParseFrom(proto.IdBytes);
                if (idemixProto == null)
                {
                    throw new ArgumentException("The identity does not contain a serialized idemix identity");
                }
                logger.Trace("Deserializing Nym and attribute values");
                pseudonym = new ECP(BIG.FromBytes(idemixProto.NymX.ToByteArray()), BIG.FromBytes(idemixProto.NymY.ToByteArray()));
                OrganizationUnit ou   = OrganizationUnit.Parser.ParseFrom(idemixProto.Ou);
                MSPRole          role = MSPRole.Parser.ParseFrom(idemixProto.Role);

                Ou       = ou.OrganizationalUnitIdentifier;
                RoleMask = role.Role.ToIdemixRole();
                ipkHash  = ou.CertifiersIdentifier.ToByteArray();
                logger.Trace("Deserializing Proof");
                associationProof = new IdemixSignature(Signature.Parser.ParseFrom(idemixProto.Proof.ToByteArray()));
            }
            catch (InvalidProtocolBufferException e)
            {
                throw new CryptoException("Cannot deserialize MSP ID", e);
            }
        }
        /**
         * Cryptographically verify the IdemixCredRequest
         *
         * @param ipk the issuer public key
         * @return true iff valid
         */
        public bool Check(IdemixIssuerPublicKey ipk)
        {
            if (Nym == null || issuerNonce == null || proofC == null || proofS == null || ipk == null)
            {
                return(false);
            }

            ECP t = ipk.Hsk.Mul(proofS);

            t.Sub(Nym.Mul(proofC));

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


            // Hash proofData to hproofdata
            byte[] hproofdata = proofData.HashModOrder().ToBytes();

            return(Enumerable.SequenceEqual(proofC.ToBytes(), hproofdata));
        }
Beispiel #7
0
        /* this-=Q */
        public void Sub(ECP Q)
        {
            ECP NQ = new ECP(Q);

            NQ.Neg();
            Add(NQ);
        }
        /**
         * Verify this IdemixPseudonymSignature
         *
         * @param nym the pseudonym with respect to which the signature is verified
         * @param ipk the issuer public key
         * @param msg the message that should be signed in this signature
         * @return true iff valid
         */
        public bool Verify(ECP nym, IdemixIssuerPublicKey ipk, byte[] msg)
        {
            if (nym == null || ipk == null || msg == null)
            {
                return(false);
            }

            ECP t = ipk.Hsk.Mul2(proofSSk, ipk.HRand, proofSRNym);

            t.Sub(nym.Mul(proofC));

            // 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(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());

            byte[] hashedProofData = finalProofData.HashModOrder().ToBytes();
            return(Enumerable.SequenceEqual(proofC.ToBytes(), hashedProofData));
        }
Beispiel #9
0
        /* this=P */
        public void Copy(ECP P)
        {
            x.Copy(P.x);
            if (CURVETYPE != MONTGOMERY)
            {
                y.Copy(P.y);
            }

            z.Copy(P.z);
            //INF=P.INF;
        }
Beispiel #10
0
        /* convert to hex string */
        public string ToRawString()
        {
            //if (is_infinity()) return "infinity";
            //affine();
            ECP W = new ECP(this);

            if (CURVETYPE == MONTGOMERY)
            {
                return("(" + W.x.Redc().ToString() + "," + W.z.Redc().ToString() + ")");
            }
            else
            {
                return("(" + W.x.Redc().ToString() + "," + W.y.Redc().ToString() + "," + W.z.Redc().ToString() + ")");
            }
        }
Beispiel #11
0
        /* Conditional move of Q to P dependant on d */
        private void CMove(ECP Q, int d)
        {
            x.CMove(Q.x, d);
            if (CURVETYPE != MONTGOMERY)
            {
                y.CMove(Q.y, d);
            }

            z.CMove(Q.z, d);
            //	if (CURVETYPE!=EDWARDS)
            //	{
            //		boolean bd;
            //		if (d==0) bd=false;
            //		else bd=true;
            //		INF^=(INF^Q.INF)&bd;
            //	}
        }
        /**
         * Constructor creating a new credential
         *
         * @param key   the issuer key pair
         * @param m     a credential request
         * @param attrs an array of attribute values as BIG
         */
        public IdemixCredential(IdemixIssuerKey key, IdemixCredRequest m, BIG[] attrs)
        {
            if (key == null || key.Ipk == null || m == null || attrs == null)
            {
                throw new ArgumentException("Cannot create idemix credential from null input");
            }
            if (attrs.Length != key.Ipk.AttributeNames.Length)
            {
                throw new ArgumentException("Amount of attribute values does not match amount of attributes in issuer public key");
            }
            RAND rng = IdemixUtils.GetRand();

            // Place a BBS+ signature on the user key and the attribute values
            // (For BBS+, see "Constant-Size Dynamic k-TAA" by Man Ho Au, Willy Susilo, Yi Mu)
            E = rng.RandModOrder();
            S = rng.RandModOrder();

            B = new ECP();
            B.Copy(IdemixUtils.GenG1);
            B.Add(m.Nym);
            B.Add(key.Ipk.HRand.Mul(S));

            for (int i = 0; i < attrs.Length / 2; i++)
            {
                B.Add(key.Ipk.HAttrs[2 * i].Mul2(attrs[2 * i], key.Ipk.HAttrs[2 * i + 1], attrs[2 * i + 1]));
            }

            if (attrs.Length % 2 != 0)
            {
                B.Add(key.Ipk.HAttrs[attrs.Length - 1].Mul(attrs[attrs.Length - 1]));
            }

            BIG exp = new BIG(key.Isk).Plus(E);

            exp.Mod(IdemixUtils.GROUP_ORDER);
            exp.InvModp(IdemixUtils.GROUP_ORDER);
            A = B.Mul(exp);

            Attrs = new byte[attrs.Length][];
            for (int i = 0; i < attrs.Length; i++)
            {
                byte[] b = new byte[IdemixUtils.FIELD_BYTES];
                attrs[i].ToBytes(b);
                Attrs[i] = b;
            }
        }
        /**
         * Create Idemix Identity from the following inputs:
         *
         * @param mspId is MSP ID sting
         * @param nym   is Identity Mixer Pseudonym
         * @param ou    is OU attribute
         * @param roleMask  is a bitmask that represent all the roles attached to this identity
         * @param proof is Proof
         */
        public IdemixIdentity(string mspId, IdemixIssuerPublicKey ipk, ECP nym, string ou, IdemixRoles roleMask, IdemixSignature proof)
        {
            if (mspId == null)
            {
                throw new ArgumentException("MSP ID must not be null");
            }

            if (string.IsNullOrEmpty(mspId))
            {
                throw new ArgumentException("MSP ID must not be empty");
            }

            if (ipk == null)
            {
                throw new ArgumentException("Issuer Public Key must not be empty");
            }

            if (nym == null)
            {
                throw new ArgumentException("Identity Mixer Pseudonym (nym) must not be null");
            }

            if (ou == null)
            {
                throw new ArgumentException("OU attribute must not be null");
            }

            if (string.IsNullOrEmpty(ou))
            {
                throw new ArgumentException("OU attribute must not be empty");
            }

            if (proof == null)
            {
                throw new ArgumentException("Proof must not be null");
            }


            this.mspId       = mspId;
            ipkHash          = ipk.Hash;
            pseudonym        = nym;
            Ou               = ou;
            RoleMask         = roleMask;
            associationProof = proof;
        }
        /**
         * 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);
        }
Beispiel #15
0
        public static ECP Generator()
        {
            ECP G;
            BIG gx, gy;

            gx = new BIG(ROM.CURVE_Gx);

            if (CURVETYPE != MONTGOMERY)
            {
                gy = new BIG(ROM.CURVE_Gy);
                G  = new ECP(gx, gy);
            }
            else
            {
                G = new ECP(gx);
            }

            return(G);
        }
Beispiel #16
0
        /* convert to hex string */
        public override string ToString()
        {
            ECP W = new ECP(this);

            W.Affine();
            if (W.IsInfinity())
            {
                return("infinity");
            }

            if (CURVETYPE == MONTGOMERY)
            {
                return("(" + W.x.Redc().ToString() + ")");
            }
            else
            {
                return("(" + W.x.Redc().ToString() + "," + W.y.Redc().ToString() + ")");
            }
        }
Beispiel #17
0
        /* Constant time select from pre-computed table */
        private void Select(ECP[] W, int b)
        {
            ECP MP   = new ECP();
            int m    = b >> 31;
            int babs = (b ^ m) - m;

            babs = (babs - 1) / 2;
            CMove(W[0], Teq(babs, 0)); // conditional move
            CMove(W[1], Teq(babs, 1));
            CMove(W[2], Teq(babs, 2));
            CMove(W[3], Teq(babs, 3));
            CMove(W[4], Teq(babs, 4));
            CMove(W[5], Teq(babs, 5));
            CMove(W[6], Teq(babs, 6));
            CMove(W[7], Teq(babs, 7));

            MP.Copy(this);
            MP.Neg();
            CMove(MP, (int)(m & 1));
        }
        /**
         * verify cryptographically verifies the credential
         *
         * @param sk  the secret key of the user
         * @param ipk the public key of the issuer
         * @return true iff valid
         */
        public bool Verify(BIG sk, IdemixIssuerPublicKey ipk)
        {
            if (ipk == null || Attrs.Length != ipk.AttributeNames.Length)
            {
                return(false);
            }

            foreach (byte[] attr in Attrs)
            {
                if (attr == null)
                {
                    return(false);
                }
            }

            ECP bPrime = new ECP();

            bPrime.Copy(IdemixUtils.GenG1);
            bPrime.Add(ipk.Hsk.Mul2(sk, ipk.HRand, S));
            for (int i = 0; i < Attrs.Length / 2; i++)
            {
                bPrime.Add(ipk.HAttrs[2 * i].Mul2(BIG.FromBytes(Attrs[2 * i]), ipk.HAttrs[2 * i + 1], BIG.FromBytes(Attrs[2 * i + 1])));
            }

            if (Attrs.Length % 2 != 0)
            {
                bPrime.Add(ipk.HAttrs[Attrs.Length - 1].Mul(BIG.FromBytes(Attrs[Attrs.Length - 1])));
            }

            if (!B.Equals(bPrime))
            {
                return(false);
            }

            ECP2 a = IdemixUtils.GenG2.Mul(E);

            a.Add(ipk.W);
            a.Affine();
            return(PAIR.FExp(PAIR.Ate(a, A)).Equals(PAIR.FExp(PAIR.Ate(IdemixUtils.GenG2, B))));
        }
        /**
         * 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);
        }
Beispiel #20
0
        /* convert to byte array */
        public void ToBytes(sbyte[] b, bool compress)
        {
            sbyte[] t = new sbyte[BIG.MODBYTES];
            ECP     W = new ECP(this);

            W.Affine();

            W.x.Redc().ToBytes(t);
            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                b[i + 1] = t[i];
            }

            if (CURVETYPE == MONTGOMERY)
            {
                b[0] = 0x06;
                return;
            }

            if (compress)
            {
                b[0] = 0x02;
                if (y.Redc().Parity() == 1)
                {
                    b[0] = 0x03;
                }

                return;
            }

            b[0] = 0x04;

            W.y.Redc().ToBytes(t);
            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                b[i + BIG.MODBYTES + 1] = t[i];
            }
        }
Beispiel #21
0
        /* Map byte string to curve point */
        public static ECP MapIt(sbyte[] h)
        {
            BIG q = new BIG(ROM.Modulus);
            BIG x = BIG.FromBytes(h);

            x.Mod(q);
            ECP P;

            while (true)
            {
                while (true)
                {
                    if (CURVETYPE != MONTGOMERY)
                    {
                        P = new ECP(x, 0);
                    }
                    else
                    {
                        P = new ECP(x);
                    }

                    x.Inc(1);
                    x.Norm();
                    if (!P.IsInfinity())
                    {
                        break;
                    }
                }

                P.Cfp();
                if (!P.IsInfinity())
                {
                    break;
                }
            }

            return(P);
        }
Beispiel #22
0
        /* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
        public void DAdd(ECP Q, ECP W)
        {
            FP A  = new FP(x);
            FP B  = new FP(x);
            FP C  = new FP(Q.x);
            FP D  = new FP(Q.x);
            FP DA = new FP(0);
            FP CB = new FP(0);

            A.Add(z);
            B.Sub(z);

            C.Add(Q.z);
            D.Sub(Q.z);
            A.Norm();

            D.Norm();
            DA.Copy(D);
            DA.Mul(A);

            C.Norm();
            B.Norm();
            CB.Copy(C);
            CB.Mul(B);

            A.Copy(DA);
            A.Add(CB);
            A.Norm();
            A.Sqr();
            B.Copy(DA);
            B.Sub(CB);
            B.Norm();
            B.Sqr();

            x.Copy(A);
            z.Copy(W.x);
            z.Mul(B);
        }
        /**
         * Construct an IdemixIssuerPublicKey from a serialized issuer public key
         *
         * @param proto a protobuf representation of an issuer public key
         */
        public IdemixIssuerPublicKey(IssuerPublicKey proto)
        {
            // check for bad input
            if (proto == null)
            {
                throw new ArgumentException("Cannot create IdemixIssuerPublicKey from null input");
            }

            if (proto.HAttrs.Count < proto.AttributeNames.Count)
            {
                throw new ArgumentException("Serialized IPk does not contain enough HAttr values");
            }

            AttributeNames = new string[proto.AttributeNames.Count];
            for (int i = 0; i < proto.AttributeNames.Count; i++)
            {
                AttributeNames[i] = proto.AttributeNames[i];
            }

            HAttrs = new ECP[proto.HAttrs.Count];
            for (int i = 0; i < proto.HAttrs.Count; i++)
            {
                HAttrs[i] = proto.HAttrs[i].ToECP();
            }

            BarG1  = proto.BarG1.ToECP();
            BarG2  = proto.BarG2.ToECP();
            HRand  = proto.HRand.ToECP();
            Hsk    = proto.HSk.ToECP();
            ProofC = BIG.FromBytes(proto.ProofC.ToByteArray());
            ProofS = BIG.FromBytes(proto.ProofS.ToByteArray());
            W      = proto.W.ToECP2();

            // Compute Hash of IdemixIssuerPublicKey
            byte[] serializedIpk = ToProto().ToByteArray();
            Hash = serializedIpk.HashModOrder().ToBytes();
        }
Beispiel #24
0
        /* return e.this */

        public ECP Mul(BIG e)
        {
            if (e.IsZilch() || IsInfinity())
            {
                return(new ECP());
            }

            ECP P = new ECP();

            if (CURVETYPE == MONTGOMERY)
            {
                /* use Ladder */
                int nb, i, b;
                ECP D  = new ECP();
                ECP R0 = new ECP();
                R0.Copy(this);
                ECP R1 = new ECP();
                R1.Copy(this);
                R1.Dbl();

                D.Copy(this);
                D.Affine();
                nb = e.NBits();
                for (i = nb - 2; i >= 0; i--)
                {
                    b = e.Bit(i);
                    P.Copy(R1);

                    P.DAdd(R0, D);
                    R0.CSwap(R1, b);
                    R1.Copy(P);
                    R0.Dbl();
                    R0.CSwap(R1, b);
                }

                P.Copy(R0);
            }
            else
            {
                // fixed size windows
                int     i, nb, s, ns;
                BIG     mt = new BIG();
                BIG     t  = new BIG();
                ECP     Q  = new ECP();
                ECP     C  = new ECP();
                ECP[]   W  = new ECP[8];
                sbyte[] w  = new sbyte[1 + (BIG.NLEN * BIG.BASEBITS + 3) / 4];

                //affine();

                // precompute table
                Q.Copy(this);

                Q.Dbl();
                W[0] = new ECP();
                W[0].Copy(this);

                for (i = 1; i < 8; i++)
                {
                    W[i] = new ECP();
                    W[i].Copy(W[i - 1]);
                    W[i].Add(Q);
                }

                // make exponent odd - add 2P if even, P if odd
                t.Copy(e);
                s = t.Parity();
                t.Inc(1);
                t.Norm();
                ns = t.Parity();
                mt.Copy(t);
                mt.Inc(1);
                mt.Norm();
                t.CMove(mt, s);
                Q.CMove(this, ns);
                C.Copy(Q);

                nb = 1 + (t.NBits() + 3) / 4;

                // convert exponent to signed 4-bit window
                for (i = 0; i < nb; i++)
                {
                    w[i] = (sbyte)(t.LastBits(5) - 16);
                    t.Dec(w[i]);
                    t.Norm();
                    t.FShr(4);
                }

                w[nb] = (sbyte)t.LastBits(5);

                P.Copy(W[(w[nb] - 1) / 2]);
                for (i = nb - 1; i >= 0; i--)
                {
                    Q.Select(W, w[i]);
                    P.Dbl();
                    P.Dbl();
                    P.Dbl();
                    P.Dbl();
                    P.Add(Q);
                }

                P.Sub(C); // apply correction
            }

            P.Affine();
            return(P);
        }
Beispiel #25
0
        /* this+=Q */
        public void Add(ECP Q)
        {
            //		if (INF)
            //		{
            //			copy(Q);
            //			return;
            //		}
            //		if (Q.INF) return;

            if (CURVETYPE == WEIERSTRASS)
            {
                if (ROM.CURVE_A == 0)
                {
                    // Edits made
                    //System.out.println("Into add");
                    int b  = 3 * ROM.CURVE_B_I;
                    FP  t0 = new FP(x);
                    t0.Mul(Q.x);
                    FP t1 = new FP(y);
                    t1.Mul(Q.y);
                    FP t2 = new FP(z);
                    t2.Mul(Q.z);
                    FP t3 = new FP(x);
                    t3.Add(y);
                    t3.Norm();
                    FP t4 = new FP(Q.x);
                    t4.Add(Q.y);
                    t4.Norm();
                    t3.Mul(t4);
                    t4.Copy(t0);
                    t4.Add(t1);

                    t3.Sub(t4);
                    t3.Norm();
                    t4.Copy(y);
                    t4.Add(z);
                    t4.Norm();
                    FP x3 = new FP(Q.y);
                    x3.Add(Q.z);
                    x3.Norm();

                    t4.Mul(x3);
                    x3.Copy(t1);
                    x3.Add(t2);

                    t4.Sub(x3);
                    t4.Norm();
                    x3.Copy(x);
                    x3.Add(z);
                    x3.Norm();
                    FP y3 = new FP(Q.x);
                    y3.Add(Q.z);
                    y3.Norm();
                    x3.Mul(y3);
                    y3.Copy(t0);
                    y3.Add(t2);
                    y3.RSub(x3);
                    y3.Norm();
                    x3.Copy(t0);
                    x3.Add(t0);
                    t0.Add(x3);
                    t0.Norm();
                    t2.IMul(b);

                    FP z3 = new FP(t1);
                    z3.Add(t2);
                    z3.Norm();
                    t1.Sub(t2);
                    t1.Norm();
                    y3.IMul(b);

                    x3.Copy(y3);
                    x3.Mul(t4);
                    t2.Copy(t3);
                    t2.Mul(t1);
                    x3.RSub(t2);
                    y3.Mul(t0);
                    t1.Mul(z3);
                    y3.Add(t1);
                    t0.Mul(t3);
                    z3.Mul(t4);
                    z3.Add(t0);

                    x.Copy(x3);
                    x.Norm();
                    y.Copy(y3);
                    y.Norm();
                    z.Copy(z3);
                    z.Norm();
                    //System.out.println("Out of add");
                }
                else
                {
                    FP t0 = new FP(x);
                    FP t1 = new FP(y);
                    FP t2 = new FP(z);
                    FP t3 = new FP(x);
                    FP t4 = new FP(Q.x);
                    FP z3 = new FP(0);
                    FP y3 = new FP(Q.x);
                    FP x3 = new FP(Q.y);
                    FP b  = new FP(0);

                    if (ROM.CURVE_B_I == 0)
                    {
                        b.Copy(new FP(new BIG(ROM.CURVE_B)));
                    }

                    t0.Mul(Q.x); //1
                    t1.Mul(Q.y); //2
                    t2.Mul(Q.z); //3

                    t3.Add(y);
                    t3.Norm();  //4
                    t4.Add(Q.y);
                    t4.Norm();  //5
                    t3.Mul(t4); //6
                    t4.Copy(t0);
                    t4.Add(t1); //t4.norm(); //7
                    t3.Sub(t4);
                    t3.Norm();  //8
                    t4.Copy(y);
                    t4.Add(z);
                    t4.Norm();  //9
                    x3.Add(Q.z);
                    x3.Norm();  //10
                    t4.Mul(x3); //11
                    x3.Copy(t1);
                    x3.Add(t2); //x3.norm();//12

                    t4.Sub(x3);
                    t4.Norm(); //13
                    x3.Copy(x);
                    x3.Add(z);
                    x3.Norm();  //14
                    y3.Add(Q.z);
                    y3.Norm();  //15

                    x3.Mul(y3); //16
                    y3.Copy(t0);
                    y3.Add(t2); //y3.norm();//17

                    y3.RSub(x3);
                    y3.Norm(); //18
                    z3.Copy(t2);


                    if (ROM.CURVE_B_I == 0)
                    {
                        z3.Mul(b); //18
                    }
                    else
                    {
                        z3.IMul(ROM.CURVE_B_I);
                    }

                    x3.Copy(y3);
                    x3.Sub(z3);
                    x3.Norm();  //20
                    z3.Copy(x3);
                    z3.Add(x3); //z3.norm(); //21

                    x3.Add(z3); //x3.norm(); //22
                    z3.Copy(t1);
                    z3.Sub(x3);
                    z3.Norm(); //23
                    x3.Add(t1);
                    x3.Norm(); //24

                    if (ROM.CURVE_B_I == 0)
                    {
                        y3.Mul(b); //18
                    }
                    else
                    {
                        y3.IMul(ROM.CURVE_B_I);
                    }

                    t1.Copy(t2);
                    t1.Add(t2); //t1.norm();//26
                    t2.Add(t1); //t2.norm();//27

                    y3.Sub(t2); //y3.norm(); //28

                    y3.Sub(t0);
                    y3.Norm();  //29
                    t1.Copy(y3);
                    t1.Add(y3); //t1.norm();//30
                    y3.Add(t1);
                    y3.Norm();  //31

                    t1.Copy(t0);
                    t1.Add(t0); //t1.norm(); //32
                    t0.Add(t1); //t0.norm();//33
                    t0.Sub(t2);
                    t0.Norm();  //34
                    t1.Copy(t4);
                    t1.Mul(y3); //35
                    t2.Copy(t0);
                    t2.Mul(y3); //36
                    y3.Copy(x3);
                    y3.Mul(z3); //37
                    y3.Add(t2); //y3.norm();//38
                    x3.Mul(t3); //39
                    x3.Sub(t1); //40
                    z3.Mul(t4); //41
                    t1.Copy(t3);
                    t1.Mul(t0); //42
                    z3.Add(t1);
                    x.Copy(x3);
                    x.Norm();
                    y.Copy(y3);
                    y.Norm();
                    z.Copy(z3);
                    z.Norm();
                }
            }

            if (CURVETYPE == EDWARDS)
            {
                //System.out.println("Into add");
                FP A = new FP(z);
                FP B = new FP(0);
                FP C = new FP(x);
                FP D = new FP(y);
                FP E = new FP(0);
                FP F = new FP(0);
                FP G = new FP(0);

                A.Mul(Q.z);
                B.Copy(A);
                B.Sqr();
                C.Mul(Q.x);
                D.Mul(Q.y);

                E.Copy(C);
                E.Mul(D);

                if (ROM.CURVE_B_I == 0)
                {
                    FP b = new FP(new BIG(ROM.CURVE_B));
                    E.Mul(b);
                }
                else
                {
                    E.IMul(ROM.CURVE_B_I);
                }

                F.Copy(B);
                F.Sub(E);
                G.Copy(B);
                G.Add(E);

                if (ROM.CURVE_A == 1)
                {
                    E.Copy(D);
                    E.Sub(C);
                }

                C.Add(D);

                B.Copy(x);
                B.Add(y);
                D.Copy(Q.x);
                D.Add(Q.y);
                B.Norm();
                D.Norm();
                B.Mul(D);
                B.Sub(C);
                B.Norm();
                F.Norm();
                B.Mul(F);
                x.Copy(A);
                x.Mul(B);
                G.Norm();
                if (ROM.CURVE_A == 1)
                {
                    E.Norm();
                    C.Copy(E);
                    C.Mul(G);
                }

                if (ROM.CURVE_A == -1)
                {
                    C.Norm();
                    C.Mul(G);
                }

                y.Copy(A);
                y.Mul(C);

                z.Copy(F);
                z.Mul(G);
                //System.out.println("Out of add");
            }

            return;
        }
Beispiel #26
0
 public ECP(ECP e)
 {
     x = new FP(e.x);
     y = new FP(e.y);
     z = new FP(e.z);
 }
Beispiel #27
0
            private void Test()
            {
                RAND rng = IdemixUtils.GetRand();
                // WeakBB test
                // Random message to sign
                BIG wbbMessage = rng.RandModOrder();
                // Sign the message with keypair secret key
                ECP wbbSignature = WeakBB.WeakBBSign(setup.wbbKeyPair.Sk, wbbMessage);

                // Check the signature with valid PK and valid message
                Assert.IsTrue(WeakBB.weakBBVerify(setup.wbbKeyPair.Pk, wbbSignature, wbbMessage));
                // Try to check a random message
                Assert.IsFalse(WeakBB.weakBBVerify(setup.wbbKeyPair.Pk, wbbSignature, rng.RandModOrder()));

                // user completes the idemixCredential and checks validity
                Assert.IsTrue(setup.idemixCredential.Verify(setup.sk, setup.key.Ipk));

                // Test serialization of IdemixidemixCredential
                Assert.IsTrue(new IdemixCredential(setup.idemixCredential.ToProto()).Verify(setup.sk, setup.key.Ipk));

                // Create CRI that contains no revocation mechanism
                int epoch = 0;

                BIG[] rhIndex = { new BIG(0) };
                CredentialRevocationInformation cri = RevocationAuthority.CreateCRI(setup.revocationKeyPair, rhIndex, epoch, RevocationAlgorithm.ALG_NO_REVOCATION);

                // Create a new unlinkable pseudonym
                IdemixPseudonym pseudonym = new IdemixPseudonym(setup.sk, setup.key.Ipk); //tcert

                // Test signing no disclosure
                bool[]          disclosure = { false, false, false, false, false };
                byte[]          msg        = { 1, 2, 3, 4, 5 };
                IdemixSignature signature  = new IdemixSignature(setup.idemixCredential, setup.sk, pseudonym, setup.key.Ipk, disclosure, msg, 0, cri);

                Assert.IsNotNull(signature);

                // Test bad disclosure: Disclosure > number of attributes || Disclosure < number of attributes
                bool[] badDisclosure  = { false, true };
                bool[] badDisclosure2 = { true, true, true, true, true, true, true };
                try
                {
                    new IdemixSignature(setup.idemixCredential, setup.sk, pseudonym, setup.key.Ipk, badDisclosure, msg, 0, cri);
                    new IdemixSignature(setup.idemixCredential, setup.sk, pseudonym, setup.key.Ipk, badDisclosure2, msg, 0, cri);
                    Assert.Fail("Expected an ArgumentException");
                }
                catch (ArgumentException)
                {
                    //ignored
                    /* Do nothing, the expected behaviour is to catch this exception.*/
                }

                // check that the signature is valid
                Assert.IsTrue(signature.Verify(disclosure, setup.key.Ipk, msg, setup.attrs, 0, setup.revocationKeyPair, epoch));

                // Test serialization of IdemixSignature
                Assert.IsTrue(new IdemixSignature(signature.ToProto()).Verify(disclosure, setup.key.Ipk, msg, setup.attrs, 0, setup.revocationKeyPair, epoch));

                // Test signing selective disclosure
                bool[] disclosure2 = { false, true, true, true, false };
                signature = new IdemixSignature(setup.idemixCredential, setup.sk, pseudonym, setup.key.Ipk, disclosure2, msg, 0, cri);
                Assert.IsNotNull(signature);

                // check that the signature is valid
                Assert.IsTrue(signature.Verify(disclosure2, setup.key.Ipk, msg, setup.attrs, 0, setup.revocationKeyPair, epoch));

                // Test signature verification with different disclosure
                Assert.IsFalse(signature.Verify(disclosure, setup.key.Ipk, msg, setup.attrs, 0, setup.revocationKeyPair, epoch));

                // test signature verification with different issuer public key
                Assert.IsFalse(signature.Verify(disclosure2, new IdemixIssuerKey(new [] { "Attr1, Attr2, Attr3, Attr4, Attr5" }).Ipk, msg, setup.attrs, 0, setup.revocationKeyPair, epoch));

                // test signature verification with different message
                byte[] msg2 = { 1, 1, 1 };
                Assert.IsFalse(signature.Verify(disclosure2, setup.key.Ipk, msg2, setup.attrs, 0, setup.revocationKeyPair, epoch));

                // Sign a message with respect to a pseudonym
                IdemixPseudonymSignature nymsig = new IdemixPseudonymSignature(setup.sk, pseudonym, setup.key.Ipk, msg);

                // check that the pseudonym signature is valid
                Assert.IsTrue(nymsig.Verify(pseudonym.Nym, setup.key.Ipk, msg));

                // Test serialization of IdemixPseudonymSignature
                Assert.IsTrue(new IdemixPseudonymSignature(nymsig.ToProto()).Verify(pseudonym.Nym, setup.key.Ipk, msg));
            }
        /**
         * Verify this signature
         *
         * @param disclosure      an array indicating which attributes it expects to be disclosed
         * @param ipk             the issuer public key
         * @param msg             the message that should be signed in this signature
         * @param attributeValues BIG array where attributeValues[i] contains the desired attribute value for the i-th attribute if its disclosed
         * @param rhIndex         index of the attribute that represents the revocation-handle
         * @param revPk           the long term public key used to authenticate CRIs
         * @param epoch           monotonically increasing counter representing a time window
         * @return true iff valid
         */
        // ReSharper disable once ParameterHidesMember
        public bool Verify(bool[] disclosure, IdemixIssuerPublicKey ipk, byte[] msg, BIG[] attributeValues, int rhIndex, KeyPair revPk, int epoch)
        {
            if (disclosure == null || ipk == null || msg == null || attributeValues == null || attributeValues.Length != ipk.AttributeNames.Length || disclosure.Length != ipk.AttributeNames.Length)
            {
                return(false);
            }

            for (int i = 0; i < ipk.AttributeNames.Length; i++)
            {
                if (disclosure[i] && attributeValues[i] == null)
                {
                    return(false);
                }
            }

            int[] hiddenIndices = HiddenIndices(disclosure);
            if (proofSAttrs.Length != hiddenIndices.Length)
            {
                return(false);
            }

            if (aPrime.IsInfinity())
            {
                return(false);
            }

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

            RevocationAlgorithm revocationAlgorithm = (RevocationAlgorithm)nonRevocationProof.RevocationAlg;

            if (disclosure[rhIndex])
            {
                throw new ArgumentException("Attribute " + rhIndex + " is disclosed but also used a revocation handle attribute, which should remain hidden");
            }


            // Verify EpochPK
            if (!RevocationAuthority.VerifyEpochPK(revPk, revocationPk, revocationPKSig, epoch, revocationAlgorithm))
            {
                // Signature is based on an invalid revocation epoch public key
                return(false);
            }

            FP12 temp1 = PAIR.Ate(ipk.W, aPrime);
            FP12 temp2 = PAIR.Ate(IdemixUtils.GenG2, aBar);

            temp2.Inverse();
            temp1.mul(temp2);
            if (!PAIR.FExp(temp1).IsUnity())
            {
                return(false);
            }


            ECP t1   = aPrime.Mul2(proofSE, ipk.HRand, proofSR2);
            ECP temp = new ECP();

            temp.Copy(aBar);
            temp.Sub(bPrime);
            t1.Sub(PAIR.G1Mul(temp, proofC));

            ECP t2 = PAIR.G1Mul(ipk.HRand, proofSSPrime);

            t2.Add(bPrime.Mul2(proofSR3, ipk.Hsk, proofSSk));

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

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

            temp = new ECP();
            temp.Copy(IdemixUtils.GenG1);

            for (int i = 0; i < disclosure.Length; i++)
            {
                if (disclosure[i])
                {
                    temp.Add(PAIR.G1Mul(ipk.HAttrs[i], attributeValues[i]));
                }
            }

            t2.Add(PAIR.G1Mul(temp, proofC));

            ECP t3 = ipk.Hsk.Mul2(proofSSk, ipk.HRand, proofSRNym);

            t3.Sub(nym.Mul(proofC));

            // Check with non-revoked-verifier
            INonRevocationVerifier nonRevokedVerifier = NonRevocationVerifier.GetNonRevocationVerifier(revocationAlgorithm);
            int hiddenRHIndex = Array.IndexOf(hiddenIndices, rhIndex);

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

            BIG proofSRh = proofSAttrs[hiddenRHIndex];

            byte[] nonRevokedProofBytes = nonRevokedVerifier.RecomputeFSContribution(nonRevocationProof, proofC, revocationPk.ToECP2(), proofSRh);
            if (nonRevokedProofBytes == null)
            {
                return(false);
            }


            // 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(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());

            byte[] hashedProofData = finalProofData.HashModOrder().ToBytes();
            return(Enumerable.SequenceEqual(proofC.ToBytes(), hashedProofData));
        }
        /**
         * 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);
        }
Beispiel #30
0
        /* Return e.this+f.Q */

        public ECP Mul2(BIG e, ECP Q, BIG f)
        {
            BIG te = new BIG();
            BIG tf = new BIG();
            BIG mt = new BIG();
            ECP S  = new ECP();
            ECP T  = new ECP();
            ECP C  = new ECP();

            ECP[]   W = new ECP[8];
            sbyte[] w = new sbyte[1 + (BIG.NLEN * BIG.BASEBITS + 1) / 2];
            int     i, s, ns, nb;
            sbyte   a, b;

            //affine();
            //Q.affine();

            te.Copy(e);
            tf.Copy(f);

            // precompute table
            W[1] = new ECP();
            W[1].Copy(this);
            W[1].Sub(Q);
            W[2] = new ECP();
            W[2].Copy(this);
            W[2].Add(Q);
            S.Copy(Q);
            S.Dbl();
            W[0] = new ECP();
            W[0].Copy(W[1]);
            W[0].Sub(S);
            W[3] = new ECP();
            W[3].Copy(W[2]);
            W[3].Add(S);
            T.Copy(this);
            T.Dbl();
            W[5] = new ECP();
            W[5].Copy(W[1]);
            W[5].Add(T);
            W[6] = new ECP();
            W[6].Copy(W[2]);
            W[6].Add(T);
            W[4] = new ECP();
            W[4].Copy(W[5]);
            W[4].Sub(S);
            W[7] = new ECP();
            W[7].Copy(W[6]);
            W[7].Add(S);

            // if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction

            s = te.Parity();
            te.Inc(1);
            te.Norm();
            ns = te.Parity();
            mt.Copy(te);
            mt.Inc(1);
            mt.Norm();
            te.CMove(mt, s);
            T.CMove(this, ns);
            C.Copy(T);

            s = tf.Parity();
            tf.Inc(1);
            tf.Norm();
            ns = tf.Parity();
            mt.Copy(tf);
            mt.Inc(1);
            mt.Norm();
            tf.CMove(mt, s);
            S.CMove(Q, ns);
            C.Add(S);

            mt.Copy(te);
            mt.Add(tf);
            mt.Norm();
            nb = 1 + (mt.NBits() + 1) / 2;

            // convert exponent to signed 2-bit window
            for (i = 0; i < nb; i++)
            {
                a = (sbyte)(te.LastBits(3) - 4);
                te.Dec(a);
                te.Norm();
                te.FShr(2);
                b = (sbyte)(tf.LastBits(3) - 4);
                tf.Dec(b);
                tf.Norm();
                tf.FShr(2);
                w[i] = (sbyte)(4 * a + b);
            }

            w[nb] = (sbyte)(4 * te.LastBits(3) + tf.LastBits(3));
            S.Copy(W[(w[nb] - 1) / 2]);

            for (i = nb - 1; i >= 0; i--)
            {
                T.Select(W, w[i]);
                S.Dbl();
                S.Dbl();
                S.Add(T);
            }

            S.Sub(C); // apply correction
            S.Affine();
            return(S);
        }