Пример #1
0
        /**
         * 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);
            }
        }
Пример #2
0
        /**
         * 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;
        }
Пример #3
0
        /**
         * Helper function to create IdemixSigningIdentity from a file generated by idemixgen go tool
         *
         * @param mspId
         * @return IdemixSigningIdentity object
         * @throws IOException
         * @throws InvalidProtocolBufferException
         */
        private IdemixSigningIdentity CreateIdemixSigningIdentity(string mspId)
        {
            IdemixMSPSignerConfig signerConfig;

            signerConfig = ReadIdemixMSPConfig(Path.Combine(TEST_PATH, mspId, USER_PATH).Locate(), SIGNER_CONFIG);
            Assert.IsNotNull(signerConfig);

            IssuerPublicKey       ipkProto = ReadIdemixIssuerPublicKey(Path.Combine(TEST_PATH, mspId, VERIFIER_PATH).Locate(), IPK_CONFIG);
            IdemixIssuerPublicKey ipkt     = new IdemixIssuerPublicKey(ipkProto);

            Assert.IsTrue(ipkt.Check());

            KeyPair revPk = ReadIdemixRevocationPublicKey(Path.Combine(TEST_PATH, mspId, VERIFIER_PATH).Locate(), REVOCATION_PUBLIC_KEY);

            BIG skt = BIG.FromBytes(signerConfig.Sk.ToByteArray());

            Credential credProto = Credential.Parser.ParseFrom(signerConfig.Cred);

            Assert.IsNotNull(credProto);

            IdemixCredential credt = new IdemixCredential(credProto);

            CredentialRevocationInformation crit = CredentialRevocationInformation.Parser.ParseFrom(signerConfig.CredentialRevocationInformation);

            return(new IdemixSigningIdentity(ipkt, revPk, mspId, skt, credt, crit, signerConfig.OrganizationalUnitIdentifier, (IdemixRoles)signerConfig.Role));
        }
Пример #4
0
        /**
         * Returns an amcl.BN256.ECP2 on input of an ECP2 protobuf object.
         *
         * @param w a protobuf object representing an ECP2
         * @return a ECP2 created from the protobuf object
         */
        public static ECP2 ToECP2(this Protos.Idemix.ECP2 w)
        {
            byte[] valuexa = w.Xa.ToByteArray();
            byte[] valuexb = w.Xb.ToByteArray();
            byte[] valueya = w.Ya.ToByteArray();
            byte[] valueyb = w.Yb.ToByteArray();
            FP2    valuex  = new FP2(BIG.FromBytes(valuexa), BIG.FromBytes(valuexb));
            FP2    valuey  = new FP2(BIG.FromBytes(valueya), BIG.FromBytes(valueyb));

            return(new ECP2(valuex, valuey));
        }
Пример #5
0
        /**
         * Construct a IdemixCredRequest from a serialized credrequest
         *
         * @param proto a protobuf representation of a credential request
         */
        public IdemixCredRequest(CredRequest proto)
        {
            if (proto == null)
            {
                throw new ArgumentException("Cannot create idemix credrequest from null input");
            }

            Nym         = proto.Nym.ToECP();
            proofC      = BIG.FromBytes(proto.ProofC.ToByteArray());
            proofS      = BIG.FromBytes(proto.ProofS.ToByteArray());
            issuerNonce = BIG.FromBytes(proto.IssuerNonce.ToByteArray());
        }
        /**
         * Construct a new signature from a serialized IdemixPseudonymSignature
         *
         * @param proto a protobuf object representing an IdemixPseudonymSignature
         */
        public IdemixPseudonymSignature(NymSignature proto)
        {
            if (proto == null)
            {
                throw new ArgumentException("Cannot create idemix nym signature from null input");
            }

            proofC     = BIG.FromBytes(proto.ProofC.ToByteArray());
            proofSSk   = BIG.FromBytes(proto.ProofSSk.ToByteArray());
            proofSRNym = BIG.FromBytes(proto.ProofSRNym.ToByteArray());
            nonce      = BIG.FromBytes(proto.Nonce.ToByteArray());
        }
