Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | 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, T2 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