Crypto++  5.6.3
Free C++ class library of cryptographic schemes
mqv.h
Go to the documentation of this file.
1 // mqv.h - 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 
6 #ifndef CRYPTOPP_MQV_H
7 #define CRYPTOPP_MQV_H
8 
9 #include "cryptlib.h"
10 #include "gfpcrypt.h"
11 #include "modarith.h"
12 #include "integer.h"
13 #include "algebra.h"
14 #include "misc.h"
15 
16 NAMESPACE_BEGIN(CryptoPP)
17 
18 //! \class MQV_Domain
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 paramters 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 template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption>
27 {
28 public:
29  typedef GROUP_PARAMETERS GroupParameters;
30  typedef typename GroupParameters::Element Element;
32 
33  //! \brief Construct a MQV domain
35 
36  //! \brief Construct a MQV domain
37  //! \param params group parameters and options
38  MQV_Domain(const GroupParameters &params)
39  : m_groupParameters(params) {}
40 
41  //! \brief Construct a MQV domain
42  //! \param bt BufferedTransformation with group parameters and options
44  {m_groupParameters.BERDecode(bt);}
45 
46  //! \brief Construct a MQV domain
47  //! \tparam T1 template parameter used as a constructor parameter
48  //! \tparam T2 template parameter used as a constructor parameter
49  //! \param v1 first parameter
50  //! \param v2 second parameter
51  //! \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
52  template <class T1, class T2>
53  MQV_Domain(T1 v1, T2 v2)
54  {m_groupParameters.Initialize(v1, v2);}
55 
56  //! \brief Construct a MQV domain
57  //! \tparam T1 template parameter used as a constructor parameter
58  //! \tparam T2 template parameter used as a constructor parameter
59  //! \tparam T3 template parameter used as a constructor parameter
60  //! \param v1 first parameter
61  //! \param v2 second parameter
62  //! \param v3 third parameter
63  //! \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
64  template <class T1, class T2, class T3>
65  MQV_Domain(T1 v1, T2 v2, T3 v3)
66  {m_groupParameters.Initialize(v1, v2, v3);}
67 
68  //! \brief Construct a MQV domain
69  //! \tparam T1 template parameter used as a constructor parameter
70  //! \tparam T2 template parameter used as a constructor parameter
71  //! \tparam T3 template parameter used as a constructor parameter
72  //! \tparam T4 template parameter used as a constructor parameter
73  //! \param v1 first parameter
74  //! \param v2 second parameter
75  //! \param v3 third parameter
76  //! \param v4 third parameter
77  //! \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
78  template <class T1, class T2, class T3, class T4>
79  MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
80  {m_groupParameters.Initialize(v1, v2, v3, v4);}
81 
82  //! \brief Retrieves the group parameters for this domain
83  //! \return the group parameters for this domain as a const reference
84  const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
85 
86  //! \brief Retrieves the group parameters for this domain
87  //! \return the group parameters for this domain as a non-const reference
88  GroupParameters & AccessGroupParameters() {return m_groupParameters;}
89 
90  //! \brief Retrieves the crypto parameters for this domain
91  //! \return the crypto parameters for this domain as a non-const reference
92  CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
93 
94  //! \brief Provides the size of the agreed value
95  //! \return size of agreed value produced in this domain
96  //! \details The length is calculated using <tt>GetEncodedElementSize(false)</tt>, which means the
97  //! element is encoded in a non-reversible format. A non-reversible format means its a raw byte array,
98  //! and it lacks presentation format like an ASN.1 BIT_STRING or OCTET_STRING.
99  unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
100 
101  //! \brief Provides the size of the static private key
102  //! \return size of static private keys in this domain
103  //! \details The length is calculated using the byte count of the subgroup order.
104  unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
105 
106  //! \brief Provides the size of the static public key
107  //! \return size of static public keys in this domain
108  //! \details The length is calculated using <tt>GetEncodedElementSize(true)</tt>, which means the
109  //! element is encoded in a reversible format. A reversible format means it has a presentation format,
110  //! and its an ANS.1 encoded element or point.
111  unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
112 
113  //! \brief Generate static private key in this domain
114  //! \param rng a RandomNumberGenerator derived class
115  //! \param privateKey a byte buffer for the generated private key in this domain
116  //! \details The private key is a random scalar used as an exponent in the range <tt>[1,MaxExponent()]</tt>.
117  //! \pre <tt>COUNTOF(privateKey) == PrivateStaticKeyLength()</tt>
118  void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
119  {
120  Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
121  x.Encode(privateKey, StaticPrivateKeyLength());
122  }
123 
124  //! \brief Generate a static public key from a private key in this domain
125  //! \param rng a RandomNumberGenerator derived class
126  //! \param privateKey a byte buffer with the previously generated private key
127  //! \param publicKey a byte buffer for the generated public key in this domain
128  //! \details The public key is an element or point on the curve, and its stored in a revrsible format.
129  //! A reversible format means it has a presentation format, and its an ANS.1 encoded element or point.
130  //! \pre <tt>COUNTOF(publicKey) == PublicStaticKeyLength()</tt>
131  void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
132  {
133  CRYPTOPP_UNUSED(rng);
134  const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
135  Integer x(privateKey, StaticPrivateKeyLength());
136  Element y = params.ExponentiateBase(x);
137  params.EncodeElement(true, y, publicKey);
138  }
139 
140  unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
141  unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
142 
143  void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
144  {
145  const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
146  Integer x(rng, Integer::One(), params.GetMaxExponent());
147  x.Encode(privateKey, StaticPrivateKeyLength());
148  Element y = params.ExponentiateBase(x);
149  params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
150  }
151 
152  void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
153  {
154  CRYPTOPP_UNUSED(rng);
155  memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
156  }
157 
158  bool Agree(byte *agreedValue,
159  const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
160  const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
161  bool validateStaticOtherPublicKey=true) const
162  {
163  try
164  {
165  const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
166  Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
167  Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
168 
169  Integer s(staticPrivateKey, StaticPrivateKeyLength());
170  Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
171  Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
172 
173  const Integer &r = params.GetSubgroupOrder();
174  Integer h2 = Integer::Power2((r.BitCount()+1)/2);
175  Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r;
176  Integer tt = h2 + params.ConvertElementToInteger(VV) % h2;
177 
178  if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
179  {
180  Element P = params.ExponentiateElement(WW, tt);
181  P = m_groupParameters.MultiplyElements(P, VV);
182  Element R[2];
183  const Integer e2[2] = {r, e};
184  params.SimultaneousExponentiate(R, P, e2, 2);
185  if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
186  return false;
187  params.EncodeElement(false, R[1], agreedValue);
188  }
189  else
190  {
191  const Integer &k = params.GetCofactor();
192  if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
193  e = ModularArithmetic(r).Divide(e, k);
194  Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
195  if (params.IsIdentity(P))
196  return false;
197  params.EncodeElement(false, P, agreedValue);
198  }
199  }
200  catch (DL_BadElement &)
201  {
202  return false;
203  }
204  return true;
205  }
206 
207 private:
208  DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
209  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
210 
211  GroupParameters m_groupParameters;
212 };
213 
214 //! Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
216 
217 NAMESPACE_END
218 
219 #endif
virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0
Exponentiates a base to multiple exponents.
MQV_Domain(T1 v1, T2 v2)
Construct a MQV domain.
Definition: mqv.h:53
Utility functions for the Crypto++ library.
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3270
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:131
virtual Integer ConvertElementToInteger(const Element &element) const =0
Converts an element to an Integer.
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:752
MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
Construct a MQV domain.
Definition: mqv.h:79
unsigned int EphemeralPublicKeyLength() const
Provides the size of ephemeral public key.
Definition: mqv.h:141
Abstract base classes that provide a uniform interface to this library.
virtual Integer GetMaxExponent() const =0
Retrieves the maximum exponent for the group.
Ring of congruence classes modulo n.
Definition: modarith.h:34
Interface for random number generators.
Definition: cryptlib.h:1186
MQV_Domain(BufferedTransformation &bt)
Construct a MQV domain.
Definition: mqv.h:43
Classes for performing mathematics over different fields.
Interface for buffered transformations.
Definition: cryptlib.h:1352
static const Integer & One()
Integer representing 1.
Definition: integer.cpp:2948
MQV_Domain< DL_GroupParameters_GFP_DefaultSafePrime > MQV
Menezes-Qu-Vanstone in GF(p) with key validation, AKA MQV
Definition: mqv.h:215
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
Definition: integer.cpp:3209
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
Cofactor multiplication compatible with ordinary Diffie-Hellman.
Definition: pubkey.h:1960
MQV domain for performing authenticated key agreement.
Definition: mqv.h:26
No cofactor multiplication applied.
Definition: pubkey.h:1956
static Integer Power2(size_t e)
Exponentiates to a power of 2.
Definition: integer.cpp:2927
unsigned int EphemeralPrivateKeyLength() const
Provides the size of ephemeral private key.
Definition: mqv.h:140
unsigned int StaticPrivateKeyLength() const
Provides the size of the static private key.
Definition: mqv.h:104
Multiple precision integer with arithmetic operations.
Definition: integer.h:31
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition: mqv.h:99
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate static private key in this domain.
Definition: mqv.h:118
Implementation of schemes based on DL over GF(p)
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.
virtual bool IsIdentity(const Element &element) const =0
Determines if an element is an identity.
Exception thrown when an invalid group element is encountered.
Definition: pubkey.h:742
virtual Integer GetCofactor() const
Retrieves the cofactor.
Definition: pubkey.h:866
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate ephemeral public key.
Definition: mqv.h:152
const Integer & Divide(const Integer &a, const Integer &b) const
Divides elements in the ring.
Definition: modarith.h:200
virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0
Decodes the element.
MQV_Domain(const GroupParameters &params)
Construct a MQV domain.
Definition: mqv.h:38
MQV_Domain(T1 v1, T2 v2, T3 v3)
Construct a MQV domain.
Definition: mqv.h:65
MQV_Domain()
Construct a MQV domain.
Definition: mqv.h:34
Interface for crypto prameters.
Definition: cryptlib.h:2189
CryptoParameters & AccessCryptoParameters()
Retrieves the crypto parameters for this domain.
Definition: mqv.h:92
Class file for performing modular arithmetic.
Crypto++ library namespace.
const GroupParameters & GetGroupParameters() const
Retrieves the group parameters for this domain.
Definition: mqv.h:84
Interface for domains of authenticated key agreement protocols.
Definition: cryptlib.h:2740
GroupParameters & AccessGroupParameters()
Retrieves the group parameters for this domain.
Definition: mqv.h:88
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate ephemeral private key.
Definition: mqv.h:143
virtual Element ExponentiateBase(const Integer &exponent) const
Retrieves the subgroup generator.
Definition: pubkey.h:821
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:158
unsigned int StaticPublicKeyLength() const
Provides the size of the static public key.
Definition: mqv.h:111
virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
Exponentiates an element.
Definition: pubkey.h:831