Пример #7
0
        public IUser GetUser(string id)
        {
            IdemixMSPSignerConfig signerConfig = ReadIdemixMSPConfig(Path.Combine(mspId, USER_PATH + id));
            KeyPair          revocationPk      = ReadIdemixRevocationPublicKey(mspId);
            BIG              sk   = BIG.FromBytes(signerConfig.Sk.ToByteArray());
            IdemixCredential cred = new IdemixCredential(Credential.Parser.ParseFrom(signerConfig.Cred));
            CredentialRevocationInformation cri = CredentialRevocationInformation.Parser.ParseFrom(signerConfig.CredentialRevocationInformation);

            IdemixEnrollment enrollment = new IdemixEnrollment(ipk, revocationPk, mspId, sk, cred, cri, signerConfig.OrganizationalUnitIdentifier, (IdemixRoles)signerConfig.Role);

            return(new IdemixUser(id, mspId, enrollment));
        }
Пример #8
0
        /**
         * hashModOrder hashes bytes to an amcl.BIG
         * in 0, ..., GROUP_ORDER
         *
         * @param data the data to be hashed
         * @return a BIG in 0, ..., GROUP_ORDER-1 that is the hash of the data
         */
        public static BIG HashModOrder(this byte[] data)
        {
            HASH256 hash = new HASH256();

            foreach (byte b in data)
            {
                hash.Process(b);
            }

            byte[] hasheddata = (byte[])(Array)hash.Hash();

            BIG ret = BIG.FromBytes(hasheddata);

            ret.Mod(GROUP_ORDER);

            return(ret);
        }
Пример #9
0
        /**
         * Construct an IdemixCredential from a serialized credential
         *
         * @param proto a protobuf representation of a credential
         */
        public IdemixCredential(Credential proto)
        {
            if (proto == null)
            {
                throw new ArgumentException("Cannot create idemix credential from null input");
            }

            A     = proto.A.ToECP();
            B     = proto.B.ToECP();
            E     = BIG.FromBytes(proto.E.ToByteArray());
            S     = BIG.FromBytes(proto.S.ToByteArray());
            Attrs = new byte[proto.Attrs.Count][];
            for (int i = 0; i < proto.Attrs.Count; i++)
            {
                Attrs[i] = proto.Attrs[i].ToByteArray();
            }
        }
Пример #10
0
        public void TestSerializingAndDeserializingIdentity()
        {
            SerializedIdentity proto = signingIdentity.CreateSerializedIdentity();

            Assert.IsNotNull(proto);

            SerializedIdemixIdentity idemixProto = null;

            try
            {
                idemixProto = SerializedIdemixIdentity.Parser.ParseFrom(proto.IdBytes);
            }
            catch (InvalidProtocolBufferException e)
            {
                Assert.Fail("Could not parse Idemix Serialized Identity" + e.Message);
            }

            if (idemixProto != null)
            {
                new ECP(BIG.FromBytes(idemixProto.NymX.ToByteArray()), BIG.FromBytes(idemixProto.NymY.ToByteArray()));
                idemixProto.Ou.ToByteArray();
                idemixProto.Role.ToByteArray();
                try
                {
                    new IdemixSignature(Signature.Parser.ParseFrom(idemixProto.Proof.ToByteArray()));
                }
                catch (InvalidProtocolBufferException e)
                {
                    Assert.Fail("Cannot deserialize proof" + e.Message);
                }
            }

            try
            {
                new IdemixIdentity(proto);
            }
            catch (System.Exception e) when(e is CryptoException || e is ArgumentException)
            {
                Assert.Fail("Cannot create Idemix Identity from Proto" + e.Message);
            }
        }
