Crypto++ 8.2
Free C&
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
17NAMESPACE_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
27template <class GROUP_PARAMETERS, class COFACTOR_OPTION = typename GROUP_PARAMETERS::DefaultCofactorOption>
29{
30public:
31 typedef GROUP_PARAMETERS GroupParameters;
32 typedef typename GroupParameters::Element Element;
34
35 /// \brief Construct a 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
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>, which means the
99 /// element is encoded in a non-reversible format. A non-reversible format means its a raw byte array,
100 /// and it lacks presentation format like an ASN.1 BIT_STRING or OCTET_STRING.
101 unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
102
103 /// \brief Provides the size of the static private key
104 /// \return size of static private keys in this domain
105 /// \details The length is calculated using the byte count of the subgroup order.
106 unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
107
108 /// \brief Provides the size of the static public key
109 /// \return size of static public keys in this domain
110 /// \details The length is calculated using <tt>GetEncodedElementSize(true)</tt>, which means the
111 /// element is encoded in a reversible format. A reversible format means it has a presentation format,
112 /// and its an ANS.1 encoded element or point.
113 unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
114
115 /// \brief Generate static private key in this domain
116 /// \param rng a RandomNumberGenerator derived class
117 /// \param privateKey a byte buffer for the generated private key in this domain
118 /// \details The private key is a random scalar used as an exponent in the range <tt>[1,MaxExponent()]</tt>.
119 /// \pre <tt>COUNTOF(privateKey) == PrivateStaticKeyLength()</tt>
120 void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
121 {
122 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
123 x.Encode(privateKey, StaticPrivateKeyLength());
124 }
125
126 /// \brief Generate a static public key from a private key in this domain
127 /// \param rng a RandomNumberGenerator derived class
128 /// \param privateKey a byte buffer with the previously generated private key
129 /// \param publicKey a byte buffer for the generated public key in this domain
130 /// \details The public key is an element or point on the curve, and its stored in a revrsible format.
131 /// A reversible format means it has a presentation format, and its an ANS.1 encoded element or point.
132 /// \pre <tt>COUNTOF(publicKey) == PublicStaticKeyLength()</tt>
133 void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
134 {
135 CRYPTOPP_UNUSED(rng);
136 const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
137 Integer x(privateKey, StaticPrivateKeyLength());
138 Element y = params.ExponentiateBase(x);
139 params.EncodeElement(true, y, publicKey);
140 }
141
143 unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
144
145 void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
146 {
147 const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
148 Integer x(rng, Integer::One(), params.GetMaxExponent());
149 x.Encode(privateKey, StaticPrivateKeyLength());
150 Element y = params.ExponentiateBase(x);
151 params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
152 }
153
154 void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
155 {
156 CRYPTOPP_UNUSED(rng);
157 memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
158 }
159
160 bool Agree(byte *agreedValue,
161 const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
162 const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
163 bool validateStaticOtherPublicKey=true) const
164 {
165 try
166 {
167 const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
168 Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
169 Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
170
171 Integer s(staticPrivateKey, StaticPrivateKeyLength());
172 Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
173 Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
174
175 const Integer &r = params.GetSubgroupOrder();
176 Integer h2 = Integer::Power2((r.BitCount()+1)/2);
177 Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r;
178 Integer tt = h2 + params.ConvertElementToInteger(VV) % h2;
179
180 if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
181 {
182 Element P = params.ExponentiateElement(WW, tt);
183 P = m_groupParameters.MultiplyElements(P, VV);
184 Element R[2];
185 const Integer e2[2] = {r, e};
186 params.SimultaneousExponentiate(R, P, e2, 2);
187 if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
188 return false;
189 params.EncodeElement(false, R[1], agreedValue);
190 }
191 else
192 {
193 const Integer &k = params.GetCofactor();
194 if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
195 e = ModularArithmetic(r).Divide(e, k);
196 Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
197 if (params.IsIdentity(P))
198 return false;
199 params.EncodeElement(false, P, agreedValue);
200 }
201 }
202 catch (DL_BadElement &)
203 {
204 return false;
205 }
206 return true;
207 }
208
209private:
210 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
211 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
212
213 GroupParameters m_groupParameters;
214};
215
216/// Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
217/// \sa MQV, HMQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain
218/// \since Crypto++ 3.0
220
221NAMESPACE_END
222
223#endif
Classes for performing mathematics over different fields.
Interface for domains of authenticated key agreement protocols.
Definition: cryptlib.h:2957
Interface for buffered transformations.
Definition: cryptlib.h:1599
Interface for crypto prameters.
Definition: cryptlib.h:2436
Exception thrown when an invalid group element is encountered.
Definition: pubkey.h:744
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:754
virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
Exponentiates an element.
Definition: pubkey.h:849
virtual Integer GetCofactor() const
Retrieves the cofactor.
Definition: pubkey.h:884
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
virtual Integer GetMaxExponent() const =0
Retrieves the maximum exponent for the group.
virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0
Exponentiates a base to multiple exponents.
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.
virtual Element ExponentiateBase(const Integer &exponent) const
Exponentiates the base.
Definition: pubkey.h:839
virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0
Decodes the element.
virtual Integer ConvertElementToInteger(const Element &element) const =0
Converts an element to an Integer.
virtual bool IsIdentity(const Element &element) const =0
Determines if an element is an identity.
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
Definition: integer.cpp:3345
static const Integer & One()
Integer representing 1.
Definition: integer.cpp:4877
static Integer Power2(size_t e)
Exponentiates to a power of 2.
Definition: integer.cpp:3079
MQV domain for performing authenticated key agreement.
Definition: mqv.h:29
unsigned int EphemeralPublicKeyLength() const
Provides the size of ephemeral public key.
Definition: mqv.h:143
MQV_Domain(T1 v1, T2 v2)
Construct a MQV domain.
Definition: mqv.h:55
const GroupParameters & GetGroupParameters() const
Retrieves the group parameters for this domain.
Definition: mqv.h:86
MQV_Domain(BufferedTransformation &bt)
Construct a MQV domain.
Definition: mqv.h:45
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate ephemeral public key.
Definition: mqv.h:154
unsigned int EphemeralPrivateKeyLength() const
Provides the size of ephemeral private key.
Definition: mqv.h:142
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate static private key in this domain.
Definition: mqv.h:120
CryptoParameters & AccessCryptoParameters()
Retrieves the crypto parameters for this domain.
Definition: mqv.h:94
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:133
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition: mqv.h:101
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate ephemeral private key.
Definition: mqv.h:145
MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
Construct a MQV domain.
Definition: mqv.h:81
bool Agree(byte *agreedValue, const byte *staticPrivateKey, const byte *ephemeralPrivateKey, const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, bool validateStaticOtherPublicKey=true) const
Derive agreed value.
Definition: mqv.h:160
MQV_Domain(const GroupParameters &params)
Construct a MQV domain.
Definition: mqv.h:40
unsigned int StaticPrivateKeyLength() const
Provides the size of the static private key.
Definition: mqv.h:106
MQV_Domain(T1 v1, T2 v2, T3 v3)
Construct a MQV domain.
Definition: mqv.h:67
GroupParameters & AccessGroupParameters()
Retrieves the group parameters for this domain.
Definition: mqv.h:90
unsigned int StaticPublicKeyLength() const
Provides the size of the static public key.
Definition: mqv.h:113
MQV_Domain()
Construct a MQV domain.
Definition: mqv.h:36
Ring of congruence classes modulo n.
Definition: modarith.h:39
const Integer & Divide(const Integer &a, const Integer &b) const
Divides elements in the ring.
Definition: modarith.h:202
Interface for random number generators.
Definition: cryptlib.h:1384
Abstract base classes that provide a uniform interface to this library.
Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
Multiple precision integer with arithmetic operations.
Utility functions for the Crypto++ library.
Class file for performing modular arithmetic.
MQV_Domain< DL_GroupParameters_GFP_DefaultSafePrime > MQV
Menezes-Qu-Vanstone in GF(p) with key validation, AKA MQV
Definition: mqv.h:219
Crypto++ library namespace.
@ NO_COFACTOR_MULTIPLICTION
No cofactor multiplication applied.
Definition: pubkey.h:2062
@ COMPATIBLE_COFACTOR_MULTIPLICTION
Cofactor multiplication compatible with ordinary Diffie-Hellman.
Definition: pubkey.h:2066