Revert "Add HMQV implementation (and merge the old FHMQV into the new codebase)"
This reverts commit ec35099589.
pull/215/merge
parent
efd1b9e3d5
commit
c6c0bdeebe
|
|
@ -1 +0,0 @@
|
|||
3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101
|
||||
|
|
@ -1 +0,0 @@
|
|||
3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101
|
||||
|
|
@ -1 +0,0 @@
|
|||
30820140020101303C06072A8648CE3D0101023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF30640430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC0430B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF046104AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973020101
|
||||
|
|
@ -1 +0,0 @@
|
|||
308201AC020101304D06072A8648CE3D0101024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF308188044201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC04420051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F000481850400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409020101
|
||||
|
|
@ -1 +0,0 @@
|
|||
3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101
|
||||
|
|
@ -1 +0,0 @@
|
|||
3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101
|
||||
|
|
@ -1 +0,0 @@
|
|||
30820140020101303C06072A8648CE3D0101023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF30640430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC0430B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF046104AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973020101
|
||||
|
|
@ -1 +0,0 @@
|
|||
308201AC020101304D06072A8648CE3D0101024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF308188044201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC04420051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F000481850400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409020101
|
||||
44
eccrypto.h
44
eccrypto.h
|
|
@ -16,8 +16,6 @@
|
|||
#include "gfpcrypt.h"
|
||||
#include "dh.h"
|
||||
#include "mqv.h"
|
||||
#include "hmqv.h"
|
||||
#include "fhmqv.h"
|
||||
#include "ecp.h"
|
||||
#include "ec2n.h"
|
||||
|
||||
|
|
@ -215,44 +213,6 @@ struct ECMQV
|
|||
#endif
|
||||
};
|
||||
|
||||
//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation,
|
||||
/*! <a href="http://eprint.iacr.org/2005/176">HMQV: A High-Performance Secure Diffie-Hellman Protocol</a>
|
||||
Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately.
|
||||
*/
|
||||
template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption, class HASH = SHA256>
|
||||
struct HMQV
|
||||
{
|
||||
typedef HMQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION, HASH> Domain;
|
||||
|
||||
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
|
||||
virtual ~HMQV() {}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain HMQV160;
|
||||
typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain HMQV256;
|
||||
typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain HMQV384;
|
||||
typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain HMQV512;
|
||||
|
||||
//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation,
|
||||
/*! <a href="http://eprint.iacr.org/2009/408">A Secure and Efficient Authenticated DiffieHellman Protocol</a>
|
||||
Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C.
|
||||
*/
|
||||
template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption, class HASH = SHA256>
|
||||
struct FHMQV
|
||||
{
|
||||
typedef FHMQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION, HASH> Domain;
|
||||
|
||||
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
|
||||
virtual ~FHMQV() {}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain FHMQV160;
|
||||
typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain FHMQV256;
|
||||
typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain FHMQV384;
|
||||
typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain FHMQV512;
|
||||
|
||||
//! EC keys
|
||||
template <class EC>
|
||||
struct DL_Keys_EC
|
||||
|
|
@ -323,10 +283,10 @@ struct ECNR : public DL_SS<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, DL_SignatureMe
|
|||
};
|
||||
|
||||
//! Elliptic Curve Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">ECIES</a>
|
||||
/*! Choose NoCofactorMultiplication and DHAES_MODE = false for compatibilty with SEC1 and Crypto++ 4.2.
|
||||
/*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2.
|
||||
The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best
|
||||
efficiency and security. */
|
||||
template <class EC, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true>
|
||||
template <class EC, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = false>
|
||||
struct ECIES
|
||||
: public DL_ES<
|
||||
DL_Keys_EC<EC>,
|
||||
|
|
|
|||
14
fhmqv.cpp
14
fhmqv.cpp
|
|
@ -1,14 +0,0 @@
|
|||
// fhmqv.cpp - written and placed in the public domain by Jeffrey Walton
|
||||
// Shamelessly based upon Wei Dai's MQV source files
|
||||
|
||||
#include "pch.h"
|
||||
#include "fhmqv.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void TestInstantiations_FHMQV()
|
||||
{
|
||||
FullyHashedMQV fhmqv;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
294
fhmqv.h
294
fhmqv.h
|
|
@ -1,294 +0,0 @@
|
|||
// fhmqv.h - written and placed in the public domain by Jeffrey Walton
|
||||
// Shamelessly based upon Wei Dai's MQV source files
|
||||
|
||||
#ifndef CRYPTOPP_FHMQV_H
|
||||
#define CRYPTOPP_FHMQV_H
|
||||
|
||||
/** \file
|
||||
*/
|
||||
|
||||
#include "gfpcrypt.h"
|
||||
#include "algebra.h"
|
||||
#include "sha.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation,
|
||||
/*! <a href="http://eprint.iacr.org/2009/408">A Secure and Efficient Authenticated Diffie–Hellman Protocol</a>
|
||||
Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C.
|
||||
*/
|
||||
template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption, class HASH = SHA512>
|
||||
class FHMQV_Domain: public AuthenticatedKeyAgreementDomain
|
||||
{
|
||||
public:
|
||||
typedef GROUP_PARAMETERS GroupParameters;
|
||||
typedef typename GroupParameters::Element Element;
|
||||
typedef FHMQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION, HASH> Domain;
|
||||
|
||||
FHMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {}
|
||||
|
||||
FHMQV_Domain(const GroupParameters ¶ms, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {}
|
||||
|
||||
FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.BERDecode(bt);}
|
||||
|
||||
template <class T1>
|
||||
FHMQV_Domain(T1 v1, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.Initialize(v1);}
|
||||
|
||||
template <class T1, class T2>
|
||||
FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.Initialize(v1, v2);}
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.Initialize(v1, v2, v3);}
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.Initialize(v1, v2, v3, v4);}
|
||||
|
||||
protected:
|
||||
|
||||
inline void Hash(const Element* sigma,
|
||||
const byte* e1, size_t e1len, const byte* e2, size_t e2len,
|
||||
const byte* s1, size_t s1len, const byte* s2, size_t s2len,
|
||||
byte* digest, size_t dlen) const
|
||||
{
|
||||
HASH hash;
|
||||
size_t idx = 0, req = dlen;
|
||||
size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE);
|
||||
|
||||
if(sigma)
|
||||
{
|
||||
Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
|
||||
SecByteBlock sbb(x.MinEncodedSize());
|
||||
x.Encode(sbb.BytePtr(), sbb.SizeInBytes());
|
||||
hash.Update(sbb.BytePtr(), sbb.SizeInBytes());
|
||||
}
|
||||
|
||||
hash.Update(e1, e1len);
|
||||
hash.Update(e2, e2len);
|
||||
hash.Update(s1, s1len);
|
||||
hash.Update(s2, s2len);
|
||||
|
||||
hash.TruncatedFinal(digest, blk);
|
||||
req -= blk;
|
||||
|
||||
// All this to catch tail bytes for large curves and small hashes
|
||||
while(req != 0)
|
||||
{
|
||||
hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE);
|
||||
|
||||
idx += (size_t)HASH::DIGESTSIZE;
|
||||
blk = std::min(req, (size_t)HASH::DIGESTSIZE);
|
||||
hash.TruncatedFinal(&digest[idx], blk);
|
||||
|
||||
req -= blk;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
|
||||
GroupParameters & AccessGroupParameters(){return m_groupParameters;}
|
||||
|
||||
CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();}
|
||||
|
||||
//! return length of agreed value produced
|
||||
unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
|
||||
//! return length of static private keys in this domain
|
||||
unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
|
||||
//! return length of static public keys in this domain
|
||||
unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);}
|
||||
|
||||
//! generate static private key
|
||||
/*! \pre size of privateKey == PrivateStaticKeyLength() */
|
||||
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
|
||||
{
|
||||
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
|
||||
x.Encode(privateKey, StaticPrivateKeyLength());
|
||||
}
|
||||
|
||||
//! generate static public key
|
||||
/*! \pre size of publicKey == PublicStaticKeyLength() */
|
||||
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
|
||||
{
|
||||
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
|
||||
Integer x(privateKey, StaticPrivateKeyLength());
|
||||
Element y = params.ExponentiateBase(x);
|
||||
params.EncodeElement(true, y, publicKey);
|
||||
}
|
||||
|
||||
unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
|
||||
unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();}
|
||||
|
||||
//! return length of ephemeral private keys in this domain
|
||||
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
|
||||
{
|
||||
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
|
||||
Integer x(rng, Integer::One(), params.GetMaxExponent());
|
||||
x.Encode(privateKey, StaticPrivateKeyLength());
|
||||
Element y = params.ExponentiateBase(x);
|
||||
params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
|
||||
}
|
||||
|
||||
//! return length of ephemeral public keys in this domain
|
||||
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
|
||||
{
|
||||
memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
|
||||
}
|
||||
|
||||
//! derive agreed value from your private keys and couterparty's public keys, return false in case of failure
|
||||
/*! \note The ephemeral public key will always be validated.
|
||||
If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.
|
||||
\pre size of agreedValue == AgreedValueLength()
|
||||
\pre length of staticPrivateKey == StaticPrivateKeyLength()
|
||||
\pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
|
||||
\pre length of staticOtherPublicKey == StaticPublicKeyLength()
|
||||
\pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
|
||||
*/
|
||||
bool Agree(byte *agreedValue,
|
||||
const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
|
||||
const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
|
||||
bool validateStaticOtherPublicKey=true) const
|
||||
{
|
||||
byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL;
|
||||
size_t xxs = 0, yys = 0, aas = 0, bbs = 0;
|
||||
|
||||
// Depending on the role, this will hold either A's or B's static
|
||||
// (long term) public key. AA or BB will then point into tt.
|
||||
SecByteBlock tt(StaticPublicKeyLength());
|
||||
|
||||
try
|
||||
{
|
||||
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
|
||||
|
||||
if(m_role == RoleServer)
|
||||
{
|
||||
Integer b(staticPrivateKey, StaticPrivateKeyLength());
|
||||
Element B = params.ExponentiateBase(b);
|
||||
params.EncodeElement(true, B, tt);
|
||||
|
||||
XX = const_cast<byte*>(ephemeralOtherPublicKey);
|
||||
xxs = EphemeralPublicKeyLength();
|
||||
YY = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength();
|
||||
yys = EphemeralPublicKeyLength();
|
||||
AA = const_cast<byte*>(staticOtherPublicKey);
|
||||
aas = StaticPublicKeyLength();
|
||||
BB = tt.BytePtr();
|
||||
bbs = tt.SizeInBytes();
|
||||
}
|
||||
else if(m_role == RoleClient)
|
||||
{
|
||||
Integer a(staticPrivateKey, StaticPrivateKeyLength());
|
||||
Element A = params.ExponentiateBase(a);
|
||||
params.EncodeElement(true, A, tt);
|
||||
|
||||
XX = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength();
|
||||
xxs = EphemeralPublicKeyLength();
|
||||
YY = const_cast<byte*>(ephemeralOtherPublicKey);
|
||||
yys = EphemeralPublicKeyLength();
|
||||
AA = tt.BytePtr();
|
||||
aas = tt.SizeInBytes();
|
||||
BB = const_cast<byte*>(staticOtherPublicKey);
|
||||
bbs = StaticPublicKeyLength();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
|
||||
// VerifyPoint to ensure the element is in G*. If the other's PublicKey is
|
||||
// requested to be validated, we manually call ValidateElement at level 3.
|
||||
Element VV1 = params.DecodeElement(staticOtherPublicKey, false);
|
||||
if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL))
|
||||
return false;
|
||||
|
||||
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
|
||||
// VerifyPoint to ensure the element is in G*. Crank it up.
|
||||
Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false);
|
||||
if(!params.ValidateElement(3, VV2, NULL))
|
||||
return false;
|
||||
|
||||
const Integer& p = params.GetGroupOrder();
|
||||
const Integer& q = params.GetSubgroupOrder();
|
||||
const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8);
|
||||
|
||||
Integer d, e;
|
||||
SecByteBlock dd(len), ee(len);
|
||||
|
||||
Hash(NULL, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes());
|
||||
d.Decode(dd.BytePtr(), dd.SizeInBytes());
|
||||
|
||||
Hash(NULL, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes());
|
||||
e.Decode(ee.BytePtr(), ee.SizeInBytes());
|
||||
|
||||
Element sigma;
|
||||
if(m_role == RoleServer)
|
||||
{
|
||||
Integer y(ephemeralPrivateKey, StaticPrivateKeyLength());
|
||||
Integer b(staticPrivateKey, StaticPrivateKeyLength());
|
||||
Integer s_B = (y + e * b) % q;
|
||||
|
||||
Element A = params.DecodeElement(AA, false);
|
||||
Element X = params.DecodeElement(XX, false);
|
||||
|
||||
Element t1 = params.ExponentiateElement(A, d);
|
||||
Element t2 = m_groupParameters.MultiplyElements(X, t1);
|
||||
|
||||
sigma = params.ExponentiateElement(t2, s_B);
|
||||
}
|
||||
else
|
||||
{
|
||||
Integer x(ephemeralPrivateKey, StaticPrivateKeyLength());
|
||||
Integer a(staticPrivateKey, StaticPrivateKeyLength());
|
||||
Integer s_A = (x + d * a) % q;
|
||||
|
||||
Element B = params.DecodeElement(BB, false);
|
||||
Element Y = params.DecodeElement(YY, false);
|
||||
|
||||
Element t1 = params.ExponentiateElement(B, e);
|
||||
Element t2 = m_groupParameters.MultiplyElements(Y, t1);
|
||||
|
||||
sigma = params.ExponentiateElement(t2, s_A);
|
||||
}
|
||||
|
||||
Hash(&sigma, XX, xxs, YY, yys, AA, aas, BB, bbs, agreedValue, AgreedValueLength());
|
||||
}
|
||||
catch (DL_BadElement &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// The paper uses Initiator and Recipient - make it classical.
|
||||
enum KeyAgreementRole{ RoleServer = 1, RoleClient };
|
||||
|
||||
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
|
||||
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const{return m_groupParameters;}
|
||||
|
||||
KeyAgreementRole m_role;
|
||||
GroupParameters m_groupParameters;
|
||||
};
|
||||
|
||||
//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation,
|
||||
/*! <a href="http://eprint.iacr.org/2009/408">A Secure and Efficient Authenticated Diffie–Hellman Protocol</a>
|
||||
Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C.
|
||||
*/
|
||||
typedef FHMQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> FullyHashedMQV;
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
14
hmqv.cpp
14
hmqv.cpp
|
|
@ -1,14 +0,0 @@
|
|||
// hmqv.cpp - written and placed in the public domain by Uri Blumenthal
|
||||
// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files
|
||||
|
||||
#include "pch.h"
|
||||
#include "hmqv.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void TestInstantiations_HMQV()
|
||||
{
|
||||
HashedMQV hmqv;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
303
hmqv.h
303
hmqv.h
|
|
@ -1,303 +0,0 @@
|
|||
// hmqv.h - written and placed in the public domain by Uri Blumenthal
|
||||
// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files
|
||||
|
||||
#ifndef CRYPTOPP_HMQV_H
|
||||
#define CRYPTOPP_HMQV_H
|
||||
|
||||
/** \file
|
||||
*/
|
||||
|
||||
#include "gfpcrypt.h"
|
||||
#include "algebra.h"
|
||||
#include "sha.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation,
|
||||
/*! <a href="http://eprint.iacr.org/2005/176">HMQV: A High-Performance Secure Diffie-Hellman Protocol</a>
|
||||
Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately.
|
||||
*/
|
||||
template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption, class HASH = SHA512>
|
||||
class HMQV_Domain: public AuthenticatedKeyAgreementDomain
|
||||
{
|
||||
public:
|
||||
typedef GROUP_PARAMETERS GroupParameters;
|
||||
typedef typename GroupParameters::Element Element;
|
||||
typedef HMQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION, HASH> Domain;
|
||||
|
||||
HMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {}
|
||||
|
||||
HMQV_Domain(const GroupParameters ¶ms, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {}
|
||||
|
||||
HMQV_Domain(BufferedTransformation &bt, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.BERDecode(bt);}
|
||||
|
||||
template <class T1>
|
||||
HMQV_Domain(T1 v1, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.Initialize(v1);}
|
||||
|
||||
template <class T1, class T2>
|
||||
HMQV_Domain(T1 v1, T2 v2, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.Initialize(v1, v2);}
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.Initialize(v1, v2, v3);}
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true)
|
||||
: m_role(clientRole ? RoleClient : RoleServer)
|
||||
{m_groupParameters.Initialize(v1, v2, v3, v4);}
|
||||
|
||||
protected:
|
||||
// Hash invocation by client and server differ only in what keys
|
||||
// each provides.
|
||||
|
||||
inline void Hash(const Element* sigma,
|
||||
const byte* e1, size_t e1len, // Ephemeral key and key length
|
||||
const byte* s1, size_t s1len, // Static key and key length
|
||||
byte* digest, size_t dlen) const
|
||||
{
|
||||
HASH hash;
|
||||
size_t idx = 0, req = dlen;
|
||||
size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE);
|
||||
|
||||
if(sigma)
|
||||
{
|
||||
if (e1len != 0 || s1len != 0) {
|
||||
assert(0);
|
||||
}
|
||||
Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
|
||||
SecByteBlock sbb(x.MinEncodedSize());
|
||||
x.Encode(sbb.BytePtr(), sbb.SizeInBytes());
|
||||
hash.Update(sbb.BytePtr(), sbb.SizeInBytes());
|
||||
} else {
|
||||
if (e1len == 0 || s1len == 0) {
|
||||
assert(0);
|
||||
}
|
||||
hash.Update(e1, e1len);
|
||||
hash.Update(s1, s1len);
|
||||
}
|
||||
|
||||
hash.TruncatedFinal(digest, blk);
|
||||
req -= blk;
|
||||
|
||||
// All this to catch tail bytes for large curves and small hashes
|
||||
while(req != 0)
|
||||
{
|
||||
hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE);
|
||||
|
||||
idx += (size_t)HASH::DIGESTSIZE;
|
||||
blk = std::min(req, (size_t)HASH::DIGESTSIZE);
|
||||
hash.TruncatedFinal(&digest[idx], blk);
|
||||
|
||||
req -= blk;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
|
||||
GroupParameters & AccessGroupParameters(){return m_groupParameters;}
|
||||
|
||||
CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();}
|
||||
|
||||
//! return length of agreed value produced
|
||||
unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
|
||||
//! return length of static private keys in this domain
|
||||
unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
|
||||
//! return length of static public keys in this domain
|
||||
unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);}
|
||||
|
||||
//! generate static private key
|
||||
/*! \pre size of privateKey == PrivateStaticKeyLength() */
|
||||
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
|
||||
{
|
||||
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
|
||||
x.Encode(privateKey, StaticPrivateKeyLength());
|
||||
}
|
||||
|
||||
//! generate static public key
|
||||
/*! \pre size of publicKey == PublicStaticKeyLength() */
|
||||
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
|
||||
{
|
||||
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
|
||||
Integer x(privateKey, StaticPrivateKeyLength());
|
||||
Element y = params.ExponentiateBase(x);
|
||||
params.EncodeElement(true, y, publicKey);
|
||||
}
|
||||
|
||||
unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
|
||||
unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();}
|
||||
|
||||
//! return length of ephemeral private keys in this domain
|
||||
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
|
||||
{
|
||||
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
|
||||
Integer x(rng, Integer::One(), params.GetMaxExponent());
|
||||
x.Encode(privateKey, StaticPrivateKeyLength());
|
||||
Element y = params.ExponentiateBase(x);
|
||||
params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
|
||||
}
|
||||
|
||||
//! return length of ephemeral public keys in this domain
|
||||
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
|
||||
{
|
||||
memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
|
||||
}
|
||||
|
||||
//! derive agreed value from your private keys and couterparty's public keys, return false in case of failure
|
||||
/*! \note The ephemeral public key will always be validated.
|
||||
If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.
|
||||
\pre size of agreedValue == AgreedValueLength()
|
||||
\pre length of staticPrivateKey == StaticPrivateKeyLength()
|
||||
\pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
|
||||
\pre length of staticOtherPublicKey == StaticPublicKeyLength()
|
||||
\pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
|
||||
*/
|
||||
bool Agree(byte *agreedValue,
|
||||
const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
|
||||
const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
|
||||
bool validateStaticOtherPublicKey=true) const
|
||||
{
|
||||
byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL;
|
||||
size_t xxs = 0, yys = 0, aas = 0, bbs = 0;
|
||||
|
||||
// Depending on the role, this will hold either A's or B's static
|
||||
// (long term) public key. AA or BB will then point into tt.
|
||||
SecByteBlock tt(StaticPublicKeyLength());
|
||||
|
||||
try
|
||||
{
|
||||
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
|
||||
|
||||
if(m_role == RoleServer)
|
||||
{
|
||||
Integer b(staticPrivateKey, StaticPrivateKeyLength());
|
||||
Element B = params.ExponentiateBase(b);
|
||||
params.EncodeElement(true, B, tt);
|
||||
|
||||
XX = const_cast<byte*>(ephemeralOtherPublicKey);
|
||||
xxs = EphemeralPublicKeyLength();
|
||||
YY = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength();
|
||||
yys = EphemeralPublicKeyLength();
|
||||
AA = const_cast<byte*>(staticOtherPublicKey);
|
||||
aas = StaticPublicKeyLength();
|
||||
BB = tt.BytePtr();
|
||||
bbs = tt.SizeInBytes();
|
||||
}
|
||||
else if(m_role == RoleClient)
|
||||
{
|
||||
Integer a(staticPrivateKey, StaticPrivateKeyLength());
|
||||
Element A = params.ExponentiateBase(a);
|
||||
params.EncodeElement(true, A, tt);
|
||||
|
||||
XX = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength();
|
||||
xxs = EphemeralPublicKeyLength();
|
||||
YY = const_cast<byte*>(ephemeralOtherPublicKey);
|
||||
yys = EphemeralPublicKeyLength();
|
||||
AA = tt.BytePtr();
|
||||
aas = tt.SizeInBytes();
|
||||
BB = const_cast<byte*>(staticOtherPublicKey);
|
||||
bbs = StaticPublicKeyLength();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
|
||||
// VerifyPoint to ensure the element is in G*. If the other's PublicKey is
|
||||
// requested to be validated, we manually call ValidateElement at level 3.
|
||||
Element VV1 = params.DecodeElement(staticOtherPublicKey, false);
|
||||
if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL))
|
||||
return false;
|
||||
|
||||
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
|
||||
// VerifyPoint to ensure the element is in G*. Crank it up.
|
||||
Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false);
|
||||
if(!params.ValidateElement(3, VV2, NULL))
|
||||
return false;
|
||||
|
||||
// const Integer& p = params.GetGroupOrder(); // not used, remove later
|
||||
const Integer& q = params.GetSubgroupOrder();
|
||||
const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8);
|
||||
|
||||
Integer d, e;
|
||||
SecByteBlock dd(len), ee(len);
|
||||
|
||||
// Compute $d = \hat{H}(X, \hat{B})$
|
||||
Hash(NULL, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes());
|
||||
d.Decode(dd.BytePtr(), dd.SizeInBytes());
|
||||
|
||||
// Compute $e = \hat{H}(Y, \hat{A})$
|
||||
Hash(NULL, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes());
|
||||
e.Decode(ee.BytePtr(), ee.SizeInBytes());
|
||||
|
||||
Element sigma;
|
||||
if(m_role == RoleServer)
|
||||
{
|
||||
Integer y(ephemeralPrivateKey, StaticPrivateKeyLength());
|
||||
Integer b(staticPrivateKey, StaticPrivateKeyLength());
|
||||
Integer s_B = (y + e * b) % q;
|
||||
|
||||
Element A = params.DecodeElement(AA, false);
|
||||
Element X = params.DecodeElement(XX, false);
|
||||
|
||||
Element t1 = params.ExponentiateElement(A, d);
|
||||
Element t2 = m_groupParameters.MultiplyElements(X, t1);
|
||||
|
||||
// $\sigma_B}=(X \cdot A^{d})^{s_B}
|
||||
sigma = params.ExponentiateElement(t2, s_B);
|
||||
}
|
||||
else
|
||||
{
|
||||
Integer x(ephemeralPrivateKey, StaticPrivateKeyLength());
|
||||
Integer a(staticPrivateKey, StaticPrivateKeyLength());
|
||||
Integer s_A = (x + d * a) % q;
|
||||
|
||||
Element B = params.DecodeElement(BB, false);
|
||||
Element Y = params.DecodeElement(YY, false);
|
||||
|
||||
Element t1 = params.ExponentiateElement(B, e);
|
||||
Element t2 = m_groupParameters.MultiplyElements(Y, t1);
|
||||
|
||||
// $\sigma_A}=(Y \cdot B^{e})^{s_A}
|
||||
sigma = params.ExponentiateElement(t2, s_A);
|
||||
}
|
||||
Hash(&sigma, NULL, 0, NULL, 0, agreedValue, AgreedValueLength());
|
||||
}
|
||||
catch (DL_BadElement &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// The paper uses Initiator and Recipient - make it classical.
|
||||
enum KeyAgreementRole{ RoleServer = 1, RoleClient };
|
||||
|
||||
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
|
||||
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const{return m_groupParameters;}
|
||||
|
||||
KeyAgreementRole m_role;
|
||||
GroupParameters m_groupParameters;
|
||||
};
|
||||
|
||||
//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation,
|
||||
/*! <a href="http://eprint.iacr.org/2005/176">HMQV: A High-Performance Secure Diffie-Hellman Protocol</a>
|
||||
Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately.
|
||||
*/
|
||||
typedef HMQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> HashedMQV;
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -149,8 +149,6 @@ bool ValidateAll(bool thorough)
|
|||
pass=ValidateBBS() && pass;
|
||||
pass=ValidateDH() && pass;
|
||||
pass=ValidateMQV() && pass;
|
||||
pass=ValidateHMQV() && pass;
|
||||
pass=ValidateFHMQV() && pass;
|
||||
pass=ValidateRSA() && pass;
|
||||
pass=ValidateElGamal() && pass;
|
||||
pass=ValidateDLIES() && pass;
|
||||
|
|
|
|||
236
validat2.cpp
236
validat2.cpp
|
|
@ -18,8 +18,6 @@
|
|||
#include "dsa.h"
|
||||
#include "dh.h"
|
||||
#include "mqv.h"
|
||||
#include "hmqv.h"
|
||||
#include "fhmqv.h"
|
||||
#include "luc.h"
|
||||
#include "xtrcrypt.h"
|
||||
#include "rabin.h"
|
||||
|
|
@ -386,240 +384,6 @@ bool ValidateMQV()
|
|||
return AuthenticatedKeyAgreementValidate(mqv);
|
||||
}
|
||||
|
||||
bool ValidateHMQV()
|
||||
{
|
||||
std::cout << "\nHMQV validation suite running...\n\n";
|
||||
|
||||
//HMQV< ECP >::Domain hmqvB(false /*server*/);
|
||||
HMQV256 hmqvB(false);
|
||||
FileSource f256("TestData/hmqv256.dat", true, new HexDecoder());
|
||||
FileSource f384("TestData/hmqv384.dat", true, new HexDecoder());
|
||||
FileSource f512("TestData/hmqv512.dat", true, new HexDecoder());
|
||||
hmqvB.AccessGroupParameters().BERDecode(f256);
|
||||
|
||||
std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl;
|
||||
|
||||
if (hmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3))
|
||||
std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const OID oid = ASN1::secp256r1();
|
||||
HMQV< ECP >::Domain hmqvA(oid, true /*client*/);
|
||||
|
||||
if (hmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3))
|
||||
std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
SecByteBlock sprivA(hmqvA.StaticPrivateKeyLength()), sprivB(hmqvB.StaticPrivateKeyLength());
|
||||
SecByteBlock eprivA(hmqvA.EphemeralPrivateKeyLength()), eprivB(hmqvB.EphemeralPrivateKeyLength());
|
||||
SecByteBlock spubA(hmqvA.StaticPublicKeyLength()), spubB(hmqvB.StaticPublicKeyLength());
|
||||
SecByteBlock epubA(hmqvA.EphemeralPublicKeyLength()), epubB(hmqvB.EphemeralPublicKeyLength());
|
||||
SecByteBlock valA(hmqvA.AgreedValueLength()), valB(hmqvB.AgreedValueLength());
|
||||
|
||||
hmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA);
|
||||
hmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB);
|
||||
hmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA);
|
||||
hmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB);
|
||||
|
||||
memset(valA.begin(), 0x00, valA.size());
|
||||
memset(valB.begin(), 0x11, valB.size());
|
||||
|
||||
if (!(hmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && hmqvB.Agree(valB, sprivB, eprivB, spubA, epubA)))
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(valA.begin(), valB.begin(), hmqvA.AgreedValueLength()))
|
||||
{
|
||||
std::cout << "FAILED authenticated agreed values not equal" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "passed authenticated key agreement" << std::endl;
|
||||
|
||||
// Now test HMQV with NIST P-384 curve and SHA384 hash
|
||||
std::cout << endl;
|
||||
std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl;
|
||||
|
||||
HMQV384 hmqvB384(false);
|
||||
hmqvB384.AccessGroupParameters().BERDecode(f384);
|
||||
|
||||
if (hmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3))
|
||||
std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const OID oid384 = ASN1::secp384r1();
|
||||
HMQV384 hmqvA384(oid384, true /*client*/);
|
||||
|
||||
if (hmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3))
|
||||
std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
SecByteBlock sprivA384(hmqvA384.StaticPrivateKeyLength()), sprivB384(hmqvB384.StaticPrivateKeyLength());
|
||||
SecByteBlock eprivA384(hmqvA384.EphemeralPrivateKeyLength()), eprivB384(hmqvB384.EphemeralPrivateKeyLength());
|
||||
SecByteBlock spubA384(hmqvA384.StaticPublicKeyLength()), spubB384(hmqvB384.StaticPublicKeyLength());
|
||||
SecByteBlock epubA384(hmqvA384.EphemeralPublicKeyLength()), epubB384(hmqvB384.EphemeralPublicKeyLength());
|
||||
SecByteBlock valA384(hmqvA384.AgreedValueLength()), valB384(hmqvB384.AgreedValueLength());
|
||||
|
||||
hmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384);
|
||||
hmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384);
|
||||
hmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384);
|
||||
hmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384);
|
||||
|
||||
memset(valA384.begin(), 0x00, valA384.size());
|
||||
memset(valB384.begin(), 0x11, valB384.size());
|
||||
|
||||
if (!(hmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && hmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384)))
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(valA384.begin(), valB384.begin(), hmqvA384.AgreedValueLength()))
|
||||
{
|
||||
std::cout << "FAILED authenticated agreed values not equal" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "passed authenticated key agreement" << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateFHMQV()
|
||||
{
|
||||
std::cout << "\nFHMQV validation suite running...\n\n";
|
||||
|
||||
//FHMQV< ECP >::Domain fhmqvB(false /*server*/);
|
||||
FHMQV256 fhmqvB(false);
|
||||
FileSource f256("TestData/fhmqv256.dat", true, new HexDecoder());
|
||||
FileSource f384("TestData/fhmqv384.dat", true, new HexDecoder());
|
||||
FileSource f512("TestData/fhmqv512.dat", true, new HexDecoder());
|
||||
fhmqvB.AccessGroupParameters().BERDecode(f256);
|
||||
|
||||
std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl;
|
||||
|
||||
if (fhmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3))
|
||||
std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const OID oid = ASN1::secp256r1();
|
||||
FHMQV< ECP >::Domain fhmqvA(oid, true /*client*/);
|
||||
|
||||
if (fhmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3))
|
||||
std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
SecByteBlock sprivA(fhmqvA.StaticPrivateKeyLength()), sprivB(fhmqvB.StaticPrivateKeyLength());
|
||||
SecByteBlock eprivA(fhmqvA.EphemeralPrivateKeyLength()), eprivB(fhmqvB.EphemeralPrivateKeyLength());
|
||||
SecByteBlock spubA(fhmqvA.StaticPublicKeyLength()), spubB(fhmqvB.StaticPublicKeyLength());
|
||||
SecByteBlock epubA(fhmqvA.EphemeralPublicKeyLength()), epubB(fhmqvB.EphemeralPublicKeyLength());
|
||||
SecByteBlock valA(fhmqvA.AgreedValueLength()), valB(fhmqvB.AgreedValueLength());
|
||||
|
||||
fhmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA);
|
||||
fhmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB);
|
||||
fhmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA);
|
||||
fhmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB);
|
||||
|
||||
memset(valA.begin(), 0x00, valA.size());
|
||||
memset(valB.begin(), 0x11, valB.size());
|
||||
|
||||
if (!(fhmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && fhmqvB.Agree(valB, sprivB, eprivB, spubA, epubA)))
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(valA.begin(), valB.begin(), fhmqvA.AgreedValueLength()))
|
||||
{
|
||||
std::cout << "FAILED authenticated agreed values not equal" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "passed authenticated key agreement" << std::endl;
|
||||
|
||||
// Now test FHMQV with NIST P-384 curve and SHA384 hash
|
||||
std::cout << endl;
|
||||
std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl;
|
||||
|
||||
FHMQV384 fhmqvB384(false);
|
||||
fhmqvB384.AccessGroupParameters().BERDecode(f384);
|
||||
|
||||
if (fhmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3))
|
||||
std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const OID oid384 = ASN1::secp384r1();
|
||||
FHMQV384 fhmqvA384(oid384, true /*client*/);
|
||||
|
||||
if (fhmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3))
|
||||
std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
SecByteBlock sprivA384(fhmqvA384.StaticPrivateKeyLength()), sprivB384(fhmqvB384.StaticPrivateKeyLength());
|
||||
SecByteBlock eprivA384(fhmqvA384.EphemeralPrivateKeyLength()), eprivB384(fhmqvB384.EphemeralPrivateKeyLength());
|
||||
SecByteBlock spubA384(fhmqvA384.StaticPublicKeyLength()), spubB384(fhmqvB384.StaticPublicKeyLength());
|
||||
SecByteBlock epubA384(fhmqvA384.EphemeralPublicKeyLength()), epubB384(fhmqvB384.EphemeralPublicKeyLength());
|
||||
SecByteBlock valA384(fhmqvA384.AgreedValueLength()), valB384(fhmqvB384.AgreedValueLength());
|
||||
|
||||
fhmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384);
|
||||
fhmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384);
|
||||
fhmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384);
|
||||
fhmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384);
|
||||
|
||||
memset(valA384.begin(), 0x00, valA384.size());
|
||||
memset(valB384.begin(), 0x11, valB384.size());
|
||||
|
||||
if (!(fhmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && fhmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384)))
|
||||
{
|
||||
std::cout << "FAILED authenticated key agreement failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(valA384.begin(), valB384.begin(), fhmqvA384.AgreedValueLength()))
|
||||
{
|
||||
std::cout << "FAILED authenticated agreed values not equal" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "passed authenticated key agreement" << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateLUC_DH()
|
||||
{
|
||||
cout << "\nLUC-DH validation suite running...\n\n";
|
||||
|
|
|
|||
|
|
@ -71,8 +71,6 @@ bool ValidateCMAC();
|
|||
bool ValidateBBS();
|
||||
bool ValidateDH();
|
||||
bool ValidateMQV();
|
||||
bool ValidateHMQV();
|
||||
bool ValidateFHMQV();
|
||||
bool ValidateRSA();
|
||||
bool ValidateElGamal();
|
||||
bool ValidateDLIES();
|
||||
|
|
|
|||
Loading…
Reference in New Issue