type 1 (P-384) identities
This commit is contained in:
parent
6e771607c0
commit
83d723eb79
15 changed files with 467 additions and 591 deletions
|
@ -40,7 +40,8 @@ namespace ZeroTier {
|
|||
namespace {
|
||||
|
||||
// These can't be changed without a new identity type. They define the
|
||||
// parameters of the hashcash hashing/searching algorithm.
|
||||
// parameters of the hashcash hashing/searching algorithm for type 0
|
||||
// identities.
|
||||
#define ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN 17
|
||||
#define ZT_IDENTITY_GEN_MEMORY 2097152
|
||||
|
||||
|
@ -86,9 +87,9 @@ struct _Identity_generate_cond
|
|||
{
|
||||
inline _Identity_generate_cond() {}
|
||||
inline _Identity_generate_cond(unsigned char *sb,char *gm) : digest(sb),genmem(gm) {}
|
||||
inline bool operator()(const C25519::Pair &kp) const
|
||||
inline bool operator()(const uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN]) const
|
||||
{
|
||||
_computeMemoryHardHash(kp.pub.data,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
|
||||
_computeMemoryHardHash(pub,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
|
||||
return (digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN);
|
||||
}
|
||||
unsigned char *digest;
|
||||
|
@ -100,71 +101,44 @@ struct _Identity_generate_cond
|
|||
void Identity::generate(const Type t)
|
||||
{
|
||||
uint8_t digest[64];
|
||||
|
||||
_type = t;
|
||||
_hasPrivate = true;
|
||||
|
||||
char *const genmem = new char[ZT_IDENTITY_GEN_MEMORY];
|
||||
switch(t) {
|
||||
case C25519: {
|
||||
C25519::Pair kp;
|
||||
do {
|
||||
kp = C25519::generateSatisfying(_Identity_generate_cond(digest,genmem));
|
||||
_address.setTo(digest + 59,ZT_ADDRESS_LENGTH); // last 5 bytes are address
|
||||
} while (_address.isReserved());
|
||||
memcpy(_k.t0.pub.data,kp.pub.data,ZT_C25519_PUBLIC_KEY_LEN);
|
||||
memcpy(_k.t0.priv.data,kp.priv.data,ZT_C25519_PRIVATE_KEY_LEN);
|
||||
_type = C25519;
|
||||
_hasPrivate = true;
|
||||
} break;
|
||||
case P384: {
|
||||
do {
|
||||
ECC384GenerateKey(_k.t1.pub,_k.t1.priv);
|
||||
_computeMemoryHardHash(_k.t1.pub,ZT_ECC384_PUBLIC_KEY_SIZE,digest,genmem);
|
||||
if (digest[0] >= ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN)
|
||||
continue;
|
||||
_address.setTo(digest + 59,ZT_ADDRESS_LENGTH);
|
||||
} while (_address.isReserved());
|
||||
_type = P384;
|
||||
_hasPrivate = true;
|
||||
} break;
|
||||
}
|
||||
do {
|
||||
C25519::generateSatisfying(_Identity_generate_cond(digest,genmem),_pub.c25519,_priv.c25519);
|
||||
_address.setTo(digest + 59,ZT_ADDRESS_LENGTH); // last 5 bytes are address
|
||||
} while (_address.isReserved());
|
||||
delete [] genmem;
|
||||
|
||||
if (t == P384)
|
||||
ECC384GenerateKey(_pub.p384,_priv.p384);
|
||||
}
|
||||
|
||||
bool Identity::locallyValidate() const
|
||||
{
|
||||
if (_address.isReserved())
|
||||
return false;
|
||||
uint8_t digest[64];
|
||||
|
||||
char *genmem = nullptr;
|
||||
try {
|
||||
uint8_t digest[64];
|
||||
genmem = new char[ZT_IDENTITY_GEN_MEMORY];
|
||||
switch(_type) {
|
||||
case C25519:
|
||||
_computeMemoryHardHash(_k.t0.pub.data,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
|
||||
break;
|
||||
case P384:
|
||||
_computeMemoryHardHash(_k.t1.pub,ZT_ECC384_PUBLIC_KEY_SIZE,digest,genmem);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
_computeMemoryHardHash(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
|
||||
delete [] genmem;
|
||||
unsigned char addrb[5];
|
||||
_address.copyTo(addrb,5);
|
||||
return (
|
||||
(digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN)&&
|
||||
(digest[59] == addrb[0])&&
|
||||
(digest[60] == addrb[1])&&
|
||||
(digest[61] == addrb[2])&&
|
||||
(digest[62] == addrb[3])&&
|
||||
(digest[63] == addrb[4]));
|
||||
return ((_address == Address(digest + 59,ZT_ADDRESS_LENGTH))&&(!_address.isReserved())&&(digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN));
|
||||
} catch ( ... ) {
|
||||
if (genmem) delete [] genmem;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
|
||||
{
|
||||
switch(_type) {
|
||||
|
||||
case C25519: {
|
||||
char *p = buf;
|
||||
Utils::hex10(_address.toInt(),p);
|
||||
|
@ -172,16 +146,17 @@ char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_
|
|||
*(p++) = ':';
|
||||
*(p++) = '0';
|
||||
*(p++) = ':';
|
||||
Utils::hex(_k.t0.pub.data,ZT_C25519_PUBLIC_KEY_LEN,p);
|
||||
Utils::hex(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,p);
|
||||
p += ZT_C25519_PUBLIC_KEY_LEN * 2;
|
||||
if ((_hasPrivate)&&(includePrivate)) {
|
||||
*(p++) = ':';
|
||||
Utils::hex(_k.t0.priv.data,ZT_C25519_PRIVATE_KEY_LEN,p);
|
||||
Utils::hex(_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN,p);
|
||||
p += ZT_C25519_PRIVATE_KEY_LEN * 2;
|
||||
}
|
||||
*p = (char)0;
|
||||
return buf;
|
||||
} break;
|
||||
|
||||
case P384: {
|
||||
char *p = buf;
|
||||
Utils::hex10(_address.toInt(),p);
|
||||
|
@ -189,38 +164,43 @@ char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_
|
|||
*(p++) = ':';
|
||||
*(p++) = '1';
|
||||
*(p++) = ':';
|
||||
Utils::hex(_k.t1.pub,ZT_ECC384_PUBLIC_KEY_SIZE,p);
|
||||
p += ZT_ECC384_PUBLIC_KEY_SIZE * 2;
|
||||
int el = Utils::b32e((const uint8_t *)(&_pub),ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE,p,(unsigned int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
|
||||
if (el <= 0) return nullptr;
|
||||
p += el;
|
||||
if ((_hasPrivate)&&(includePrivate)) {
|
||||
*(p++) = ':';
|
||||
Utils::hex(_k.t1.priv,ZT_ECC384_PRIVATE_KEY_SIZE,p);
|
||||
p += ZT_ECC384_PRIVATE_KEY_SIZE * 2;
|
||||
el = Utils::b32e((const uint8_t *)(&_pub),ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE,p,(unsigned int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
|
||||
if (el <= 0) return nullptr;
|
||||
p += el;
|
||||
}
|
||||
*p = (char)0;
|
||||
return buf;
|
||||
} break;
|
||||
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Identity::fromString(const char *str)
|
||||
{
|
||||
_hasPrivate = false;
|
||||
|
||||
if (!str) {
|
||||
_address.zero();
|
||||
return false;
|
||||
}
|
||||
|
||||
char tmp[ZT_IDENTITY_STRING_BUFFER_LENGTH];
|
||||
if (!Utils::scopy(tmp,sizeof(tmp),str)) {
|
||||
_address.zero();
|
||||
return false;
|
||||
}
|
||||
|
||||
_hasPrivate = false;
|
||||
|
||||
int fno = 0;
|
||||
char *saveptr = (char *)0;
|
||||
for(char *f=Utils::stok(tmp,":",&saveptr);(f);f=Utils::stok((char *)0,":",&saveptr)) {
|
||||
for(char *f=Utils::stok(tmp,":",&saveptr);((f)&&(fno < 4));f=Utils::stok((char *)0,":",&saveptr)) {
|
||||
switch(fno++) {
|
||||
|
||||
case 0:
|
||||
_address = Address(Utils::hexStrToU64(f));
|
||||
if (_address.isReserved()) {
|
||||
|
@ -228,6 +208,7 @@ bool Identity::fromString(const char *str)
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if ((f[0] == '0')&&(!f[1])) {
|
||||
_type = C25519;
|
||||
|
@ -238,47 +219,56 @@ bool Identity::fromString(const char *str)
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch(_type) {
|
||||
|
||||
case C25519:
|
||||
if (Utils::unhex(f,_k.t0.pub.data,ZT_C25519_PUBLIC_KEY_LEN) != ZT_C25519_PUBLIC_KEY_LEN) {
|
||||
if (Utils::unhex(f,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN) != ZT_C25519_PUBLIC_KEY_LEN) {
|
||||
_address.zero();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case P384:
|
||||
if (Utils::unhex(f,_k.t1.pub,ZT_ECC384_PUBLIC_KEY_SIZE) != ZT_ECC384_PUBLIC_KEY_SIZE) {
|
||||
if (Utils::b32d(f,(uint8_t *)(&_pub),ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE) != (ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE)) {
|
||||
_address.zero();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
switch(_type) {
|
||||
case C25519:
|
||||
if (Utils::unhex(f,_k.t0.priv.data,ZT_C25519_PRIVATE_KEY_LEN) != ZT_C25519_PRIVATE_KEY_LEN) {
|
||||
_address.zero();
|
||||
return false;
|
||||
} else {
|
||||
_hasPrivate = true;
|
||||
}
|
||||
break;
|
||||
case P384:
|
||||
if (Utils::unhex(f,_k.t1.priv,ZT_ECC384_PRIVATE_KEY_SIZE) != ZT_ECC384_PRIVATE_KEY_SIZE) {
|
||||
_address.zero();
|
||||
return false;
|
||||
} else {
|
||||
_hasPrivate = true;
|
||||
}
|
||||
break;
|
||||
if (strlen(f) > 1) {
|
||||
switch(_type) {
|
||||
|
||||
case C25519:
|
||||
if (Utils::unhex(f,_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN) != ZT_C25519_PRIVATE_KEY_LEN) {
|
||||
_address.zero();
|
||||
return false;
|
||||
} else {
|
||||
_hasPrivate = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case P384:
|
||||
if (Utils::b32d(f,(uint8_t *)(&_priv),ZT_C25519_PRIVATE_KEY_LEN + ZT_ECC384_PRIVATE_KEY_SIZE) != (ZT_C25519_PRIVATE_KEY_LEN + ZT_ECC384_PRIVATE_KEY_SIZE)) {
|
||||
_address.zero();
|
||||
return false;
|
||||
} else {
|
||||
_hasPrivate = true;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_address.zero();
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (fno < 3) {
|
||||
_address.zero();
|
||||
return false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue