/// <summary> Equality check between this <c>IDEscrowParams</c> and another.</summary>
        /// <remarks> Since IssuerParameters does not implement Equals, we only
        /// compare the UIDp of the issuer params.  Same for <c>GroupDescription</c>,
        /// so we only compare the group name. </remarks>
        /// <returns> <c>true</c> if equal, <c>false</c> otherwise </returns>
        public bool Equals(IDEscrowParams iep)
        {
            if (iep == null)
            {
                return(false);
            }

            // compare the UIDp field of issuer params only
            if (!ip.UidP.SequenceEqual(iep.ip.UidP))
            {
                return(false);
            }
            if (!G.GroupName.Equals(iep.G.GroupName))
            {
                return(false);
            }
            if (!ge.Equals(iep.Ge))
            {
                return(false);
            }

            // Note: we don't have a good way to compare hash functions, but
            // if the issuer parameters are the same the hash functions should be too

            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// Verifies that an <c>IECiphertext</c> was computed correctly.
        /// </summary>
        /// <param name="param">Paramters of the ID escrow scheme.</param>
        /// <param name="ctext"> A ciphertext created with <c>param</c> and <c>pk</c>.</param>
        /// <param name="tokenID">The ID of the U-Prove token this ciphertext is assocaited with.</param>
        /// <param name="pk">Public key of the Auditor (the authority who can decrypt <c>ctext</c>).</param>
        /// <param name="Cxb"> The commitment value (commitment to x_b, with bases g, g1).</param>
        /// <returns><c>true</c> if the ciphertext is valid, and <c>false</c> otherwise.</returns>
        /// <remarks>
        /// The input <c>pk</c> is assumed to be valid, coming from a
        /// trusted source (e.g., a certificate or a trusted store of parameters), and that they
        /// are consistent with the group specified by <c>param</c>.
        /// </remarks>
        public static bool Verify(IDEscrowParams param, IDEscrowCiphertext ctext, byte[] tokenID, IDEscrowPublicKey pk, GroupElement Cxb)
        {
            GroupElement g  = param.ip.Gq.G;   // first base for commitment
            GroupElement g1 = param.ip.G[1];   // second base for commitment

            if (param == null || ctext == null || tokenID == null || pk == null || Cxb == null || g == null || g1 == null)
            {
                throw new ArgumentNullException("null input to Verify");
            }
            if (tokenID.Length == 0)
            {
                throw new ArgumentOutOfRangeException("tokenID has length 0");
            }

            Group         G     = param.ip.Gq;
            FieldZq       F     = param.Zq;
            IDEscrowProof proof = ctext.proof;

            // [1.]Checks on inputs.  These should be done during deserialization -- but we do
            // them explicitly anyway, in case they were missed
            if (!IsGroupElement(G, ctext.E1) || !IsGroupElement(G, ctext.E2) || !IsGroupElement(G, Cxb))
            {
                return(false);
            }

            if (!F.IsElement(proof.c) || !F.IsElement(proof.rOb) ||
                !F.IsElement(proof.rR) || !F.IsElement(proof.rXb))
            {
                return(false);
            }

            // [2.] Recompute inputs to hash (using tilde{x} instead of x'' for this section.)
            GroupElement tildeCxb = G.MultiExponentiate(
                new GroupElement[] { g, g1, Cxb },
                new FieldZqElement[] { proof.rXb, proof.rOb, proof.c }); // tildeCxb = (g^rXb)*(g1^rOb)*(Cxb^c)


            GroupElement tildeE1 = G.MultiExponentiate(
                new GroupElement[] { param.Ge, ctext.E1 },
                new FieldZqElement[] { proof.rR, proof.c }); // tildeE1 = (E1^c)*(ge^rR)

            GroupElement tildeE2 = G.MultiExponentiate(
                new GroupElement[] { param.Ge, pk.H, ctext.E2 },
                new FieldZqElement[] { proof.rXb, proof.rR, proof.c }); // tildeE2 = (ge^rXb)*(H^rR)*(E2^c)

            // [3.]
            FieldZqElement cPrime = ComputeChallenge(param.ip, tokenID, pk, Cxb, ctext.E1, ctext.E2, tildeCxb, tildeE1, tildeE2, ctext.additionalInfo);

            // [4.]
            if (cPrime.Equals(proof.c))
            {
                return(true);
            }

            return(false);
        }
Beispiel #3
0
        /// <summary>
        /// Create a verifiable encryption of a pseudonym.  The output IECiphertext
        /// object will contain the ciphertext and proof that it was formed correctly.
        /// The pseudonym that is encrypted is (param.Ge)^(x_b), where x_b is an attribute
        /// from the token.
        /// </summary>
        /// <param name="param"> Paramters of the ID escrow scheme.</param>
        /// <param name="pk"> Public key of the Auditor (the authority who can decrypt the output ciphertex).</param>
        /// <param name="tokenID"> The ID of the U-Prove token this ciphertext is assocaited with.</param>
        /// <param name="Cxb"> The commitment value (commitment to x_b, with bases g, g1).</param>
        /// <param name="x_b"> The attributed commited to by <c>Cxb</c></param>
        /// <param name="o_b"> The randomizer value used to create <c>Cxb</c></param>
        /// <param name="additionalInfo"> Arbitrary data that will be cryptographically bound to the ciphertext,
        ///   but <b>NOT</b> encrypted, and will be included with the output ciphertext.
        ///   The integrity of the <c>additionalInfo</c> is protected, i.e., modifying
        ///   the <c>additionalInfo</c> included in the ciphertext will cause verification/decryption to fail.
        ///   The <c>additionalInfo</c> field is sometimes referred to in the cryptographic literature
        ///   as a <i>label</i>. </param>
        /// <param name="preGenRandom">Optional pre-generated random values to be used in the protocol.
        /// Set to <c>null</c> if unused.  The primary use of this field is for testing with test vectors.</param>
        /// <returns>An <c>IECiphertext</c> object with the ciphertext and proof.</returns>
        /// <remarks>
        /// The additionalInfo field may be null to signify that there is no input, all other input
        /// paramters must be non-null.
        ///
        /// Input validation is limited to checking for non-null. We assume that all group & field elements are consistent
        /// with the parameters specified by the IdEscrowParams.
        /// </remarks>
        public static IDEscrowCiphertext VerifiableEncrypt(IDEscrowParams param, IDEscrowPublicKey pk, byte[] tokenID, GroupElement Cxb,
                                                           FieldZqElement x_b, FieldZqElement o_b, byte[] additionalInfo, IDEscrowProofGenerationRandomData preGenRandom = null)
        {
            // Notation & numbering follows draft spec -- subject to change.
            GroupElement g  = param.ip.Gq.G; // first base for commitment Cxb
            GroupElement g1 = param.ip.G[1]; // second base for Cxb

            if (param == null || pk == null || tokenID == null || Cxb == null || g == null || g1 == null || x_b == null || o_b == null)
            {
                throw new ArgumentNullException("Null input to VerifiableEncrypt");
            }
            if (tokenID.Length == 0)
            {
                throw new ArgumentOutOfRangeException("tokenID has length 0");
            }

            Group   G = param.G;
            FieldZq F = param.Zq;

            if (preGenRandom == null || preGenRandom.HasNullValue())
            {
                preGenRandom = IDEscrowProofGenerationRandomData.Generate(F);
            }

            // [1.] Encrypt
            // Compute E1
            FieldZqElement r  = preGenRandom.R;
            GroupElement   E1 = param.Ge.Exponentiate(r);       // E1 = (g_e)^r

            // Compute E2 = (g_e)^x_b * H^r
            GroupElement E2 = G.MultiExponentiate(new GroupElement[] { pk.H, param.Ge }, new FieldZqElement[] { r, x_b });

            // [2.] Generate proof of correctness
            // [2.a]
            FieldZqElement xbPrime = preGenRandom.XbPrime;
            FieldZqElement rPrime  = preGenRandom.RPrime;
            FieldZqElement obPrime = preGenRandom.ObPrime;

            // [2.b]
            GroupElement CxbPrime = G.MultiExponentiate(new GroupElement[] { g, g1 }, new FieldZqElement[] { xbPrime, obPrime });         // Cxb' = (g^xb')*(g1^ob')
            GroupElement E1Prime  = param.Ge.Exponentiate(rPrime);                                                                        // E1' = (ge)^r'
            GroupElement E2Prime  = G.MultiExponentiate(new GroupElement[] { param.Ge, pk.H }, new FieldZqElement[] { xbPrime, rPrime }); // E2' = ((g_e)^xb')*(H^r')

            // [2.c]
            FieldZqElement c = ComputeChallenge(param.ip, tokenID, pk, Cxb, E1, E2, CxbPrime, E1Prime, E2Prime, additionalInfo);

            // [2.d]
            FieldZqElement rXb = ComputeResponse(xbPrime, c, x_b);
            FieldZqElement rR  = ComputeResponse(rPrime, c, r);
            FieldZqElement rOb = ComputeResponse(obPrime, c, o_b);

            IDEscrowProof      proof = new IDEscrowProof(c, rXb, rR, rOb);
            IDEscrowCiphertext ctext = new IDEscrowCiphertext(E1, E2, proof, additionalInfo);

            return(ctext);
        }
        /// <summary>
        ///  Verify that this public key is consistent with the parameters.
        /// </summary>
        /// <param name="param">paramters of ID escrow scheme. </param>
        /// <returns></returns>
        public bool Verify(IDEscrowParams param)
        {
            try
            {
                param.ip.Gq.ValidateGroupElement(h);
            }
            catch
            {
                return(false);
            }

            return(true);
        }
        /// <summary>
        ///  Checks that <c>sk</c> is consistent with this public key and <c>param</c>.
        /// </summary>
        /// <returns><c>true</c> if valid, <c>false</c> otherwise.</returns>
        public bool Verify(IDEscrowParams param, IDEscrowPrivateKey sk)
        {
            if (!param.ip.Zq.IsElement(sk.X))  // is x in the right field?
            {
                return(false);
            }

            GroupElement hPrime = param.Ge.Exponentiate(sk.X);

            if (!hPrime.Equals(h))                      // is h = ge^x ?
            {
                return(false);
            }

            return(true);
        }
Beispiel #6
0
        /// <summary>
        ///  Verifies that an <c>IECiphertext</c> was computed correctly.
        ///  This is a wrapper around <c>IEFunctions.Verify</c> for use with U-Prove.
        /// </summary>
        /// <param name="escrowParams">Parameters of the ID escrow scheme</param>
        /// <param name="ctext">A ciphertext created with <c>param</c> and <c>pk</c>. </param>
        /// <param name="proof">The associated U-Prove presentation proof.</param>
        /// <param name="token">The associated U-Prove token.</param>
        /// <param name="pk">The auditor's public key</param>
        /// <returns> True if the ciphertext is valid, false if it is invalid.</returns>
        /// <remarks>The identity <b>must be</b> the first committed attribute in the proof (as
        /// in <c>UProveVerifiableEncrypt</c>).</remarks>
        public static bool UProveVerify(IDEscrowParams escrowParams, IDEscrowCiphertext ctext, PresentationProof proof, UProveToken token, IDEscrowPublicKey pk)
        {
            if (escrowParams == null || ctext == null || proof == null || token == null || pk == null)
            {
                throw new ArgumentException("null input to UProveVerify");
            }

            if (proof.Commitments == null || proof.Commitments.Length < 1)
            {
                throw new InvalidUProveArtifactException("invalid inputs to UProveVerifiableEncrypt");
            }

            GroupElement Cx1 = proof.Commitments[0].TildeC;

            byte[] tokenId = ProtocolHelper.ComputeTokenID(escrowParams.ip, token);
            return(IDEscrowFunctions.Verify(escrowParams, ctext, tokenId, pk, Cx1));
        }
Beispiel #7
0
        /// <summary>
        /// Decrypts an ID escrow ciphertext without verifying the proof.
        /// The proof must be verified by <c>IEFunctions.Verify</c> before decryption.
        /// The IEVerifier verification step also checks the validity of
        /// the ciphertext.
        /// </summary>
        /// <param name="ctext">Ciphertext to be decrypted</param>
        /// <param name="sk"> Decryption key.</param>
        /// <param name="ip"> Issuer paramters associated with the ID escrow scheme.</param>
        /// <returns></returns>
        /// <remarks>
        /// Semantic verification of the label (the <c>additionalInfo</c> field of <c>ctext</c>),
        /// i.e., whether it makes sense for the application is assumed to be done out-of-band.
        /// For example, the application may check that the label includes a timestamp, and that
        /// this timestamp falls within a given interval.
        ///
        /// The IssuerParameters for decryption should match the issuer paramters used to create
        /// the IEParam object used for decryption (i.e., IEParam.ip).
        /// </remarks>
        public static GroupElement Decrypt(IDEscrowParams param, IDEscrowCiphertext ctext, IDEscrowPrivateKey sk)
        {
            if (ctext == null || sk == null || param == null)
            {
                throw new ArgumentNullException("null input to Decrypt");
            }

            Group G = param.ip.Gq;

            if (!IsGroupElement(G, ctext.E1) || !IsGroupElement(G, ctext.E2))   // this should never fail if Verify is called first, but we check again anyway.
            {
                throw new ArgumentException("E1 or E2 is not a valid group element in Decrypt");
            }

            GroupElement PE = ctext.E1.Exponentiate(sk.X.Negate());   // PE = E1^(-x) = H^(-r)

            PE = PE.Multiply(ctext.E2);                               // PE = E2/E1^(x)
            return(PE);
        }
Beispiel #8
0
        /// <summary>
        /// Create a verifiable encryption of a pseudonym based on a U-Prove presentation proof.  This is a wrapper
        /// of <c>VerifiableEncrypt</c>.
        ///
        /// </summary>
        /// <param name="escrowParams"> Parameters of the ID escrow scheme</param>
        /// <param name="escrowPublicKey">  Public key of the Auditor (the authority who can decrypt the output ciphertex).</param>
        /// <param name="token"> The U-Prove token corresponding to the <c>proof</c>. </param>
        /// <param name="additionalInfo">See documentation of <c>VerifiableEncrypt</c></param>
        /// <param name="proof">A U-Prove prsentation proof.</param>
        /// <param name="cpv">Commitment opening information, output when generating <c>proof</c>.</param>
        /// <param name="idAttributeIndex"> Index of the attribute to use for identity escrow (1-based indexing). This attribute <b>must be</b>
        ///                                 the first commited attribute (take care if using multiple extensions). </param>
        /// <param name="attributes"> Attributes in <c>token</c>.</param>

        /// <returns></returns>
        public static IDEscrowCiphertext UProveVerifableEncrypt(IDEscrowParams escrowParams, IDEscrowPublicKey escrowPublicKey,
                                                                UProveToken token, byte[] additionalInfo, PresentationProof proof,
                                                                CommitmentPrivateValues cpv, int idAttributeIndex, byte[][] attributes)
        {
            if (token == null || escrowParams == null || proof == null || cpv == null)
            {
                throw new ArgumentNullException("null input to UProveVerifiableEncrypt");
            }

            if (proof.Commitments == null || proof.Commitments.Length < 1 ||
                attributes.Length < idAttributeIndex || cpv.TildeO == null || cpv.TildeO.Length < 1)
            {
                throw new InvalidUProveArtifactException("invalid inputs to UProveVerifiableEncrypt");
            }


            byte[]         tokenId = ProtocolHelper.ComputeTokenID(escrowParams.ip, token);
            GroupElement   Cx1     = proof.Commitments[0].TildeC;                                                                       // x1 is the first committed attribute
            FieldZqElement x1      = ProtocolHelper.ComputeXi(escrowParams.ip, idAttributeIndex - 1, attributes[idAttributeIndex - 1]); // arrays are 0-based
            FieldZqElement tildeO1 = cpv.TildeO[0];

            return(IDEscrowFunctions.VerifiableEncrypt(escrowParams, escrowPublicKey, tokenId, Cx1, x1, tildeO1, additionalInfo));
        }
 /// <summary>
 ///  Generates a new, random, private key.
 /// </summary>
 /// <remarks>The random number generator used is the one associated
 ///  with <c>iep</c> (indirectly, via the <c>IssuerParamters</c>).
 ///  </remarks>
 public IDEscrowPrivateKey(IDEscrowParams iep)
 {
     UProveCrypto.Math.FieldZq F = iep.ip.Zq;
     x = F.GetRandomElement(true);
 }
 /// <summary>
 ///  Constructs a public key from the private key.
 /// </summary>
 public IDEscrowPublicKey(IDEscrowParams param, IDEscrowPrivateKey priv)
 {
     h = param.Ge.Exponentiate(priv.X);       // H = (g_e)^x
 }