Identity.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  4. *
  5. * (c) ZeroTier, Inc.
  6. * https://www.zerotier.com/
  7. */
  8. #include "Identity.hpp"
  9. #include "Constants.hpp"
  10. #include "ECC.hpp"
  11. #include "SHA512.hpp"
  12. #include "Salsa20.hpp"
  13. #include "Utils.hpp"
  14. #include <stdint.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. // These can't be changed without a new identity type. They define the
  19. // parameters of the hashcash hashing/searching algorithm.
  20. #define ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN 17
  21. #define ZT_IDENTITY_GEN_MEMORY 2097152
  22. namespace ZeroTier {
  23. // A memory-hard composition of SHA-512 and Salsa20 for hashcash hashing
  24. static inline void _computeMemoryHardHash(const void* publicKey, unsigned int publicKeyBytes, void* digest, void* genmem)
  25. {
  26. // Digest publicKey[] to obtain initial digest
  27. SHA512(digest, publicKey, publicKeyBytes);
  28. // Initialize genmem[] using Salsa20 in a CBC-like configuration since
  29. // ordinary Salsa20 is randomly seek-able. This is good for a cipher
  30. // but is not what we want for sequential memory-hardness.
  31. memset(genmem, 0, ZT_IDENTITY_GEN_MEMORY);
  32. Salsa20 s20(digest, (char*)digest + 32);
  33. s20.crypt20((char*)genmem, (char*)genmem, 64);
  34. for (unsigned long i = 64; i < ZT_IDENTITY_GEN_MEMORY; i += 64) {
  35. unsigned long k = i - 64;
  36. *((uint64_t*)((char*)genmem + i)) = *((uint64_t*)((char*)genmem + k));
  37. *((uint64_t*)((char*)genmem + i + 8)) = *((uint64_t*)((char*)genmem + k + 8));
  38. *((uint64_t*)((char*)genmem + i + 16)) = *((uint64_t*)((char*)genmem + k + 16));
  39. *((uint64_t*)((char*)genmem + i + 24)) = *((uint64_t*)((char*)genmem + k + 24));
  40. *((uint64_t*)((char*)genmem + i + 32)) = *((uint64_t*)((char*)genmem + k + 32));
  41. *((uint64_t*)((char*)genmem + i + 40)) = *((uint64_t*)((char*)genmem + k + 40));
  42. *((uint64_t*)((char*)genmem + i + 48)) = *((uint64_t*)((char*)genmem + k + 48));
  43. *((uint64_t*)((char*)genmem + i + 56)) = *((uint64_t*)((char*)genmem + k + 56));
  44. s20.crypt20((char*)genmem + i, (char*)genmem + i, 64);
  45. }
  46. // Render final digest using genmem as a lookup table
  47. for (unsigned long i = 0; i < (ZT_IDENTITY_GEN_MEMORY / sizeof(uint64_t));) {
  48. unsigned long idx1 = (unsigned long)(Utils::ntoh(((uint64_t*)genmem)[i++]) % (64 / sizeof(uint64_t)));
  49. unsigned long idx2 = (unsigned long)(Utils::ntoh(((uint64_t*)genmem)[i++]) % (ZT_IDENTITY_GEN_MEMORY / sizeof(uint64_t)));
  50. uint64_t tmp = ((uint64_t*)genmem)[idx2];
  51. ((uint64_t*)genmem)[idx2] = ((uint64_t*)digest)[idx1];
  52. ((uint64_t*)digest)[idx1] = tmp;
  53. s20.crypt20(digest, digest, 64);
  54. }
  55. }
  56. // Hashcash generation halting condition -- halt when first byte is less than
  57. // threshold value.
  58. struct _Identity_generate_cond {
  59. _Identity_generate_cond()
  60. {
  61. }
  62. _Identity_generate_cond(unsigned char* sb, char* gm) : digest(sb), genmem(gm)
  63. {
  64. }
  65. inline bool operator()(const ECC::Pair& kp) const
  66. {
  67. _computeMemoryHardHash(kp.pub.data, ZT_ECC_PUBLIC_KEY_SET_LEN, digest, genmem);
  68. return (digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN);
  69. }
  70. unsigned char* digest;
  71. char* genmem;
  72. };
  73. void Identity::generate()
  74. {
  75. unsigned char digest[64];
  76. char* genmem = new char[ZT_IDENTITY_GEN_MEMORY];
  77. ECC::Pair kp;
  78. do {
  79. kp = ECC::generateSatisfying(_Identity_generate_cond(digest, genmem));
  80. _address.setTo(digest + 59, ZT_ADDRESS_LENGTH); // last 5 bytes are address
  81. } while (_address.isReserved());
  82. _publicKey = kp.pub;
  83. if (! _privateKey) {
  84. _privateKey = new ECC::Private();
  85. }
  86. *_privateKey = kp.priv;
  87. delete[] genmem;
  88. }
  89. bool Identity::locallyValidate() const
  90. {
  91. if (_address.isReserved()) {
  92. return false;
  93. }
  94. unsigned char digest[64];
  95. char* genmem = new char[ZT_IDENTITY_GEN_MEMORY];
  96. _computeMemoryHardHash(_publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN, digest, genmem);
  97. delete[] genmem;
  98. unsigned char addrb[5];
  99. _address.copyTo(addrb, 5);
  100. 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]));
  101. }
  102. char* Identity::toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
  103. {
  104. char* p = buf;
  105. Utils::hex10(_address.toInt(), p);
  106. p += 10;
  107. *(p++) = ':';
  108. *(p++) = '0';
  109. *(p++) = ':';
  110. Utils::hex(_publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN, p);
  111. p += ZT_ECC_PUBLIC_KEY_SET_LEN * 2;
  112. if ((_privateKey) && (includePrivate)) {
  113. *(p++) = ':';
  114. Utils::hex(_privateKey->data, ZT_ECC_PRIVATE_KEY_SET_LEN, p);
  115. p += ZT_ECC_PRIVATE_KEY_SET_LEN * 2;
  116. }
  117. *p = (char)0;
  118. return buf;
  119. }
  120. bool Identity::fromString(const char* str)
  121. {
  122. if (! str) {
  123. _address.zero();
  124. return false;
  125. }
  126. char tmp[ZT_IDENTITY_STRING_BUFFER_LENGTH];
  127. if (! Utils::scopy(tmp, sizeof(tmp), str)) {
  128. _address.zero();
  129. return false;
  130. }
  131. delete _privateKey;
  132. _privateKey = (ECC::Private*)0;
  133. int fno = 0;
  134. char* saveptr = (char*)0;
  135. for (char* f = Utils::stok(tmp, ":", &saveptr); (f); f = Utils::stok((char*)0, ":", &saveptr)) {
  136. switch (fno++) {
  137. case 0:
  138. _address = Address(Utils::hexStrToU64(f));
  139. if (_address.isReserved()) {
  140. _address.zero();
  141. return false;
  142. }
  143. break;
  144. case 1:
  145. if ((f[0] != '0') || (f[1])) {
  146. _address.zero();
  147. return false;
  148. }
  149. break;
  150. case 2:
  151. if (Utils::unhex(f, _publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN) != ZT_ECC_PUBLIC_KEY_SET_LEN) {
  152. _address.zero();
  153. return false;
  154. }
  155. break;
  156. case 3:
  157. _privateKey = new ECC::Private();
  158. if (Utils::unhex(f, _privateKey->data, ZT_ECC_PRIVATE_KEY_SET_LEN) != ZT_ECC_PRIVATE_KEY_SET_LEN) {
  159. _address.zero();
  160. return false;
  161. }
  162. break;
  163. default:
  164. _address.zero();
  165. return false;
  166. }
  167. }
  168. if (fno < 3) {
  169. _address.zero();
  170. return false;
  171. }
  172. return true;
  173. }
  174. } // namespace ZeroTier