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 "misc.h"
14 
15 NAMESPACE_BEGIN(CryptoPP)
16 
17 //! \class MQV_Domain
18 //! \brief MQV domain for performing authenticated key agreement
19 //! \tparam GROUP_PARAMETERS doamin parameters
20 //! \tparam COFACTOR_OPTION cofactor option
21 //! \details GROUP_PARAMETERS paramters include the curve coefcients and the base point.
22 //! Binary curves use a polynomial to represent its characteristic, while prime curves
23 //! use a prime number.
24 template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption>
26 {
27 public:
28  typedef GROUP_PARAMETERS GroupParameters;
29  typedef typename GroupParameters::Element Element;
31 
32  MQV_Domain() {}
33 
34  MQV_Domain(const GroupParameters &params)
35  : m_groupParameters(params) {}
36 
38  {m_groupParameters.BERDecode(bt);}
39 
40  template <class T1, class T2>
41  MQV_Domain(T1 v1, T2 v2)
42  {m_groupParameters.Initialize(v1, v2);}
43 
44  template <class T1, class T2, class T3>
45  MQV_Domain(T1 v1, T2 v2, T3 v3)
46  {m_groupParameters.Initialize(v1, v2, v3);}
47 
48  template <class T1, class T2, class T3, class T4>
49  MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
50  {m_groupParameters.Initialize(v1, v2, v3, v4);}
51 
52  const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
53  GroupParameters & AccessGroupParameters() {return m_groupParameters;}
54 
55  CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
56 
57  unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
58  unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
59  unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
60 
61  void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
62  {
63  Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
64  x.Encode(privateKey, StaticPrivateKeyLength());
65  }
66 
67  void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
68  {
69  CRYPTOPP_UNUSED(rng);
70  const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
71  Integer x(privateKey, StaticPrivateKeyLength());
72  Element y = params.ExponentiateBase(x);
73  params.EncodeElement(true, y, publicKey);
74  }
75 
76  unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
77  unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
78 
79  void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
80  {
81  const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
82  Integer x(rng, Integer::One(), params.GetMaxExponent());
83  x.Encode(privateKey, StaticPrivateKeyLength());
84  Element y = params.ExponentiateBase(x);
85  params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
86  }
87 
88  void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
89  {
90  CRYPTOPP_UNUSED(rng);
91  memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
92  }
93 
94  bool Agree(byte *agreedValue,
95  const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
96  const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
97  bool validateStaticOtherPublicKey=true) const
98  {
99  try
100  {
101  const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
102  Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
103  Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
104 
105  Integer s(staticPrivateKey, StaticPrivateKeyLength());
106  Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
107  Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
108 
109  const Integer &r = params.GetSubgroupOrder();
110  Integer h2 = Integer::Power2((r.BitCount()+1)/2);
111  Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r;
112  Integer tt = h2 + params.ConvertElementToInteger(VV) % h2;
113 
114  if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
115  {
116  Element P = params.ExponentiateElement(WW, tt);
117  P = m_groupParameters.MultiplyElements(P, VV);
118  Element R[2];
119  const Integer e2[2] = {r, e};
120  params.SimultaneousExponentiate(R, P, e2, 2);
121  if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
122  return false;
123  params.EncodeElement(false, R[1], agreedValue);
124  }
125  else
126  {
127  const Integer &k = params.GetCofactor();
128  if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
129  e = ModularArithmetic(r).Divide(e, k);
130  Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
131  if (params.IsIdentity(P))
132  return false;
133  params.EncodeElement(false, P, agreedValue);
134  }
135  }
136  catch (DL_BadElement &)
137  {
138  return false;
139  }
140  return true;
141  }
142 
143 private:
144  DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
145  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
146 
147  GroupParameters m_groupParameters;
148 };
149 
150 //! Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
152 
153 NAMESPACE_END
154 
155 #endif
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:3179
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
generate static public key
Definition: mqv.h:67
interface for DL group parameters
Definition: pubkey.h:722
void BERDecode(BufferedTransformation &bt)
for backwards compatibility, calls AccessMaterial().Load(bt)
Definition: cryptlib.h:2065
unsigned int EphemeralPublicKeyLength() const
return length of ephemeral public keys in this domain
Definition: mqv.h:77
Abstract base classes that provide a uniform interface to this library.
Ring of congruence classes modulo n.
Definition: modarith.h:27
Interface for random number generators.
Definition: cryptlib.h:1085
Interface for buffered transformations.
Definition: cryptlib.h:1247
static const Integer & One()
Integer representing 1.
Definition: integer.cpp:2931
MQV_Domain< DL_GroupParameters_GFP_DefaultSafePrime > MQV
Menezes-Qu-Vanstone in GF(p) with key validation, AKA MQV
Definition: mqv.h:151
unsigned int BitCount() const
number of significant bits = floor(log2(abs(*this))) + 1
Definition: integer.cpp:3118
MQV domain for performing authenticated key agreement.
Definition: mqv.h:25
static Integer Power2(size_t e)
Exponentiates to a power of 2.
Definition: integer.cpp:2910
unsigned int EphemeralPrivateKeyLength() const
return length of ephemeral private keys in this domain
Definition: mqv.h:76
unsigned int StaticPrivateKeyLength() const
return length of static private keys in this domain
Definition: mqv.h:58
Multiple precision integer with arithmetic operations.
Definition: integer.h:31
unsigned int AgreedValueLength() const
return length of agreed value produced
Definition: mqv.h:57
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
generate static private key
Definition: mqv.h:61
Implementation of schemes based on DL over GF(p)
to be thrown by DecodeElement and AgreeWithStaticPrivateKey
Definition: pubkey.h:714
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
generate ephemeral public key
Definition: mqv.h:88
Interface for crypto prameters.
Definition: cryptlib.h:2050
Class file for performing modular arithmetic.
Crypto++ library namespace.
Interface for domains of authenticated key agreement protocols.
Definition: cryptlib.h:2444
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
generate ephemeral private key
Definition: mqv.h:79
bool Agree(byte *agreedValue, const byte *staticPrivateKey, const byte *ephemeralPrivateKey, const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, bool validateStaticOtherPublicKey=true) const
derive agreed value from your private keys and couterparty&#39;s public keys, return false in case of fai...
Definition: mqv.h:94
unsigned int StaticPublicKeyLength() const
return length of static public keys in this domain
Definition: mqv.h:59