curve25519-donna-64bit.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. Public domain by Adam Langley <agl@imperialviolet.org> &
  3. Andrew M. <liquidsun@gmail.com>
  4. See: https://github.com/floodyberry/curve25519-donna
  5. 64bit integer curve25519 implementation
  6. */
  7. #if !defined(ED25519_SSE2) && defined(ED25519_64BIT)
  8. typedef uint64_t bignum25519[5];
  9. static const uint64_t reduce_mask_40 = ((uint64_t)1 << 40) - 1;
  10. static const uint64_t reduce_mask_51 = ((uint64_t)1 << 51) - 1;
  11. static const uint64_t reduce_mask_56 = ((uint64_t)1 << 56) - 1;
  12. /* out = in */
  13. DONNA_INLINE static void
  14. curve25519_copy(bignum25519 out, const bignum25519 in) {
  15. out[0] = in[0];
  16. out[1] = in[1];
  17. out[2] = in[2];
  18. out[3] = in[3];
  19. out[4] = in[4];
  20. }
  21. /* out = a + b */
  22. DONNA_INLINE static void
  23. curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) {
  24. out[0] = a[0] + b[0];
  25. out[1] = a[1] + b[1];
  26. out[2] = a[2] + b[2];
  27. out[3] = a[3] + b[3];
  28. out[4] = a[4] + b[4];
  29. }
  30. /* out = a + b, where a and/or b are the result of a basic op (add,sub) */
  31. DONNA_INLINE static void
  32. curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) {
  33. out[0] = a[0] + b[0];
  34. out[1] = a[1] + b[1];
  35. out[2] = a[2] + b[2];
  36. out[3] = a[3] + b[3];
  37. out[4] = a[4] + b[4];
  38. }
  39. DONNA_INLINE static void
  40. curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) {
  41. uint64_t c;
  42. out[0] = a[0] + b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51;
  43. out[1] = a[1] + b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51;
  44. out[2] = a[2] + b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51;
  45. out[3] = a[3] + b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51;
  46. out[4] = a[4] + b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51;
  47. out[0] += c * 19;
  48. }
  49. /* multiples of p */
  50. static const uint64_t twoP0 = 0x0fffffffffffda;
  51. static const uint64_t twoP1234 = 0x0ffffffffffffe;
  52. static const uint64_t fourP0 = 0x1fffffffffffb4;
  53. static const uint64_t fourP1234 = 0x1ffffffffffffc;
  54. /* out = a - b */
  55. DONNA_INLINE static void
  56. curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) {
  57. out[0] = a[0] + twoP0 - b[0];
  58. out[1] = a[1] + twoP1234 - b[1];
  59. out[2] = a[2] + twoP1234 - b[2];
  60. out[3] = a[3] + twoP1234 - b[3];
  61. out[4] = a[4] + twoP1234 - b[4];
  62. }
  63. /* out = a - b, where a and/or b are the result of a basic op (add,sub) */
  64. DONNA_INLINE static void
  65. curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) {
  66. out[0] = a[0] + fourP0 - b[0];
  67. out[1] = a[1] + fourP1234 - b[1];
  68. out[2] = a[2] + fourP1234 - b[2];
  69. out[3] = a[3] + fourP1234 - b[3];
  70. out[4] = a[4] + fourP1234 - b[4];
  71. }
  72. DONNA_INLINE static void
  73. curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) {
  74. uint64_t c;
  75. out[0] = a[0] + fourP0 - b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51;
  76. out[1] = a[1] + fourP1234 - b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51;
  77. out[2] = a[2] + fourP1234 - b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51;
  78. out[3] = a[3] + fourP1234 - b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51;
  79. out[4] = a[4] + fourP1234 - b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51;
  80. out[0] += c * 19;
  81. }
  82. /* out = -a */
  83. DONNA_INLINE static void
  84. curve25519_neg(bignum25519 out, const bignum25519 a) {
  85. uint64_t c;
  86. out[0] = twoP0 - a[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51;
  87. out[1] = twoP1234 - a[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51;
  88. out[2] = twoP1234 - a[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51;
  89. out[3] = twoP1234 - a[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51;
  90. out[4] = twoP1234 - a[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51;
  91. out[0] += c * 19;
  92. }
  93. /* out = a * b */
  94. DONNA_INLINE static void
  95. curve25519_mul(bignum25519 out, const bignum25519 in2, const bignum25519 in) {
  96. #if !defined(HAVE_NATIVE_UINT128)
  97. uint128_t mul;
  98. #endif
  99. uint128_t t[5];
  100. uint64_t r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c;
  101. r0 = in[0];
  102. r1 = in[1];
  103. r2 = in[2];
  104. r3 = in[3];
  105. r4 = in[4];
  106. s0 = in2[0];
  107. s1 = in2[1];
  108. s2 = in2[2];
  109. s3 = in2[3];
  110. s4 = in2[4];
  111. #if defined(HAVE_NATIVE_UINT128)
  112. t[0] = ((uint128_t) r0) * s0;
  113. t[1] = ((uint128_t) r0) * s1 + ((uint128_t) r1) * s0;
  114. t[2] = ((uint128_t) r0) * s2 + ((uint128_t) r2) * s0 + ((uint128_t) r1) * s1;
  115. t[3] = ((uint128_t) r0) * s3 + ((uint128_t) r3) * s0 + ((uint128_t) r1) * s2 + ((uint128_t) r2) * s1;
  116. t[4] = ((uint128_t) r0) * s4 + ((uint128_t) r4) * s0 + ((uint128_t) r3) * s1 + ((uint128_t) r1) * s3 + ((uint128_t) r2) * s2;
  117. #else
  118. mul64x64_128(t[0], r0, s0)
  119. mul64x64_128(t[1], r0, s1) mul64x64_128(mul, r1, s0) add128(t[1], mul)
  120. mul64x64_128(t[2], r0, s2) mul64x64_128(mul, r2, s0) add128(t[2], mul) mul64x64_128(mul, r1, s1) add128(t[2], mul)
  121. mul64x64_128(t[3], r0, s3) mul64x64_128(mul, r3, s0) add128(t[3], mul) mul64x64_128(mul, r1, s2) add128(t[3], mul) mul64x64_128(mul, r2, s1) add128(t[3], mul)
  122. mul64x64_128(t[4], r0, s4) mul64x64_128(mul, r4, s0) add128(t[4], mul) mul64x64_128(mul, r3, s1) add128(t[4], mul) mul64x64_128(mul, r1, s3) add128(t[4], mul) mul64x64_128(mul, r2, s2) add128(t[4], mul)
  123. #endif
  124. r1 *= 19;
  125. r2 *= 19;
  126. r3 *= 19;
  127. r4 *= 19;
  128. #if defined(HAVE_NATIVE_UINT128)
  129. t[0] += ((uint128_t) r4) * s1 + ((uint128_t) r1) * s4 + ((uint128_t) r2) * s3 + ((uint128_t) r3) * s2;
  130. t[1] += ((uint128_t) r4) * s2 + ((uint128_t) r2) * s4 + ((uint128_t) r3) * s3;
  131. t[2] += ((uint128_t) r4) * s3 + ((uint128_t) r3) * s4;
  132. t[3] += ((uint128_t) r4) * s4;
  133. #else
  134. mul64x64_128(mul, r4, s1) add128(t[0], mul) mul64x64_128(mul, r1, s4) add128(t[0], mul) mul64x64_128(mul, r2, s3) add128(t[0], mul) mul64x64_128(mul, r3, s2) add128(t[0], mul)
  135. mul64x64_128(mul, r4, s2) add128(t[1], mul) mul64x64_128(mul, r2, s4) add128(t[1], mul) mul64x64_128(mul, r3, s3) add128(t[1], mul)
  136. mul64x64_128(mul, r4, s3) add128(t[2], mul) mul64x64_128(mul, r3, s4) add128(t[2], mul)
  137. mul64x64_128(mul, r4, s4) add128(t[3], mul)
  138. #endif
  139. r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51);
  140. add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51);
  141. add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51);
  142. add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51);
  143. add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51);
  144. r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51;
  145. r1 += c;
  146. out[0] = r0;
  147. out[1] = r1;
  148. out[2] = r2;
  149. out[3] = r3;
  150. out[4] = r4;
  151. }
  152. DONNA_NOINLINE static void
  153. curve25519_mul_noinline(bignum25519 out, const bignum25519 in2, const bignum25519 in) {
  154. curve25519_mul(out, in2, in);
  155. }
  156. /* out = in^(2 * count) */
  157. DONNA_NOINLINE static void
  158. curve25519_square_times(bignum25519 out, const bignum25519 in, uint64_t count) {
  159. #if !defined(HAVE_NATIVE_UINT128)
  160. uint128_t mul;
  161. #endif
  162. uint128_t t[5];
  163. uint64_t r0,r1,r2,r3,r4,c;
  164. uint64_t d0,d1,d2,d4,d419;
  165. r0 = in[0];
  166. r1 = in[1];
  167. r2 = in[2];
  168. r3 = in[3];
  169. r4 = in[4];
  170. do {
  171. d0 = r0 * 2;
  172. d1 = r1 * 2;
  173. d2 = r2 * 2 * 19;
  174. d419 = r4 * 19;
  175. d4 = d419 * 2;
  176. #if defined(HAVE_NATIVE_UINT128)
  177. t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 ));
  178. t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19));
  179. t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 ));
  180. t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 ));
  181. t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 ));
  182. #else
  183. mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul)
  184. mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul)
  185. mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul)
  186. mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul)
  187. mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul)
  188. #endif
  189. r0 = lo128(t[0]) & reduce_mask_51;
  190. r1 = lo128(t[1]) & reduce_mask_51; shl128(c, t[0], 13); r1 += c;
  191. r2 = lo128(t[2]) & reduce_mask_51; shl128(c, t[1], 13); r2 += c;
  192. r3 = lo128(t[3]) & reduce_mask_51; shl128(c, t[2], 13); r3 += c;
  193. r4 = lo128(t[4]) & reduce_mask_51; shl128(c, t[3], 13); r4 += c;
  194. shl128(c, t[4], 13); r0 += c * 19;
  195. c = r0 >> 51; r0 &= reduce_mask_51;
  196. r1 += c ; c = r1 >> 51; r1 &= reduce_mask_51;
  197. r2 += c ; c = r2 >> 51; r2 &= reduce_mask_51;
  198. r3 += c ; c = r3 >> 51; r3 &= reduce_mask_51;
  199. r4 += c ; c = r4 >> 51; r4 &= reduce_mask_51;
  200. r0 += c * 19;
  201. } while(--count);
  202. out[0] = r0;
  203. out[1] = r1;
  204. out[2] = r2;
  205. out[3] = r3;
  206. out[4] = r4;
  207. }
  208. DONNA_INLINE static void
  209. curve25519_square(bignum25519 out, const bignum25519 in) {
  210. #if !defined(HAVE_NATIVE_UINT128)
  211. uint128_t mul;
  212. #endif
  213. uint128_t t[5];
  214. uint64_t r0,r1,r2,r3,r4,c;
  215. uint64_t d0,d1,d2,d4,d419;
  216. r0 = in[0];
  217. r1 = in[1];
  218. r2 = in[2];
  219. r3 = in[3];
  220. r4 = in[4];
  221. d0 = r0 * 2;
  222. d1 = r1 * 2;
  223. d2 = r2 * 2 * 19;
  224. d419 = r4 * 19;
  225. d4 = d419 * 2;
  226. #if defined(HAVE_NATIVE_UINT128)
  227. t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 ));
  228. t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19));
  229. t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 ));
  230. t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 ));
  231. t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 ));
  232. #else
  233. mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul)
  234. mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul)
  235. mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul)
  236. mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul)
  237. mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul)
  238. #endif
  239. r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51);
  240. add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51);
  241. add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51);
  242. add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51);
  243. add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51);
  244. r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51;
  245. r1 += c;
  246. out[0] = r0;
  247. out[1] = r1;
  248. out[2] = r2;
  249. out[3] = r3;
  250. out[4] = r4;
  251. }
  252. /* Take a little-endian, 32-byte number and expand it into polynomial form */
  253. DONNA_INLINE static void
  254. curve25519_expand(bignum25519 out, const unsigned char *in) {
  255. static const union { uint8_t b[2]; uint16_t s; } endian_check = {{1,0}};
  256. uint64_t x0,x1,x2,x3;
  257. if (endian_check.s == 1) {
  258. x0 = *(uint64_t *)(in + 0);
  259. x1 = *(uint64_t *)(in + 8);
  260. x2 = *(uint64_t *)(in + 16);
  261. x3 = *(uint64_t *)(in + 24);
  262. } else {
  263. #define F(s) \
  264. ((((uint64_t)in[s + 0]) ) | \
  265. (((uint64_t)in[s + 1]) << 8) | \
  266. (((uint64_t)in[s + 2]) << 16) | \
  267. (((uint64_t)in[s + 3]) << 24) | \
  268. (((uint64_t)in[s + 4]) << 32) | \
  269. (((uint64_t)in[s + 5]) << 40) | \
  270. (((uint64_t)in[s + 6]) << 48) | \
  271. (((uint64_t)in[s + 7]) << 56))
  272. x0 = F(0);
  273. x1 = F(8);
  274. x2 = F(16);
  275. x3 = F(24);
  276. }
  277. out[0] = x0 & reduce_mask_51; x0 = (x0 >> 51) | (x1 << 13);
  278. out[1] = x0 & reduce_mask_51; x1 = (x1 >> 38) | (x2 << 26);
  279. out[2] = x1 & reduce_mask_51; x2 = (x2 >> 25) | (x3 << 39);
  280. out[3] = x2 & reduce_mask_51; x3 = (x3 >> 12);
  281. out[4] = x3 & reduce_mask_51;
  282. }
  283. /* Take a fully reduced polynomial form number and contract it into a
  284. * little-endian, 32-byte array
  285. */
  286. DONNA_INLINE static void
  287. curve25519_contract(unsigned char *out, const bignum25519 input) {
  288. uint64_t t[5];
  289. uint64_t f, i;
  290. t[0] = input[0];
  291. t[1] = input[1];
  292. t[2] = input[2];
  293. t[3] = input[3];
  294. t[4] = input[4];
  295. #define curve25519_contract_carry() \
  296. t[1] += t[0] >> 51; t[0] &= reduce_mask_51; \
  297. t[2] += t[1] >> 51; t[1] &= reduce_mask_51; \
  298. t[3] += t[2] >> 51; t[2] &= reduce_mask_51; \
  299. t[4] += t[3] >> 51; t[3] &= reduce_mask_51;
  300. #define curve25519_contract_carry_full() curve25519_contract_carry() \
  301. t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51;
  302. #define curve25519_contract_carry_final() curve25519_contract_carry() \
  303. t[4] &= reduce_mask_51;
  304. curve25519_contract_carry_full()
  305. curve25519_contract_carry_full()
  306. /* now t is between 0 and 2^255-1, properly carried. */
  307. /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */
  308. t[0] += 19;
  309. curve25519_contract_carry_full()
  310. /* now between 19 and 2^255-1 in both cases, and offset by 19. */
  311. t[0] += (reduce_mask_51 + 1) - 19;
  312. t[1] += (reduce_mask_51 + 1) - 1;
  313. t[2] += (reduce_mask_51 + 1) - 1;
  314. t[3] += (reduce_mask_51 + 1) - 1;
  315. t[4] += (reduce_mask_51 + 1) - 1;
  316. /* now between 2^255 and 2^256-20, and offset by 2^255. */
  317. curve25519_contract_carry_final()
  318. #define write51full(n,shift) \
  319. f = ((t[n] >> shift) | (t[n+1] << (51 - shift))); \
  320. for (i = 0; i < 8; i++, f >>= 8) *out++ = (unsigned char)f;
  321. #define write51(n) write51full(n,13*n)
  322. write51(0)
  323. write51(1)
  324. write51(2)
  325. write51(3)
  326. }
  327. #if !defined(ED25519_GCC_64BIT_CHOOSE)
  328. /* out = (flag) ? in : out */
  329. DONNA_INLINE static void
  330. curve25519_move_conditional_bytes(uint8_t out[96], const uint8_t in[96], uint64_t flag) {
  331. const uint64_t nb = flag - 1, b = ~nb;
  332. const uint64_t *inq = (const uint64_t *)in;
  333. uint64_t *outq = (uint64_t *)out;
  334. outq[0] = (outq[0] & nb) | (inq[0] & b);
  335. outq[1] = (outq[1] & nb) | (inq[1] & b);
  336. outq[2] = (outq[2] & nb) | (inq[2] & b);
  337. outq[3] = (outq[3] & nb) | (inq[3] & b);
  338. outq[4] = (outq[4] & nb) | (inq[4] & b);
  339. outq[5] = (outq[5] & nb) | (inq[5] & b);
  340. outq[6] = (outq[6] & nb) | (inq[6] & b);
  341. outq[7] = (outq[7] & nb) | (inq[7] & b);
  342. outq[8] = (outq[8] & nb) | (inq[8] & b);
  343. outq[9] = (outq[9] & nb) | (inq[9] & b);
  344. outq[10] = (outq[10] & nb) | (inq[10] & b);
  345. outq[11] = (outq[11] & nb) | (inq[11] & b);
  346. }
  347. /* if (iswap) swap(a, b) */
  348. DONNA_INLINE static void
  349. curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint64_t iswap) {
  350. const uint64_t swap = (uint64_t)(-(int64_t)iswap);
  351. uint64_t x0,x1,x2,x3,x4;
  352. x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0;
  353. x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1;
  354. x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2;
  355. x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3;
  356. x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4;
  357. }
  358. #endif /* ED25519_GCC_64BIT_CHOOSE */
  359. #define ED25519_64BIT_TABLES
  360. #endif /* !defined(ED25519_SSE2) && defined(ED25519_64BIT) */