Just use unordered_map, and some other cleanup.

This commit is contained in:
Adam Ierymenko 2020-03-31 09:01:58 -07:00
parent b3314cd34f
commit 1f85b0402e
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
6 changed files with 70 additions and 56 deletions

View file

@ -2367,19 +2367,19 @@ ZT_INLINE void get_hram(unsigned char *hram,const unsigned char *sm,const unsign
namespace ZeroTier {
void C25519::generate(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN])
void C25519::generate(uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE])
{
Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN);
Utils::getSecureRandom(priv,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
_calcPubDH(pub,priv);
_calcPubED(pub,priv);
}
void C25519::agree(const uint8_t mine[ZT_C25519_PRIVATE_KEY_LEN],const uint8_t their[ZT_C25519_PUBLIC_KEY_LEN],uint8_t rawkey[32])
void C25519::agree(const uint8_t mine[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE],const uint8_t their[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],uint8_t rawkey[ZT_C25519_ECDH_SHARED_SECRET_SIZE])
{
crypto_scalarmult(rawkey,mine,their);
}
void C25519::sign(const uint8_t myPrivate[ZT_C25519_PRIVATE_KEY_LEN],const uint8_t myPublic[ZT_C25519_PUBLIC_KEY_LEN],const void *msg,unsigned int len,void *signature)
void C25519::sign(const uint8_t myPrivate[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE],const uint8_t myPublic[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],const void *msg,unsigned int len,void *signature)
{
unsigned char digest[64]; // we sign the first 32 bytes of SHA-512(msg)
SHA512(digest,msg,len);
@ -2427,7 +2427,7 @@ void C25519::sign(const uint8_t myPrivate[ZT_C25519_PRIVATE_KEY_LEN],const uint8
sig[32 + i] = s[i];
}
bool C25519::verify(const uint8_t their[ZT_C25519_PUBLIC_KEY_LEN],const void *msg,unsigned int len,const void *signature,const unsigned int siglen)
bool C25519::verify(const uint8_t their[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],const void *msg,unsigned int len,const void *signature,const unsigned int siglen)
{
if (siglen < 64) return false;
@ -2465,14 +2465,14 @@ bool C25519::verify(const uint8_t their[ZT_C25519_PUBLIC_KEY_LEN],const void *ms
return Utils::secureEq(sig,t2,32);
}
void C25519::_calcPubDH(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],const uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN])
void C25519::_calcPubDH(uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],const uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE])
{
// First 32 bytes of pub and priv are the keys for ECDH key
// agreement. This generates the public portion from the private.
crypto_scalarmult_base(pub,priv);
}
void C25519::_calcPubED(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],const uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN])
void C25519::_calcPubED(uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],const uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE])
{
struct {
uint8_t extsk[64];

View file

@ -22,10 +22,10 @@
namespace ZeroTier {
#define ZT_C25519_PUBLIC_KEY_LEN 64
#define ZT_C25519_PRIVATE_KEY_LEN 64
#define ZT_C25519_COMBINED_PUBLIC_KEY_SIZE 64
#define ZT_C25519_COMBINED_PRIVATE_KEY_SIZE 64
#define ZT_C25519_SIGNATURE_LEN 96
#define ZT_C25519_SHARED_KEY_LEN 32
#define ZT_C25519_ECDH_SHARED_SECRET_SIZE 32
/**
* A combined Curve25519 ECDH and Ed25519 signature engine
@ -36,7 +36,7 @@ public:
/**
* Generate a C25519 elliptic curve key pair
*/
static void generate(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN]);
static void generate(uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE]);
/**
* Generate a key pair satisfying a condition
@ -52,9 +52,9 @@ public:
* @tparam F Type of 'cond'
*/
template<typename F>
static ZT_INLINE void generateSatisfying(F cond,uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN])
static ZT_INLINE void generateSatisfying(F cond,uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE])
{
Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN);
Utils::getSecureRandom(priv,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
_calcPubED(pub,priv); // do Ed25519 key -- bytes 32-63 of pub and priv
do {
++(((uint64_t *)priv)[1]);
@ -73,15 +73,18 @@ public:
* @param their Their public key
* @param rawkey Buffer to receive raw (not hashed) agreed upon key
*/
static void agree(const uint8_t mine[ZT_C25519_PRIVATE_KEY_LEN],const uint8_t their[ZT_C25519_PUBLIC_KEY_LEN],uint8_t rawkey[ZT_C25519_SHARED_KEY_LEN]);
static void agree(const uint8_t mine[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE],const uint8_t their[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],uint8_t rawkey[ZT_C25519_ECDH_SHARED_SECRET_SIZE]);
/**
* Sign a message with a sender's key pair
*
* For legacy reasons ZeroTier ed25519 signatures end with an additional 32 bytes
* that are the first 32 bytes of SHA512(msg). The verify() function considers these
* bytes optional and will accept signatures of 64 or 96 bytes in length, checking
* the hash bytes if they are present.
* LEGACY: ZeroTier's ed25519 signatures contain an extra 32 bytes which are the first
* 32 bytes of SHA512(msg). These exist because an early version of the ZeroTier multicast
* algorithm did a lot of signature verification and we wanted a way to skip the more
* expensive ed25519 verification if the signature was obviously wrong.
*
* This verify() function will accept a 64 or 96 bit signature, checking the last 32
* bytes only if present.
*
* @param myPrivate My private key
* @param myPublic My public key
@ -89,7 +92,7 @@ public:
* @param len Length of message in bytes
* @param signature Buffer to fill with signature -- MUST be 96 bytes in length
*/
static void sign(const uint8_t myPrivate[ZT_C25519_PRIVATE_KEY_LEN],const uint8_t myPublic[ZT_C25519_PUBLIC_KEY_LEN],const void *msg,unsigned int len,void *signature);
static void sign(const uint8_t myPrivate[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE],const uint8_t myPublic[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],const void *msg,unsigned int len,void *signature);
/**
* Verify a message's signature
@ -101,16 +104,16 @@ public:
* @param siglen Length of signature in bytes
* @return True if signature is valid and the message is authentic and unmodified
*/
static bool verify(const uint8_t their[ZT_C25519_PUBLIC_KEY_LEN],const void *msg,unsigned int len,const void *signature,unsigned int siglen);
static bool verify(const uint8_t their[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],const void *msg,unsigned int len,const void *signature,unsigned int siglen);
private:
// derive first 32 bytes of kp.pub from first 32 bytes of kp.priv
// this is the ECDH key
static void _calcPubDH(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],const uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN]);
static void _calcPubDH(uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],const uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE]);
// derive 2nd 32 bytes of kp.pub from 2nd 32 bytes of kp.priv
// this is the Ed25519 sign/verify key
static void _calcPubED(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],const uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN]);
static void _calcPubED(uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE],const uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE]);
};
} // namespace ZeroTier

