Beispiel #1
0
        /// <summary>
        /// Computes the revocation witness for a specific user attribute.
        /// </summary>
        /// <param name="revoked">Set of revoked values.</param>
        /// <param name="xid">The user attribute.</param>
        /// <returns>A revocation witness.</returns>
        public RevocationWitness ComputeRevocationWitness(HashSet <FieldZqElement> revoked, FieldZqElement xid)
        {
            if (revoked.Contains(xid))
            {
                throw new ArgumentException("xid cannot be in revoked set");
            }
            Group          Gq             = RAParameters.group;
            FieldZq        Zq             = Gq.FieldZq;
            FieldZqElement d              = Zq.One;
            FieldZqElement deltaPlusXProd = Zq.One;

            foreach (var x in revoked)
            {
                if (x + this.PrivateKey == Zq.Zero)
                {
                    throw new ArgumentException("revocationList cannot contain the negation of the private key");
                }
                d *= (x - xid);
                deltaPlusXProd *= (this.PrivateKey + x);
            }

            GroupElement W = RAParameters.gt.Exponentiate((deltaPlusXProd - d) * (PrivateKey + xid).Invert());
            GroupElement Q = Gq.MultiExponentiate(new GroupElement[] { Accumulator, W, RAParameters.gt }, new FieldZqElement[] { Zq.One, xid.Negate(), d.Negate() });

            return(new RevocationWitness(d, W, Q));
        }
 /// <summary>
 /// Create a new object to hold the proof values.
 /// </summary>
 public IDEscrowProof(FieldZqElement c, FieldZqElement rXb, FieldZqElement rR, FieldZqElement rOb)
 {
     this.c   = c;
     this.rXb = rXb;
     this.rR  = rR;
     this.rOb = rOb;
 }
