Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

mqv.h
Go to the documentation of this file.

    00001 #ifndef CRYPTOPP_MQV_H
    00002 #define CRYPTOPP_MQV_H
    00003
    00004 /** \file
    00005 */
    00006
    00007 #include "gfpcrypt.h"
    00008
    00009 NAMESPACE_BEGIN(CryptoPP)
    00010
    00011 //! _
    00012 template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption>
    00013 class MQV_Domain : public AuthenticatedKeyAgreementDomain
    00014 {
    00015 public:
    00016     typedef GROUP_PARAMETERS GroupParameters;
    00017     typedef typename GroupParameters::Element Element;
    00018     typedef MQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain;
    00019
    00020     MQV_Domain() {}
    00021
    00022     MQV_Domain(const GroupParameters &params)
    00023         : m_groupParameters(params) {}
    00024
    00025     MQV_Domain(BufferedTransformation &bt)
    00026         {m_groupParameters.BERDecode(bt);}
    00027
    00028     template <class T1, class T2>
    00029     MQV_Domain(T1 v1, T2 v2)
    00030         {m_groupParameters.Initialize(v1, v2);}
    00031
    00032     template <class T1, class T2, class T3>
    00033     MQV_Domain(T1 v1, T2 v2, T3 v3)
    00034         {m_groupParameters.Initialize(v1, v2, v3);}
    00035
    00036     template <class T1, class T2, class T3, class T4>
    00037     MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
    00038         {m_groupParameters.Initialize(v1, v2, v3, v4);}
    00039
    00040     const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
    00041     GroupParameters & AccessGroupParameters() {return m_groupParameters;}
    00042
    00043     CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
    00044
    00045     unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
    00046     unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
    00047     unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
    00048
    00049     void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
    00050     {
    00051         Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
    00052         x.Encode(privateKey, StaticPrivateKeyLength());
    00053     }
    00054
    00055     void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
    00056     {
    00057         const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
    00058         Integer x(privateKey, StaticPrivateKeyLength());
    00059         Element y = params.ExponentiateBase(x);
    00060         params.EncodeElement(true, y, publicKey);
    00061     }
    00062
    00063     unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
    00064     unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
    00065
    00066     void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
    00067     {
    00068         const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
    00069         Integer x(rng, Integer::One(), params.GetMaxExponent());
    00070         x.Encode(privateKey, StaticPrivateKeyLength());
    00071         Element y = params.ExponentiateBase(x);
    00072         params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
    00073     }
    00074
    00075     void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
    00076     {
    00077         memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
    00078     }
    00079
    00080     bool Agree(byte *agreedValue,
    00081         const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
    00082         const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
    00083         bool validateStaticOtherPublicKey=true) const
    00084     {
    00085         try
    00086         {
    00087             const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
    00088             Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
    00089             Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
    00090
    00091             Integer s(staticPrivateKey, StaticPrivateKeyLength());
    00092             Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
    00093             Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
    00094
    00095             const Integer &r = params.GetSubgroupOrder();
    00096             Integer h2 = Integer::Power2((r.BitCount()+1)/2);
    00097             Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r;
    00098             Integer tt = h2 + params.ConvertElementToInteger(VV) % h2;
    00099
    00100             if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
    00101             {
    00102                 Element P = params.ExponentiateElement(WW, tt);
    00103                 P = m_groupParameters.MultiplyElements(P, VV);
    00104                 Element R[2];
    00105                 const Integer e2[2] = {r, e};
    00106                 params.SimultaneousExponentiate(R, P, e2, 2);
    00107                 if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
    00108                     return false;
    00109                 params.EncodeElement(false, R[1], agreedValue);
    00110             }
    00111             else
    00112             {
    00113                 const Integer &k = params.GetCofactor();
    00114                 if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
    00115                     e = ModularArithmetic(r).Divide(e, k);
    00116                 Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
    00117                 if (params.IsIdentity(P))
    00118                     return false;
    00119                 params.EncodeElement(false, P, agreedValue);
    00120             }
    00121         }
    00122         catch (DL_BadElement &)
    00123         {
    00124             return false;
    00125         }
    00126         return true;
    00127     }
    00128
    00129 private:
    00130     DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
    00131     const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
    00132
    00133     GroupParameters m_groupParameters;
    00134 };
    00135
    00136 //! Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
    00137 typedef MQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> MQV;
    00138
    00139 NAMESPACE_END
    00140
    00141 #endif