diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2018-12-06 12:00:49 -0800 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2018-12-06 12:00:49 -0800 |
commit | 18d1772bb472770517dd5f863849d0d08defd71c (patch) | |
tree | c127accc254bbb9880d119052b2209e4bc717731 /node | |
parent | 5535cad773b69cb9359185deead1a3d5ec7bad8a (diff) | |
download | infinitytier-18d1772bb472770517dd5f863849d0d08defd71c.tar.gz infinitytier-18d1772bb472770517dd5f863849d0d08defd71c.zip |
stuff for speed and stuff (testing)
Diffstat (limited to 'node')
-rw-r--r-- | node/C25519.cpp | 94 |
1 files changed, 82 insertions, 12 deletions
diff --git a/node/C25519.cpp b/node/C25519.cpp index 77084bd8..e3d23dee 100644 --- a/node/C25519.cpp +++ b/node/C25519.cpp @@ -15,6 +15,8 @@ Derived from public domain code by D. J. Bernstein. #include "C25519.hpp" #include "SHA512.hpp" #include "Buffer.hpp" +#include "Hashtable.hpp" +#include "Mutex.hpp" #ifdef __WINDOWS__ #pragma warning(disable: 4146) @@ -1996,11 +1998,28 @@ void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char } // anonymous namespace #ifdef ZT_USE_FAST_X64_ED25519 -extern "C" void ed25519_amd64_asm_sign(const unsigned char *sk,const unsigned char *pk,const unsigned char *m,const unsigned int mlen,unsigned char *sig); +extern "C" void ed25519_amd64_asm_sign(const unsigned char *sk,const unsigned char *pk,const unsigned char *digest,unsigned char *sig); #endif namespace ZeroTier { +struct C25519CacheKey +{ + uint64_t messageDigest[4]; + uint64_t publicKey[4]; + inline unsigned long hashCode() const { return (unsigned long)(messageDigest[0] ^ publicKey[0]); } + inline bool operator==(const C25519CacheKey &k) const { return (memcmp(this,&k,sizeof(C25519CacheKey)) == 0); } + inline bool operator!=(const C25519CacheKey &k) const { return (memcmp(this,&k,sizeof(C25519CacheKey)) != 0); } +}; +struct C25519CacheValue +{ + uint64_t signature[12]; + uint64_t timestamp; +}; +static uint64_t _ed25519TimestampCounter = 0; +static Hashtable<C25519CacheKey,C25519CacheValue> _ed25519Cache; +static Mutex _ed25519CacheLock; + void C25519::agree(const C25519::Private &mine,const C25519::Public &their,void *keybuf,unsigned int keylen) { unsigned char rawkey[32]; @@ -2019,8 +2038,24 @@ void C25519::agree(const C25519::Private &mine,const C25519::Public &their,void void C25519::sign(const C25519::Private &myPrivate,const C25519::Public &myPublic,const void *msg,unsigned int len,void *signature) { + unsigned char digest[64]; // we sign the first 32 bytes of SHA-512(msg) + SHA512::hash(digest,msg,len); + + C25519CacheKey ck; + ZT_FAST_MEMCPY(ck.messageDigest,digest,32); + ZT_FAST_MEMCPY(ck.publicKey,myPublic.data + 32,32); + C25519CacheValue *cv = (C25519CacheValue *)0; + { + Mutex::Lock l(_ed25519CacheLock); + cv = _ed25519Cache.get(ck); + } + if (cv) { + ZT_FAST_MEMCPY(signature,cv->signature,ZT_C25519_SIGNATURE_LEN); + return; + } + #ifdef ZT_USE_FAST_X64_ED25519 - ed25519_amd64_asm_sign(myPrivate.data + 32,myPublic.data + 32,(const unsigned char *)msg,len,(unsigned char *)signature); + ed25519_amd64_asm_sign(myPrivate.data + 32,myPublic.data + 32,digest,(unsigned char *)signature); #else sc25519 sck, scs, scsk; ge25519 ger; @@ -2030,9 +2065,6 @@ void C25519::sign(const C25519::Private &myPrivate,const C25519::Public &myPubli unsigned char hmg[crypto_hash_sha512_BYTES]; unsigned char hram[crypto_hash_sha512_BYTES]; unsigned char *sig = (unsigned char *)signature; - unsigned char digest[64]; // we sign the first 32 bytes of SHA-512(msg) - - SHA512::hash(digest,msg,len); SHA512::hash(extsk,myPrivate.data + 32,32); extsk[0] &= 248; @@ -2067,22 +2099,60 @@ void C25519::sign(const C25519::Private &myPrivate,const C25519::Public &myPubli for(unsigned int i=0;i<32;i++) sig[32 + i] = s[i]; #endif + +/* + Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers); + Address *a = (Address *)0; + SharedPtr<Peer> *p = (SharedPtr<Peer> *)0; + while (i.next(a,p)) + _savePeer((void *)0,*p); +*/ + C25519CacheValue cvn; + memcpy(cvn.signature,signature,ZT_C25519_SIGNATURE_LEN); + { + Mutex::Lock l(_ed25519CacheLock); + + if (_ed25519Cache.size() > 1048576) { + const uint64_t before = _ed25519TimestampCounter - ((1048576 / 3) * 2); + Hashtable< C25519CacheKey,C25519CacheValue >::Iterator i(_ed25519Cache); + C25519CacheKey *ik = (C25519CacheKey *)0; + C25519CacheValue *iv = (C25519CacheValue *)0; + while (i.next(ik,iv)) { + if (iv->timestamp < before) + _ed25519Cache.erase(*ik); + } + } + + cvn.timestamp = ++_ed25519TimestampCounter; + _ed25519Cache.set(ck,cvn); + } } bool C25519::verify(const C25519::Public &their,const void *msg,unsigned int len,const void *signature) { + const unsigned char *const sig = (const unsigned char *)signature; + unsigned char digest[64]; // we sign the first 32 bytes of SHA-512(msg) + SHA512::hash(digest,msg,len); + if (!Utils::secureEq(sig + 64,digest,32)) + return false; + + C25519CacheKey ck; + ZT_FAST_MEMCPY(ck.messageDigest,digest,32); + ZT_FAST_MEMCPY(ck.publicKey,their.data + 32,32); + C25519CacheValue *cv = (C25519CacheValue *)0; + { + Mutex::Lock l(_ed25519CacheLock); + cv = _ed25519Cache.get(ck); + } + if (cv) { + return Utils::secureEq(cv->signature,signature,ZT_C25519_SIGNATURE_LEN); + } + unsigned char t2[32]; ge25519 get1, get2; sc25519 schram, scs; unsigned char hram[crypto_hash_sha512_BYTES]; unsigned char m[96]; - unsigned char digest[64]; // we sign the first 32 bytes of SHA-512(msg) - const unsigned char *sig = (const unsigned char *)signature; - - // First check the message's integrity - SHA512::hash(digest,msg,len); - if (!Utils::secureEq(sig + 64,digest,32)) - return false; if (ge25519_unpackneg_vartime(&get1,their.data + 32)) return false; |