Beispiel #3
0
        /// <summary>
        /// Returns verifier parameters corresponding to prover parameters generated by
        /// GetDateTimeProverParameters.
        /// </summary>
        /// <param name="crypto">Cryptographic parameters.</param>
        /// <param name="commitmentToDayOfYear">Prover supplied commitment to day of year in [0,365].</param>
        /// <param name="commitmentToYear">Prover supplied commitment to year in [minYear, maxYear].</param>
        /// <param name="rangeProofType">Range proof type.</param>
        /// <param name="verifierTargetDate">verifier target date in [minYear, maxYear+1).</param>
        /// <param name="minYear">Used to determine range.  Must be same as used by prover.</param>
        /// <param name="maxYear">Used to determine range.  Must be same as used by prover.</param>
        /// <returns></returns>
        public static VerifierRangeProofParameters GetDateTimeVerifierParameters(CryptoParameters crypto, GroupElement commitmentToYear, GroupElement commitmentToDayOfYear, VerifierRangeProofParameters.ProofType rangeProofType, DateTime verifierTargetDate, int minYear, int maxYear)
        {
            // Compute (commitmentToYear / G^minYear)^366  * commitmentToDayOfYear
            GroupElement[] bases = new GroupElement[]
            {
                commitmentToYear,
                crypto.G
            };
            FieldZqElement[] exponents = new FieldZqElement[]
            {
                crypto.FieldZq.GetElement(366),
                crypto.FieldZq.GetElement((uint)(minYear * 366)).Negate()
            };
            GroupElement commitmentToYearAndDay = crypto.Group.MultiExponentiate(bases, exponents) * commitmentToDayOfYear;


            int maxValue           = (maxYear - minYear) * 366 + 365;
            int verifierYearAndDay = EncodeYearAndDay(verifierTargetDate, minYear);

            return(new VerifierRangeProofParameters(
                       crypto,
                       commitmentToYearAndDay,
                       rangeProofType,
                       verifierYearAndDay,
                       0,
                       maxValue));
        }
        /// <summary>
        ///  This setup method initializes the issuer, do it once and save the IssuerParameters they were used for verifying the issuer later (Verifier / Prover)
        ///  and are used for initiate the issuer at another time
        /// </summary>
        /// <param name="UIDP">issuer identifier</param>
        /// <param name="appSpecification">description for the issuer</param>
        /// <param name="maxNumberOfAttributes">number of attributes which should be supported in a token -> max allowed attributes are 25</param>
        /// <param name="groupType">ECC or Subgroup</param>
        /// <param name="supportDevice">ture, if the issuer allows to protect a token with a hard tokens</param>
        public IssuingIssuer(string UIDP, string appSpecification, int maxNumberOfAttributes,
                             GroupType groupType = GroupType.ECC, bool supportDevice = false)
        {
            isDeviceProtected = supportDevice;
            try
            {
                // max allowed are 50 attributes
                if (maxNumberOfAttributes > 50)
                {
                    throw new Exception("General supported are max 25 attributes");
                }

                IssuerSetupParameters isp = new IssuerSetupParameters(maxNumberOfAttributes);
                isp.UidP = encoding.GetBytes(UIDP);
                isp.S    = encoding.GetBytes(appSpecification);
                isp.GroupConstruction          = groupType;
                isp.UseRecommendedParameterSet = true;

                ikap = isp.Generate(isDeviceProtected);

                privateKey = ikap.PrivateKey;
                string pk     = privateKey.ToBase64String();
                string ipJSON = ikap.IssuerParameters.Serialize();
                LogService.Log(LogService.LogType.Info, "IssuingIssuer - successfully set up. IssuerParameters are: '" + ipJSON + "'");
            }
            catch (Exception e)
            {
                LogService.Log(LogService.LogType.FatalError, "IssuingIssuer - Error during issuer setup.", e);
                throw new CommunicationException("IssuingIssuer - Error during issuer setup", e);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Generates the second issuance message.
        /// </summary>
        /// <param name="message">The first issuance message.</param>
        /// <returns>The second issuance message.</returns>
        public SecondIssuanceMessage GenerateSecondMessage(FirstIssuanceMessage message)
        {
            if (state != State.Initialized)
            {
                throw new InvalidOperationException("Prover not initialized properly");
            }

            Group Gq = ip.Gq;

            this.sigmaZ = message.sigmaZ.Exponentiate(beta0Inverse);        // remove the blind that was included in gamma (if no blind beta0Inverse = 1)

            sigmaZPrime = new GroupElement[numberOfTokens];
            sigmaAPrime = new GroupElement[numberOfTokens];
            sigmaBPrime = new GroupElement[numberOfTokens];
            sigmaCPrime = new FieldZqElement[numberOfTokens];
            FieldZqElement[] sigmaC = new FieldZqElement[numberOfTokens];
            for (int i = 0; i < numberOfTokens; i++)
            {
                FieldZqElement sigmaBExponent = alpha[i].Multiply(beta0Inverse);  // will remove the collab-issuance blind, if present

                sigmaZPrime[i] = this.sigmaZ.Exponentiate(alpha[i]);
                sigmaAPrime[i] = t1[i] * message.sigmaA[i];
                sigmaBPrime[i] = Gq.MultiExponentiate(new GroupElement[] { sigmaZPrime[i], h[i], message.sigmaB[i] }, new FieldZqElement[] { beta1[i], beta2[i], sigmaBExponent });
                HashFunction hash = ip.HashFunction;
                hash.Hash(h[i]);
                hash.Hash(PI);
                hash.Hash(sigmaZPrime[i]);
                hash.Hash(sigmaAPrime[i]);
                hash.Hash(sigmaBPrime[i]);
                sigmaCPrime[i] = ip.Zq.GetElementFromDigest(hash.Digest);
                sigmaC[i]      = sigmaCPrime[i] + beta1[i];
            }
            state = State.Second;
            return(new SecondIssuanceMessage(sigmaC));
        }
        public static void MyClassInitialize(TestContext testContext)
        {
            //
            // generate issuer parameters
            //
            IssuerSetupParameters isp = new IssuerSetupParameters(maxNumberOfAttributes);

            isp.UidP = new byte[] { (byte)0 };
            //isp.NumberOfAttributes = 1;
            isp.E = new byte[] { (byte)0 };  // encode xid directly has an
            IssuerKeyAndParameters ikap = isp.Generate();

            ip = ikap.IssuerParameters;

            //
            // issue a token
            //
            xid = ip.Gq.FieldZq.GetRandomElement(false);
            IssuerProtocolParameters ipp = new IssuerProtocolParameters(ikap);
            ProverProtocolParameters ppp = new ProverProtocolParameters(ip);

            attributes         = new byte[][] { xid.ToByteArray() };
            ipp.Attributes     = ppp.Attributes = attributes;
            ipp.NumberOfTokens = ppp.NumberOfTokens = 1;
            Issuer issuer = ipp.CreateIssuer();
            Prover prover = ppp.CreateProver();

            upkt = prover.GenerateTokens(issuer.GenerateThirdMessage(prover.GenerateSecondMessage(issuer.GenerateFirstMessage())))[0];
        }
Beispiel #7
0
 /// <summary>
 /// Constructs a new <code>ProverRandomData</code> instance.
 /// </summary>
 /// <param name="alpha">An array of alpha values.</param>
 /// <param name="beta1">An array of beta1 values.</param>
 /// <param name="beta2">An array of beta2 values.</param>
 /// <param name="beta0">A beta0 value. Defaults to <code>null</code>.</param>
 public ProverRandomData(FieldZqElement[] alpha, FieldZqElement[] beta1, FieldZqElement[] beta2, FieldZqElement beta0 = null)
 {
     this.beta0 = beta0;
     this.alpha = alpha;
     this.beta1 = beta1;
     this.beta2 = beta2;
 }
        /// <summary>
        /// Checks that the token public key is consistent with the other token values.
        /// </summary>
        /// <returns></returns>
        public bool Validate(GroupElement devicePublicKey)
        {
            // compute H from token manually
            FieldZqElement[] exponents = new FieldZqElement[this.G.Length];
            exponents[0] = this.Alpha;
            for (int i = 0; i < this.NumberOfAttributesXI; ++i)
            {
                exponents[i + 1] = this.AttributeXI(i + 1) * this.Alpha;
            }
            exponents[exponents.Length - 1] = this.AttributeXT * this.Alpha;
            GroupElement expectedPublicKey = this.Group.MultiExponentiate(this.G, exponents);

            // factor in device public key
            if (devicePublicKey != null)
            {
                expectedPublicKey *= devicePublicKey;
            }


            // check public key (this also validates all other elements in token).
            if (this.PublicKey != expectedPublicKey)
            {
                return(false);
            }
            return(true);
        }
        /// <summary>
        /// Creates a UProve token for non-device protected tokens.
        /// </summary>
        /// <param name="pppp">Prover presentation protocol parameters for non-device protected token.</param>
        /// <param name="device">Device information. Required for device protected tokens.</param>
        public OpenUProveToken(ProverPresentationProtocolParameters pppp) : base(null, null, null)
        {
            if (pppp == null)
            {
                throw new ArgumentNullException("UProveToken constructor expects non-null input.");
            }

            this.Group = pppp.IP.Gq;
            this.Bases = new GroupElement[pppp.Attributes.Length + 2];
            for (int i = 0; i < this.G.Length; ++i)
            {
                this.G[i] = pppp.IP.G[i];
            }
            this.Value = pppp.KeyAndToken.Token.H;

            this.Exponents = new FieldZqElement[this.RepresentationLength];
            this.Alpha     = pppp.KeyAndToken.PrivateKey.Invert();

            FieldZqElement [] attributes = new FieldZqElement[pppp.Attributes.Length];
            for (int i = 0; i < attributes.Length; ++i)
            {
                attributes[i] = ProtocolHelper.ComputeXi(pppp.IP, i, pppp.Attributes[i]);
            }
            this.SetAttributeXI(attributes);
            this.AttributeXT = ProtocolHelper.ComputeXt(pppp.IP, pppp.KeyAndToken.Token.TI, pppp.KeyAndToken.Token.IsDeviceProtected);
        }
Beispiel #10
0
 /// <summary>
 /// Takes as input a series of commitments to 0 and 1, and composes them into a single Pedersen commitment:
 /// output.CommittedValue = product (2^i * committedBits[i].CommittedValue)
 /// </summary>
 /// <param name="committedBits">Array of commitments to Zero and One. Each commitment must use the same bases G and H.</param>
 /// <param name="fieldZq">Field corresponding to all PedersenCommitments</param>
 /// <param name="composition">Output paramter.</param>
 /// <returns>True on success, false on failure.</returns>
 private static bool ComposeCommitments(PedersenCommitment[] committedBits, FieldZq fieldZq, out PedersenCommitment composition)
 {
     try
     {
         FieldZqElement        two               = fieldZq.GetElement(2);
         FieldZqElement        powerOfTwo        = fieldZq.One;
         DLRepOfGroupElement[] bitsExpPowerOfTwo = new DLRepOfGroupElement[committedBits.Length];
         for (int i = 0; i < committedBits.Length; ++i)
         {
             bitsExpPowerOfTwo[i] = committedBits[i].Exponentiate(powerOfTwo);
             powerOfTwo           = powerOfTwo * two;
         }
         DLRepOfGroupElement actualComposition;
         bool success = DLRepOfGroupElement.TryStrictMultiply(bitsExpPowerOfTwo, out actualComposition);
         if (success)
         {
             composition = new PedersenCommitment(actualComposition);
             return(true);
         }
     }
     catch (Exception)
     {
         // do nothing
     }
     composition = null;
     return(false);
 }
Beispiel #11
0
        public void GroupDivideTest()
        {
            Group group = ECParameterSets.ParamSet_EC_P384_V1.Group;

            for (int i = 0; i < 10; ++i)
            {
                GroupElement a = group.GetRandomElement(false);
                GroupElement b = group.GetRandomElement(true);
                GroupElement c = group.Divide(a, b);
                Assert.AreEqual <GroupElement>(a * group.Invert(b), c, "a.divide(b).");
            }

            for (int i = 0; i < 20; ++i)
            {
                FieldZqElement a = group.FieldZq.GetRandomElement(true);
                FieldZqElement b = group.FieldZq.GetRandomElement(true);
                Assert.AreEqual(group.G.Exponentiate(a - b), group.Divide(group.G.Exponentiate(a), group.G.Exponentiate(b)));
            }

            FieldZqElement one   = _smallGroup.FieldZq.One;
            FieldZqElement two   = _smallGroup.FieldZq.GetElement(2);
            FieldZqElement three = _smallGroup.FieldZq.GetElement(3);
            FieldZqElement four  = _smallGroup.FieldZq.GetElement(4);
            GroupElement   G     = _smallGroup.G;

            Assert.AreEqual <GroupElement>(_smallGroup.Invert(G), _smallGroup.Divide(G.Exponentiate(two), G.Exponentiate(three)), "G^2/G^3");
            Assert.AreEqual <GroupElement>(G.Exponentiate(two), _smallGroup.Divide(G.Exponentiate(one), G.Exponentiate(four)), "G^1/G^4");
            Assert.AreEqual <GroupElement>(G.Exponentiate(three), _smallGroup.Divide(G.Exponentiate(one), G.Exponentiate(three)), "G^1/G^3");
        }
        public void TestIEEncrypt()
        {
            // Create a commitment and attribute value.
            // Need g, g1, Cxb, xb, ob
            FieldZq        F  = ip.Zq;
            FieldZqElement xb = F.GetRandomElement(true);
            FieldZqElement ob = F.GetRandomElement(true);

            Cxb = ip.Gq.G.Exponentiate(xb);               // Cxb = g^xb
            Cxb = Cxb.Multiply(ip.G[1].Exponentiate(ob)); // Cxb = (g^xb)*(g1^ob)

            // Create the pseudonym (which will be used later to check that decryption is correct)
            PE = ieParam.Ge.Exponentiate(xb);

            // Encrypt
            ctext = IDEscrowFunctions.VerifiableEncrypt(ieParam, pk, tokenID, Cxb, xb, ob, additionalInfo);

            // Serialize
            string ctextStr = ip.Serialize(ctext);

            Assert.IsFalse(ctextStr.Contains(":null"));

            // deserialize and compare
            IDEscrowCiphertext ctext2 = ip.Deserialize <IDEscrowCiphertext>(ctextStr);

            Assert.IsTrue(ctext.Equals(ctext2));
        }
Beispiel #13
0
        /// <summary>
        /// Verifies that a UProve token attribute is not equal to the given attribute value.
        /// </summary>
        /// <param name="verifier">Verifier info about token.</param>
        /// <param name="attributeIndexForVerifier">Target attribute, 1-based index.</param>
        /// <param name="attributeValue">Bad value for attribute.</param>
        /// <returns></returns>
        public bool Verify(
            VerifierPresentationProtocolParameters verifier,
            int attributeIndexForVerifier,
            byte [] attributeValue)
        {
            // Verify UProve Integration Proof
            if (this.UPIProof == null)
            {
                return(false);
            }
            VerifierPresentationProtocolParameters[] verifiers = new VerifierPresentationProtocolParameters[1] {
                verifier
            };
            int[] attributeIndices = new int[1] {
                attributeIndexForVerifier
            };
            if (!this.UPIProof.Verify(verifiers, attributeIndices))
            {
                return(false);
            }

            // Verify Inequality Proof
            FieldZqElement committedAttribute             = ProtocolHelper.ComputeXi(verifier.IP, attributeIndexForVerifier - 1, attributeValue);
            VerifierInequalityProofParameters ieqVerifier = new VerifierInequalityProofParameters(this.UPIProof.PedersenCommitmentValues[0], committedAttribute, new CryptoParameters(verifier.IP));

            return(this.Verify(ieqVerifier));
        }
Beispiel #14
0
        /// <summary>
        /// If verifier knows Integer B, returns the default bit-decomposition. Returns Null if verifier does not know integer B.
        /// If bit[i] = 0, output[i] = verifier.G^0.
        /// If bit[i] = 1, output[i] = verifier.G.
        /// </summary>
        /// <param name="verifier">Verifier parameters.</param>
        /// <returns></returns>
        private static DLRepOfGroupElement[] DefaultOpenDecompositionOfIntegerB(VerifierRangeProofParameters verifier)
        {
            if (!verifier.IntegerBIsKnown)
            {
                return(null);
            }
            FieldZqElement integerB            = verifier.FieldZq.GetElement((uint)verifier.RangeNormalizedIntegerB);
            int            decompositionLength = ComputeDecompositionLength(verifier);
            BitArray       bitsB = VerifierBitDecompositionParameters.GetBitDecomposition(integerB, decompositionLength, verifier.FieldZq);

            PedersenCommitment[] defaultBitDecomposition = new PedersenCommitment[bitsB.Length];
            GroupElement []      bases = new GroupElement [2] {
                verifier.G, verifier.H
            };
            FieldZqElement [] exponent0 = new FieldZqElement[2] {
                verifier.FieldZq.Zero, verifier.FieldZq.Zero,
            };

            FieldZqElement [] exponent1 = new FieldZqElement[2] {
                verifier.FieldZq.One, verifier.FieldZq.Zero,
            };

            for (int i = 0; i < defaultBitDecomposition.Length; ++i)
            {
                if (!bitsB.Get(i))
                {
                    defaultBitDecomposition[i] = new PedersenCommitment(bases, exponent0, verifier.Group);
                }
                else
                {
                    defaultBitDecomposition[i] = new PedersenCommitment(bases, exponent1, verifier.Group);
                }
            }
            return(defaultBitDecomposition);
        }
Beispiel #15
0
        public void InequalityProofSerializationTest()
        {
            for (int i = 0; i < StaticHelperClass.ParameterArray.Length; ++i)
            {
                CryptoParameters   crypto = StaticHelperClass.ParameterArray[i];
                FieldZqElement     x      = crypto.FieldZq.GetElement(1000);
                FieldZqElement     y      = crypto.FieldZq.GetElement(2000);
                PedersenCommitment X      = new PedersenCommitment(x, crypto);
                PedersenCommitment Y      = new PedersenCommitment(y, crypto);

                ProverInequalityProofParameters prover = new ProverInequalityProofParameters(X, Y, crypto);
                InequalityProof proof        = new InequalityProof(prover);
                string          json         = CryptoSerializer.Serialize <InequalityProof>(proof);
                InequalityProof deserialized = CryptoSerializer.Deserialize <InequalityProof>(json);
                Assert.IsTrue(proof.Verify(prover), "Verify proof");
                Assert.AreEqual(proof.A, deserialized.A, "A");
                Assert.AreEqual(proof.B, deserialized.B, "B");

                prover       = new ProverInequalityProofParameters(X, y, crypto);
                proof        = new InequalityProof(prover);
                json         = CryptoSerializer.Serialize <InequalityProof>(proof);
                deserialized = CryptoSerializer.Deserialize <InequalityProof>(json);
                Assert.IsTrue(proof.Verify(prover), "Verify proof");
                Assert.AreEqual(proof.A, deserialized.A, "A");
                Assert.AreEqual(proof.B, deserialized.B, "B");
            }
        }
Beispiel #16
0
        public void InequalityParamsSerializationTest()
        {
            for (int i = 0; i < StaticHelperClass.ParameterArray.Length; ++i)
            {
                CryptoParameters   crypto = StaticHelperClass.ParameterArray[i];
                FieldZqElement     x      = crypto.FieldZq.GetElement(1000);
                FieldZqElement     y      = crypto.FieldZq.GetElement(2000);
                PedersenCommitment X      = new PedersenCommitment(x, crypto);
                PedersenCommitment Y      = new PedersenCommitment(y, crypto);

                VerifierInequalityProofParameters verifier = new VerifierInequalityProofParameters(X.Value, Y.Value, crypto);
                string json = CryptoSerializer.Serialize <VerifierInequalityProofParameters>(verifier);
                VerifierInequalityProofParameters deserialized = CryptoSerializer.Deserialize <VerifierInequalityProofParameters>(json);
                StaticHelperClass.AssertProofParametersAreEqual(verifier, deserialized, "Verifier X Y");

                verifier     = new VerifierInequalityProofParameters(X.Value, y, crypto);
                json         = CryptoSerializer.Serialize <VerifierInequalityProofParameters>(verifier);
                deserialized = CryptoSerializer.Deserialize <VerifierInequalityProofParameters>(json);
                StaticHelperClass.AssertProofParametersAreEqual(verifier, deserialized, "Verifier X value");

                ProverInequalityProofParameters prover = new ProverInequalityProofParameters(X, Y, crypto);
                json = CryptoSerializer.Serialize <ProverInequalityProofParameters>(prover);
                ProverInequalityProofParameters dProver = CryptoSerializer.Deserialize <ProverInequalityProofParameters>(json);
                StaticHelperClass.AssertProofParametersAreEqual(dProver, prover, "Prover X Y");

                prover  = new ProverInequalityProofParameters(X, y, crypto);
                json    = CryptoSerializer.Serialize <ProverInequalityProofParameters>(prover);
                dProver = CryptoSerializer.Deserialize <ProverInequalityProofParameters>(json);
                StaticHelperClass.AssertProofParametersAreEqual(dProver, prover, "Prover X value");
            }
        }
        public void SimpleConstructorTest()
        {
            for (int i = 0; i < _parameters.Length; ++i)
            {
                FieldZqElement committedValue = _parameters[i].FieldZq.GetRandomElement(true);
                GroupElement   g = _parameters[i].G;
                GroupElement   h = _parameters[i].H;

                PedersenCommitment pedCom1 = new PedersenCommitment(committedValue, _parameters[i]);
                FieldZqElement     opening = pedCom1.ExponentAtIndex(1);

                Assert.AreEqual(g, pedCom1.BaseAtIndex(0), "pedcom1 has wrong base_0");
                Assert.AreEqual(h, pedCom1.BaseAtIndex(1), "pedcom1 has wrong base_1");
                Assert.AreEqual(committedValue, pedCom1.CommittedValue, "pedcom1 used wrong committed value");
                GroupElement expectedCommitmentValue = g.Exponentiate(committedValue) * h.Exponentiate(opening);
                Assert.AreEqual(expectedCommitmentValue, pedCom1.Value, "pedcom1 computed wrong value");


                PedersenCommitment pedCom2 = new PedersenCommitment(g, h, committedValue, opening, _parameters[i].Group);
                Assert.AreEqual(pedCom1, pedCom2, "pedcom1 and pedcom2 different");

                FieldZqElement[] exponents = new FieldZqElement[2] {
                    committedValue, opening
                };
                GroupElement[] bases = new GroupElement[2] {
                    g, h
                };
                PedersenCommitment pedCom3 = new PedersenCommitment(bases, exponents, _parameters[i].Group);
                Assert.AreEqual(pedCom1, pedCom3, "pedcom1 and pedcom3 different");
                Assert.AreEqual(pedCom2, pedCom3, "pedcom2 and pedcom3 different");
            }
        }
        public void TestIEWithSerialized()
        {
            // Does a complete encrypt/decrypt sequence from serialized values.
            // Kind of redundant because each of the testmethods above test serialization
            // of individual data types

            //Serialize and deserialize all objects
            IDEscrowParams     ieParam2 = ip.Deserialize <IDEscrowParams>(ip.Serialize(ieParam));
            IDEscrowPublicKey  pk2      = ip.Deserialize <IDEscrowPublicKey>(ip.Serialize(pk));
            IDEscrowPrivateKey sk2      = ip.Deserialize <IDEscrowPrivateKey>(ip.Serialize(sk));

            // Encrypt
            FieldZq        F    = ip.Zq;
            FieldZqElement xb2  = F.GetRandomElement(true);
            FieldZqElement ob2  = F.GetRandomElement(true);
            GroupElement   Cxb2 = ip.Gq.G.Exponentiate(xb2);  // Cxb = g^xb

            Cxb2 = Cxb2.Multiply(ip.G[1].Exponentiate(ob2));  // Cxb = (g^xb)*(g1^ob)
            GroupElement PE2 = ieParam2.Ge.Exponentiate(xb2);

            IDEscrowCiphertext ctext2 = IDEscrowFunctions.VerifiableEncrypt(ieParam2, pk2, tokenID, Cxb2, xb2, ob2, additionalInfo);

            ctext2 = ip.Deserialize <IDEscrowCiphertext>(ip.Serialize(ctext2));

            // Verify
            bool isValid = IDEscrowFunctions.Verify(ieParam2, ctext2, tokenID, pk2, Cxb2);

            Assert.IsTrue(isValid);

            // Decrypt
            GroupElement PEPrime = IDEscrowFunctions.Decrypt(ieParam2, ctext2, sk2);

            Assert.IsTrue(PE2.Equals(PEPrime));
        }
Beispiel #19
0
        /// <summary>
        /// Generates the third issuance message.
        /// </summary>
        /// <param name="message">The second issuance message.</param>
        /// <returnn>The third issuance message.</returnn>
        public ThirdIssuanceMessage GenerateThirdMessage(SecondIssuanceMessage message)
        {
            if (state != State.First)
            {
                throw new InvalidOperationException("GenerateFirstMessage must be called first");
            }

            if (message.sigmaC.Length != numberOfTokens)
            {
                throw new ArgumentException("invalid sigmaC array length");
            }

            FieldZqElement[] sigmaR = new FieldZqElement[message.sigmaC.Length];
            Group            Gq     = ikap.IssuerParameters.Gq;
            FieldZq          Zq     = ikap.IssuerParameters.Zq;

            for (int i = 0; i < message.sigmaC.Length; i++)
            {
                sigmaR[i] = message.sigmaC[i] * ikap.PrivateKey + w[i];
                w[i]      = Zq.Zero;
            }
            w     = null;
            state = State.Third;
            return(new ThirdIssuanceMessage(sigmaR));
        }
        public void CSDLRepArrayTestWithGroup()
        {
            DLRepOfGroupElement[] input          = StaticHelperClass.GenerateRandomDLRepOfGroupElementArray(10, 7, this.paramIndex);
            FieldZqElement[][]    inputExponents = new FieldZqElement[10][];
            for (int dlIndex = 0; dlIndex < 10; ++dlIndex)
            {
                inputExponents[dlIndex] = new FieldZqElement[7];
                for (int exponentIndex = 0; exponentIndex < 7; ++exponentIndex)
                {
                    inputExponents[dlIndex][exponentIndex] = input[dlIndex].ExponentAtIndex(exponentIndex);
                }
            }


            string[] serializedTT          = CryptoSerializer.Serialize(input, true, true);
            DLRepOfGroupElement[] outputTT = CryptoSerializer.Deserialize <DLRepOfGroupElement>(serializedTT, null, null);
            StaticHelperClass.AssertArraysAreEqual(input, outputTT, "outputTT");

            string[]              serializedNT = CryptoSerializer.Serialize(input, true, false);
            GroupElement[]        newBases     = StaticHelperClass.GenerateRandomBases(input[0].RepresentationLength, this.paramIndex);
            DLRepOfGroupElement[] outputNT     = CryptoSerializer.Deserialize <DLRepOfGroupElement>(serializedNT, null, newBases);
            Assert.AreEqual(input.Length, outputNT.Length, "outputNT.Length");
            for (int i = 0; i < outputNT.Length; ++i)
            {
                DLRepOfGroupElement expected = new DLRepOfGroupElement(newBases, inputExponents[i], this.crypto.Group);
                expected.Value = input[i].Value;
                Assert.AreEqual(expected, outputNT[i], "outputNT " + i);
            }

            FieldZqElement[] commitments = StaticHelperClass.GenerateRandomExponents(10, this.paramIndex);
            FieldZqElement[] openings    = StaticHelperClass.GenerateRandomExponents(10, this.paramIndex);
            input = PedersenCommitment.GetCommitments(this.crypto, commitments, openings);
        }
        public void BDSerializationTest()
        {
            FieldZqElement     bigNum               = _parameters[0].FieldZq.GetElement(2056);
            PedersenCommitment bigNumCommit         = new PedersenCommitment(bigNum, _parameters[0]);
            int decompositionLength                 = 15;
            ProverBitDecompositionParameters prover = new ProverBitDecompositionParameters(
                bigNumCommit,
                decompositionLength,
                _parameters[0]);

            BitDecompositionProof proof = new BitDecompositionProof(prover);

            Assert.IsTrue(proof.Verify(prover), "original proof verification.");
            string jsonProof = CryptoSerializer.Serialize <BitDecompositionProof>(proof);
            // TODO: switch to using ip-based de-serialization; need to harmonize with U-Prove SDK code
            IssuerParameters ip = new IssuerParameters();

            ip.Gq = prover.Group;
            BitDecompositionProof deserializedProof = ip.Deserialize <BitDecompositionProof>(jsonProof);// CryptoSerializer.Deserialize<BitDecompositionProof>(jsonProof);

            Assert.IsTrue(deserializedProof.Verify(prover), "deserialized proof verfication");


            string jsonProver = CryptoSerializer.Serialize <ProverBitDecompositionParameters>(prover);
            ProverBitDecompositionParameters deserializedProver = CryptoSerializer.Deserialize <ProverBitDecompositionParameters>(jsonProver);

            Assert.IsTrue(deserializedProof.Verify(deserializedProver), "deserialized proof with deserialized prover.");

            BitDecompositionProof proof2 = new BitDecompositionProof(deserializedProver);

            Assert.IsTrue(proof2.Verify(deserializedProver), "proof2.verify(deserializedProver)");
            Assert.IsTrue(proof2.Verify(prover), "Proof2.verify(prover)");
        }
        public void BDBadProofTest()
        {
            FieldZqElement     bigNum       = _parameters[0].FieldZq.GetElement(30);
            PedersenCommitment bigNumCommit = new PedersenCommitment(bigNum, _parameters[0]);
            int decompositionLength         = 8;


            ProverBitDecompositionParameters proverParams = new ProverBitDecompositionParameters(
                bigNumCommit,
                decompositionLength,
                _parameters[0]);
            BitDecompositionProof proof         = new BitDecompositionProof(proverParams);
            PrivateObject         proofAccessor = new PrivateObject(proof);

            SetMembershipProof[] smProof    = (SetMembershipProof[])proofAccessor.GetField("bitCommitmentProof");
            SetMembershipProof[] badSmProof = smProof;
            SetMembershipProof   tmp        = smProof[1];

            badSmProof[1] = badSmProof[0];
            proofAccessor.SetFieldOrProperty("bitCommitmentProof", badSmProof);
            Assert.IsFalse(proof.Verify(proverParams), "bad set membeship proof.");
            proofAccessor.SetFieldOrProperty("bitCommitmentProof", smProof);
            smProof[1] = tmp;
            Assert.IsTrue(proof.Verify(proverParams), "good set membership proof.");

            EqualityProof eqProof         = (EqualityProof)proofAccessor.GetField("compositionProof");
            PrivateObject eqProofAccessor = new PrivateObject(eqProof);

            GroupElement [] b = (GroupElement[])eqProofAccessor.GetField("b");
            b[1] = b[0];
            eqProofAccessor.SetField("b", b);
            Assert.IsFalse(proof.Verify(proverParams), "bad equality proof");
        }
Beispiel #23
0
        /// <summary>
        /// Generates the second issuance message.
        /// </summary>
        /// <param name="message">The first issuance message.</param>
        /// <returns>The second issuance message.</returns>
        public SecondIssuanceMessage GenerateSecondMessage(FirstIssuanceMessage message)
        {
            if (state != State.Initialized)
            {
                throw new InvalidOperationException("Prover not initialized properly");
            }

            Group Gq = ip.Gq;

            this.sigmaZ = message.sigmaZ;

            sigmaZPrime = new GroupElement[numberOfTokens];
            sigmaAPrime = new GroupElement[numberOfTokens];
            sigmaBPrime = new GroupElement[numberOfTokens];
            sigmaCPrime = new FieldZqElement[numberOfTokens];
            FieldZqElement[] sigmaC = new FieldZqElement[numberOfTokens];
            for (int i = 0; i < numberOfTokens; i++)
            {
                FieldZqElement blindingExponent = alpha[i];
                sigmaZPrime[i] = message.sigmaZ.Exponentiate(blindingExponent);
                sigmaAPrime[i] = t1[i] * message.sigmaA[i];
                sigmaBPrime[i] = sigmaZPrime[i].Exponentiate(beta1[i]) * t2[i] * message.sigmaB[i].Exponentiate(blindingExponent);

                HashFunction hash = ip.HashFunction;
                hash.Hash(h[i]);
                hash.Hash(PI);
                hash.Hash(sigmaZPrime[i]);
                hash.Hash(sigmaAPrime[i]);
                hash.Hash(sigmaBPrime[i]);
                sigmaCPrime[i] = ip.Zq.GetElementFromDigest(hash.Digest);
                sigmaC[i]      = sigmaCPrime[i] + beta1[i];
            }
            state = State.Second;
            return(new SecondIssuanceMessage(sigmaC));
        }
Beispiel #24
0
        /// <summary>
        /// Get the issuance state after the second message generation.
        /// </summary>
        /// <returns>The issuance state after the second message generation.</returns>
        public PostSecondMessageState ExportPostSecondMessageState()
        {
            if (state != State.Second)
            {
                throw new InvalidOperationException("GenerateSeondMessage must be called first");
            }

            PostSecondMessageState psms = new PostSecondMessageState();

            psms.TI = TI;
            psms.PI = PI;
            FieldZqElement[] alphaInverse = new FieldZqElement[numberOfTokens];
            for (int i = 0; i < numberOfTokens; i++)
            {
                alphaInverse[i] = ukat[i].PrivateKey;
            }
            psms.AlphaInverse      = alphaInverse;
            psms.Beta2             = beta2;
            psms.H                 = h;
            psms.SigmaZPrime       = sigmaZPrime;
            psms.SigmaAPrime       = sigmaAPrime;
            psms.SigmaBPrime       = sigmaBPrime;
            psms.SigmaCPrime       = sigmaCPrime;
            psms.IsDeviceProtected = isDeviceProtected;

            // we update the state so this object cannot be used by mistake to complete the issuance
            // (we don't want the same randomizers to be used twice on two issuer-provided messages)
            state = State.Tokens;

            return(psms);
        }
 /// <summary>
 /// Constructs a non-revocation proof instance.
 /// </summary>
 /// <param name="cPrime">The <c>c'</c> value.</param>
 /// <param name="s">The <c>s</c> value.</param>
 /// <param name="X">The <c>X</c> value.</param>
 /// <param name="Y">The <c>Y</c> value.</param>
 /// <param name="Cd">The <c>Cd</c> value.</param>
 public NonRevocationProof(FieldZqElement cPrime, FieldZqElement[] s, GroupElement X, GroupElement Y, GroupElement Cd)
 {
     if (cPrime == null)
     {
         throw new ArgumentNullException("cPrime");
     }
     this.cPrime = cPrime;
     if (s == null || s.Length != 6)
     {
         throw new ArgumentException("s");
     }
     this.s = s;
     if (X == null)
     {
         throw new ArgumentNullException("X");
     }
     this.X = X;
     if (Y == null)
     {
         throw new ArgumentNullException("Y");
     }
     this.Y = Y;
     if (Cd == null)
     {
         throw new ArgumentNullException("Cd");
     }
     this.Cd = Cd;
 }
        /// <summary>
        /// Helper method for constructing proof. Computes a[index], c[index], r[index] values for when
        /// the committedValue is not equal to prover.MemberSet[index].
        /// </summary>
        /// <param name="index">Index into prover.MemberSet</param>
        /// <param name="prover">Prover parameters</param>
        /// <param name="randomChallengeValue">Value to set c[index]</param>
        /// <param name="randomResponseValue">Value to set r[index]</param>
        private void generateFakeProof(int index, ProverSetMembershipParameters prover, FieldZqElement randomChallengeValue, FieldZqElement randomResponseValue)
        {
            if (index < this.c.Length)
            {
                this.c[index] = randomChallengeValue;
            }

            this.r[index] = randomResponseValue;

            // compute this.a[index] as a multi-exponentiation
            // a[index] = h^r[index] * g^{memberset[index] + c[index]} * X^{-c[index]
            GroupElement[] bases = new GroupElement[3]
            {
                prover.H,                         // h
                prover.G,                         // g
                prover.ClosedCommitment           // X
            };
            FieldZqElement[] exponents = new FieldZqElement[3]
            {
                randomResponseValue,                            // r[index]
                prover.MemberSet[index] * randomChallengeValue, // memberset[index] * c
                randomChallengeValue.Negate()                   // -c
            };
            this.a[index] = prover.Group.MultiExponentiate(bases, exponents);
        }
Beispiel #27
0
 /// <summary>
 /// Constructs a new <code>IDEscrowProofGenerationRandomData</code> instance.
 /// </summary>
 /// <param name="r">The <code>r</code> value.</param>
 /// <param name="xbPrime">The <code>xbPrime</code> values.</param>
 /// <param name="rPrime">The <code>rPrime</code> value.</param>
 /// <param name="obPrime">The <code>obPrime</code> value.</param>
 public IDEscrowProofGenerationRandomData(FieldZqElement r, FieldZqElement xbPrime, FieldZqElement rPrime, FieldZqElement obPrime)
 {
     this.r       = r;
     this.xbPrime = xbPrime;
     this.rPrime  = rPrime;
     this.obPrime = obPrime;
 }
Beispiel #28
0
        public void InequalityParamUnknownValueTest()
        {
            CryptoParameters crypto = StaticHelperClass.ParameterArray[1];
            FieldZqElement   x      = crypto.FieldZq.GetRandomElement(false);
            FieldZqElement   y      = x + crypto.FieldZq.One;

            // inequality does not hold
            PedersenCommitment X    = new PedersenCommitment(x, crypto);
            PedersenCommitment Y    = new PedersenCommitment(y, crypto);
            PedersenCommitment badY = new PedersenCommitment(x, crypto);
            ProverInequalityProofParameters badProver = new ProverInequalityProofParameters(X, badY, crypto);

            Assert.IsFalse(badProver.Verify(), "x=y");

            // X uses wrong bases
            PedersenCommitment badX = new PedersenCommitment(crypto.H, crypto.G, x, x, crypto.Group);

            badProver = new ProverInequalityProofParameters(badX, Y, crypto);
            Assert.IsFalse(badProver.Verify(), "bad bases in X");

            // Y uses wrong bases
            badProver = new ProverInequalityProofParameters(Y, badX, crypto);
            Assert.IsFalse(badProver.Verify(), "bad bases in Y");

            //good parameters ok
            ProverInequalityProofParameters prover = new ProverInequalityProofParameters(X, Y, crypto);

            Assert.IsTrue(prover.Verify(), "prover verify");
            VerifierInequalityProofParameters verifier = new VerifierInequalityProofParameters(X.Value, Y.Value, crypto);

            Assert.IsTrue(verifier.Verify(), "verifier ok.");
        }
Beispiel #29
0
        /// <summary>
        /// Verifies a U-Prove token signature.
        /// </summary>
        /// <param name="ip">The Issuer parameters corresponding to the U-Prove token.</param>
        /// <param name="upt">The U-Prove token to verify.</param>
        /// <exception cref="InvalidUProveArtifactException">If the U-Prove token is invalid.</exception>
        public static void VerifyTokenSignature(IssuerParameters ip, UProveToken upt)
        {
            Group   Gq = ip.Gq;
            FieldZq Zq = ip.Zq;

            if (upt.H == Gq.Identity)
            {
                throw new InvalidUProveArtifactException("Invalid U-Prove token (public key H = 1)");
            }
            GroupElement[]   bases     = new GroupElement[2];
            FieldZqElement[] exponents = new FieldZqElement[2];

            HashFunction hash = ip.HashFunction;

            hash.Hash(upt.H);
            hash.Hash(upt.PI);
            hash.Hash(upt.SigmaZPrime);
            bases[0] = Gq.G; exponents[0] = upt.SigmaRPrime;
            bases[1] = ip.G[0]; exponents[1] = upt.SigmaCPrime.Negate();
            hash.Hash(Gq.MultiExponentiate(bases, exponents));
            bases[0] = upt.H; exponents[0] = upt.SigmaRPrime;
            bases[1] = upt.SigmaZPrime; exponents[1] = upt.SigmaCPrime.Negate();
            hash.Hash(Gq.MultiExponentiate(bases, exponents));
            if (upt.SigmaCPrime != Zq.GetElementFromDigest(hash.Digest))
            {
                throw new InvalidUProveArtifactException("Invalid U-Prove token signature");
            }
        }
        /// <summary>
        /// Verifies that the given (commitment, challenge, response) values are a
        /// valid proof for this object.  See IOpenEquation for how commitment and response are generated.
        /// </summary>
        /// <param name="challenge">The challenge for this proof (second step in Sigma protocol).</param>
        /// <param name="responseValues">The response (third step in Sigma protocol).</param>
        /// <param name="commitment">The commitment (first step in Sigma protocol).</param>
        /// <returns></returns>
        public override bool Verify(GroupElement commitment, FieldZqElement challenge, FieldZqElement[] response)
        {
            if ((response == null) || (response.Length != this.RepresentationLength))
            {
                return(false);
            }

            GroupElement[]   bases     = new GroupElement[this.RepresentationLength + 1];
            FieldZqElement[] exponents = new FieldZqElement[this.RepresentationLength + 1];
            for (int i = 0; i < response.Length; ++i)
            {
                bases[i]     = this.BaseAtIndex(i);
                exponents[i] = response[i];
            }
            exponents[0] = challenge.Negate();
            bases[this.RepresentationLength]     = this.PublicKey;
            exponents[this.RepresentationLength] = response[0];

            GroupElement verifier = this.Group.MultiExponentiate(bases, exponents);

            if (commitment != verifier)
            {
                return(false);
            }
            return(true);
        }
 /// <summary>
 /// Add the value to this value and return the result.
 /// </summary>
 /// <param name="e">The value to add to this value.</param>
 /// <returns>This value plus e.</returns>
 public override FieldZqElement Add(FieldZqElement e)
 {
     return new FieldZqElementBCImpl(i.Add((e as FieldZqElementBCImpl).i) % field.modulus, field);
 }
        /// <summary>
        /// Returns true if the given element is an element from this field.
        /// </summary>
        /// <param name="element">The element to check.</param>
        /// <returns>True if the given element is an element from this field.</returns>
        public override bool IsElement(FieldZqElement element)
        {
            FieldZqElementBCImpl xdImpl = element as FieldZqElementBCImpl;
            if (xdImpl == null)
            {
                throw new ArgumentNullException();
            }

            if (((xdImpl.field) as FieldZqBCImpl).modulus != modulus)
            {
                return false;
            }

            if (xdImpl.i < BCBigInt.Zero || xdImpl.i >= this.modulus)
            {
                return false;
            }

            return true;

        }
 /// <summary>
 /// Returns <code>this^exponent</code>.
 /// </summary>
 /// <param name="exponent">The exponent.</param>
 /// <returns>A group element.</returns>
 public override GroupElement Exponentiate(FieldZqElement exponent)
 {
     return new ECGroupElementBCImpl(
         Point.Multiply( (exponent as FieldZqElementBCImpl).i) as FpPoint );
 }
 /// <summary>
 /// Multiply this element by the element e.
 /// </summary>
 /// <param name="e">The value to multiply this value by.</param>
 /// <returns>The value of this * e.</returns>
 public override FieldZqElement Multiply(FieldZqElement e)
 {
     return new FieldZqElementBCImpl(i.Multiply((e as FieldZqElementBCImpl).i) % field.modulus, field);
 }
 /// <summary>
 /// Bouncy castle implementation of multi-exponentiation.
 /// </summary>
 /// <param name="g">bases</param>
 /// <param name="f">exponents</param>
 /// <returns></returns>
 public override GroupElement MultiExponentiate(GroupElement[] g, FieldZqElement[] f)
 {
     if (g == null || f == null || g.Length != f.Length)
     {
         throw new ArgumentException("g and f must be non-null and of the same length");
     }
     GroupElement value = Identity;
     for (int i = 0; i < g.Length; i++)
     {
         value *= g[i].Exponentiate(f[i]);
     }
     return value;
 }
 /// <summary>
 /// Exponentiate this value to the exponent power.
 /// </summary>
 /// <param name="exponent">The exponent to raise this value to.</param>
 /// <returns>This value to the exponent power.</returns>
 public override FieldZqElement ModPow(FieldZqElement exponent)
 {
     return new FieldZqElementBCImpl(i.ModPow((exponent as FieldZqElementBCImpl).i, field.modulus), field);
 }
 public override GroupElement Exponentiate(FieldZqElement exponent)
 {
     return new SubgroupGroupElementBCImpl(i.ModPow(((FieldZqElementBCImpl)exponent).i, p), p);
 }