Crypto++ 8.6 Free C++ class library of cryptographic schemes

mqv.h
Go to the documentation of this file.
1 // mqv.h - originally written and placed in the public domain by Wei Dai
2
3 /// \file mqv.h
4 /// \brief Classes for Menezes–Qu–Vanstone (MQV) key agreement
5 /// \since Crypto++ 3.0
6
7 #ifndef CRYPTOPP_MQV_H
8 #define CRYPTOPP_MQV_H
9
10 #include "cryptlib.h"
11 #include "gfpcrypt.h"
12 #include "modarith.h"
13 #include "integer.h"
14 #include "algebra.h"
15 #include "misc.h"
16
17 NAMESPACE_BEGIN(CryptoPP)
18
19 /// \brief MQV domain for performing authenticated key agreement
20 /// \tparam GROUP_PARAMETERS doamin parameters
21 /// \tparam COFACTOR_OPTION cofactor option
22 /// \details GROUP_PARAMETERS parameters include the curve coefcients and the base point.
23 /// Binary curves use a polynomial to represent its characteristic, while prime curves
24 /// use a prime number.
25 /// \sa MQV, HMQV, FHMQV, and AuthenticatedKeyAgreementDomain
26 /// \since Crypto++ 3.0
27 template <class GROUP_PARAMETERS, class COFACTOR_OPTION = typename GROUP_PARAMETERS::DefaultCofactorOption>
28 class MQV_Domain : public AuthenticatedKeyAgreementDomain
29 {
30 public:
31 typedef GROUP_PARAMETERS GroupParameters;
32 typedef typename GroupParameters::Element Element;
33 typedef MQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain;
34
35 /// \brief Construct a MQV domain
36 MQV_Domain() {}
37
38 /// \brief Construct a MQV domain
39 /// \param params group parameters and options
40 MQV_Domain(const GroupParameters &params)
41 : m_groupParameters(params) {}
42
43 /// \brief Construct a MQV domain
44 /// \param bt BufferedTransformation with group parameters and options
45 MQV_Domain(BufferedTransformation &bt)
46 {m_groupParameters.BERDecode(bt);}
47
48 /// \brief Construct a MQV domain
49 /// \tparam T1 template parameter used as a constructor parameter
50 /// \tparam T2 template parameter used as a constructor parameter
51 /// \param v1 first parameter
52 /// \param v2 second parameter
53 /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
54 template <class T1, class T2>
55 MQV_Domain(T1 v1, T2 v2)
56 {m_groupParameters.Initialize(v1, v2);}
57
58 /// \brief Construct a MQV domain
59 /// \tparam T1 template parameter used as a constructor parameter
60 /// \tparam T2 template parameter used as a constructor parameter
61 /// \tparam T3 template parameter used as a constructor parameter
62 /// \param v1 first parameter
63 /// \param v2 second parameter
64 /// \param v3 third parameter
65 /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
66 template <class T1, class T2, class T3>
67 MQV_Domain(T1 v1, T2 v2, T3 v3)
68 {m_groupParameters.Initialize(v1, v2, v3);}
69
70 /// \brief Construct a MQV domain
71 /// \tparam T1 template parameter used as a constructor parameter
72 /// \tparam T2 template parameter used as a constructor parameter
73 /// \tparam T3 template parameter used as a constructor parameter
74 /// \tparam T4 template parameter used as a constructor parameter
75 /// \param v1 first parameter
76 /// \param v2 second parameter
77 /// \param v3 third parameter
78 /// \param v4 third parameter
79 /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
80 template <class T1, class T2, class T3, class T4>
81 MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
82 {m_groupParameters.Initialize(v1, v2, v3, v4);}
83
84 /// \brief Retrieves the group parameters for this domain
85 /// \return the group parameters for this domain as a const reference
86 const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
87
88 /// \brief Retrieves the group parameters for this domain
89 /// \return the group parameters for this domain as a non-const reference
90 GroupParameters & AccessGroupParameters() {return m_groupParameters;}
91
92 /// \brief Retrieves the crypto parameters for this domain
93 /// \return the crypto parameters for this domain as a non-const reference
94 CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
95
96 /// \brief Provides the size of the agreed value
97 /// \return size of agreed value produced in this domain
98 /// \details The length is calculated using <tt>GetEncodedElementSize(false)</tt>,
99 /// which means the element is encoded in a non-reversible format. A
100 /// non-reversible format means its a raw byte array, and it lacks presentation
101 /// format like an ASN.1 BIT_STRING or OCTET_STRING.
102 unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
103
104 /// \brief Provides the size of the static private key
105 /// \return size of static private keys in this domain
106 /// \details The length is calculated using the byte count of the subgroup order.
107 unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
108
109 /// \brief Provides the size of the static public key
110 /// \return size of static public keys in this domain
111 /// \details The length is calculated using <tt>GetEncodedElementSize(true)</tt>,
112 /// which means the element is encoded in a reversible format. A reversible
113 /// format means it has a presentation format, and its an ANS.1 encoded element
114 /// or point.
115 unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
116
117 /// \brief Generate static private key in this domain
118 /// \param rng a RandomNumberGenerator derived class
119 /// \param privateKey a byte buffer for the generated private key in this domain
120 /// \details The private key is a random scalar used as an exponent in the range
121 /// <tt>[1,MaxExponent()]</tt>.
122 /// \pre <tt>COUNTOF(privateKey) == PrivateStaticKeyLength()</tt>
123 void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
124 {
125 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
126 x.Encode(privateKey, StaticPrivateKeyLength());
127 }
128
129 /// \brief Generate a static public key from a private key in this domain
130 /// \param rng a RandomNumberGenerator derived class
131 /// \param privateKey a byte buffer with the previously generated private key
132 /// \param publicKey a byte buffer for the generated public key in this domain
133 /// \details The public key is an element or point on the curve, and its stored
134 /// in a revrsible format. A reversible format means it has a presentation
135 /// format, and its an ANS.1 encoded element or point.
136 /// \pre <tt>COUNTOF(publicKey) == PublicStaticKeyLength()</tt>
137 void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
138 {
139 CRYPTOPP_UNUSED(rng);
140 const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
141 Integer x(privateKey, StaticPrivateKeyLength());
142 Element y = params.ExponentiateBase(x);
143 params.EncodeElement(true, y, publicKey);
144 }
145
146 /// \brief Provides the size of the ephemeral private key
147 /// \return size of ephemeral private keys in this domain
148 /// \details An ephemeral private key is a private key and public key.
149 /// The serialized size is different than a static private key.
150 unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
151
152 /// \brief Provides the size of the ephemeral public key
153 /// \return size of ephemeral public keys in this domain
154 /// \details An ephemeral public key is a public key.
155 /// The serialized size is the same as a static public key.
156 unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
157
158 /// \brief Generate ephemeral private key in this domain
159 /// \param rng a RandomNumberGenerator derived class
160 /// \param privateKey a byte buffer for the generated private key in this domain
161 /// \pre <tt>COUNTOF(privateKey) == EphemeralPrivateKeyLength()</tt>
162 void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
163 {
164 const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
165 Integer x(rng, Integer::One(), params.GetMaxExponent());
166 x.Encode(privateKey, StaticPrivateKeyLength());
167 Element y = params.ExponentiateBase(x);
168 params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
169 }
170
171 /// \brief Generate ephemeral public key from a private key in this domain
172 /// \param rng a RandomNumberGenerator derived class
173 /// \param privateKey a byte buffer with the previously generated private key
174 /// \param publicKey a byte buffer for the generated public key in this domain
175 /// \pre <tt>COUNTOF(publicKey) == EphemeralPublicKeyLength()</tt>
176 void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
177 {
178 CRYPTOPP_UNUSED(rng);
179 std::memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
180 }
181
182 /// \brief Derive agreed value or shared secret
183 /// \param agreedValue the shared secret
184 /// \param staticPrivateKey your long term private key
185 /// \param ephemeralPrivateKey your ephemeral private key
186 /// \param staticOtherPublicKey couterparty's long term public key
187 /// \param ephemeralOtherPublicKey couterparty's ephemeral public key
188 /// \param validateStaticOtherPublicKey flag indicating validation
189 /// \return true upon success, false in case of failure
190 /// \details Agree() performs the authenticated key agreement. Agree()
191 /// derives a shared secret from your private keys and couterparty's
192 /// public keys. Each instance or run of the protocol should use a new
193 /// ephemeral key pair.
194 /// \details The other's ephemeral public key will always be validated at
195 /// Level 1 to ensure it is a point on the curve.
196 /// <tt>validateStaticOtherPublicKey</tt> determines how thoroughly other's
197 /// static public key is validated. If you have previously validated the
198 /// couterparty's static public key, then use
199 /// <tt>validateStaticOtherPublicKey=false</tt> to save time.
200 /// \pre <tt>COUNTOF(agreedValue) == AgreedValueLength()</tt>
201 /// \pre <tt>COUNTOF(staticPrivateKey) == StaticPrivateKeyLength()</tt>
202 /// \pre <tt>COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength()</tt>
203 /// \pre <tt>COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength()</tt>
204 /// \pre <tt>COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength()</tt>
205 bool Agree(byte *agreedValue,
206 const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
207 const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
208 bool validateStaticOtherPublicKey=true) const
209 {
210 try
211 {
212 const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
213 Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
214 Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
215
216 Integer s(staticPrivateKey, StaticPrivateKeyLength());
217 Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
218 Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
219
220 const Integer &r = params.GetSubgroupOrder();
221 Integer h2 = Integer::Power2((r.BitCount()+1)/2);
222 Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r;
223 Integer tt = h2 + params.ConvertElementToInteger(VV) % h2;
224
225 if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
226 {
227 Element P = params.ExponentiateElement(WW, tt);
228 P = m_groupParameters.MultiplyElements(P, VV);
229 Element R[2];
230 const Integer e2[2] = {r, e};
231 params.SimultaneousExponentiate(R, P, e2, 2);
232 if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
233 return false;
234 params.EncodeElement(false, R[1], agreedValue);
235 }
236 else
237 {
238 const Integer &k = params.GetCofactor();
239 if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
240 e = ModularArithmetic(r).Divide(e, k);
241 Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
242 if (params.IsIdentity(P))
243 return false;
244 params.EncodeElement(false, P, agreedValue);
245 }
246 }
247 catch (DL_BadElement &)
248 {
249 return false;
250 }
251 return true;
252 }
253
254 private:
255 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
256 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
257
258 GroupParameters m_groupParameters;
259 };
260
261 /// Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
262 /// \sa MQV, HMQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain
263 /// \since Crypto++ 3.0
264 typedef MQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> MQV;
265
266 NAMESPACE_END
267
268 #endif
algebra.h
Classes for performing mathematics over different fields.
AuthenticatedKeyAgreementDomain
Interface for domains of authenticated key agreement protocols.
Definition: cryptlib.h:3077
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1657
CryptoParameters
Interface for crypto parameters.
Definition: cryptlib.h:2551
DL_BadElement
Exception thrown when an invalid group element is encountered.
Definition: pubkey.h:772
DL_GroupParameters
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:782
DL_GroupParameters::ExponentiateElement
virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
Exponentiates an element.
Definition: pubkey.h:879
DL_GroupParameters::GetCofactor
virtual Integer GetCofactor() const
Retrieves the cofactor.
Definition: pubkey.h:914
DL_GroupParameters::EncodeElement
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
DL_GroupParameters::GetMaxExponent
virtual Integer GetMaxExponent() const =0
Retrieves the maximum exponent for the group.
DL_GroupParameters::SimultaneousExponentiate
virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0
Exponentiates a base to multiple exponents.
DL_GroupParameters::ExponentiateBase
virtual Element ExponentiateBase(const Integer &exponent) const
Exponentiates the base.
Definition: pubkey.h:869
DL_GroupParameters::GetSubgroupOrder
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.
DL_GroupParameters::DecodeElement
virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0
Decodes the element.
DL_GroupParameters::ConvertElementToInteger
virtual Integer ConvertElementToInteger(const Element &element) const =0
Converts an element to an Integer.
DL_GroupParameters::IsIdentity
virtual bool IsIdentity(const Element &element) const =0
Determines if an element is an identity.
Integer
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
Integer::Power2
static Integer Power2(size_t e)
Exponentiates to a power of 2.
Integer::One
static const Integer & One()
Integer representing 1.
Integer::BitCount
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
MQV_Domain
MQV domain for performing authenticated key agreement.
Definition: mqv.h:29
MQV_Domain::EphemeralPublicKeyLength
unsigned int EphemeralPublicKeyLength() const
Provides the size of the ephemeral public key.
Definition: mqv.h:156
MQV_Domain::MQV_Domain
MQV_Domain(T1 v1, T2 v2)
Construct a MQV domain.
Definition: mqv.h:55
MQV_Domain::MQV_Domain
MQV_Domain(BufferedTransformation &bt)
Construct a MQV domain.
Definition: mqv.h:45
MQV_Domain::GenerateEphemeralPublicKey
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate ephemeral public key from a private key in this domain.
Definition: mqv.h:176
MQV_Domain::EphemeralPrivateKeyLength
unsigned int EphemeralPrivateKeyLength() const
Provides the size of the ephemeral private key.
Definition: mqv.h:150
MQV_Domain::GenerateStaticPrivateKey
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate static private key in this domain.
Definition: mqv.h:123
MQV_Domain::GenerateStaticPublicKey
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a static public key from a private key in this domain.
Definition: mqv.h:137
MQV_Domain::AgreedValueLength
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition: mqv.h:102
MQV_Domain::GenerateEphemeralPrivateKey
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate ephemeral private key in this domain.
Definition: mqv.h:162
MQV_Domain::MQV_Domain
MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
Construct a MQV domain.
Definition: mqv.h:81
MQV_Domain::Agree
bool Agree(byte *agreedValue, const byte *staticPrivateKey, const byte *ephemeralPrivateKey, const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, bool validateStaticOtherPublicKey=true) const
Derive agreed value or shared secret.
Definition: mqv.h:205
MQV_Domain::MQV_Domain
MQV_Domain(const GroupParameters &params)
Construct a MQV domain.
Definition: mqv.h:40
MQV_Domain::StaticPrivateKeyLength
unsigned int StaticPrivateKeyLength() const
Provides the size of the static private key.
Definition: mqv.h:107
MQV_Domain::MQV_Domain
MQV_Domain(T1 v1, T2 v2, T3 v3)
Construct a MQV domain.
Definition: mqv.h:67
MQV_Domain::AccessGroupParameters
GroupParameters & AccessGroupParameters()
Retrieves the group parameters for this domain.
Definition: mqv.h:90
MQV_Domain::StaticPublicKeyLength
unsigned int StaticPublicKeyLength() const
Provides the size of the static public key.
Definition: mqv.h:115
MQV_Domain::GetGroupParameters
const GroupParameters & GetGroupParameters() const
Retrieves the group parameters for this domain.
Definition: mqv.h:86
MQV_Domain::MQV_Domain
MQV_Domain()
Construct a MQV domain.
Definition: mqv.h:36
MQV_Domain::AccessCryptoParameters
CryptoParameters & AccessCryptoParameters()
Retrieves the crypto parameters for this domain.
Definition: mqv.h:94
ModularArithmetic
Ring of congruence classes modulo n.
Definition: modarith.h:44
ModularArithmetic::Divide
const Integer & Divide(const Integer &a, const Integer &b) const
Divides elements in the ring.
Definition: modarith.h:218
RandomNumberGenerator
Interface for random number generators.
Definition: cryptlib.h:1440
cryptlib.h
Abstract base classes that provide a uniform interface to this library.
gfpcrypt.h
Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
integer.h
Multiple precision integer with arithmetic operations.
misc.h
Utility functions for the Crypto++ library.
modarith.h
Class file for performing modular arithmetic.
MQV
MQV_Domain< DL_GroupParameters_GFP_DefaultSafePrime > MQV
Menezes-Qu-Vanstone in GF(p) with key validation, AKA MQV
Definition: mqv.h:264
CryptoPP
Crypto++ library namespace.
NO_COFACTOR_MULTIPLICTION
@ NO_COFACTOR_MULTIPLICTION
No cofactor multiplication applied.
Definition: pubkey.h:2125
COMPATIBLE_COFACTOR_MULTIPLICTION
@ COMPATIBLE_COFACTOR_MULTIPLICTION
Cofactor multiplication compatible with ordinary Diffie-Hellman.
Definition: pubkey.h:2129