cleanup, docs

This commit is contained in:
Adam Ierymenko 2020-02-26 12:40:29 -08:00
parent 5cec5fe6b1
commit 1c7e1da4d1
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
4 changed files with 30 additions and 16 deletions

View file

@ -105,7 +105,7 @@ bool Identity::generate(const Type t)
ECC384GenerateKey(_pub.p384,_priv.p384); ECC384GenerateKey(_pub.p384,_priv.p384);
Utils::storeBigEndian(_pub.t1mimc52,mimc52Delay(&_pub,sizeof(_pub) - sizeof(_pub.t1mimc52),ZT_V1_IDENTITY_MIMC52_VDF_ROUNDS_BASE)); Utils::storeBigEndian(_pub.t1mimc52,mimc52Delay(&_pub,sizeof(_pub) - sizeof(_pub.t1mimc52),ZT_V1_IDENTITY_MIMC52_VDF_ROUNDS_BASE));
_computeHash(); _computeHash();
_address.setTo(_hash.data()); _address.setTo(_fp.data());
if (!_address.isReserved()) if (!_address.isReserved())
break; break;
} }
@ -130,12 +130,12 @@ bool Identity::locallyValidate() const
char *genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY]; char *genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
_computeMemoryHardHash(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem); _computeMemoryHardHash(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
delete [] genmem; delete [] genmem;
return ((_address == Address(digest + 59))&&(!_address.isReserved())&&(digest[0] < 17)); return ((_address == Address(digest + 59))&&(digest[0] < 17));
} catch ( ... ) {} } catch ( ... ) {}
break; break;
case P384: case P384:
if ((_address == Address(_hash.data()))&&(!_address.isReserved())) { 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 // 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 // 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 // but it could have some use in the future. There is no harm in doing it, and we'll accept any round count
@ -303,7 +303,7 @@ char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_
bool Identity::fromString(const char *str) bool Identity::fromString(const char *str)
{ {
_hash.zero(); _fp.zero();
_hasPrivate = false; _hasPrivate = false;
if (!str) { if (!str) {
@ -438,7 +438,7 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool incl
int Identity::unmarshal(const uint8_t *data,const int len) noexcept int Identity::unmarshal(const uint8_t *data,const int len) noexcept
{ {
_hash.zero(); _fp.zero();
_hasPrivate = false; _hasPrivate = false;
if (len < (ZT_ADDRESS_LENGTH + 1)) if (len < (ZT_ADDRESS_LENGTH + 1))
@ -504,15 +504,15 @@ void Identity::_computeHash()
{ {
switch(_type) { switch(_type) {
default: default:
_hash.zero(); _fp.zero();
break; break;
case C25519: case C25519:
SHA384(_hash.data(),_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN); SHA384(_fp.data(),_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
break; break;
case P384: case P384:
SHA384(_hash.data(),&_pub,sizeof(_pub)); SHA384(_fp.data(),&_pub,sizeof(_pub));
break; break;
} }
} }

View file

@ -41,7 +41,10 @@ namespace ZeroTier {
* and Ed25519 and type 1 identities that include both a 25519 key pair and a NIST P-384 * and Ed25519 and type 1 identities that include both a 25519 key pair and a NIST P-384
* key pair. Type 1 identities use P-384 for signatures but use both key pairs at once * key pair. Type 1 identities use P-384 for signatures but use both key pairs at once
* (hashing both keys together) for key agreement with other type 1 identities, and can * (hashing both keys together) for key agreement with other type 1 identities, and can
* agree with type 0 identities by only using the Curve25519 component. * agree with type 0 identities using only Curve25519.
*
* Type 1 identities are better in many ways but type 0 will remain the default until
* 1.x nodes are pretty much dead in the wild.
*/ */
class Identity : public TriviallyCopyable class Identity : public TriviallyCopyable
{ {
@ -121,7 +124,7 @@ public:
* *
* @return Hash of public key(s) * @return Hash of public key(s)
*/ */
ZT_ALWAYS_INLINE const Fingerprint &fingerprint() const noexcept { return _hash; } ZT_ALWAYS_INLINE const Fingerprint &fingerprint() const noexcept { return _fp; }
/** /**
* Compute a hash of this identity's public and private keys. * Compute a hash of this identity's public and private keys.
@ -198,11 +201,11 @@ public:
*/ */
explicit ZT_ALWAYS_INLINE operator bool() const noexcept { return (_address); } explicit ZT_ALWAYS_INLINE operator bool() const noexcept { return (_address); }
ZT_ALWAYS_INLINE unsigned long hashCode() const noexcept { return _hash.hashCode(); } ZT_ALWAYS_INLINE unsigned long hashCode() const noexcept { return _fp.hashCode(); }
ZT_ALWAYS_INLINE bool operator==(const Identity &id) const noexcept ZT_ALWAYS_INLINE bool operator==(const Identity &id) const noexcept
{ {
return ((_address == id._address)&&(_type == id._type)&&(memcmp(_hash.data(),id._hash.data(),ZT_SHA384_DIGEST_LEN) == 0)); return ((_address == id._address)&&(_type == id._type)&&(memcmp(_fp.data(),id._fp.data(),ZT_SHA384_DIGEST_LEN) == 0));
} }
ZT_ALWAYS_INLINE bool operator!=(const Identity &id) const noexcept { return !(*this == id); } ZT_ALWAYS_INLINE bool operator!=(const Identity &id) const noexcept { return !(*this == id); }
ZT_ALWAYS_INLINE bool operator<(const Identity &id) const noexcept ZT_ALWAYS_INLINE bool operator<(const Identity &id) const noexcept
@ -213,7 +216,7 @@ public:
if ((int)_type < (int)id._type) if ((int)_type < (int)id._type)
return true; return true;
if (_type == id._type) if (_type == id._type)
return memcmp(_hash.data(),id._hash.data(),ZT_SHA384_DIGEST_LEN) < 0; return memcmp(_fp.data(),id._fp.data(),ZT_SHA384_DIGEST_LEN) < 0;
} }
return false; return false;
} }
@ -229,7 +232,7 @@ private:
void _computeHash(); void _computeHash();
Address _address; Address _address;
Fingerprint _hash; Fingerprint _fp;
ZT_PACKED_STRUCT(struct { // do not re-order these fields ZT_PACKED_STRUCT(struct { // do not re-order these fields
uint8_t c25519[ZT_C25519_PRIVATE_KEY_LEN]; uint8_t c25519[ZT_C25519_PRIVATE_KEY_LEN];
uint8_t p384[ZT_ECC384_PRIVATE_KEY_SIZE]; uint8_t p384[ZT_ECC384_PRIVATE_KEY_SIZE];

View file

@ -42,8 +42,7 @@ ZT_ALWAYS_INLINE uint64_t mulmod52(uint64_t a,uint64_t b,const uint64_t m) noexc
// It seems to be the fastest method on systems with a good double precision FPU. // It seems to be the fastest method on systems with a good double precision FPU.
return ((a * b) - (((uint64_t)(((double)a * (double)b) / (double)m) - 1ULL) * m)) % m; return ((a * b) - (((uint64_t)(((double)a * (double)b) / (double)m) - 1ULL) * m)) % m;
#else #else
// This is significantly slower on systems with a good FPU but will work any others. It supports 63 bits // This can be used as a fallback for any systems without FPU or with FPU precision issues.
// of precision even though we use only 52.
int64_t res = 0; int64_t res = 0;
for(;;) { for(;;) {
if (a & 1ULL) if (a & 1ULL)

View file

@ -1024,6 +1024,12 @@ extern "C" const char *ZTT_benchmarkCrypto()
} }
int64_t end = now(); int64_t end = now();
ZT_T_PRINTF("%.4f ms/generation (average, can vary quite a bit)" ZT_EOL_S,(double)(end - start) / 5.0); ZT_T_PRINTF("%.4f ms/generation (average, can vary quite a bit)" ZT_EOL_S,(double)(end - start) / 5.0);
ZT_T_PRINTF("[crypto] Benchmarking V0 Identity full validation... ");
start = now();
for(long i=0;i<10;++i)
foo = (uint8_t)id.locallyValidate();
end = now();
ZT_T_PRINTF("%.4f μs/validation" ZT_EOL_S,((double)(end - start) * 1000.0) / 10.0);
ZT_T_PRINTF("[crypto] Benchmarking V1 Identity generation... "); ZT_T_PRINTF("[crypto] Benchmarking V1 Identity generation... ");
start = now(); start = now();
for(long i=0;i<5;++i) { for(long i=0;i<5;++i) {
@ -1032,6 +1038,12 @@ extern "C" const char *ZTT_benchmarkCrypto()
} }
end = now(); end = now();
ZT_T_PRINTF("%.4f ms/generation (relatively constant time)" ZT_EOL_S,(double)(end - start) / 5.0); ZT_T_PRINTF("%.4f ms/generation (relatively constant time)" ZT_EOL_S,(double)(end - start) / 5.0);
ZT_T_PRINTF("[crypto] Benchmarking V1 Identity full validation... ");
start = now();
for(long i=0;i<100;++i)
foo = (uint8_t)id.locallyValidate();
end = now();
ZT_T_PRINTF("%.4f μs/validation" ZT_EOL_S,((double)(end - start) * 1000.0) / 100.0);
} }
} catch (std::exception &e) { } catch (std::exception &e) {
ZT_T_PRINTF(ZT_EOL_S "[crypto] Unexpected exception: %s" ZT_EOL_S,e.what()); ZT_T_PRINTF(ZT_EOL_S "[crypto] Unexpected exception: %s" ZT_EOL_S,e.what());