From fbfa99fac5b4bbe411fbca490639936bb45954d0 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 27 Feb 2020 09:43:58 -0800 Subject: [PATCH] Speed up V1 identity verification a little, and add some comments. --- controller/DB.cpp | 7 ++- node/Identity.cpp | 61 ++++++++++-------- node/Identity.hpp | 2 +- node/MIMC52.cpp | 77 ++++++++++++++--------- node/Tests.cpp | 6 +- node/Utils.hpp | 154 ++++++++++++++++++++++++++++++---------------- 6 files changed, 193 insertions(+), 114 deletions(-) diff --git a/controller/DB.cpp b/controller/DB.cpp index 19cfd0931..d97892423 100644 --- a/controller/DB.cpp +++ b/controller/DB.cpp @@ -338,8 +338,11 @@ void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool void DB::_fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info) { - for(auto ab=nw->activeBridgeMembers.begin();ab!=nw->activeBridgeMembers.end();++ab) - info.activeBridges.push_back(Address(*ab)); + for(auto ab=nw->activeBridgeMembers.begin();ab!=nw->activeBridgeMembers.end();++ab) { + const Address aba(*ab); + if (nw->authorizedMembers.count(aba) != 0) + info.activeBridges.push_back(aba); + } std::sort(info.activeBridges.begin(),info.activeBridges.end()); for(auto ip=nw->allocatedIps.begin();ip!=nw->allocatedIps.end();++ip) info.allocatedIps.push_back(*ip); diff --git a/node/Identity.cpp b/node/Identity.cpp index b105a0895..8aecaf7b3 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -89,11 +89,13 @@ bool Identity::generate(const Type t) switch(t) { case C25519: { + // Generate C25519/Ed25519 key pair whose hash satisfies a "hashcash" criterion and generate the + // address from the last 40 bits of this hash. This is different from the fingerprint hash for V0. uint8_t digest[64]; char *const genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY]; do { C25519::generateSatisfying(_v0_identity_generate_cond(digest,genmem),_pub.c25519,_priv.c25519); - _address.setTo(digest + 59); // last 5 bytes are address + _address.setTo(digest + 59); } while (_address.isReserved()); delete[] genmem; _computeHash(); @@ -101,9 +103,15 @@ bool Identity::generate(const Type t) case P384: { for(;;) { + // Generate C25519, Ed25519, and NIST P-384 key pairs. C25519::generate(_pub.c25519,_priv.c25519); ECC384GenerateKey(_pub.p384,_priv.p384); + + // Execute the MIMC52 verifiable delay function, resulting a near constant time delay relative + // to the speed of the current CPU. This result is incorporated into the final hash. Utils::storeBigEndian(_pub.t1mimc52,mimc52Delay(&_pub,sizeof(_pub) - sizeof(_pub.t1mimc52),ZT_V1_IDENTITY_MIMC52_VDF_ROUNDS_BASE)); + + // Compute SHA384 fingerprint hash of keys and MIMC output and generate address directly from it. _computeHash(); _address.setTo(_fp.data()); if (!_address.isReserved()) @@ -118,35 +126,36 @@ bool Identity::generate(const Type t) return true; } -bool Identity::locallyValidate() const +bool Identity::locallyValidate() const noexcept { - if ((_address.isReserved())||(!_address)) - return false; - switch (_type) { + try { + if ((!_address.isReserved()) && (_address)) { + switch (_type) { - case C25519: - try { - uint8_t digest[64]; - char *genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY]; - _computeMemoryHardHash(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem); - delete [] genmem; - return ((_address == Address(digest + 59))&&(digest[0] < 17)); - } catch ( ... ) {} - break; + case C25519: { + uint8_t digest[64]; + char *genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY]; + _computeMemoryHardHash(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem); + delete[] genmem; + return ((_address == Address(digest + 59)) && (digest[0] < 17)); + } + + case P384: + if (_address == Address(_fp.data())) { + // The most significant 8 bits of the MIMC proof included with v1 identities can be used to store a multiplier + // that can indicate that more work than the required minimum has been performed. Right now this is never done + // but it could have some use in the future. There is no harm in doing it, and we'll accept any round count + // that is at least ZT_V1_IDENTITY_MIMC52_VDF_ROUNDS_BASE. + unsigned long rounds = (((unsigned long)_pub.t1mimc52[0] & 15U) + 1U); // max: 16 * ZT_V1_IDENTITY_MIMC52_VDF_ROUNDS_BASE + rounds *= ZT_V1_IDENTITY_MIMC52_VDF_ROUNDS_BASE; + return mimc52Verify(&_pub,sizeof(_pub) - sizeof(_pub.t1mimc52),rounds,Utils::loadBigEndian(_pub.t1mimc52)); + } else { + return false; + } - case P384: - if (_address == Address(_fp.data())) { - // The most significant 8 bits of the MIMC proof included with v1 identities can be used to store a multiplier - // that can indicate that more work than the required minimum has been performed. Right now this is never done - // but it could have some use in the future. There is no harm in doing it, and we'll accept any round count - // that is at least ZT_V1_IDENTITY_MIMC52_VDF_ROUNDS_BASE. - const unsigned long rounds = ZT_V1_IDENTITY_MIMC52_VDF_ROUNDS_BASE * ((unsigned long)_pub.t1mimc52[0] + 1U); - if (mimc52Verify(&_pub,sizeof(_pub) - sizeof(_pub.t1mimc52),rounds,Utils::loadBigEndian(_pub.t1mimc52))) - return true; } - break; - - } + } + } catch ( ... ) {} return false; } diff --git a/node/Identity.hpp b/node/Identity.hpp index b40e997e3..d0f1d5fac 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -105,7 +105,7 @@ public: * * @return True if validation check passes */ - bool locallyValidate() const; + bool locallyValidate() const noexcept; /** * @return True if this identity contains a private key diff --git a/node/MIMC52.cpp b/node/MIMC52.cpp index a4bc26015..36dbbaa57 100644 --- a/node/MIMC52.cpp +++ b/node/MIMC52.cpp @@ -13,10 +13,9 @@ #include "MIMC52.hpp" #include "SHA512.hpp" -#include "AES.hpp" #include "Utils.hpp" -// Set this to use a much slower but portable modmul code that doesn't rely on a proper 64-bit FPU. +// Define this to use much slower but 100% portable code if an architecture's FPU isn't up to the task. //#define ZT_MIMC52_NO_FPU namespace ZeroTier { @@ -27,24 +26,26 @@ namespace { const uint64_t s_mimc52Primes[512] = { 4503599627332907ULL,4503599627332943ULL,4503599627333243ULL,4503599627333321ULL,4503599627333393ULL,4503599627333423ULL,4503599627333549ULL,4503599627333603ULL,4503599627333771ULL,4503599627333813ULL,4503599627333921ULL,4503599627333951ULL,4503599627334077ULL,4503599627334131ULL,4503599627334161ULL,4503599627334167ULL,4503599627334173ULL,4503599627334221ULL,4503599627334251ULL,4503599627334257ULL,4503599627334263ULL,4503599627334419ULL,4503599627334473ULL,4503599627334539ULL,4503599627334623ULL,4503599627334641ULL,4503599627334653ULL,4503599627334767ULL,4503599627334839ULL,4503599627334917ULL,4503599627335097ULL,4503599627335169ULL,4503599627335223ULL,4503599627335253ULL,4503599627335439ULL,4503599627335499ULL,4503599627335643ULL,4503599627335871ULL,4503599627335877ULL,4503599627335931ULL,4503599627335943ULL,4503599627335967ULL,4503599627335973ULL,4503599627335979ULL,4503599627336081ULL,4503599627336099ULL,4503599627336129ULL,4503599627336267ULL,4503599627336477ULL,4503599627336507ULL,4503599627336543ULL,4503599627336651ULL,4503599627336723ULL,4503599627336963ULL,4503599627336993ULL,4503599627337029ULL,4503599627337047ULL,4503599627337071ULL,4503599627337197ULL,4503599627337233ULL,4503599627337311ULL,4503599627337407ULL,4503599627337443ULL,4503599627337467ULL,4503599627337479ULL,4503599627337491ULL,4503599627337527ULL,4503599627337563ULL,4503599627337623ULL,4503599627337689ULL,4503599627337761ULL,4503599627338067ULL,4503599627338121ULL,4503599627338169ULL,4503599627338337ULL,4503599627338439ULL,4503599627338499ULL,4503599627338631ULL,4503599627338739ULL,4503599627338829ULL,4503599627338901ULL,4503599627338991ULL,4503599627338997ULL,4503599627339003ULL,4503599627339159ULL,4503599627339201ULL,4503599627339207ULL,4503599627339237ULL,4503599627339279ULL,4503599627339327ULL,4503599627339363ULL,4503599627339447ULL,4503599627339507ULL,4503599627339531ULL,4503599627339609ULL,4503599627339651ULL,4503599627339801ULL,4503599627339807ULL,4503599627339819ULL,4503599627339867ULL,4503599627339909ULL,4503599627339933ULL,4503599627339951ULL,4503599627339963ULL,4503599627340029ULL,4503599627340137ULL,4503599627340197ULL,4503599627340227ULL,4503599627340251ULL,4503599627340293ULL,4503599627340377ULL,4503599627340413ULL,4503599627340491ULL,4503599627340581ULL,4503599627340617ULL,4503599627340629ULL,4503599627340881ULL,4503599627340893ULL,4503599627340953ULL,4503599627340971ULL,4503599627341013ULL,4503599627341037ULL,4503599627341091ULL,4503599627341169ULL,4503599627341271ULL,4503599627341301ULL,4503599627341523ULL,4503599627341571ULL,4503599627341601ULL,4503599627341667ULL,4503599627341673ULL,4503599627341721ULL,4503599627341799ULL,4503599627341931ULL,4503599627341979ULL,4503599627342033ULL,4503599627342099ULL,4503599627342177ULL,4503599627342183ULL,4503599627342267ULL,4503599627342327ULL,4503599627342423ULL,4503599627342477ULL,4503599627342531ULL,4503599627342537ULL,4503599627342591ULL,4503599627342657ULL,4503599627342759ULL,4503599627342873ULL,4503599627342891ULL,4503599627343101ULL,4503599627343191ULL,4503599627343287ULL,4503599627343293ULL,4503599627343389ULL,4503599627343413ULL,4503599627343617ULL,4503599627343857ULL,4503599627343899ULL,4503599627343953ULL,4503599627344001ULL,4503599627344073ULL,4503599627344151ULL,4503599627344247ULL,4503599627344343ULL,4503599627344361ULL,4503599627344427ULL,4503599627344481ULL,4503599627344577ULL,4503599627344709ULL,4503599627344751ULL,4503599627344901ULL,4503599627344931ULL,4503599627344967ULL,4503599627345111ULL,4503599627345123ULL,4503599627345243ULL,4503599627345339ULL,4503599627345513ULL,4503599627345543ULL,4503599627345573ULL,4503599627345627ULL,4503599627345729ULL,4503599627345801ULL,4503599627345849ULL,4503599627345873ULL,4503599627345879ULL,4503599627345933ULL,4503599627345969ULL,4503599627346011ULL,4503599627346161ULL,4503599627346329ULL,4503599627346341ULL,4503599627346419ULL,4503599627346569ULL,4503599627346623ULL,4503599627346671ULL,4503599627346851ULL,4503599627346887ULL,4503599627346917ULL,4503599627346929ULL,4503599627346947ULL,4503599627346959ULL,4503599627347013ULL,4503599627347019ULL,4503599627347091ULL,4503599627347277ULL,4503599627347391ULL,4503599627347433ULL,4503599627347439ULL,4503599627347553ULL,4503599627347589ULL,4503599627347781ULL,4503599627347823ULL,4503599627347829ULL,4503599627347859ULL,4503599627348021ULL,4503599627348231ULL,4503599627348357ULL,4503599627348411ULL,4503599627348429ULL,4503599627348501ULL,4503599627348537ULL,4503599627348543ULL,4503599627348711ULL,4503599627348747ULL,4503599627348867ULL,4503599627348909ULL,4503599627348957ULL,4503599627349041ULL,4503599627349191ULL,4503599627349233ULL,4503599627349299ULL,4503599627349353ULL,4503599627349677ULL,4503599627349887ULL,4503599627349947ULL,4503599627350157ULL,4503599627350193ULL,4503599627350223ULL,4503599627350331ULL,4503599627350367ULL,4503599627350487ULL,4503599627350511ULL,4503599627350613ULL,4503599627350781ULL,4503599627350799ULL,4503599627350871ULL,4503599627351051ULL,4503599627351159ULL,4503599627351267ULL,4503599627351273ULL,4503599627351393ULL,4503599627351459ULL,4503599627351621ULL,4503599627351651ULL,4503599627351813ULL,4503599627351873ULL,4503599627352083ULL,4503599627352227ULL,4503599627352257ULL,4503599627352269ULL,4503599627352719ULL,4503599627352731ULL,4503599627352803ULL,4503599627352809ULL,4503599627352827ULL,4503599627352893ULL,4503599627352929ULL,4503599627352941ULL,4503599627353007ULL,4503599627353121ULL,4503599627353139ULL,4503599627353181ULL,4503599627353193ULL,4503599627353283ULL,4503599627353373ULL,4503599627353397ULL,4503599627353451ULL,4503599627353487ULL,4503599627353517ULL,4503599627353523ULL,4503599627353529ULL,4503599627353781ULL,4503599627353793ULL,4503599627353817ULL,4503599627353829ULL,4503599627353913ULL,4503599627354129ULL,4503599627354351ULL,4503599627354363ULL,4503599627354369ULL,4503599627354579ULL,4503599627354783ULL,4503599627354813ULL,4503599627355053ULL,4503599627355107ULL,4503599627355113ULL,4503599627355137ULL,4503599627355161ULL,4503599627355263ULL,4503599627355383ULL,4503599627355593ULL,4503599627355743ULL,4503599627355749ULL,4503599627355797ULL,4503599627355827ULL,4503599627355887ULL,4503599627355923ULL,4503599627355929ULL,4503599627355989ULL,4503599627356019ULL,4503599627356073ULL,4503599627356091ULL,4503599627356103ULL,4503599627356169ULL,4503599627356199ULL,4503599627356223ULL,4503599627356307ULL,4503599627356373ULL,4503599627356481ULL,4503599627356541ULL,4503599627356631ULL,4503599627356799ULL,4503599627356889ULL,4503599627356919ULL,4503599627357027ULL,4503599627357087ULL,4503599627357177ULL,4503599627357273ULL,4503599627357279ULL,4503599627357357ULL,4503599627357417ULL,4503599627357483ULL,4503599627357807ULL,4503599627357867ULL,4503599627358059ULL,4503599627358101ULL,4503599627358173ULL,4503599627358281ULL,4503599627358437ULL,4503599627358473ULL,4503599627358527ULL,4503599627358641ULL,4503599627358707ULL,4503599627358791ULL,4503599627358989ULL,4503599627359031ULL,4503599627359037ULL,4503599627359127ULL,4503599627359163ULL,4503599627359169ULL,4503599627359187ULL,4503599627359241ULL,4503599627359247ULL,4503599627359397ULL,4503599627359523ULL,4503599627359559ULL,4503599627359751ULL,4503599627359793ULL,4503599627359823ULL,4503599627359829ULL,4503599627359841ULL,4503599627359919ULL,4503599627359961ULL,4503599627359967ULL,4503599627359997ULL,4503599627360021ULL,4503599627360033ULL,4503599627360237ULL,4503599627360279ULL,4503599627360303ULL,4503599627360381ULL,4503599627360549ULL,4503599627360579ULL,4503599627360633ULL,4503599627360663ULL,4503599627360711ULL,4503599627360777ULL,4503599627360927ULL,4503599627361059ULL,4503599627361077ULL,4503599627361239ULL,4503599627361353ULL,4503599627361509ULL,4503599627361617ULL,4503599627361641ULL,4503599627361893ULL,4503599627361917ULL,4503599627361953ULL,4503599627362103ULL,4503599627362109ULL,4503599627362217ULL,4503599627362271ULL,4503599627362307ULL,4503599627362361ULL,4503599627362457ULL,4503599627362499ULL,4503599627362529ULL,4503599627362631ULL,4503599627362793ULL,4503599627362799ULL,4503599627362859ULL,4503599627363093ULL,4503599627363117ULL,4503599627363183ULL,4503599627363201ULL,4503599627363231ULL,4503599627363261ULL,4503599627363279ULL,4503599627363297ULL,4503599627363471ULL,4503599627363483ULL,4503599627363549ULL,4503599627363567ULL,4503599627363621ULL,4503599627363729ULL,4503599627363741ULL,4503599627363783ULL,4503599627363813ULL,4503599627363873ULL,4503599627363891ULL,4503599627363897ULL,4503599627363987ULL,4503599627364119ULL,4503599627364203ULL,4503599627364239ULL,4503599627364353ULL,4503599627364359ULL,4503599627364371ULL,4503599627364521ULL,4503599627364611ULL,4503599627364671ULL,4503599627364707ULL,4503599627364737ULL,4503599627364869ULL,4503599627364917ULL,4503599627364941ULL,4503599627365073ULL,4503599627365259ULL,4503599627365337ULL,4503599627365367ULL,4503599627365463ULL,4503599627365481ULL,4503599627365511ULL,4503599627365541ULL,4503599627365613ULL,4503599627365721ULL,4503599627365763ULL,4503599627365961ULL,4503599627366093ULL,4503599627366303ULL,4503599627366363ULL,4503599627366423ULL,4503599627366513ULL,4503599627366549ULL,4503599627366627ULL,4503599627366747ULL,4503599627366759ULL,4503599627366921ULL,4503599627366999ULL,4503599627367017ULL,4503599627367101ULL,4503599627367119ULL,4503599627367221ULL,4503599627367479ULL,4503599627367497ULL,4503599627367563ULL,4503599627367587ULL,4503599627367611ULL,4503599627367767ULL,4503599627367803ULL,4503599627367887ULL,4503599627367977ULL,4503599627368241ULL,4503599627368271ULL,4503599627368319ULL,4503599627368421ULL,4503599627368451ULL,4503599627368487ULL,4503599627368613ULL,4503599627368769ULL,4503599627368847ULL,4503599627368871ULL,4503599627368889ULL,4503599627368979ULL,4503599627369039ULL,4503599627369093ULL,4503599627369291ULL,4503599627369309ULL,4503599627369327ULL,4503599627369357ULL,4503599627369387ULL,4503599627369399ULL,4503599627369411ULL,4503599627369603ULL,4503599627369657ULL,4503599627369699ULL,4503599627369741ULL,4503599627369837ULL,4503599627369861ULL,4503599627369939ULL,4503599627370023ULL,4503599627370083ULL,4503599627370101ULL,4503599627370161ULL,4503599627370227ULL,4503599627370287ULL,4503599627370299ULL,4503599627370323ULL,4503599627370353ULL,4503599627370449ULL }; // This ASM code works on x64 but is slightly *slower* than the FPU trick as the -// latter avoids 128-bit divq. +// latter avoids 128-bit integer division. #if 0 +// r = (a * b) % m #define mulmod52(r,a,b,m) __asm__( \ "mulq %2;" \ "divq %3;" \ :"=&d"(r) \ :"a"(a),"r"(b),"r"(m)); + +// i = (i ^ 3) % m #define cubemod52(i,m) __asm__( \ - "movq %1,%%r10;" \ "movq %1,%%rax;" \ - "mulq %%r10;" \ + "mulq %1;" \ "divq %2;" \ "mov %%rdx,%%rax;" \ - "mulq %%r10;" \ + "mulq %1;" \ "divq %2;" \ :"=&d"(i) \ :"r"(i),"r"(m) \ - :"rax","r10"); + :"rax"); #endif #ifdef ZT_MIMC52_NO_FPU @@ -87,10 +88,17 @@ ZT_ALWAYS_INLINE uint64_t modpow52(uint64_t a,uint64_t e,const uint64_t p) noexc } } -ZT_ALWAYS_INLINE void mimc52Init(uint64_t hash[6],uint64_t k[128],const void *const salt,const unsigned int saltSize,uint64_t &p,uint64_t &x) noexcept +// See: https://en.wikipedia.org/wiki/Speck_(cipher) +#define SPECK_ROR(x,r) ((x >> r) | (x << (64U - r))) +#define SPECK_ROL(x,r) ((x << r) | (x >> (64U - r))) +#define SPECK_R(x,y,k) (x = SPECK_ROR(x,8U), x += y, x ^= k, y = SPECK_ROL(y,3U), y ^= x) + +ZT_ALWAYS_INLINE void mimc52Init(uint64_t k[128],const void *const salt,const unsigned int saltSize,uint64_t &p,uint64_t &x) noexcept { + uint64_t hash[6]; SHA384(hash,salt,saltSize); + // Choose a prime and a delay starting point / verification end point. #if __BYTE_ORDER == __LITTLE_ENDIAN p = s_mimc52Primes[hash[0] & 511U]; x = hash[1] % p; @@ -99,30 +107,45 @@ ZT_ALWAYS_INLINE void mimc52Init(uint64_t hash[6],uint64_t k[128],const void *co x = Utils::swapBytes(hash[1]) % p; #endif - AES aes(hash + 2); - uint64_t ctr[2]; - ctr[1] = 0; - for(unsigned int i=0;i<128;i+=2) { // AES-CTR (with little-endian counter) to expand salt into 'k' + // Use the Speck128 round function as a fast PRNG to generate MIMC round constants. Speck128 initial inputs are + // from the last 256 bits of the salt hash. MIMC round constants could be static, but generating them from the + // salt may improve the overall randomness and non-reversibility of the delay function. #if __BYTE_ORDER == __LITTLE_ENDIAN - ctr[0] = (uint64_t)i; + uint64_t ka = hash[2]; + uint64_t kb = hash[3]; #else - ctr[0] = (uint64_t)i << 56U; + uint64_t ka = Utils::swapBytes(hash[2]); + uint64_t kb = Utils::swapBytes(hash[3]); +#endif + uint64_t sy = hash[4],sx = hash[5]; + for(unsigned long i=0;i<128;i+=2) { + ka += i; + kb += i; + SPECK_R(sx,sy,kb); + SPECK_R(ka,kb,0U); + SPECK_R(sx,sy,kb); + SPECK_R(ka,kb,1U); + SPECK_R(sx,sy,kb); + SPECK_R(ka,kb,2U); + SPECK_R(sx,sy,kb); + SPECK_R(ka,kb,3U); + SPECK_R(sx,sy,kb); +#if __BYTE_ORDER == __LITTLE_ENDIAN + k[i] = sy; + k[i+1] = sx; +#else + k[i] = Utils::swapBytes(sy); + k[i+1] = Utils::swapBytes(sx); #endif - aes.encrypt(ctr,k + i); } - -#if __BYTE_ORDER != __LITTLE_ENDIAN - for(unsigned int i=0;i<128;++i) - k[i] = Utils::swapBytes(k[i]); -#endif } } // anonymous namespace uint64_t mimc52Delay(const void *const salt,const unsigned int saltSize,const unsigned long rounds) { - uint64_t hash[6],k[128],x,p; - mimc52Init(hash,k,salt,saltSize,p,x); + uint64_t k[128],x,p; + mimc52Init(k,salt,saltSize,p,x); const uint64_t e = ((p * 2) - 1) / 3; const uint64_t m52 = 0xfffffffffffffULL; @@ -136,8 +159,8 @@ uint64_t mimc52Delay(const void *const salt,const unsigned int saltSize,const un bool mimc52Verify(const void *const salt,const unsigned int saltSize,unsigned long rounds,const uint64_t proof) { - uint64_t hash[6],k[128],x,p; - mimc52Init(hash,k,salt,saltSize,p,x); + uint64_t k[128],x,p; + mimc52Init(k,salt,saltSize,p,x); const uint64_t m52 = 0xfffffffffffffULL; uint64_t y = proof & m52; @@ -152,15 +175,13 @@ bool mimc52Verify(const void *const salt,const unsigned int saltSize,unsigned lo of = (double)y; oi = y; - ii = of * of; + ii = (of * of) / pp; y *= oi; - ii /= pp; y -= ((uint64_t)ii - one) * p; //y %= p; - ii = (double)y * of; + ii = ((double)y * of) / pp; y *= oi; - ii /= pp; y -= ((uint64_t)ii - one) * p; y %= p; #endif diff --git a/node/Tests.cpp b/node/Tests.cpp index 11aa484f7..be68599be 100644 --- a/node/Tests.cpp +++ b/node/Tests.cpp @@ -180,8 +180,8 @@ 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 "237ce8d8e2:1:5w3rj6am3sa7f5vtwm535iswob6ngmkpdidijz5ormqrfwkj55lhwyyszruu4rkbjycmlxzzoiuwtyw5s2mybknqx5j2cwxnaflqbwycoio2hqzcro5afrpcncnxlemzs6bt5linlib5flsej3f3r3bbzclxk733ei7tdrtm5uruiwpmyi4vgaafze42sx6hpe:mwjavgvhxz75ow2fhgq3zu4qfou5kce4wzegpjjd6545fpjnhjxb26e5unuutv7k3c6sm6umpyvatgpufwehi4wqmyudvq724h2klbiem6txs2h5iit5crgg3e6se5xeomuqhircv7zhkylrtnlgh57il742pwkrdgt4lz5fstetmiw7y3rq" -#define IDENTITY_V1_KNOWN_BAD_0 "238ce8d8e2:1:5w3rj6am3sa7f5vtwm535iswob6ngmkpdidijz5ormqrfwkj55lhwyyszruu4rkbjycmlxzzoiuwtyw5s2mybknqx5j2cwxnaflqbwycoio2hqzcro5afrpcncnxlemzs6bt5linlib5flsej3f3r3bbzclxk733ei7tdrtm5uruiwpmyi4vgaafze42sx6hpe:mwjavgvhxz75ow2fhgq3zu4qfou5kce4wzegpjjd6545fpjnhjxb26e5unuutv7k3c6sm6umpyvatgpufwehi4wqmyudvq724h2klbiem6txs2h5iit5crgg3e6se5xeomuqhircv7zhkylrtnlgh57il742pwkrdgt4lz5fstetmiw7y3rq" +#define IDENTITY_V1_KNOWN_GOOD_0 "12a4e65422:1:norcnqlkhl2ly6aljrguqntd7bfwdpfpgse32gy2nonhrninfyfxbz4qyj4i7jm2jn6c5hnr6fe3j7a556w5irhtmz77ajdkw6ge2nadlwczld5yak4mhdj46bcwvgzpu3evsfbx44psgughwwgp7rl5ju2gcw4mil5csvd3dp6itwqksyzf6aake3fpn5seo4:ds3mdnqdnbveqlyqq446if3tdilsva4fpsaqahqysavvbv23j655yfahihupezaic56uqrk2dbaamdj2fzmyzulhraux2daj3p6hnxyrhbwugu2ukuqi4eucdck4eczjqcgmv33w65nyxkm3gvhahmoc3zwt2nqmexcdsxlqccexfcpvinuq" +#define IDENTITY_V1_KNOWN_BAD_0 "22a4e65422:1:norcnqlkhl2ly6aljrguqntd7bfwdpfpgse32gy2nonhrninfyfxbz4qyj4i7jm2jn6c5hnr6fe3j7a556w5irhtmz77ajdkw6ge2nadlwczld5yak4mhdj46bcwvgzpu3evsfbx44psgughwwgp7rl5ju2gcw4mil5csvd3dp6itwqksyzf6aake3fpn5seo4:ds3mdnqdnbveqlyqq446if3tdilsva4fpsaqahqysavvbv23j655yfahihupezaic56uqrk2dbaamdj2fzmyzulhraux2daj3p6hnxyrhbwugu2ukuqi4eucdck4eczjqcgmv33w65nyxkm3gvhahmoc3zwt2nqmexcdsxlqccexfcpvinuq" // -------------------------------------------------------------------------------------------------------------------- @@ -639,7 +639,7 @@ extern "C" const char *ZTT_crypto() { ZT_T_PRINTF("[crypto] Testing MIMC52 VDF... "); const uint64_t proof = mimc52Delay("testing",7,1000); - if ((!mimc52Verify("testing",7,1000,proof))||(proof != 0x0007a1a0a1b0fe32)) { + if ((!mimc52Verify("testing",7,1000,proof))||(proof != 0x000b501115c73369)) { ZT_T_PRINTF("FAILED (%.16llx)" ZT_EOL_S,proof); return "MIMC52 failed simple delay/verify test"; } diff --git a/node/Utils.hpp b/node/Utils.hpp index 41c3b0d06..ccf40ca0d 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -423,14 +423,14 @@ static ZT_ALWAYS_INLINE uint64_t swapBytes(uint64_t n) noexcept #endif #else return ( - ((n & 0x00000000000000FFULL) << 56) | - ((n & 0x000000000000FF00ULL) << 40) | - ((n & 0x0000000000FF0000ULL) << 24) | - ((n & 0x00000000FF000000ULL) << 8) | - ((n & 0x000000FF00000000ULL) >> 8) | - ((n & 0x0000FF0000000000ULL) >> 24) | - ((n & 0x00FF000000000000ULL) >> 40) | - ((n & 0xFF00000000000000ULL) >> 56) + ((n & 0x00000000000000ffULL) << 56) | + ((n & 0x000000000000ff00ULL) << 40) | + ((n & 0x0000000000ff0000ULL) << 24) | + ((n & 0x00000000ff000000ULL) << 8) | + ((n & 0x000000ff00000000ULL) >> 8) | + ((n & 0x0000ff0000000000ULL) >> 24) | + ((n & 0x00ff000000000000ULL) >> 40) | + ((n & 0xff00000000000000ULL) >> 56) ); #endif } @@ -446,15 +446,32 @@ template static ZT_ALWAYS_INLINE I loadBigEndian(const void *const p) noexcept { #ifdef ZT_NO_UNALIGNED_ACCESS - I x = (I)0; - for(unsigned int k=0;k(&x)[k] = reinterpret_cast(p)[(sizeof(I)-1)-k]; -#else - reinterpret_cast(&x)[k] = reinterpret_cast(p)[k]; -#endif + if (sizeof(I) == 8) { + return (I)( + ((uint64_t)reinterpret_cast(p)[0] << 56U) | + ((uint64_t)reinterpret_cast(p)[1] << 48U) | + ((uint64_t)reinterpret_cast(p)[2] << 40U) | + ((uint64_t)reinterpret_cast(p)[3] << 32U) | + ((uint64_t)reinterpret_cast(p)[4] << 24U) | + ((uint64_t)reinterpret_cast(p)[5] << 16U) | + ((uint64_t)reinterpret_cast(p)[6] << 8U) | + (uint64_t)reinterpret_cast(p)[7] + ); + } else if (sizeof(I) == 4) { + return (I)( + ((uint32_t)reinterpret_cast(p)[0] << 24U) | + ((uint32_t)reinterpret_cast(p)[1] << 16U) | + ((uint32_t)reinterpret_cast(p)[2] << 8U) | + (uint32_t)reinterpret_cast(p)[3] + ); + } else if (sizeof(I) == 2) { + return (I)( + ((unsigned int)reinterpret_cast(p)[0] << 8U) | + (unsigned int)reinterpret_cast(p)[1] + ); + } else { + return (I)reinterpret_cast(p)[0]; } - return x; #else return ntoh(*reinterpret_cast(p)); #endif @@ -468,15 +485,28 @@ static ZT_ALWAYS_INLINE I loadBigEndian(const void *const p) noexcept * #param i Integer to write */ template -static ZT_ALWAYS_INLINE void storeBigEndian(void *const p,const I i) noexcept +static ZT_ALWAYS_INLINE void storeBigEndian(void *const p,I i) noexcept { #ifdef ZT_NO_UNALIGNED_ACCESS - for(unsigned int k=0;k(p)[k] = reinterpret_cast(&i)[(sizeof(I)-1)-k]; -#else - reinterpret_cast(p)[k] = reinterpret_cast(&i)[k]; -#endif + if (sizeof(I) == 8) { + reinterpret_cast(p)[0] = (uint8_t)(reinterpret_cast(i) >> 56U); + reinterpret_cast(p)[1] = (uint8_t)(reinterpret_cast(i) >> 48U); + reinterpret_cast(p)[2] = (uint8_t)(reinterpret_cast(i) >> 40U); + reinterpret_cast(p)[3] = (uint8_t)(reinterpret_cast(i) >> 32U); + reinterpret_cast(p)[4] = (uint8_t)(reinterpret_cast(i) >> 24U); + reinterpret_cast(p)[5] = (uint8_t)(reinterpret_cast(i) >> 16U); + reinterpret_cast(p)[6] = (uint8_t)(reinterpret_cast(i) >> 8U); + reinterpret_cast(p)[7] = (uint8_t)reinterpret_cast(i); + } else if (sizeof(I) == 4) { + reinterpret_cast(p)[0] = (uint8_t)(reinterpret_cast(i) >> 24U); + reinterpret_cast(p)[1] = (uint8_t)(reinterpret_cast(i) >> 16U); + reinterpret_cast(p)[2] = (uint8_t)(reinterpret_cast(i) >> 8U); + reinterpret_cast(p)[3] = (uint8_t)reinterpret_cast(i); + } else if (sizeof(I) == 2) { + reinterpret_cast(p)[0] = (uint8_t)(reinterpret_cast(i) >> 8U); + reinterpret_cast(p)[1] = (uint8_t)reinterpret_cast(i); + } else { + reinterpret_cast(p)[0] = (uint8_t)i; } #else *reinterpret_cast(p) = hton(i); @@ -486,33 +516,42 @@ static ZT_ALWAYS_INLINE void storeBigEndian(void *const p,const I i) noexcept /** * Decode a little-endian value from a byte stream * - * @tparam I Type to decode (should be unsigned e.g. uint32_t or uint64_t) + * @tparam I Type to decode * @param p Byte stream, must be at least sizeof(I) in size * @return Decoded integer */ template static ZT_ALWAYS_INLINE I loadLittleEndian(const void *const p) noexcept { -#ifdef ZT_NO_UNALIGNED_ACCESS - I x = (I)0; - for(unsigned int k=0;k(&x)[k] = reinterpret_cast(p)[k]; -#else - reinterpret_cast(&x)[k] = reinterpret_cast(p)[(sizeof(I)-1)-k]; -#endif +#if __BYTE_ORDER == __BIG_ENDIAN || defined(ZT_NO_UNALIGNED_ACCESS) + if (sizeof(I) == 8) { + return (I)( + (uint64_t)reinterpret_cast(p)[0] | + ((uint64_t)reinterpret_cast(p)[1] << 8U) | + ((uint64_t)reinterpret_cast(p)[2] << 16U) | + ((uint64_t)reinterpret_cast(p)[3] << 24U) | + ((uint64_t)reinterpret_cast(p)[4] << 32U) | + ((uint64_t)reinterpret_cast(p)[5] << 40U) | + ((uint64_t)reinterpret_cast(p)[6] << 48U) | + ((uint64_t)reinterpret_cast(p)[7] << 56U) + ); + } else if (sizeof(I) == 4) { + return (I)( + (uint32_t)reinterpret_cast(p)[0] | + ((uint32_t)reinterpret_cast(p)[1] << 8U) | + ((uint32_t)reinterpret_cast(p)[2] << 16U) | + ((uint32_t)reinterpret_cast(p)[3] << 24U) + ); + } else if (sizeof(I) == 2) { + return (I)( + (unsigned int)reinterpret_cast(p)[0] | + ((unsigned int)reinterpret_cast(p)[1] << 8U) + ); + } else { + return (I)reinterpret_cast(p)[0]; } - return x; #else -#if __BYTE_ORDER == __LITTLE_ENDIAN return *reinterpret_cast(p); -#else - I x = (I)0; - for(unsigned int k=0;k(&x)[k] = reinterpret_cast(p)[(sizeof(I)-1)-k]; - } - return x; -#endif #endif } @@ -526,22 +565,29 @@ static ZT_ALWAYS_INLINE I loadLittleEndian(const void *const p) noexcept template static ZT_ALWAYS_INLINE void storeLittleEndian(void *const p,const I i) noexcept { -#ifdef ZT_NO_UNALIGNED_ACCESS - for(unsigned int k=0;k(p)[k] = reinterpret_cast(&i)[k]; -#else - reinterpret_cast(p)[k] = reinterpret_cast(&i)[(sizeof(I)-1)-k]; -#endif +#if __BYTE_ORDER == __BIG_ENDIAN || defined(ZT_NO_UNALIGNED_ACCESS) + if (sizeof(I) == 8) { + reinterpret_cast(p)[0] = (uint8_t)reinterpret_cast(i); + reinterpret_cast(p)[1] = (uint8_t)(reinterpret_cast(i) >> 8U); + reinterpret_cast(p)[2] = (uint8_t)(reinterpret_cast(i) >> 16U); + reinterpret_cast(p)[3] = (uint8_t)(reinterpret_cast(i) >> 24U); + reinterpret_cast(p)[4] = (uint8_t)(reinterpret_cast(i) >> 32U); + reinterpret_cast(p)[5] = (uint8_t)(reinterpret_cast(i) >> 40U); + reinterpret_cast(p)[6] = (uint8_t)(reinterpret_cast(i) >> 48U); + reinterpret_cast(p)[7] = (uint8_t)(reinterpret_cast(i) >> 56U); + } else if (sizeof(I) == 4) { + reinterpret_cast(p)[0] = (uint8_t)reinterpret_cast(i); + reinterpret_cast(p)[1] = (uint8_t)(reinterpret_cast(i) >> 8U); + reinterpret_cast(p)[2] = (uint8_t)(reinterpret_cast(i) >> 16U); + reinterpret_cast(p)[3] = (uint8_t)(reinterpret_cast(i) >> 24U); + } else if (sizeof(I) == 2) { + reinterpret_cast(p)[0] = (uint8_t)reinterpret_cast(i); + reinterpret_cast(p)[1] = (uint8_t)(reinterpret_cast(i) >> 8U); + } else { + reinterpret_cast(p)[0] = (uint8_t)i; } #else -#if __BYTE_ORDER == __LITTLE_ENDIAN *reinterpret_cast(p) = i; -#else - for(unsigned int k=0;k(p)[k] = reinterpret_cast(&i)[(sizeof(I)-1)-k]; - } -#endif #endif }