Пример #11
0
        /**
         * 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))));
        }
        /**
         * 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();
        }
Пример #13
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);
        }
Пример #14
0
        public static void Setup(TestContext context)
        {
            // Parse crypto material from files
            IdemixMSPSignerConfig signerConfig = null;

            try
            {
                signerConfig = ReadIdemixMSPConfig(Path.Combine(TEST_PATH, MSP1OU1, USER_PATH).Locate(), SIGNER_CONFIG);
            }
            catch (System.Exception e)
            {
                Assert.Fail("Unexpected exception while reading signerconfig: " + e.Message);
            }

            Assert.IsNotNull(signerConfig);

            try
            {
                revocationPk = ReadIdemixRevocationPublicKey(Path.Combine(TEST_PATH, MSP1OU1, VERIFIER_PATH).Locate(), REVOCATION_PUBLIC_KEY);
            }
            catch (System.Exception e)
            {
                Assert.Fail("Unexpected exception while reading revocation public key: " + e.Message);
            }

            Assert.IsNotNull(revocationPk);

            IssuerPublicKey ipkProto = null;

            try
            {
                ipkProto = ReadIdemixIssuerPublicKey(Path.Combine(TEST_PATH, MSP1OU1, VERIFIER_PATH).Locate(), IPK_CONFIG);
            }
            catch (IOException e1)
            {
                Assert.Fail("Unexpected exception while reading revocation public key" + e1.Message);
            }

            ipk = new IdemixIssuerPublicKey(ipkProto);
            Assert.IsTrue(ipk.Check());

            sk = BIG.FromBytes(signerConfig.Sk.ToByteArray());

            Credential credProto = null;

            try
            {
                credProto = Credential.Parser.ParseFrom(signerConfig.Cred);
            }
            catch (InvalidProtocolBufferException)
            {
                Assert.Fail("Could not parse a credential");
            }

            Assert.IsNotNull(credProto);

            cred = new IdemixCredential(credProto);

            try
            {
                cri = CredentialRevocationInformation.Parser.ParseFrom(signerConfig.CredentialRevocationInformation);
            }
            catch (InvalidProtocolBufferException e)
            {
                Assert.Fail("failed to extract cri from signer config: " + e.Message);
            }

            Assert.IsNotNull(cri);

            try
            {
                signingIdentity = new IdemixSigningIdentity(ipk, revocationPk, MSP1OU1, sk, cred, cri, OU1, IdemixRoles.MEMBER);
            }
            catch (System.Exception e) when(e is CryptoException || e is ArgumentException)
            {
                Assert.Fail("Could not create Idemix Signing Identity" + e.Message);
            }

            Assert.IsNotNull(signingIdentity);

            nym = signingIdentity.Pseudonym;

            nymPublic = nym.Nym;

            proof = signingIdentity.Proof;
        }
Пример #15
0
        /**
         * Create new Idemix Signing Identity with a fresh pseudonym
         *
         * @param ipk          issuer public key
         * @param revocationPk the issuer's long term revocation public key
         * @param mspId        MSP identifier
         * @param sk           user's secret
         * @param cred         idemix credential
         * @param cri          the credential revocation information
         * @param ou           is OU attribute
         * @param role         is role attribute
         * @throws CryptoException
         * @throws InvalidArgumentException
         */
        public IdemixSigningIdentity(IdemixIssuerPublicKey ipk, KeyPair revocationPk, string mspId, BIG sk, IdemixCredential cred, CredentialRevocationInformation cri, string ou, IdemixRoles role)
        {
            // input checks
            if (ipk == null)
            {
                throw new ArgumentException("Issuer Public Key (IPK) must not be null");
            }
            if (revocationPk == null)
            {
                throw new ArgumentException("Revocation PK must not be null");
            }
            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 (ou == null)
            {
                throw new ArgumentException("OU must not be null");
            }
            if (string.IsNullOrEmpty(ou))
            {
                throw new ArgumentException("OU must not be empty");
            }
            if (sk == null)
            {
                throw new ArgumentException("SK must not be null");
            }
            if (cred == null)
            {
                throw new ArgumentException("Credential must not be null");
            }
            if (cri == null)
            {
                throw new ArgumentException("Credential revocation information must not be null");
            }

            logger.Trace($"Verifying public key with hash: [{BitConverter.ToString(ipk.Hash).Replace("-", "")}] \nAttributes: [{string.Join(",", ipk.AttributeNames)}]");

            if (!ipk.Check())
            {
                CryptoException e = new CryptoException("Issuer public key is not valid");
                logger.Error("", e);
                throw e;
            }

            this.ipk = ipk;
            this.sk  = sk;
            this.cri = cri;

            logger.Trace("Verifying the credential");

            // cryptographically verify credential
            // (check if the issuer's signature is valid)
            if (!cred.Verify(sk, ipk))
            {
                CryptoException e = new CryptoException("Credential is not cryptographically valid");
                logger.Error("", e);
                throw e;
            }

            logger.Trace("Checking attributes");

            // attribute checks
            // 4 attributes are expected:
            // - organization unit (disclosed)
            // - role: admin or member (disclosed)
            // - enrollment id (hidden, for future auditing feature and authorization with CA)
            // - revocation handle (hidden, for future revocation support)
            if (cred.Attrs.Length != 4)
            {
                throw new CryptoException($"Error: There are {cred.Attrs.Length} attributes and the expected are 4");
            }

            byte[] ouBytes   = cred.Attrs[0];
            byte[] roleBytes = cred.Attrs[1];
            byte[] eIdBytes  = cred.Attrs[2];
            byte[] rHBytes   = cred.Attrs[3];

            BIG[] attributes = new BIG[4];
            attributes[0] = BIG.FromBytes(ouBytes);
            attributes[1] = BIG.FromBytes(roleBytes);
            attributes[2] = BIG.FromBytes(eIdBytes);
            attributes[3] = BIG.FromBytes(rHBytes);

            // check that the OU string matches the credential's attribute value
            if (!ou.ToBytes().HashModOrder().ToBytes().SequenceEqual(ouBytes))
            {
                throw new ArgumentException("the OU string does not match the credential");
            }

            // check that the role matches the credential's attribute value
            if (!new BIG((int)role).ToBytes().SequenceEqual(roleBytes))
            {
                throw new ArgumentException("the role does not match the credential");
            }

            logger.Trace("Generating fresh pseudonym and proof");
            // generate a fresh pseudonym
            Pseudonym = new IdemixPseudonym(this.sk, this.ipk);

            // generate a fresh proof of possession of a credential
            // with respect to a freshly generated pseudonym
            Proof = new IdemixSignature(cred, this.sk, Pseudonym, this.ipk, disclosedFlags, msgEmpty, rhIndex, cri);
            logger.Trace("Verifying the proof");
            // verify the proof
            if (!Proof.Verify(disclosedFlags, this.ipk, msgEmpty, attributes, rhIndex, revocationPk, (int)cri.Epoch))
            {
                throw new CryptoException("Generated proof of identity is not valid");
            }

            logger.Trace("Generating the Identity Object");
            // generate a fresh identity with new pseudonym
            idemixIdentity = new IdemixIdentity(mspId, this.ipk, Pseudonym.Nym, ou, role, Proof);
            logger.Trace(idemixIdentity.ToString());
        }