View file

@ -69,9 +69,9 @@ void identityV0ProofOfWorkFrankenhash(const void *const publicKey,unsigned int p
struct identityV0ProofOfWorkCriteria
{
ZT_INLINE identityV0ProofOfWorkCriteria(unsigned char *sb,char *gm) noexcept : digest(sb),genmem(gm) {}
ZT_INLINE bool operator()(const uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN]) const noexcept
ZT_INLINE bool operator()(const uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE]) const noexcept
{
identityV0ProofOfWorkFrankenhash(pub,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
identityV0ProofOfWorkFrankenhash(pub,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,digest,genmem);
return (digest[0] < 17);
}
unsigned char *digest;
@ -222,7 +222,7 @@ bool Identity::locallyValidate() const noexcept
case C25519: {
uint8_t digest[64];
char *genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
identityV0ProofOfWorkFrankenhash(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
identityV0ProofOfWorkFrankenhash(_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,digest,genmem);
delete[] genmem;
return ((_address == Address(digest + 59)) && (digest[0] < 17));
}
@ -242,7 +242,7 @@ void Identity::hashWithPrivate(uint8_t h[ZT_IDENTITY_HASH_SIZE]) const
switch (_type) {
case C25519:
SHA384(h,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN);
SHA384(h,_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,_priv.c25519,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
break;
case P384:
@ -309,7 +309,7 @@ bool Identity::agree(const Identity &id,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH])
// If we are a C25519 key we can agree with another C25519 key or with only the
// C25519 portion of a type 1 P-384 key.
C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
SHA512(h,rawkey,ZT_C25519_SHARED_KEY_LEN);
SHA512(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE);
Utils::copy<ZT_PEER_SECRET_KEY_LENGTH>(key,h);
return true;
}
@ -323,14 +323,14 @@ bool Identity::agree(const Identity &id,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH])
// or something. For those who don't trust P384 this means the privacy of
// your traffic is also protected by C25519.
C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
ECC384ECDH(id._pub.p384,_priv.p384,rawkey + ZT_C25519_SHARED_KEY_LEN);
SHA384(h,rawkey,ZT_C25519_SHARED_KEY_LEN + ZT_ECC384_SHARED_SECRET_SIZE);
ECC384ECDH(id._pub.p384,_priv.p384,rawkey + ZT_C25519_ECDH_SHARED_SECRET_SIZE);
SHA384(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE + ZT_ECC384_SHARED_SECRET_SIZE);
Utils::copy<ZT_PEER_SECRET_KEY_LENGTH>(key,h);
return true;
} else if (id._type == C25519) {
// If the other identity is a C25519 identity we can agree using only that type.
C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
SHA512(h,rawkey,ZT_C25519_SHARED_KEY_LEN);
SHA512(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE);
Utils::copy<ZT_PEER_SECRET_KEY_LENGTH>(key,h);
return true;
}
@ -352,12 +352,12 @@ char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_
case C25519: {
*(p++) = '0';
*(p++) = ':';
Utils::hex(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,p);
p += ZT_C25519_PUBLIC_KEY_LEN * 2;
Utils::hex(_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,p);
p += ZT_C25519_COMBINED_PUBLIC_KEY_SIZE * 2;
if ((_hasPrivate)&&(includePrivate)) {
*(p++) = ':';
Utils::hex(_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN,p);
p += ZT_C25519_PRIVATE_KEY_LEN * 2;
Utils::hex(_priv.c25519,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE,p);
p += ZT_C25519_COMBINED_PRIVATE_KEY_SIZE * 2;
}
*p = (char)0;
return buf;
@ -428,7 +428,7 @@ bool Identity::fromString(const char *str)
switch(_type) {
case C25519:
if (Utils::unhex(f,strlen(f),_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN) != ZT_C25519_PUBLIC_KEY_LEN) {
if (Utils::unhex(f,strlen(f),_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE) != ZT_C25519_COMBINED_PUBLIC_KEY_SIZE) {
_address.zero();
return false;
}
@ -449,7 +449,7 @@ bool Identity::fromString(const char *str)
switch(_type) {
case C25519:
if (Utils::unhex(f,strlen(f),_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN) != ZT_C25519_PRIVATE_KEY_LEN) {
if (Utils::unhex(f,strlen(f),_priv.c25519,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) != ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
_address.zero();
return false;
} else {
@ -493,14 +493,14 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool incl
switch(_type) {
case C25519:
data[ZT_ADDRESS_LENGTH] = (uint8_t)C25519;
Utils::copy<ZT_C25519_PUBLIC_KEY_LEN>(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519);
Utils::copy<ZT_C25519_COMBINED_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519);
if ((includePrivate)&&(_hasPrivate)) {
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = ZT_C25519_PRIVATE_KEY_LEN;
Utils::copy<ZT_C25519_PRIVATE_KEY_LEN>(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,_priv.c25519);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN;
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1,_priv.c25519);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
} else {
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = 0;
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1;
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = 0;
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1;
}
case P384:
@ -532,22 +532,22 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
switch((_type = (Type)data[ZT_ADDRESS_LENGTH])) {
case C25519:
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1))
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1))
return -1;
Utils::copy<ZT_C25519_PUBLIC_KEY_LEN>(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1);
Utils::copy<ZT_C25519_COMBINED_PUBLIC_KEY_SIZE>(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1);
_computeHash();
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN];
if (privlen == ZT_C25519_PRIVATE_KEY_LEN) {
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN))
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE];
if (privlen == ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE))
return -1;
_hasPrivate = true;
Utils::copy<ZT_C25519_PRIVATE_KEY_LEN>(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN;
Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
} else if (privlen == 0) {
_hasPrivate = false;
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1;
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1;
}
break;
@ -587,7 +587,7 @@ void Identity::_computeHash()
case C25519:
_fp._fp.address = _address.toInt();
SHA384(_fp._fp.hash,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
SHA384(_fp._fp.hash,_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE);
break;
case P384:

View file

@ -28,8 +28,8 @@
#include <cstring>
#define ZT_IDENTITY_STRING_BUFFER_LENGTH 1024
#define ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE (1 + ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE)
#define ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE (ZT_C25519_PRIVATE_KEY_LEN + ZT_ECC384_PRIVATE_KEY_SIZE)
#define ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE (1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + ZT_ECC384_PUBLIC_KEY_SIZE)
#define ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE (ZT_C25519_COMBINED_PRIVATE_KEY_SIZE + ZT_ECC384_PRIVATE_KEY_SIZE)
#define ZT_IDENTITY_MARSHAL_SIZE_MAX (ZT_ADDRESS_LENGTH + 4 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE)
namespace ZeroTier {
@ -233,12 +233,12 @@ private:
Address _address;
Fingerprint _fp;
ZT_PACKED_STRUCT(struct { // do not re-order these fields
uint8_t c25519[ZT_C25519_PRIVATE_KEY_LEN];
uint8_t c25519[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE];
uint8_t p384[ZT_ECC384_PRIVATE_KEY_SIZE];
}) _priv;
ZT_PACKED_STRUCT(struct { // do not re-order these fields
uint8_t nonce; // nonce for PoW generate/verify
uint8_t c25519[ZT_C25519_PUBLIC_KEY_LEN]; // Curve25519 and Ed25519 public keys
uint8_t c25519[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE]; // Curve25519 and Ed25519 public keys
uint8_t p384[ZT_ECC384_PUBLIC_KEY_SIZE]; // NIST P-384 public key
}) _pub;
Type _type; // _type determines which fields in _priv and _pub are used

View file

@ -14,6 +14,12 @@
#ifndef ZT_MAP_HPP
#define ZT_MAP_HPP
/*
* This wraps std::unordered_map (or std::map if that is not available) and gives
* it a few extra methods. It also uses the built-in hashCode methods in key objects
* in ZeroTier instead of requiring hashers all over the place.
*/
#include "Constants.hpp"
#include "Utils.hpp"
@ -26,6 +32,7 @@
namespace ZeroTier {
#ifdef __CPP11__
struct _MapHasher
{
template<typename O>
@ -36,6 +43,7 @@ struct _MapHasher
std::size_t operator()(const uint32_t i) const noexcept { return (std::size_t)Utils::hash32(i ^ (uint32_t)Utils::s_mapNonce); }
std::size_t operator()(const int32_t i) const noexcept { return (std::size_t)Utils::hash32((uint32_t)i ^ (uint32_t)Utils::s_mapNonce); }
};
template<typename K,typename V>
class Map : public std::unordered_map<K,V,_MapHasher>
{
@ -61,7 +69,9 @@ public:
this->emplace(key,value);
}
};
#else
template<typename K,typename V>
class Map : public std::map<K,V>
{
@ -87,6 +97,7 @@ public:
(*this)[key] = value;
}
};
#endif
} // ZeroTier

View file

@ -1065,7 +1065,7 @@ extern "C" const char *ZTT_benchmarkCrypto()
}
{
uint8_t key[ZT_C25519_SHARED_KEY_LEN];
uint8_t key[ZT_C25519_ECDH_SHARED_SECRET_SIZE];
ZT_T_PRINTF("[crypto] Benchmarking Curve25519 ECDH... ");
int64_t start = now();
for(int i=0;i<150;++i) {