diff --git a/node/Identity.cpp b/node/Identity.cpp index 97aac3fd5..4a892979d 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -16,6 +16,8 @@ #include "SHA512.hpp" #include "Salsa20.hpp" #include "Utils.hpp" +#include "Speck128.hpp" +#include "Poly1305.hpp" #include #include @@ -80,25 +82,56 @@ struct _v0_identity_generate_cond bool _v1_identity_generate_cond(const void *in,const unsigned int len) { uint64_t b[98304]; // 768 KiB + uint64_t polykey[4]; SHA512(b,in,len); - for(unsigned long i=8;i<98304;i+=8) - SHA512(b + i,b + (i - 8),64); + + polykey[0] = b[2]; + polykey[1] = b[3]; + polykey[2] = b[4]; + polykey[3] = b[5]; + #if __BYTE_ORDER == __BIG_ENDIAN - for(unsigned int i=0;i<131072;i+=8) { - b[i] = Utils::swapBytes(b[i]); - b[i + 1] = Utils::swapBytes(b[i + 1]); - b[i + 2] = Utils::swapBytes(b[i + 2]); - b[i + 3] = Utils::swapBytes(b[i + 3]); - b[i + 4] = Utils::swapBytes(b[i + 4]); - b[i + 5] = Utils::swapBytes(b[i + 5]); - b[i + 6] = Utils::swapBytes(b[i + 6]); - b[i + 7] = Utils::swapBytes(b[i + 7]); - } + b[0] = Utils::swapBytes(b[0]); + b[1] = Utils::swapBytes(b[0]); + b[2] = Utils::swapBytes(b[0]); + b[3] = Utils::swapBytes(b[0]); + b[4] = Utils::swapBytes(b[0]); + b[5] = Utils::swapBytes(b[0]); + b[6] = Utils::swapBytes(b[0]); + b[7] = Utils::swapBytes(b[0]); #endif + + Speck128<24> s16; + s16.initXY(b[0],b[1]); + for(unsigned long i=0;i<(98304-8);) { + uint64_t x0 = b[i]; + uint64_t y0 = b[i + 1]; + uint64_t x1 = b[i + 2]; + uint64_t y1 = b[i + 3]; + uint64_t x2 = b[i + 4]; + uint64_t y2 = b[i + 5]; + uint64_t x3 = b[i + 6]; + uint64_t y3 = b[i + 7]; + x0 += x1; + x1 += x2; + i += 8; + x2 += x3; + x3 += y0; + s16.encrypt512(x0,y0,x1,y1,x2,y2,x3,y3); + b[i] = x0; + b[i + 1] = y0; + b[i + 2] = x1; + b[i + 3] = y1; + b[i + 4] = x2; + b[i + 5] = y2; + b[i + 6] = x3; + b[i + 7] = y3; + } std::sort(b,b + 98304); + #if __BYTE_ORDER == __BIG_ENDIAN - for(unsigned int i=0;i<131072;i+=8) { + for(unsigned int i=0;i<98304;i+=8) { b[i] = Utils::swapBytes(b[i]); b[i + 1] = Utils::swapBytes(b[i + 1]); b[i + 2] = Utils::swapBytes(b[i + 2]); @@ -110,8 +143,12 @@ bool _v1_identity_generate_cond(const void *in,const unsigned int len) } #endif - SHA384(b,b,sizeof(b)); - return reinterpret_cast(b)[0] == 0; + poly1305(b,b,sizeof(b),polykey); +#if __BYTE_ORDER == __BIG_ENDIAN + return ((Utils::swapBytes(b[0]) + Utils::swapBytes(b[1])) >> 56U) == 0; +#else + return ((b[0] + b[1]) >> 56U) == 0; +#endif } } // anonymous namespace diff --git a/node/Speck128.hpp b/node/Speck128.hpp index 15b4b170f..e38cc66c2 100644 --- a/node/Speck128.hpp +++ b/node/Speck128.hpp @@ -52,8 +52,17 @@ public: */ ZT_INLINE void init(const void *k) noexcept { - uint64_t x = Utils::loadLittleEndian(k); - uint64_t y = Utils::loadLittleEndian(reinterpret_cast(k) + 8); + initXY(Utils::loadLittleEndian(k),Utils::loadLittleEndian(reinterpret_cast(k) + 8)); + } + + /** + * Initialize Speck from a 128-bit key in two 64-bit words + * + * @param x Least significant 64 bits + * @param y Most significant 64 bits + */ + ZT_INLINE void initXY(uint64_t x,uint64_t y) noexcept + { _k[0] = x; for(uint64_t i=0;i<(R-1);++i) { x = x >> 8U | x << 56U; @@ -76,7 +85,6 @@ public: */ ZT_INLINE void encryptXY(uint64_t &x,uint64_t &y) const noexcept { -#pragma unroll for (int i=0;i> 8U | x << 56U; @@ -87,6 +95,36 @@ public: } } + /** + * Encrypt 512 bits in parallel with the same key + */ + ZT_INLINE void encrypt512(uint64_t &x0,uint64_t &y0,uint64_t &x1,uint64_t &y1,uint64_t &x2,uint64_t &y2,uint64_t &x3,uint64_t &y3) const noexcept + { + for (int i=0;i> 8U | x0 << 56U; + x1 = x1 >> 8U | x1 << 56U; + x2 = x2 >> 8U | x2 << 56U; + x3 = x3 >> 8U | x3 << 56U; + x0 += y0; + x1 += y1; + x2 += y2; + x3 += y3; + x0 ^= kk; + x1 ^= kk; + x2 ^= kk; + x3 ^= kk; + y0 = y0 << 3U | y0 >> 61U; + y1 = y1 << 3U | y1 >> 61U; + y2 = y2 << 3U | y2 >> 61U; + y3 = y3 << 3U | y3 >> 61U; + y0 ^= x0; + y1 ^= x1; + y2 ^= x2; + y3 ^= x3; + } + } + /** * Decrypt a 128-bit block as two 64-bit words * @@ -98,7 +136,6 @@ public: */ ZT_INLINE void decryptXY(uint64_t &x,uint64_t &y) const noexcept { -#pragma unroll for (int i=(R-1);i>=0;--i) { const uint64_t kk = _k[i]; y ^= x; diff --git a/node/Tests.cpp b/node/Tests.cpp index 9cd30aaf2..d2af4b339 100644 --- a/node/Tests.cpp +++ b/node/Tests.cpp @@ -177,7 +177,7 @@ static const C25519TestVector C25519_TEST_VECTORS[ZT_NUM_C25519_TEST_VECTORS] = }; #define IDENTITY_V0_KNOWN_GOOD_0 "8e4df28b72:0:ac3d46abe0c21f3cfe7a6c8d6a85cfcffcb82fbd55af6a4d6350657c68200843fa2e16f9418bbd9702cae365f2af5fb4c420908b803a681d4daef6114d78a2d7:bd8dd6e4ce7022d2f812797a80c6ee8ad180dc4ebf301dec8b06d1be08832bddd63a2f1cfa7b2c504474c75bdc8898ba476ef92e8e2d0509f8441985171ff16e" -#define IDENTITY_V1_KNOWN_GOOD_0 "cc6e483c2a:1:uojaacswtakzkpe234q67ti3hunqo5et75qwpej5gnhyofpjduncjogbrof2g72e7rhtp7xdypy2t43ojb2ewva33npnoazum3ifyladgllmc6xe2iwk7mljihrbycoitip647z4vx22vn2v2yimrgudolx4tbu3ip4f6gwt4rvjszupxk35gaalwjfvr3v5gy:apt2gnwj456cu4t5enchipsnx6nj22u6vxizzsu3azahlhqxfqymvatqvtjwtta2v32tbigt6pk7m3ndw766ynsn4hhmxnvkibhajqx5f3ugpiu5yx4xwcz6mbw2vrevxsyh3t346z37elpmgp3xdg4wyqwkyssczqdhfm3w4daq4rt75rvq" +#define IDENTITY_V1_KNOWN_GOOD_0 "fd6dae8353:1:l2m2xjob7vhygj3tnon6iiscevsbb6rqkj45enqrbguoumoravrq3agh42njh3vnhsqm6ymzfdduydufuvqwx4wggxowqcuxbt7laoyvansknsgs6fzkzjb5wyzm4lvreoddeeykyq5vtlvb37xlocmreebj2j7lwni5b6wlpdzemehd7u3bjsa:nzdfhoj2xfhmc2xkzrqhqv4h6u3clx3oubugahmrpyaxg5prhuwswio3nnvtlm7qtoxjqwkzqm5prdwf5vcnqoldwv7eoc76uy6hsv5ya7frns4meofmvgegs2uf5jzg5ajofxgjibjhgw67c5uzuqots5jcqa5z5arzjf7jdadg6pzbgnzq" // -------------------------------------------------------------------------------------------------------------------- @@ -697,12 +697,12 @@ extern "C" const char *ZTT_general() ZT_T_PRINTF("OK" ZT_EOL_S); { - ZT_T_PRINTF("[general] Example V1 identity: "); + ZT_T_PRINTF("[general] Generated V1 identity: "); id.generate(Identity::P384); id.toString(true,tmp); ZT_T_PRINTF("%s" ZT_EOL_S,tmp); id.fingerprint().toString(tmp); - ZT_T_PRINTF("[general] Fingerprint: %s" ZT_EOL_S,tmp); + ZT_T_PRINTF("[general] Identity fingerprint: %s" ZT_EOL_S,tmp); } ZT_T_PRINTF("[general] Testing Identity type 1 (P384)... ");