Пример #16
0
 /**
  * Returns an amcl.BN256.ECP on input of an ECP protobuf object.
  *
  * @param w a protobuf object representing an ECP
  * @return a ECP created from the protobuf object
  */
 public static ECP ToECP(this Protos.Idemix.ECP w)
 {
     byte[] valuex = w.X.ToByteArray();
     byte[] valuey = w.Y.ToByteArray();
     return(new ECP(BIG.FromBytes(valuex), BIG.FromBytes(valuey)));
 }
Пример #17
0
        /* convert from byte array to FP12 */
        public static FP12 FromBytes(sbyte[] w)
        {
            BIG a, b;
            FP2 c, d;
            FP4 e, f, g;

            sbyte[] t = new sbyte[BIG.MODBYTES];

            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i];
            }
            a = BIG.FromBytes(t);
            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + BIG.MODBYTES];
            }
            b = BIG.FromBytes(t);
            c = new FP2(a, b);

            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 2 * BIG.MODBYTES];
            }
            a = BIG.FromBytes(t);
            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 3 * BIG.MODBYTES];
            }
            b = BIG.FromBytes(t);
            d = new FP2(a, b);

            e = new FP4(c, d);


            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 4 * BIG.MODBYTES];
            }
            a = BIG.FromBytes(t);
            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 5 * BIG.MODBYTES];
            }
            b = BIG.FromBytes(t);
            c = new FP2(a, b);

            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 6 * BIG.MODBYTES];
            }
            a = BIG.FromBytes(t);
            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 7 * BIG.MODBYTES];
            }
            b = BIG.FromBytes(t);
            d = new FP2(a, b);

            f = new FP4(c, d);


            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 8 * BIG.MODBYTES];
            }
            a = BIG.FromBytes(t);
            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 9 * BIG.MODBYTES];
            }
            b = BIG.FromBytes(t);
            c = new FP2(a, b);

            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 10 * BIG.MODBYTES];
            }
            a = BIG.FromBytes(t);
            for (int i = 0; i < BIG.MODBYTES; i++)
            {
                t[i] = w[i + 11 * BIG.MODBYTES];
            }
            b = BIG.FromBytes(t);
            d = new FP2(a, b);

            g = new FP4(c, d);

            return(new FP12(e, f, g));
        }