curve25519.tweetnacl.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* This is based on tweetnacl. Some typedefs have been
  2. * replaced with their stdint equivalents.
  3. *
  4. * Original code was public domain. */
  5. #include <stdint.h>
  6. #include <stddef.h>
  7. #include "handy.h"
  8. typedef int64_t gf[16];
  9. static const uint8_t _0[16],
  10. _9[32] = {9};
  11. static const gf gf0,
  12. gf1 = {1},
  13. _121665 = {0xDB41, 1},
  14. D = {0x78a3, 0x1359, 0x4dca, 0x75eb,
  15. 0xd8ab, 0x4141, 0x0a4d, 0x0070,
  16. 0xe898, 0x7779, 0x4079, 0x8cc7,
  17. 0xfe73, 0x2b6f, 0x6cee, 0x5203},
  18. D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6,
  19. 0xb156, 0x8283, 0x149a, 0x00e0,
  20. 0xd130, 0xeef3, 0x80f2, 0x198e,
  21. 0xfce7, 0x56df, 0xd9dc, 0x2406},
  22. X = {0xd51a, 0x8f25, 0x2d60, 0xc956,
  23. 0xa7b2, 0x9525, 0xc760, 0x692c,
  24. 0xdc5c, 0xfdd6, 0xe231, 0xc0a4,
  25. 0x53fe, 0xcd6e, 0x36d3, 0x2169},
  26. Y = {0x6658, 0x6666, 0x6666, 0x6666,
  27. 0x6666, 0x6666, 0x6666, 0x6666,
  28. 0x6666, 0x6666, 0x6666, 0x6666,
  29. 0x6666, 0x6666, 0x6666, 0x6666},
  30. I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee,
  31. 0xe478, 0xad2f, 0x1806, 0x2f43,
  32. 0xd7a7, 0x3dfb, 0x0099, 0x2b4d,
  33. 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
  34. static void set25519(gf r, const gf a)
  35. {
  36. size_t i;
  37. for (i = 0; i < 16; i++)
  38. r[i] = a[i];
  39. }
  40. static void car25519(gf o)
  41. {
  42. int64_t c;
  43. size_t i;
  44. for (i = 0; i < 16; i++)
  45. {
  46. o[i] += (1LL << 16);
  47. c = o[i] >> 16;
  48. o[(i + 1) * (i < 15)] += c - 1 + 37 * (c - 1) * (i == 15);
  49. o[i] -= (int64_t)((uint64_t)c << 16);
  50. }
  51. }
  52. static void sel25519(gf p, gf q, int64_t b)
  53. {
  54. int64_t tmp, mask = ~(b-1);
  55. size_t i;
  56. for (i = 0; i < 16; i++)
  57. {
  58. tmp = mask & (p[i] ^ q[i]);
  59. p[i] ^= tmp;
  60. q[i] ^= tmp;
  61. }
  62. }
  63. static void pack25519(uint8_t out[32], const gf n)
  64. {
  65. size_t i, j;
  66. int b;
  67. gf m, t;
  68. set25519(t, n);
  69. car25519(t);
  70. car25519(t);
  71. car25519(t);
  72. for(j = 0; j < 2; j++)
  73. {
  74. m[0] = t[0] - 0xffed;
  75. for (i = 1; i < 15; i++)
  76. {
  77. m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
  78. m[i - 1] &= 0xffff;
  79. }
  80. m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
  81. b = (m[15] >> 16) & 1;
  82. m[14] &= 0xffff;
  83. sel25519(t, m, 1 - b);
  84. }
  85. for (i = 0; i < 16; i++)
  86. {
  87. out[2 * i] = t[i] & 0xff;
  88. out[2 * i + 1] = (uint8_t) (t[i] >> 8);
  89. }
  90. }
  91. static void unpack25519(gf o, const uint8_t *n)
  92. {
  93. size_t i;
  94. for (i = 0; i < 16; i++)
  95. o[i] = n[2 * i] + ((int64_t) n[2 * i + 1] << 8);
  96. o[15] &= 0x7fff;
  97. }
  98. static void add(gf o, const gf a, const gf b)
  99. {
  100. size_t i;
  101. for (i = 0; i < 16; i++)
  102. o[i] = a[i] + b[i];
  103. }
  104. static void sub(gf o, const gf a, const gf b)
  105. {
  106. size_t i;
  107. for (i = 0; i < 16; i++)
  108. o[i] = a[i] - b[i];
  109. }
  110. static void mul(gf o, const gf a, const gf b)
  111. {
  112. int64_t t[31];
  113. size_t i, j;
  114. for (i = 0; i < 31; i++)
  115. t[i] = 0;
  116. for (i = 0; i < 16; i++)
  117. for (j = 0; j < 16; j++)
  118. t[i + j] += a[i] * b[j];
  119. for (i = 0; i < 15; i++)
  120. t[i] += 38 * t[i + 16];
  121. for (i = 0; i < 16; i++)
  122. o[i] = t[i];
  123. car25519(o);
  124. car25519(o);
  125. }
  126. static void sqr(gf o, const gf a)
  127. {
  128. mul(o, a, a);
  129. }
  130. static void inv25519(gf o, const gf i)
  131. {
  132. gf c;
  133. int a;
  134. for (a = 0; a < 16; a++)
  135. c[a] = i[a];
  136. for (a = 253; a >= 0; a--)
  137. {
  138. sqr(c, c);
  139. if(a != 2 && a != 4)
  140. mul(c, c, i);
  141. }
  142. for (a = 0; a < 16; a++)
  143. o[a] = c[a];
  144. }
  145. void cf_curve25519_mul(uint8_t *q, const uint8_t *n, const uint8_t *p)
  146. {
  147. uint8_t z[32];
  148. gf x;
  149. gf a, b, c, d, e, f;
  150. {
  151. size_t i;
  152. for (i = 0; i < 31; i++)
  153. z[i] = n[i];
  154. z[31] = (n[31] & 127) | 64;
  155. z[0] &= 248;
  156. unpack25519(x, p);
  157. for(i = 0; i < 16; i++)
  158. {
  159. b[i] = x[i];
  160. d[i] = a[i] = c[i] = 0;
  161. }
  162. }
  163. a[0] = d[0] = 1;
  164. {int i;
  165. for (i = 254; i >= 0; i--)
  166. {
  167. int64_t r = (z[i >> 3] >> (i & 7)) & 1;
  168. sel25519(a, b, r);
  169. sel25519(c, d, r);
  170. add(e, a, c);
  171. sub(a, a, c);
  172. add(c, b, d);
  173. sub(b, b, d);
  174. sqr(d, e);
  175. sqr(f, a);
  176. mul(a, c, a);
  177. mul(c, b, e);
  178. add(e, a, c);
  179. sub(a, a, c);
  180. sqr(b, a);
  181. sub(c, d, f);
  182. mul(a, c, _121665);
  183. add(a, a, d);
  184. mul(c, c, a);
  185. mul(a, d, f);
  186. mul(d, b, x);
  187. sqr(b, e);
  188. sel25519(a, b, r);
  189. sel25519(c, d, r);
  190. }
  191. }
  192. inv25519(c, c);
  193. mul(a, a, c);
  194. pack25519(q, a);
  195. }
  196. void cf_curve25519_mul_base(uint8_t *q, const uint8_t *n)
  197. {
  198. cf_curve25519_mul(q, n, _9);
  199. }