Poly1305.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. 20080912
  3. D. J. Bernstein
  4. Public domain.
  5. */
  6. #include "Constants.hpp"
  7. #include "Poly1305.hpp"
  8. #include <stdio.h>
  9. #include <stdint.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #ifdef __WINDOWS__
  13. #pragma warning(disable: 4146)
  14. #endif
  15. namespace ZeroTier {
  16. #if 0
  17. static inline void add(unsigned int h[17],const unsigned int c[17])
  18. {
  19. unsigned int j;
  20. unsigned int u;
  21. u = 0;
  22. for (j = 0;j < 17;++j) { u += h[j] + c[j]; h[j] = u & 255; u >>= 8; }
  23. }
  24. static inline void squeeze(unsigned int h[17])
  25. {
  26. unsigned int j;
  27. unsigned int u;
  28. u = 0;
  29. for (j = 0;j < 16;++j) { u += h[j]; h[j] = u & 255; u >>= 8; }
  30. u += h[16]; h[16] = u & 3;
  31. u = 5 * (u >> 2);
  32. for (j = 0;j < 16;++j) { u += h[j]; h[j] = u & 255; u >>= 8; }
  33. u += h[16]; h[16] = u;
  34. }
  35. static const unsigned int minusp[17] = {
  36. 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
  37. } ;
  38. static inline void freeze(unsigned int h[17])
  39. {
  40. unsigned int horig[17];
  41. unsigned int j;
  42. unsigned int negative;
  43. for (j = 0;j < 17;++j) horig[j] = h[j];
  44. add(h,minusp);
  45. negative = -(h[16] >> 7);
  46. for (j = 0;j < 17;++j) h[j] ^= negative & (horig[j] ^ h[j]);
  47. }
  48. static inline void mulmod(unsigned int h[17],const unsigned int r[17])
  49. {
  50. unsigned int hr[17];
  51. unsigned int i;
  52. unsigned int j;
  53. unsigned int u;
  54. for (i = 0;i < 17;++i) {
  55. u = 0;
  56. for (j = 0;j <= i;++j) u += h[j] * r[i - j];
  57. for (j = i + 1;j < 17;++j) u += 320 * h[j] * r[i + 17 - j];
  58. hr[i] = u;
  59. }
  60. for (i = 0;i < 17;++i) h[i] = hr[i];
  61. squeeze(h);
  62. }
  63. static inline int crypto_onetimeauth(unsigned char *out,const unsigned char *in,unsigned long long inlen,const unsigned char *k)
  64. {
  65. unsigned int j;
  66. unsigned int r[17];
  67. unsigned int h[17];
  68. unsigned int c[17];
  69. r[0] = k[0];
  70. r[1] = k[1];
  71. r[2] = k[2];
  72. r[3] = k[3] & 15;
  73. r[4] = k[4] & 252;
  74. r[5] = k[5];
  75. r[6] = k[6];
  76. r[7] = k[7] & 15;
  77. r[8] = k[8] & 252;
  78. r[9] = k[9];
  79. r[10] = k[10];
  80. r[11] = k[11] & 15;
  81. r[12] = k[12] & 252;
  82. r[13] = k[13];
  83. r[14] = k[14];
  84. r[15] = k[15] & 15;
  85. r[16] = 0;
  86. for (j = 0;j < 17;++j) h[j] = 0;
  87. while (inlen > 0) {
  88. for (j = 0;j < 17;++j) c[j] = 0;
  89. for (j = 0;(j < 16) && (j < inlen);++j) c[j] = in[j];
  90. c[j] = 1;
  91. in += j; inlen -= j;
  92. add(h,c);
  93. mulmod(h,r);
  94. }
  95. freeze(h);
  96. for (j = 0;j < 16;++j) c[j] = k[j + 16];
  97. c[16] = 0;
  98. add(h,c);
  99. for (j = 0;j < 16;++j) out[j] = h[j];
  100. return 0;
  101. }
  102. void Poly1305::compute(void *auth,const void *data,unsigned int len,const void *key)
  103. throw()
  104. {
  105. crypto_onetimeauth((unsigned char *)auth,(const unsigned char *)data,len,(const unsigned char *)key);
  106. }
  107. #endif
  108. namespace {
  109. typedef struct poly1305_context {
  110. size_t aligner;
  111. unsigned char opaque[136];
  112. } poly1305_context;
  113. /*
  114. poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication and 64 bit addition
  115. */
  116. #define poly1305_block_size 16
  117. /* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */
  118. typedef struct poly1305_state_internal_t {
  119. unsigned long r[5];
  120. unsigned long h[5];
  121. unsigned long pad[4];
  122. size_t leftover;
  123. unsigned char buffer[poly1305_block_size];
  124. unsigned char final;
  125. } poly1305_state_internal_t;
  126. /* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */
  127. static unsigned long
  128. U8TO32(const unsigned char *p) {
  129. return
  130. (((unsigned long)(p[0] & 0xff) ) |
  131. ((unsigned long)(p[1] & 0xff) << 8) |
  132. ((unsigned long)(p[2] & 0xff) << 16) |
  133. ((unsigned long)(p[3] & 0xff) << 24));
  134. }
  135. /* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */
  136. static void
  137. U32TO8(unsigned char *p, unsigned long v) {
  138. p[0] = (v ) & 0xff;
  139. p[1] = (v >> 8) & 0xff;
  140. p[2] = (v >> 16) & 0xff;
  141. p[3] = (v >> 24) & 0xff;
  142. }
  143. static inline void
  144. poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
  145. poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
  146. /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
  147. st->r[0] = (U8TO32(&key[ 0]) ) & 0x3ffffff;
  148. st->r[1] = (U8TO32(&key[ 3]) >> 2) & 0x3ffff03;
  149. st->r[2] = (U8TO32(&key[ 6]) >> 4) & 0x3ffc0ff;
  150. st->r[3] = (U8TO32(&key[ 9]) >> 6) & 0x3f03fff;
  151. st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff;
  152. /* h = 0 */
  153. st->h[0] = 0;
  154. st->h[1] = 0;
  155. st->h[2] = 0;
  156. st->h[3] = 0;
  157. st->h[4] = 0;
  158. /* save pad for later */
  159. st->pad[0] = U8TO32(&key[16]);
  160. st->pad[1] = U8TO32(&key[20]);
  161. st->pad[2] = U8TO32(&key[24]);
  162. st->pad[3] = U8TO32(&key[28]);
  163. st->leftover = 0;
  164. st->final = 0;
  165. }
  166. static inline void
  167. poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) {
  168. const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */
  169. unsigned long r0,r1,r2,r3,r4;
  170. unsigned long s1,s2,s3,s4;
  171. unsigned long h0,h1,h2,h3,h4;
  172. unsigned long long d0,d1,d2,d3,d4;
  173. unsigned long c;
  174. r0 = st->r[0];
  175. r1 = st->r[1];
  176. r2 = st->r[2];
  177. r3 = st->r[3];
  178. r4 = st->r[4];
  179. s1 = r1 * 5;
  180. s2 = r2 * 5;
  181. s3 = r3 * 5;
  182. s4 = r4 * 5;
  183. h0 = st->h[0];
  184. h1 = st->h[1];
  185. h2 = st->h[2];
  186. h3 = st->h[3];
  187. h4 = st->h[4];
  188. while (bytes >= poly1305_block_size) {
  189. /* h += m[i] */
  190. h0 += (U8TO32(m+ 0) ) & 0x3ffffff;
  191. h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff;
  192. h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff;
  193. h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff;
  194. h4 += (U8TO32(m+12) >> 8) | hibit;
  195. /* h *= r */
  196. d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1);
  197. d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2);
  198. d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3);
  199. d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4);
  200. d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0);
  201. /* (partial) h %= p */
  202. c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff;
  203. d1 += c; c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff;
  204. d2 += c; c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff;
  205. d3 += c; c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff;
  206. d4 += c; c = (unsigned long)(d4 >> 26); h4 = (unsigned long)d4 & 0x3ffffff;
  207. h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff;
  208. h1 += c;
  209. m += poly1305_block_size;
  210. bytes -= poly1305_block_size;
  211. }
  212. st->h[0] = h0;
  213. st->h[1] = h1;
  214. st->h[2] = h2;
  215. st->h[3] = h3;
  216. st->h[4] = h4;
  217. }
  218. static inline void
  219. poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) {
  220. poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
  221. size_t i;
  222. /* handle leftover */
  223. if (st->leftover) {
  224. size_t want = (poly1305_block_size - st->leftover);
  225. if (want > bytes)
  226. want = bytes;
  227. for (i = 0; i < want; i++)
  228. st->buffer[st->leftover + i] = m[i];
  229. bytes -= want;
  230. m += want;
  231. st->leftover += want;
  232. if (st->leftover < poly1305_block_size)
  233. return;
  234. poly1305_blocks(st, st->buffer, poly1305_block_size);
  235. st->leftover = 0;
  236. }
  237. /* process full blocks */
  238. if (bytes >= poly1305_block_size) {
  239. size_t want = (bytes & ~(poly1305_block_size - 1));
  240. poly1305_blocks(st, m, want);
  241. m += want;
  242. bytes -= want;
  243. }
  244. /* store leftover */
  245. if (bytes) {
  246. for (i = 0; i < bytes; i++)
  247. st->buffer[st->leftover + i] = m[i];
  248. st->leftover += bytes;
  249. }
  250. }
  251. static inline void
  252. poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) {
  253. poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
  254. unsigned long h0,h1,h2,h3,h4,c;
  255. unsigned long g0,g1,g2,g3,g4;
  256. unsigned long long f;
  257. unsigned long mask;
  258. /* process the remaining block */
  259. if (st->leftover) {
  260. size_t i = st->leftover;
  261. st->buffer[i++] = 1;
  262. for (; i < poly1305_block_size; i++)
  263. st->buffer[i] = 0;
  264. st->final = 1;
  265. poly1305_blocks(st, st->buffer, poly1305_block_size);
  266. }
  267. /* fully carry h */
  268. h0 = st->h[0];
  269. h1 = st->h[1];
  270. h2 = st->h[2];
  271. h3 = st->h[3];
  272. h4 = st->h[4];
  273. c = h1 >> 26; h1 = h1 & 0x3ffffff;
  274. h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
  275. h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
  276. h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
  277. h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
  278. h1 += c;
  279. /* compute h + -p */
  280. g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff;
  281. g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff;
  282. g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff;
  283. g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff;
  284. g4 = h4 + c - (1 << 26);
  285. /* select h if h < p, or h + -p if h >= p */
  286. mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1;
  287. g0 &= mask;
  288. g1 &= mask;
  289. g2 &= mask;
  290. g3 &= mask;
  291. g4 &= mask;
  292. mask = ~mask;
  293. h0 = (h0 & mask) | g0;
  294. h1 = (h1 & mask) | g1;
  295. h2 = (h2 & mask) | g2;
  296. h3 = (h3 & mask) | g3;
  297. h4 = (h4 & mask) | g4;
  298. /* h = h % (2^128) */
  299. h0 = ((h0 ) | (h1 << 26)) & 0xffffffff;
  300. h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
  301. h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
  302. h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
  303. /* mac = (h + pad) % (2^128) */
  304. f = (unsigned long long)h0 + st->pad[0] ; h0 = (unsigned long)f;
  305. f = (unsigned long long)h1 + st->pad[1] + (f >> 32); h1 = (unsigned long)f;
  306. f = (unsigned long long)h2 + st->pad[2] + (f >> 32); h2 = (unsigned long)f;
  307. f = (unsigned long long)h3 + st->pad[3] + (f >> 32); h3 = (unsigned long)f;
  308. U32TO8(mac + 0, h0);
  309. U32TO8(mac + 4, h1);
  310. U32TO8(mac + 8, h2);
  311. U32TO8(mac + 12, h3);
  312. /* zero out the state */
  313. st->h[0] = 0;
  314. st->h[1] = 0;
  315. st->h[2] = 0;
  316. st->h[3] = 0;
  317. st->h[4] = 0;
  318. st->r[0] = 0;
  319. st->r[1] = 0;
  320. st->r[2] = 0;
  321. st->r[3] = 0;
  322. st->r[4] = 0;
  323. st->pad[0] = 0;
  324. st->pad[1] = 0;
  325. st->pad[2] = 0;
  326. st->pad[3] = 0;
  327. }
  328. } // anonymous namespace
  329. void Poly1305::compute(void *auth,const void *data,unsigned int len,const void *key)
  330. throw()
  331. {
  332. poly1305_context ctx;
  333. poly1305_init(&ctx,reinterpret_cast<const unsigned char *>(key));
  334. poly1305_update(&ctx,reinterpret_cast<const unsigned char *>(data),(size_t)len);
  335. poly1305_finish(&ctx,reinterpret_cast<unsigned char *>(auth));
  336. }
  337. } // namespace ZeroTier