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

Generated on Sat Dec 23 02:07:08 2006 for Crypto++ by  doxygen 1.5.1-p1