Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class 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, 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 Fri Aug 27 13:29:37 2004 for Crypto++ by doxygen 1.3.8