9
NAMESPACE_BEGIN(CryptoPP)
12
template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption>
13
class MQV_Domain : public AuthenticatedKeyAgreementDomain
16
typedef GROUP_PARAMETERS GroupParameters;
17
typedef typename GroupParameters::Element Element;
18
typedef MQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain;
22
MQV_Domain(const GroupParameters ¶ms)
23
: m_groupParameters(params) {}
25
MQV_Domain(BufferedTransformation &bt)
26
{m_groupParameters.BERDecode(bt);}
28
template <class T1, class T2>
29
MQV_Domain(T1 v1, T2 v2)
30
{m_groupParameters.Initialize(v1, v2);}
32
template <class T1, class T2, class T3>
33
MQV_Domain(T1 v1, T2 v2, T3 v3)
34
{m_groupParameters.Initialize(v1, v2, v3);}
36
template <class T1, class T2, class T3, class T4>
37
MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
38
{m_groupParameters.Initialize(v1, v2, v3, v4);}
40
const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
41
GroupParameters & AccessGroupParameters() {return m_groupParameters;}
43
CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
45
unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
46
unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
47
unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
49
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
51
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
52
x.Encode(privateKey, StaticPrivateKeyLength());
55
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
57
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
58
Integer x(privateKey, StaticPrivateKeyLength());
59
Element y = params.ExponentiateBase(x);
60
params.EncodeElement(true, y, publicKey);
63
unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
64
unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
66
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
68
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
69
Integer x(rng, Integer::One(), params.GetMaxExponent());
70
x.Encode(privateKey, StaticPrivateKeyLength());
71
Element y = params.ExponentiateBase(x);
72
params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
75
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
77
memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
80
bool Agree(byte *agreedValue,
81
const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
82
const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
83
bool validateStaticOtherPublicKey=true) const
87
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
88
Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
89
Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
91
Integer s(staticPrivateKey, StaticPrivateKeyLength());
92
Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
93
Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
95
const Integer &r = params.GetSubgroupOrder();
96
Integer h2 = Integer::Power2((r.BitCount()+1)/2);
97
Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r;
98
Integer tt = h2 + params.ConvertElementToInteger(VV) % h2;
100
if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
102
Element P = params.ExponentiateElement(WW, tt);
103
P = m_groupParameters.MultiplyElements(P, VV);
105
const Integer e2[2] = {r, e};
106
params.SimultaneousExponentiate(R, P, e2, 2);
107
if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
109
params.EncodeElement(false, R[1], agreedValue);
113
const Integer &k = params.GetCofactor();
114
if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
115
e = ModularArithmetic(r).Divide(e, k);
116
Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
117
if (params.IsIdentity(P))
119
params.EncodeElement(false, P, agreedValue);
122
catch (DL_BadElement &)
130
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
131
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
133
GroupParameters m_groupParameters;
136
//! Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
137
typedef MQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> MQV;