diff --git a/node/AES.cpp b/node/AES.cpp index 672265209..1182ca41e 100644 --- a/node/AES.cpp +++ b/node/AES.cpp @@ -1159,50 +1159,50 @@ static ZT_ALWAYS_INLINE __m128i _init256_2_aesni(__m128i a,__m128i b) noexcept void AES::_init_aesni(const uint8_t key[32]) noexcept { - __m128i t1,t2; + __m128i t1,t2,k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13; _k.ni.k[0] = t1 = _mm_loadu_si128((const __m128i *)key); - _k.ni.k[1] = t2 = _mm_loadu_si128((const __m128i *)(key+16)); - _k.ni.k[2] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x01)); - _k.ni.k[3] = t2 = _init256_2_aesni(t1,t2); - _k.ni.k[4] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x02)); - _k.ni.k[5] = t2 = _init256_2_aesni(t1,t2); - _k.ni.k[6] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x04)); - _k.ni.k[7] = t2 = _init256_2_aesni(t1,t2); - _k.ni.k[8] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x08)); - _k.ni.k[9] = t2 = _init256_2_aesni(t1,t2); - _k.ni.k[10] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x10)); - _k.ni.k[11] = t2 = _init256_2_aesni(t1,t2); - _k.ni.k[12] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x20)); - _k.ni.k[13] = t2 = _init256_2_aesni(t1,t2); + _k.ni.k[1] = k1 = t2 = _mm_loadu_si128((const __m128i *)(key + 16)); + _k.ni.k[2] = k2 = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x01)); + _k.ni.k[3] = k3 = t2 = _init256_2_aesni(t1,t2); + _k.ni.k[4] = k4 = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x02)); + _k.ni.k[5] = k5 = t2 = _init256_2_aesni(t1,t2); + _k.ni.k[6] = k6 = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x04)); + _k.ni.k[7] = k7 = t2 = _init256_2_aesni(t1,t2); + _k.ni.k[8] = k8 = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x08)); + _k.ni.k[9] = k9 = t2 = _init256_2_aesni(t1,t2); + _k.ni.k[10] = k10 = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x10)); + _k.ni.k[11] = k11 = t2 = _init256_2_aesni(t1,t2); + _k.ni.k[12] = k12 = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x20)); + _k.ni.k[13] = k13 = t2 = _init256_2_aesni(t1,t2); _k.ni.k[14] = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x40)); - _k.ni.k[15] = _mm_aesimc_si128(_k.ni.k[13]); - _k.ni.k[16] = _mm_aesimc_si128(_k.ni.k[12]); - _k.ni.k[17] = _mm_aesimc_si128(_k.ni.k[11]); - _k.ni.k[18] = _mm_aesimc_si128(_k.ni.k[10]); - _k.ni.k[19] = _mm_aesimc_si128(_k.ni.k[9]); - _k.ni.k[20] = _mm_aesimc_si128(_k.ni.k[8]); - _k.ni.k[21] = _mm_aesimc_si128(_k.ni.k[7]); - _k.ni.k[22] = _mm_aesimc_si128(_k.ni.k[6]); - _k.ni.k[23] = _mm_aesimc_si128(_k.ni.k[5]); - _k.ni.k[24] = _mm_aesimc_si128(_k.ni.k[4]); - _k.ni.k[25] = _mm_aesimc_si128(_k.ni.k[3]); - _k.ni.k[26] = _mm_aesimc_si128(_k.ni.k[2]); - _k.ni.k[27] = _mm_aesimc_si128(_k.ni.k[1]); + _k.ni.k[15] = _mm_aesimc_si128(k13); + _k.ni.k[16] = _mm_aesimc_si128(k12); + _k.ni.k[17] = _mm_aesimc_si128(k11); + _k.ni.k[18] = _mm_aesimc_si128(k10); + _k.ni.k[19] = _mm_aesimc_si128(k9); + _k.ni.k[20] = _mm_aesimc_si128(k8); + _k.ni.k[21] = _mm_aesimc_si128(k7); + _k.ni.k[22] = _mm_aesimc_si128(k6); + _k.ni.k[23] = _mm_aesimc_si128(k5); + _k.ni.k[24] = _mm_aesimc_si128(k4); + _k.ni.k[25] = _mm_aesimc_si128(k3); + _k.ni.k[26] = _mm_aesimc_si128(k2); + _k.ni.k[27] = _mm_aesimc_si128(k1); __m128i h = _k.ni.k[0]; // _mm_xor_si128(_mm_setzero_si128(),_k.ni.k[0]); - h = _mm_aesenc_si128(h,_k.ni.k[1]); - h = _mm_aesenc_si128(h,_k.ni.k[2]); - h = _mm_aesenc_si128(h,_k.ni.k[3]); - h = _mm_aesenc_si128(h,_k.ni.k[4]); - h = _mm_aesenc_si128(h,_k.ni.k[5]); - h = _mm_aesenc_si128(h,_k.ni.k[6]); - h = _mm_aesenc_si128(h,_k.ni.k[7]); - h = _mm_aesenc_si128(h,_k.ni.k[8]); - h = _mm_aesenc_si128(h,_k.ni.k[9]); - h = _mm_aesenc_si128(h,_k.ni.k[10]); - h = _mm_aesenc_si128(h,_k.ni.k[11]); - h = _mm_aesenc_si128(h,_k.ni.k[12]); - h = _mm_aesenc_si128(h,_k.ni.k[13]); + h = _mm_aesenc_si128(h,k1); + h = _mm_aesenc_si128(h,k2); + h = _mm_aesenc_si128(h,k3); + h = _mm_aesenc_si128(h,k4); + h = _mm_aesenc_si128(h,k5); + h = _mm_aesenc_si128(h,k6); + h = _mm_aesenc_si128(h,k7); + h = _mm_aesenc_si128(h,k8); + h = _mm_aesenc_si128(h,k9); + h = _mm_aesenc_si128(h,k10); + h = _mm_aesenc_si128(h,k11); + h = _mm_aesenc_si128(h,k12); + h = _mm_aesenc_si128(h,k13); h = _mm_aesenclast_si128(h,_k.ni.k[14]); const __m128i shuf = s_shuf; __m128i hswap = _mm_shuffle_epi8(h,shuf); diff --git a/node/Address.hpp b/node/Address.hpp index 11074723b..72785670d 100644 --- a/node/Address.hpp +++ b/node/Address.hpp @@ -29,10 +29,10 @@ class Address : public TriviallyCopyable { public: ZT_ALWAYS_INLINE Address() noexcept : _a(0) {} + explicit ZT_ALWAYS_INLINE Address(const uint64_t a) noexcept : _a(a) {} explicit ZT_ALWAYS_INLINE Address(const uint8_t b[5]) noexcept : _a(((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U) | (uint64_t)b[4]) {} - explicit ZT_ALWAYS_INLINE Address(const uint64_t a) noexcept : _a(a & 0xffffffffffULL) {} - ZT_ALWAYS_INLINE Address &operator=(const uint64_t a) noexcept { _a = (a & 0xffffffffffULL); return *this; } + ZT_ALWAYS_INLINE Address &operator=(const uint64_t a) noexcept { _a = a; return *this; } /** * @param bits Raw address -- 5 bytes, big-endian byte order @@ -49,11 +49,12 @@ public: */ ZT_ALWAYS_INLINE void copyTo(uint8_t b[5]) const noexcept { - b[0] = (uint8_t)(_a >> 32U); - b[1] = (uint8_t)(_a >> 24U); - b[2] = (uint8_t)(_a >> 16U); - b[3] = (uint8_t)(_a >> 8U); - b[4] = (uint8_t)_a; + const uint64_t a = _a; + b[0] = (uint8_t)(a >> 32U); + b[1] = (uint8_t)(a >> 24U); + b[2] = (uint8_t)(a >> 16U); + b[3] = (uint8_t)(a >> 8U); + b[4] = (uint8_t)a; } /** @@ -72,9 +73,26 @@ public: ZT_ALWAYS_INLINE unsigned long hashCode() const noexcept { return (unsigned long)_a; } /** + * @param s String with at least 11 characters of space available (10 + terminating NULL) * @return Hexadecimal string */ - ZT_ALWAYS_INLINE char *toString(char buf[ZT_ADDRESS_STRING_SIZE_MAX]) const noexcept { return Utils::hex10(_a,buf); } + ZT_ALWAYS_INLINE char *toString(char s[ZT_ADDRESS_STRING_SIZE_MAX]) const noexcept + { + const uint64_t a = _a; + const unsigned int m = 0xf; + s[0] = Utils::HEXCHARS[(unsigned int)(a >> 36U) & m]; + s[1] = Utils::HEXCHARS[(unsigned int)(a >> 32U) & m]; + s[2] = Utils::HEXCHARS[(unsigned int)(a >> 28U) & m]; + s[3] = Utils::HEXCHARS[(unsigned int)(a >> 24U) & m]; + s[4] = Utils::HEXCHARS[(unsigned int)(a >> 20U) & m]; + s[5] = Utils::HEXCHARS[(unsigned int)(a >> 16U) & m]; + s[6] = Utils::HEXCHARS[(unsigned int)(a >> 12U) & m]; + s[7] = Utils::HEXCHARS[(unsigned int)(a >> 8U) & m]; + s[8] = Utils::HEXCHARS[(unsigned int)(a >> 4U) & m]; + s[9] = Utils::HEXCHARS[(unsigned int)a & m]; + s[10] = 0; + return s; + } /** * Check if this address is reserved @@ -87,27 +105,14 @@ public: */ ZT_ALWAYS_INLINE bool isReserved() const noexcept { return ((!_a)||((_a >> 32U) == ZT_ADDRESS_RESERVED_PREFIX)); } - /** - * @param i Value from 0 to 4 (inclusive) - * @return Byte at said position (address interpreted in big-endian order) - */ - ZT_ALWAYS_INLINE uint8_t operator[](unsigned int i) const noexcept { return (uint8_t)(_a >> (32 - (i * 8))); } - ZT_ALWAYS_INLINE operator bool() const noexcept { return (_a != 0); } - ZT_ALWAYS_INLINE bool operator==(const uint64_t &a) const noexcept { return (_a == (a & 0xffffffffffULL)); } - ZT_ALWAYS_INLINE bool operator!=(const uint64_t &a) const noexcept { return (_a != (a & 0xffffffffffULL)); } - ZT_ALWAYS_INLINE bool operator>(const uint64_t &a) const noexcept { return (_a > (a & 0xffffffffffULL)); } - ZT_ALWAYS_INLINE bool operator<(const uint64_t &a) const noexcept { return (_a < (a & 0xffffffffffULL)); } - ZT_ALWAYS_INLINE bool operator>=(const uint64_t &a) const noexcept { return (_a >= (a & 0xffffffffffULL)); } - ZT_ALWAYS_INLINE bool operator<=(const uint64_t &a) const noexcept { return (_a <= (a & 0xffffffffffULL)); } - - ZT_ALWAYS_INLINE bool operator==(const Address &a) const noexcept { return (_a == a._a); } - ZT_ALWAYS_INLINE bool operator!=(const Address &a) const noexcept { return (_a != a._a); } - ZT_ALWAYS_INLINE bool operator>(const Address &a) const noexcept { return (_a > a._a); } - ZT_ALWAYS_INLINE bool operator<(const Address &a) const noexcept { return (_a < a._a); } - ZT_ALWAYS_INLINE bool operator>=(const Address &a) const noexcept { return (_a >= a._a); } - ZT_ALWAYS_INLINE bool operator<=(const Address &a) const noexcept { return (_a <= a._a); } + ZT_ALWAYS_INLINE bool operator==(const Address &a) const noexcept { return _a == a._a; } + ZT_ALWAYS_INLINE bool operator!=(const Address &a) const noexcept { return _a != a._a; } + ZT_ALWAYS_INLINE bool operator>(const Address &a) const noexcept { return _a > a._a; } + ZT_ALWAYS_INLINE bool operator<(const Address &a) const noexcept { return _a < a._a; } + ZT_ALWAYS_INLINE bool operator>=(const Address &a) const noexcept { return _a >= a._a; } + ZT_ALWAYS_INLINE bool operator<=(const Address &a) const noexcept { return _a <= a._a; } #if 0 /** diff --git a/node/C25519.hpp b/node/C25519.hpp index 6a5668998..4dc7e5506 100644 --- a/node/C25519.hpp +++ b/node/C25519.hpp @@ -73,7 +73,7 @@ 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[32]); + 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]); /** * Sign a message with a sender's key pair diff --git a/node/Endpoint.cpp b/node/Endpoint.cpp index e1afc8cc6..89ca94648 100644 --- a/node/Endpoint.cpp +++ b/node/Endpoint.cpp @@ -56,9 +56,9 @@ int Endpoint::marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const noexcept { int p; data[0] = (uint8_t)_t; - Utils::storeBigEndian(data + 1,(int16_t)_l[0]); - Utils::storeBigEndian(data + 3,(int16_t)_l[1]); - Utils::storeBigEndian(data + 5,(int16_t)_l[2]); + Utils::storeBigEndian(data + 1,(uint16_t)_l[0]); + Utils::storeBigEndian(data + 3,(uint16_t)_l[1]); + Utils::storeBigEndian(data + 5,(uint16_t)_l[2]); switch(_t) { case TYPE_ZEROTIER: data[7] = (uint8_t)(_v.zt.a >> 32U); @@ -116,9 +116,9 @@ int Endpoint::unmarshal(const uint8_t *restrict data,const int len) noexcept return -1; int p; _t = (Type)data[0]; - _l[0] = Utils::loadBigEndian(data + 1); - _l[1] = Utils::loadBigEndian(data + 3); - _l[2] = Utils::loadBigEndian(data + 5); + _l[0] = (int)Utils::loadBigEndian(data + 1); + _l[1] = (int)Utils::loadBigEndian(data + 3); + _l[2] = (int)Utils::loadBigEndian(data + 5); switch(_t) { case TYPE_NIL: return 7; diff --git a/node/Identity.cpp b/node/Identity.cpp index bb95ffa6d..fb8a012bf 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -26,13 +26,8 @@ namespace ZeroTier { namespace { -// -------------------------------------------------------------------------------------------------------------------- - -// This is the memory-intensive hash function used to compute v0 identities -// from v0 public keys. - +// This is the memory-intensive hash function used to compute v0 identities from v0 public keys. #define ZT_V0_IDENTITY_GEN_MEMORY 2097152 - static void _computeMemoryHardHash(const void *const publicKey,unsigned int publicKeyBytes,void *const digest,void *const genmem) noexcept { // Digest publicKey[] to obtain initial digest @@ -67,7 +62,6 @@ static void _computeMemoryHardHash(const void *const publicKey,unsigned int publ s20.crypt20(digest,digest,64); } } - struct _v0_identity_generate_cond { ZT_ALWAYS_INLINE _v0_identity_generate_cond() noexcept {} @@ -81,7 +75,17 @@ struct _v0_identity_generate_cond char *genmem; }; -// -------------------------------------------------------------------------------------------------------------------- +ZT_ALWAYS_INLINE void _v1_hash(uint8_t *const digest,const void *const in,const unsigned int len) noexcept +{ + SHA384(digest,in,len); + Utils::storeBigEndian(digest,Utils::loadBigEndian(digest) % 18446744073709549811ULL); // these are primes close to uint64_max + Utils::storeBigEndian(digest + 8,Utils::loadBigEndian(digest + 8) % 18446744073709549757ULL); + Utils::storeBigEndian(digest + 16,Utils::loadBigEndian(digest + 16) % 18446744073709549733ULL); + Utils::storeBigEndian(digest + 24,Utils::loadBigEndian(digest + 24) % 18446744073709549667ULL); + Utils::storeBigEndian(digest + 32,Utils::loadBigEndian(digest + 32) % 18446744073709549613ULL); + Utils::storeBigEndian(digest + 40,Utils::loadBigEndian(digest + 40) % 18446744073709549583ULL); + SHA384(digest,in,len,digest,48); +} } // anonymous namespace @@ -89,7 +93,7 @@ const Identity Identity::NIL; bool Identity::generate(const Type t) { - uint8_t digest[128]; + uint8_t digest[64]; _type = t; _hasPrivate = true; @@ -107,23 +111,16 @@ bool Identity::generate(const Type t) case P384: { AES c; - do { + for(;;) { C25519::generate(_pub.c25519,_priv.c25519); ECC384GenerateKey(_pub.p384,_priv.p384); - - SHA384(digest,&_pub,sizeof(_pub)); - c.init(digest); - c.encrypt(digest,digest + 48); - c.encrypt(digest + 16,digest + 64); - c.encrypt(digest + 32,digest + 80); - SHA384(digest,digest,96); - - if (digest[47] != 0) - continue; - - _address.setTo(digest); - } while (_address.isReserved()); - + _v1_hash(digest,&_pub,sizeof(_pub)); + if (((digest[46] & 1U)|digest[47]) == 0) { // right-most 9 bits must be zero + _address.setTo(digest); + if (!_address.isReserved()) + break; + } + } _hash.set(digest); // P384 uses the same hash for hash() and address generation } break; @@ -151,7 +148,7 @@ bool Identity::locallyValidate() const return false; case P384: - return ((_hash[47] == 0)&&(Address(_hash.data()) == _address)); + return ( (Address(_hash.data()) == _address) && (((_hash[46] & 1U)|_hash[47]) == 0) ); } return false; @@ -524,15 +521,7 @@ void Identity::_computeHash() break; case P384: - if (!_hash) { - uint8_t *const digest = _hash.data(); - SHA384(digest,&_pub,sizeof(_pub)); - AES c(digest); - c.encrypt(digest,digest + 48); - c.encrypt(digest + 16,digest + 64); - c.encrypt(digest + 32,digest + 80); - SHA384(digest,digest,96); - } + _v1_hash(_hash.data(),&_pub,sizeof(_pub)); break; } } diff --git a/node/Tests.cpp b/node/Tests.cpp index eac2aabed..2624a362a 100644 --- a/node/Tests.cpp +++ b/node/Tests.cpp @@ -178,6 +178,9 @@ static const C25519TestVector C25519_TEST_VECTORS[ZT_NUM_C25519_TEST_VECTORS] = #define IDENTITY_V0_KNOWN_GOOD_0 "8e4df28b72:0:ac3d46abe0c21f3cfe7a6c8d6a85cfcffcb82fbd55af6a4d6350657c68200843fa2e16f9418bbd9702cae365f2af5fb4c420908b803a681d4daef6114d78a2d7:bd8dd6e4ce7022d2f812797a80c6ee8ad180dc4ebf301dec8b06d1be08832bddd63a2f1cfa7b2c504474c75bdc8898ba476ef92e8e2d0509f8441985171ff16e" #define IDENTITY_V0_KNOWN_BAD_0 "9e4df28b72:0:ac3d46abe0c21f3cfe7a6c8d6a85cfcffcb82fbd55af6a4d6350657c68200843fa2e16f9418bbd9702cae365f2af5fb4c420908b803a681d4daef6114d78a2d7:bd8dd6e4ce7022d2f812797a80c6ee8ad180dc4ebf301dec8b06d1be08832bddd63a2f1cfa7b2c504474c75bdc8898ba476ef92e8e2d0509f8441985171ff16e" +#define IDENTITY_V1_KNOWN_GOOD_0 "bc72fb58e4:1:fya26hekqeromqdtpzq3mzj26zecwf7pkjahictpreapv4sw5vjcdkf6tbwaajzw6cq2ro6usrtzerccr37n52hiydogi2boaxk4tjidnhctgsbk4i4g34madrxihraurflyoe3xgeqkbpj2zrlsivscvbygzd3zfqs3qihoi6e24xy2jridq:tqaxnh3pucstd2xuwylgjfapyug7zdxorfwv37ted66qic6fu5g3pveodg7so4vt7cil7ptoht6msn6m2tsrfyd52a5f3b3g5wbd5ljjds2sftrjjw3qcb645eg4iizbqv5mlphgpa2uznonoo77qblbx6fdjh2nbt3ksooebj377rgu6qmq" +#define IDENTITY_V1_KNOWN_BAD_0 "bc82fb58e4:1:fya26hekqeromqdtpzq3mzj26zecwf7pkjahictpreapv4sw5vjcdkf6tbwaajzw6cq2ro6usrtzerccr37n52hiydogi2boaxk4tjidnhctgsbk4i4g34madrxihraurflyoe3xgeqkbpj2zrlsivscvbygzd3zfqs3qihoi6e24xy2jridq:tqaxnh3pucstd2xuwylgjfapyug7zdxorfwv37ted66qic6fu5g3pveodg7so4vt7cil7ptoht6msn6m2tsrfyd52a5f3b3g5wbd5ljjds2sftrjjw3qcb645eg4iizbqv5mlphgpa2uznonoo77qblbx6fdjh2nbt3ksooebj377rgu6qmq" + // -------------------------------------------------------------------------------------------------------------------- #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -481,7 +484,7 @@ extern "C" const char *ZTT_general() FCV ref; int frags = 1 + (int)(Utils::random() % 16); - int skip = ((k & 3) == 1) ? -1 : (int)(Utils::random() % frags); + int skip = ((k & 3U) == 1) ? -1 : (int)(Utils::random() % frags); bool complete = false; message.resize(frags); ref.resize(frags); @@ -555,6 +558,54 @@ extern "C" const char *ZTT_general() Buf::freePool(); ZT_T_PRINTF("OK (cache remaining: %u)" ZT_EOL_S,defrag.cacheSize()); } + + { + ZT_T_PRINTF("[general] Testing Identity type 0 (C25519)... "); + Identity id; + + if (!id.fromString(IDENTITY_V0_KNOWN_GOOD_0)) { + ZT_T_PRINTF("FAILED (error parsing test identity #1)" ZT_EOL_S); + return "Identity test failed: parse error"; + } + if (!id.locallyValidate()) { + ZT_T_PRINTF("FAILED (validation of known-good identity failed)" ZT_EOL_S); + return "Identity test failed: validation of known-good identity"; + } + if (!id.fromString(IDENTITY_V0_KNOWN_BAD_0)) { + ZT_T_PRINTF("FAILED (error parsing test identity #2)" ZT_EOL_S); + return "Identity test failed: parse error"; + } + if (id.locallyValidate()) { + ZT_T_PRINTF("FAILED (validation of known-bad identity returned ok)" ZT_EOL_S); + return "Identity test failed: validation of known-bad identity"; + } + + ZT_T_PRINTF("OK" ZT_EOL_S "[general] Testing Identity type 1 (P384)... "); + + //id.generate(Identity::P384); + //char tmp[1024]; + //id.toString(true,tmp); + //ZT_T_PRINTF("\n%s\n",tmp); + + if (!id.fromString(IDENTITY_V1_KNOWN_GOOD_0)) { + ZT_T_PRINTF("FAILED (error parsing test identity #1)" ZT_EOL_S); + return "Identity test failed: parse error"; + } + if (!id.locallyValidate()) { + ZT_T_PRINTF("FAILED (validation of known-good identity failed)" ZT_EOL_S); + return "Identity test failed: validation of known-good identity"; + } + if (!id.fromString(IDENTITY_V1_KNOWN_BAD_0)) { + ZT_T_PRINTF("FAILED (error parsing test identity #2)" ZT_EOL_S); + return "Identity test failed: parse error"; + } + if (id.locallyValidate()) { + ZT_T_PRINTF("FAILED (validation of known-bad identity returned ok)" ZT_EOL_S); + return "Identity test failed: validation of known-bad identity"; + } + + ZT_T_PRINTF("OK" ZT_EOL_S); + } } catch (std::exception &e) { ZT_T_PRINTF(ZT_EOL_S "[general] Unexpected exception: %s" ZT_EOL_S,e.what()); return e.what(); @@ -921,6 +972,26 @@ extern "C" const char *ZTT_benchmarkCrypto() end = now(); ZT_T_PRINTF("%.4f μs/verify" ZT_EOL_S,((double)(end - start) * 1000.0) / (double)(500 * ZT_NUM_C25519_TEST_VECTORS)); } + + { + ZT_T_PRINTF("[crypto] Benchmarking V0 Identity generation... "); + Identity id; + int64_t start = now(); + for(long i=0;i<5;++i) { + id.generate(Identity::C25519); + foo = (uint8_t)id.address().toInt(); + } + int64_t end = now(); + ZT_T_PRINTF("%.4f ms/generation" ZT_EOL_S,(double)(end - start) / 5.0); + ZT_T_PRINTF("[crypto] Benchmarking V1 Identity generation... "); + start = now(); + for(long i=0;i<5;++i) { + id.generate(Identity::P384); + foo = (uint8_t)id.address().toInt(); + } + end = now(); + ZT_T_PRINTF("%.4f ms/generation" ZT_EOL_S,(double)(end - start) / 5.0); + } } catch (std::exception &e) { ZT_T_PRINTF(ZT_EOL_S "[crypto] Unexpected exception: %s" ZT_EOL_S,e.what()); return e.what(); diff --git a/node/Utils.cpp b/node/Utils.cpp index 0c2597023..5e9ad0988 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -193,22 +193,6 @@ uint64_t unhex(const char *s) noexcept return n; } -char *hex10(uint64_t i,char s[11]) noexcept -{ - s[0] = HEXCHARS[(i >> 36U) & 0xfU]; - s[1] = HEXCHARS[(i >> 32U) & 0xfU]; - s[2] = HEXCHARS[(i >> 28U) & 0xfU]; - s[3] = HEXCHARS[(i >> 24U) & 0xfU]; - s[4] = HEXCHARS[(i >> 20U) & 0xfU]; - s[5] = HEXCHARS[(i >> 16U) & 0xfU]; - s[6] = HEXCHARS[(i >> 12U) & 0xfU]; - s[7] = HEXCHARS[(i >> 8U) & 0xfU]; - s[8] = HEXCHARS[(i >> 4U) & 0xfU]; - s[9] = HEXCHARS[i & 0xfU]; - s[10] = (char)0; - return s; -} - char *hex(const void *d,unsigned int l,char *s) noexcept { char *const save = s; diff --git a/node/Utils.hpp b/node/Utils.hpp index 5c13ddbbc..504c146a5 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -115,15 +115,6 @@ char *hex(uint64_t i,char s[17]) noexcept; */ uint64_t unhex(const char *s) noexcept; -/** - * Convert the least significant 40 bits of a uint64_t to hex - * - * @param i Unsigned 64-bit int - * @param s Buffer of size [11] to receive 10 hex characters - * @return Pointer to buffer - */ -char *hex10(uint64_t i,char s[11]) noexcept; - /** * Convert a byte array into hex *