Crypto++
mqv.h
Go to the documentation of this file.
1 #ifndef CRYPTOPP_MQV_H
2 #define CRYPTOPP_MQV_H
3 
4 /** \file
5 */
6 
7 #include "gfpcrypt.h"
8 
9 NAMESPACE_BEGIN(CryptoPP)
10 
11 //! _
12 template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption>
14 {
15 public:
16  typedef GROUP_PARAMETERS GroupParameters;
17  typedef typename GroupParameters::Element Element;
19 
20  MQV_Domain() {}
21 
22  MQV_Domain(const GroupParameters &params)
23  : m_groupParameters(params) {}
24 
26  {m_groupParameters.BERDecode(bt);}
27 
28  template <class T1, class T2>
29  MQV_Domain(T1 v1, T2 v2)
30  {m_groupParameters.Initialize(v1, v2);}
31 
32  template <class T1, class T2, class T3>
33  MQV_Domain(T1 v1, T2 v2, T3 v3)
34  {m_groupParameters.Initialize(v1, v2, v3);}
35 
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);}
39 
40  const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
41  GroupParameters & AccessGroupParameters() {return m_groupParameters;}
42 
43  CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
44 
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);}
48 
49  void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
50  {
51  Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
52  x.Encode(privateKey, StaticPrivateKeyLength());
53  }
54 
55  void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
56  {
57  const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
58  Integer x(privateKey, StaticPrivateKeyLength());
59  Element y = params.ExponentiateBase(x);
60  params.EncodeElement(true, y, publicKey);
61  }
62 
63  unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
64  unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
65 
66  void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
67  {
68  const DL_GroupParameters<Element> &params = 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());
73  }
74 
75  void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
76  {
77  memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
78  }
79 
80  bool Agree(byte *agreedValue,
81  const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
82  const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
83  bool validateStaticOtherPublicKey=true) const
84  {
85  try
86  {
87  const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
88  Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
89  Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
90 
91  Integer s(staticPrivateKey, StaticPrivateKeyLength());
92  Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
93  Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
94 
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;
99 
100  if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
101  {
102  Element P = params.ExponentiateElement(WW, tt);
103  P = m_groupParameters.MultiplyElements(P, VV);
104  Element R[2];
105  const Integer e2[2] = {r, e};
106  params.SimultaneousExponentiate(R, P, e2, 2);
107  if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
108  return false;
109  params.EncodeElement(false, R[1], agreedValue);
110  }
111  else
112  {
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))
118  return false;
119  params.EncodeElement(false, P, agreedValue);
120  }
121  }
122  catch (DL_BadElement &)
123  {
124  return false;
125  }
126  return true;
127  }
128 
129 private:
130  DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
131  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
132 
133  GroupParameters m_groupParameters;
134 };
135 
136 //! Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
138 
139 NAMESPACE_END
140 
141 #endif
static const Integer & One()
avoid calling constructors for these frequently used integers
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
generate static public key
Definition: mqv.h:55
interface for DL group parameters
Definition: pubkey.h:521
void BERDecode(BufferedTransformation &bt)
for backwards compatibility, calls AccessMaterial().Load(bt)
Definition: cryptlib.h:1142
unsigned int EphemeralPublicKeyLength() const
return length of ephemeral public keys in this domain
Definition: mqv.h:64
ring of congruence classes modulo n
Definition: modarith.h:19
interface for random number generators
Definition: cryptlib.h:668
interface for buffered transformations
Definition: cryptlib.h:770
MQV_Domain< DL_GroupParameters_GFP_DefaultSafePrime > MQV
Menezes-Qu-Vanstone in GF(p) with key validation, AKA MQV
Definition: mqv.h:137
unsigned int BitCount() const
number of significant bits = floor(log2(abs(*this))) + 1
_
Definition: mqv.h:13
unsigned int EphemeralPrivateKeyLength() const
return length of ephemeral private keys in this domain
Definition: mqv.h:63
unsigned int StaticPrivateKeyLength() const
return length of static private keys in this domain
Definition: mqv.h:46
multiple precision integer and basic arithmetics
Definition: integer.h:26
unsigned int AgreedValueLength() const
return length of agreed value produced
Definition: mqv.h:45
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
generate static private key
Definition: mqv.h:49
Implementation of schemes based on DL over GF(p)
static Integer Power2(size_t e)
return the integer 2**e
to be thrown by DecodeElement and AgreeWithStaticPrivateKey
Definition: pubkey.h:513
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
generate ephemeral public key
Definition: mqv.h:75
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const
encode in big-endian format
interface for crypto prameters
Definition: cryptlib.h:1127
interface for domains of authenticated key agreement protocols
Definition: cryptlib.h:1468
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
generate ephemeral private key
Definition: mqv.h:66
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's public keys, return false in case of fai...
Definition: mqv.h:80
unsigned int StaticPublicKeyLength() const
return length of static public keys in this domain
Definition: mqv.h:47