4 #ifndef CRYPTOPP_HMQV_H 5 #define CRYPTOPP_HMQV_H 22 template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption, class HASH =
SHA512>
26 typedef GROUP_PARAMETERS GroupParameters;
27 typedef typename GroupParameters::Element Element;
30 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 34 HMQV_Domain(
bool clientRole =
true): m_role(clientRole ? RoleClient : RoleServer) {}
36 HMQV_Domain(
const GroupParameters ¶ms,
bool clientRole =
true)
37 : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {}
40 : m_role(clientRole ? RoleClient : RoleServer)
41 {m_groupParameters.BERDecode(bt);}
45 : m_role(clientRole ? RoleClient : RoleServer)
46 {m_groupParameters.Initialize(v1);}
48 template <
class T1,
class T2>
50 : m_role(clientRole ? RoleClient : RoleServer)
51 {m_groupParameters.Initialize(v1, v2);}
53 template <
class T1,
class T2,
class T3>
54 HMQV_Domain(T1 v1, T2 v2, T3 v3,
bool clientRole =
true)
55 : m_role(clientRole ? RoleClient : RoleServer)
56 {m_groupParameters.Initialize(v1, v2, v3);}
58 template <
class T1,
class T2,
class T3,
class T4>
59 HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4,
bool clientRole =
true)
60 : m_role(clientRole ? RoleClient : RoleServer)
61 {m_groupParameters.Initialize(v1, v2, v3, v4);}
65 const GroupParameters & GetGroupParameters()
const {
return m_groupParameters;}
66 GroupParameters & AccessGroupParameters(){
return m_groupParameters;}
71 unsigned int AgreedValueLength()
const {
return GetAbstractGroupParameters().GetEncodedElementSize(
false);}
82 x.
Encode(privateKey, StaticPrivateKeyLength());
91 Integer x(privateKey, StaticPrivateKeyLength());
104 x.Encode(privateKey, StaticPrivateKeyLength());
106 params.
EncodeElement(
true, y, privateKey+StaticPrivateKeyLength());
112 CRYPTOPP_UNUSED(rng);
113 memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
126 const byte *staticPrivateKey,
const byte *ephemeralPrivateKey,
127 const byte *staticOtherPublicKey,
const byte *ephemeralOtherPublicKey,
128 bool validateStaticOtherPublicKey=
true)
const 130 byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL;
131 size_t xxs = 0, yys = 0, aas = 0, bbs = 0;
141 if(m_role == RoleServer)
143 Integer b(staticPrivateKey, StaticPrivateKeyLength());
147 XX =
const_cast<byte*
>(ephemeralOtherPublicKey);
148 xxs = EphemeralPublicKeyLength();
149 YY =
const_cast<byte*
>(ephemeralPrivateKey) + StaticPrivateKeyLength();
150 yys = EphemeralPublicKeyLength();
151 AA =
const_cast<byte*
>(staticOtherPublicKey);
152 aas = StaticPublicKeyLength();
156 else if(m_role == RoleClient)
158 Integer a(staticPrivateKey, StaticPrivateKeyLength());
162 XX =
const_cast<byte*
>(ephemeralPrivateKey) + StaticPrivateKeyLength();
163 xxs = EphemeralPublicKeyLength();
164 YY =
const_cast<byte*
>(ephemeralOtherPublicKey);
165 yys = EphemeralPublicKeyLength();
168 BB =
const_cast<byte*
>(staticOtherPublicKey);
169 bbs = StaticPublicKeyLength();
180 Element VV1 = params.
DecodeElement(staticOtherPublicKey,
false);
181 if(!params.
ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL))
186 Element VV2 = params.
DecodeElement(ephemeralOtherPublicKey,
false);
192 const unsigned int len = (((q.
BitCount()+1)/2 +7)/8);
198 Hash(NULL, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes());
199 d.
Decode(dd.BytePtr(), dd.SizeInBytes());
206 if(m_role == RoleServer)
208 Integer y(ephemeralPrivateKey, StaticPrivateKeyLength());
209 Integer b(staticPrivateKey, StaticPrivateKeyLength());
216 Element t2 = m_groupParameters.MultiplyElements(X, t1);
223 Integer x(ephemeralPrivateKey, StaticPrivateKeyLength());
224 Integer a(staticPrivateKey, StaticPrivateKeyLength());
231 Element t2 = m_groupParameters.MultiplyElements(Y, t1);
236 Hash(&sigma, NULL, 0, NULL, 0, agreedValue, AgreedValueLength());
249 inline void Hash(
const Element* sigma,
250 const byte* e1,
size_t e1len,
251 const byte* s1,
size_t s1len,
252 byte* digest,
size_t dlen)
const 255 size_t idx = 0, req = dlen;
256 size_t blk = std::min(dlen, (
size_t)HASH::DIGESTSIZE);
260 if (e1len != 0 || s1len != 0) {
263 Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
265 x.
Encode(sbb.BytePtr(), sbb.SizeInBytes());
266 hash.Update(sbb.BytePtr(), sbb.SizeInBytes());
268 if (e1len == 0 || s1len == 0) {
271 hash.Update(e1, e1len);
272 hash.Update(s1, s1len);
275 hash.TruncatedFinal(digest, blk);
281 hash.Update(&digest[idx], (
size_t)HASH::DIGESTSIZE);
283 idx += (size_t)HASH::DIGESTSIZE;
284 blk = std::min(req, (
size_t)HASH::DIGESTSIZE);
285 hash.TruncatedFinal(&digest[idx], blk);
294 enum KeyAgreementRole{ RoleServer = 1, RoleClient };
299 GroupParameters m_groupParameters;
300 KeyAgreementRole m_role;
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
return length of ephemeral public keys in this domain
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...
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
generate static public key
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Interface for Discrete Log (DL) group parameters.
unsigned int StaticPrivateKeyLength() const
return length of static private keys in this domain
Hashed Menezes-Qu-Vanstone in GF(p)
Interface for random number generators.
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
The minimum number of bytes to encode this integer.
Classes for performing mathematics over different fields.
static const Integer & One()
Integer representing 1.
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
generate static private key
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
CryptoParameters & AccessCryptoParameters()
Retrieves a reference to Crypto Parameters.
unsigned int AgreedValueLength() const
return length of agreed value produced
implements the SHA-512 standard
HMQV_Domain< DL_GroupParameters_GFP_DefaultSafePrime > HMQV
Hashed Menezes-Qu-Vanstone in GF(p)
Multiple precision integer with arithmetic operations.
Implementation of schemes based on DL over GF(p)
unsigned int EphemeralPrivateKeyLength() const
Provides the size of ephemeral private key.
virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0
Decodes the element.
unsigned int EphemeralPublicKeyLength() const
Provides the size of ephemeral public key.
Exception thrown when an invalid group element is encountered.
virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation< Element > *precomp) const =0
Check the element for errors.
Classes for SHA-1 and SHA-2 family of message digests.
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
void Decode(const byte *input, size_t inputLen, Signedness sign=UNSIGNED)
Decode from big-endian byte array.
Interface for crypto prameters.
virtual Integer GetMaxExponent() const =0
Retrieves the maximum exponent for the group.
Crypto++ library namespace.
Interface for domains of authenticated key agreement protocols.
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
return length of ephemeral private keys in this domain
size_type SizeInBytes() const
Provides the number of bytes in the SecBlock.
virtual Element ExponentiateBase(const Integer &exponent) const
Retrieves the subgroup generator.
virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
Exponentiates an element.
unsigned int StaticPublicKeyLength() const
return length of static public keys in this domain
byte * BytePtr()
Provides a byte pointer to the first element in the memory block.
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.