fe_x25519_128.i 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. /* fe_x25519_128.i
  2. *
  3. * Copyright (C) 2006-2021 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. void fe_init(void)
  22. {
  23. }
  24. /* Convert a number represented as an array of bytes to an array of words with
  25. * 51-bits of data in each word.
  26. *
  27. * in An array of bytes.
  28. * out An array of words.
  29. */
  30. void fe_frombytes(fe out, const unsigned char *in)
  31. {
  32. out[0] = (((sword64)((in[ 0] ) )) )
  33. | (((sword64)((in[ 1] ) )) << 8)
  34. | (((sword64)((in[ 2] ) )) << 16)
  35. | (((sword64)((in[ 3] ) )) << 24)
  36. | (((sword64)((in[ 4] ) )) << 32)
  37. | (((sword64)((in[ 5] ) )) << 40)
  38. | (((sword64)((in[ 6] ) & 0x07)) << 48);
  39. out[1] = (((sword64)((in[ 6] >> 3) & 0x1f)) )
  40. | (((sword64)((in[ 7] ) )) << 5)
  41. | (((sword64)((in[ 8] ) )) << 13)
  42. | (((sword64)((in[ 9] ) )) << 21)
  43. | (((sword64)((in[10] ) )) << 29)
  44. | (((sword64)((in[11] ) )) << 37)
  45. | (((sword64)((in[12] ) & 0x3f)) << 45);
  46. out[2] = (((sword64)((in[12] >> 6) & 0x03)) )
  47. | (((sword64)((in[13] ) )) << 2)
  48. | (((sword64)((in[14] ) )) << 10)
  49. | (((sword64)((in[15] ) )) << 18)
  50. | (((sword64)((in[16] ) )) << 26)
  51. | (((sword64)((in[17] ) )) << 34)
  52. | (((sword64)((in[18] ) )) << 42)
  53. | (((sword64)((in[19] ) & 0x01)) << 50);
  54. out[3] = (((sword64)((in[19] >> 1) & 0x7f)) )
  55. | (((sword64)((in[20] ) )) << 7)
  56. | (((sword64)((in[21] ) )) << 15)
  57. | (((sword64)((in[22] ) )) << 23)
  58. | (((sword64)((in[23] ) )) << 31)
  59. | (((sword64)((in[24] ) )) << 39)
  60. | (((sword64)((in[25] ) & 0x0f)) << 47);
  61. out[4] = (((sword64)((in[25] >> 4) & 0x0f)) )
  62. | (((sword64)((in[26] ) )) << 4)
  63. | (((sword64)((in[27] ) )) << 12)
  64. | (((sword64)((in[28] ) )) << 20)
  65. | (((sword64)((in[29] ) )) << 28)
  66. | (((sword64)((in[30] ) )) << 36)
  67. | (((sword64)((in[31] ) & 0x7f)) << 44);
  68. }
  69. /* Convert a number represented as an array of words to an array of bytes.
  70. * The array of words is normalized to an array of 51-bit data words and if
  71. * greater than the mod, modulo reduced by the prime 2^255 - 1.
  72. *
  73. * n An array of words.
  74. * out An array of bytes.
  75. */
  76. void fe_tobytes(unsigned char *out, const fe n)
  77. {
  78. fe in;
  79. sword64 c;
  80. in[0] = n[0];
  81. in[1] = n[1];
  82. in[2] = n[2];
  83. in[3] = n[3];
  84. in[4] = n[4];
  85. /* Normalize to 51-bits of data per word. */
  86. in[0] += (in[4] >> 51) * 19; in[4] &= 0x7ffffffffffff;
  87. in[1] += in[0] >> 51; in[0] &= 0x7ffffffffffff;
  88. in[2] += in[1] >> 51; in[1] &= 0x7ffffffffffff;
  89. in[3] += in[2] >> 51; in[2] &= 0x7ffffffffffff;
  90. in[4] += in[3] >> 51; in[3] &= 0x7ffffffffffff;
  91. in[0] += (in[4] >> 51) * 19;
  92. in[4] &= 0x7ffffffffffff;
  93. c = (in[0] + 19) >> 51;
  94. c = (in[1] + c) >> 51;
  95. c = (in[2] + c) >> 51;
  96. c = (in[3] + c) >> 51;
  97. c = (in[4] + c) >> 51;
  98. in[0] += c * 19;
  99. in[1] += in[0] >> 51; in[0] &= 0x7ffffffffffff;
  100. in[2] += in[1] >> 51; in[1] &= 0x7ffffffffffff;
  101. in[3] += in[2] >> 51; in[2] &= 0x7ffffffffffff;
  102. in[4] += in[3] >> 51; in[3] &= 0x7ffffffffffff;
  103. in[4] &= 0x7ffffffffffff;
  104. out[ 0] = (((byte)((in[0] ) )) );
  105. out[ 1] = (((byte)((in[0] >> 8) )) );
  106. out[ 2] = (((byte)((in[0] >> 16) )) );
  107. out[ 3] = (((byte)((in[0] >> 24) )) );
  108. out[ 4] = (((byte)((in[0] >> 32) )) );
  109. out[ 5] = (((byte)((in[0] >> 40) )) );
  110. out[ 6] = (((byte)((in[0] >> 48) & 0x07)) )
  111. | (((byte)((in[1] ) & 0x1f)) << 3);
  112. out[ 7] = (((byte)((in[1] >> 5) )) );
  113. out[ 8] = (((byte)((in[1] >> 13) )) );
  114. out[ 9] = (((byte)((in[1] >> 21) )) );
  115. out[10] = (((byte)((in[1] >> 29) )) );
  116. out[11] = (((byte)((in[1] >> 37) )) );
  117. out[12] = (((byte)((in[1] >> 45) & 0x3f)) )
  118. | (((byte)((in[2] ) & 0x03)) << 6);
  119. out[13] = (((byte)((in[2] >> 2) )) );
  120. out[14] = (((byte)((in[2] >> 10) )) );
  121. out[15] = (((byte)((in[2] >> 18) )) );
  122. out[16] = (((byte)((in[2] >> 26) )) );
  123. out[17] = (((byte)((in[2] >> 34) )) );
  124. out[18] = (((byte)((in[2] >> 42) )) );
  125. out[19] = (((byte)((in[2] >> 50) & 0x01)) )
  126. | (((byte)((in[3] ) & 0x7f)) << 1);
  127. out[20] = (((byte)((in[3] >> 7) )) );
  128. out[21] = (((byte)((in[3] >> 15) )) );
  129. out[22] = (((byte)((in[3] >> 23) )) );
  130. out[23] = (((byte)((in[3] >> 31) )) );
  131. out[24] = (((byte)((in[3] >> 39) )) );
  132. out[25] = (((byte)((in[3] >> 47) & 0x0f)) )
  133. | (((byte)((in[4] ) & 0x0f)) << 4);
  134. out[26] = (((byte)((in[4] >> 4) )) );
  135. out[27] = (((byte)((in[4] >> 12) )) );
  136. out[28] = (((byte)((in[4] >> 20) )) );
  137. out[29] = (((byte)((in[4] >> 28) )) );
  138. out[30] = (((byte)((in[4] >> 36) )) );
  139. out[31] = (((byte)((in[4] >> 44) & 0x7f)) );
  140. }
  141. /* Set the field element to 1.
  142. *
  143. * n The field element number.
  144. */
  145. void fe_1(fe n)
  146. {
  147. n[0] = 0x0000000000001;
  148. n[1] = 0x0000000000000;
  149. n[2] = 0x0000000000000;
  150. n[3] = 0x0000000000000;
  151. n[4] = 0x0000000000000;
  152. }
  153. /* Set the field element to 0.
  154. *
  155. * n The field element number.
  156. */
  157. void fe_0(fe n)
  158. {
  159. n[0] = 0x0000000000000;
  160. n[1] = 0x0000000000000;
  161. n[2] = 0x0000000000000;
  162. n[3] = 0x0000000000000;
  163. n[4] = 0x0000000000000;
  164. }
  165. /* Copy field element a into field element r.
  166. *
  167. * r Field element to copy into.
  168. * a Field element to copy.
  169. */
  170. void fe_copy(fe r, const fe a)
  171. {
  172. r[0] = a[0];
  173. r[1] = a[1];
  174. r[2] = a[2];
  175. r[3] = a[3];
  176. r[4] = a[4];
  177. }
  178. /* Constant time, conditional swap of field elements a and b.
  179. *
  180. * a A field element.
  181. * b A field element.
  182. * c If 1 then swap and if 0 then don't swap.
  183. */
  184. void fe_cswap(fe a, fe b, int c)
  185. {
  186. sword64 m = c;
  187. sword64 t0, t1, t2, t3, t4;
  188. /* Convert conditional into mask. */
  189. m = -m;
  190. t0 = m & (a[0] ^ b[0]);
  191. t1 = m & (a[1] ^ b[1]);
  192. t2 = m & (a[2] ^ b[2]);
  193. t3 = m & (a[3] ^ b[3]);
  194. t4 = m & (a[4] ^ b[4]);
  195. a[0] ^= t0;
  196. a[1] ^= t1;
  197. a[2] ^= t2;
  198. a[3] ^= t3;
  199. a[4] ^= t4;
  200. b[0] ^= t0;
  201. b[1] ^= t1;
  202. b[2] ^= t2;
  203. b[3] ^= t3;
  204. b[4] ^= t4;
  205. }
  206. /* Subtract b from a into r. (r = a - b)
  207. *
  208. * r A field element.
  209. * a A field element.
  210. * b A field element.
  211. */
  212. void fe_sub(fe r, const fe a, const fe b)
  213. {
  214. r[0] = a[0] - b[0];
  215. r[1] = a[1] - b[1];
  216. r[2] = a[2] - b[2];
  217. r[3] = a[3] - b[3];
  218. r[4] = a[4] - b[4];
  219. }
  220. /* Add b to a into r. (r = a + b)
  221. *
  222. * r A field element.
  223. * a A field element.
  224. * b A field element.
  225. */
  226. void fe_add(fe r, const fe a, const fe b)
  227. {
  228. r[0] = a[0] + b[0];
  229. r[1] = a[1] + b[1];
  230. r[2] = a[2] + b[2];
  231. r[3] = a[3] + b[3];
  232. r[4] = a[4] + b[4];
  233. }
  234. /* Multiply a and b into r. (r = a * b)
  235. *
  236. * r A field element.
  237. * a A field element.
  238. * b A field element.
  239. */
  240. void fe_mul(fe r, const fe a, const fe b)
  241. {
  242. const __int128_t k19 = 19;
  243. __int128_t t0 = ((__int128_t)a[0]) * b[0];
  244. __int128_t t1 = ((__int128_t)a[0]) * b[1]
  245. + ((__int128_t)a[1]) * b[0];
  246. __int128_t t2 = ((__int128_t)a[0]) * b[2]
  247. + ((__int128_t)a[1]) * b[1]
  248. + ((__int128_t)a[2]) * b[0];
  249. __int128_t t3 = ((__int128_t)a[0]) * b[3]
  250. + ((__int128_t)a[1]) * b[2]
  251. + ((__int128_t)a[2]) * b[1]
  252. + ((__int128_t)a[3]) * b[0];
  253. __int128_t t4 = ((__int128_t)a[0]) * b[4]
  254. + ((__int128_t)a[1]) * b[3]
  255. + ((__int128_t)a[2]) * b[2]
  256. + ((__int128_t)a[3]) * b[1]
  257. + ((__int128_t)a[4]) * b[0];
  258. __int128_t t5 = ((__int128_t)a[1]) * b[4]
  259. + ((__int128_t)a[2]) * b[3]
  260. + ((__int128_t)a[3]) * b[2]
  261. + ((__int128_t)a[4]) * b[1];
  262. __int128_t t6 = ((__int128_t)a[2]) * b[4]
  263. + ((__int128_t)a[3]) * b[3]
  264. + ((__int128_t)a[4]) * b[2];
  265. __int128_t t7 = ((__int128_t)a[3]) * b[4]
  266. + ((__int128_t)a[4]) * b[3];
  267. __int128_t t8 = ((__int128_t)a[4]) * b[4];
  268. /* Modulo reduce double long word. */
  269. t0 += t5 * k19;
  270. t1 += t6 * k19;
  271. t2 += t7 * k19;
  272. t3 += t8 * k19;
  273. /* Normalize to 51-bits of data per word. */
  274. t0 += (t4 >> 51) * k19; t4 &= 0x7ffffffffffff;
  275. t1 += t0 >> 51; r[0] = t0 & 0x7ffffffffffff;
  276. t2 += t1 >> 51; r[1] = t1 & 0x7ffffffffffff;
  277. t3 += t2 >> 51; r[2] = t2 & 0x7ffffffffffff;
  278. t4 += t3 >> 51; r[3] = t3 & 0x7ffffffffffff;
  279. r[0] += (t4 >> 51) * k19;
  280. r[4] = t4 & 0x7ffffffffffff;
  281. }
  282. /* Square a and put result in r. (r = a * a)
  283. *
  284. * r A field element.
  285. * a A field element.
  286. * b A field element.
  287. */
  288. void fe_sq(fe r, const fe a)
  289. {
  290. const __int128_t k19 = 19;
  291. const __int128_t k2 = 2;
  292. __int128_t t0 = ((__int128_t)a[0]) * a[0];
  293. __int128_t t1 = ((__int128_t)a[0]) * a[1] * k2;
  294. __int128_t t2 = ((__int128_t)a[0]) * a[2] * k2
  295. + ((__int128_t)a[1]) * a[1];
  296. __int128_t t3 = ((__int128_t)a[0]) * a[3] * k2
  297. + ((__int128_t)a[1]) * a[2] * k2;
  298. __int128_t t4 = ((__int128_t)a[0]) * a[4] * k2
  299. + ((__int128_t)a[1]) * a[3] * k2
  300. + ((__int128_t)a[2]) * a[2];
  301. __int128_t t5 = ((__int128_t)a[1]) * a[4] * k2
  302. + ((__int128_t)a[2]) * a[3] * k2;
  303. __int128_t t6 = ((__int128_t)a[2]) * a[4] * k2
  304. + ((__int128_t)a[3]) * a[3];
  305. __int128_t t7 = ((__int128_t)a[3]) * a[4] * k2;
  306. __int128_t t8 = ((__int128_t)a[4]) * a[4];
  307. /* Modulo reduce double long word. */
  308. t0 += t5 * k19;
  309. t1 += t6 * k19;
  310. t2 += t7 * k19;
  311. t3 += t8 * k19;
  312. /* Normalize to 51-bits of data per word. */
  313. t0 += (t4 >> 51) * k19; t4 &= 0x7ffffffffffff;
  314. t1 += t0 >> 51; r[0] = t0 & 0x7ffffffffffff;
  315. t2 += t1 >> 51; r[1] = t1 & 0x7ffffffffffff;
  316. t3 += t2 >> 51; r[2] = t2 & 0x7ffffffffffff;
  317. t4 += t3 >> 51; r[3] = t3 & 0x7ffffffffffff;
  318. r[0] += (t4 >> 51) * k19;
  319. r[4] = t4 & 0x7ffffffffffff;
  320. }
  321. /* Multiply a by 121666 and put result in r. (r = 121666 * a)
  322. *
  323. * r A field element.
  324. * a A field element.
  325. * b A field element.
  326. */
  327. void fe_mul121666(fe r, fe a)
  328. {
  329. const __int128_t k19 = 19;
  330. const __int128_t k121666 = 121666;
  331. __int128_t t0 = ((__int128_t)a[0]) * k121666;
  332. __int128_t t1 = ((__int128_t)a[1]) * k121666;
  333. __int128_t t2 = ((__int128_t)a[2]) * k121666;
  334. __int128_t t3 = ((__int128_t)a[3]) * k121666;
  335. __int128_t t4 = ((__int128_t)a[4]) * k121666;
  336. /* Normalize to 51-bits of data per word. */
  337. t0 += (t4 >> 51) * k19; t4 &= 0x7ffffffffffff;
  338. t1 += t0 >> 51; r[0] = t0 & 0x7ffffffffffff;
  339. t2 += t1 >> 51; r[1] = t1 & 0x7ffffffffffff;
  340. t3 += t2 >> 51; r[2] = t2 & 0x7ffffffffffff;
  341. t4 += t3 >> 51; r[3] = t3 & 0x7ffffffffffff;
  342. r[0] += (t4 >> 51) * k19;
  343. r[4] = t4 & 0x7ffffffffffff;
  344. }
  345. /* Find the inverse of a modulo 2^255 - 1 and put result in r.
  346. * (r * a) mod (2^255 - 1) = 1
  347. * Implementation is constant time.
  348. *
  349. * r A field element.
  350. * a A field element.
  351. */
  352. void fe_invert(fe r, const fe a)
  353. {
  354. fe t0, t1, t2, t3;
  355. int i;
  356. /* a ^ (2^255 - 21) */
  357. fe_sq(t0, a); for (i = 1; i < 1; ++i) fe_sq(t0, t0);
  358. fe_sq(t1, t0); for (i = 1; i < 2; ++i) fe_sq(t1, t1); fe_mul(t1, a, t1);
  359. fe_mul(t0, t0, t1);
  360. fe_sq(t2, t0); for (i = 1; i < 1; ++i) fe_sq(t2, t2); fe_mul(t1, t1, t2);
  361. fe_sq(t2, t1); for (i = 1; i < 5; ++i) fe_sq(t2, t2); fe_mul(t1, t2, t1);
  362. fe_sq(t2, t1); for (i = 1; i < 10; ++i) fe_sq(t2, t2); fe_mul(t2, t2, t1);
  363. fe_sq(t3, t2); for (i = 1; i < 20; ++i) fe_sq(t3, t3); fe_mul(t2, t3, t2);
  364. fe_sq(t2, t2); for (i = 1; i < 10; ++i) fe_sq(t2, t2); fe_mul(t1, t2, t1);
  365. fe_sq(t2, t1); for (i = 1; i < 50; ++i) fe_sq(t2, t2); fe_mul(t2, t2, t1);
  366. fe_sq(t3, t2); for (i = 1; i < 100; ++i) fe_sq(t3, t3); fe_mul(t2, t3, t2);
  367. fe_sq(t2, t2); for (i = 1; i < 50; ++i) fe_sq(t2, t2); fe_mul(t1, t2, t1);
  368. fe_sq(t1, t1); for (i = 1; i < 5; ++i) fe_sq(t1, t1); fe_mul( r, t1, t0);
  369. }
  370. #ifndef CURVE25519_SMALL
  371. /* Scalar multiply the field element a by n using Montgomery Ladder and places
  372. * result in r.
  373. *
  374. * r A field element as an array of bytes.
  375. * n The scalar as an array of bytes.
  376. * a A field element as an array of bytes.
  377. */
  378. int curve25519(byte* r, const byte* n, const byte* a)
  379. {
  380. fe x1, x2, z2, x3, z3;
  381. fe t0, t1;
  382. int pos;
  383. unsigned int swap;
  384. unsigned int b;
  385. fe_frombytes(x1, a);
  386. fe_1(x2);
  387. fe_0(z2);
  388. fe_copy(x3, x1);
  389. fe_1(z3);
  390. swap = 0;
  391. for (pos = 254;pos >= 0;--pos) {
  392. b = n[pos / 8] >> (pos & 7);
  393. b &= 1;
  394. swap ^= b;
  395. fe_cswap(x2, x3, swap);
  396. fe_cswap(z2, z3, swap);
  397. swap = b;
  398. fe_sub(t0, x3, z3);
  399. fe_sub(t1, x2, z2);
  400. fe_add(x2, x2, z2);
  401. fe_add(z2, x3, z3);
  402. fe_mul(z3, t0, x2);
  403. fe_mul(z2, z2, t1);
  404. fe_sq(t0, t1);
  405. fe_sq(t1, x2);
  406. fe_add(x3, z3, z2);
  407. fe_sub(z2, z3, z2);
  408. fe_mul(x2, t1, t0);
  409. fe_sub(t1, t1, t0);
  410. fe_sq(z2, z2);
  411. fe_mul121666(z3, t1);
  412. fe_sq(x3, x3);
  413. fe_add(t0, t0, z3);
  414. fe_mul(z3, x1, z2);
  415. fe_mul(z2, t1, t0);
  416. }
  417. fe_cswap(x2, x3, swap);
  418. fe_cswap(z2, z3, swap);
  419. fe_invert(z2, z2);
  420. fe_mul(x2, x2, z2);
  421. fe_tobytes(r, x2);
  422. return 0;
  423. }
  424. #endif /* !CURVE25519_SMALL */
  425. /* The field element value 0 as an array of bytes. */
  426. static const unsigned char zero[32] = {0};
  427. /* Constant time check as to whether a is not 0.
  428. *
  429. * a A field element.
  430. */
  431. int fe_isnonzero(const fe a)
  432. {
  433. unsigned char s[32];
  434. fe_tobytes(s, a);
  435. return ConstantCompare(s, zero, 32);
  436. }
  437. /* Checks whether a is negative.
  438. *
  439. * a A field element.
  440. */
  441. int fe_isnegative(const fe a)
  442. {
  443. unsigned char s[32];
  444. fe_tobytes(s, a);
  445. return s[0] & 1;
  446. }
  447. /* Negates field element a and stores the result in r.
  448. *
  449. * r A field element.
  450. * a A field element.
  451. */
  452. void fe_neg(fe r, const fe a)
  453. {
  454. r[0] = -a[0];
  455. r[1] = -a[1];
  456. r[2] = -a[2];
  457. r[3] = -a[3];
  458. r[4] = -a[4];
  459. }
  460. /* Constant time, conditional move of b into a.
  461. * a is not changed if the condition is 0.
  462. *
  463. * a A field element.
  464. * b A field element.
  465. * c If 1 then copy and if 0 then don't copy.
  466. */
  467. void fe_cmov(fe a, const fe b, int c)
  468. {
  469. sword64 m = c;
  470. sword64 t0, t1, t2, t3, t4;
  471. /* Convert conditional into mask. */
  472. m = -m;
  473. t0 = m & (a[0] ^ b[0]);
  474. t1 = m & (a[1] ^ b[1]);
  475. t2 = m & (a[2] ^ b[2]);
  476. t3 = m & (a[3] ^ b[3]);
  477. t4 = m & (a[4] ^ b[4]);
  478. a[0] ^= t0;
  479. a[1] ^= t1;
  480. a[2] ^= t2;
  481. a[3] ^= t3;
  482. a[4] ^= t4;
  483. }
  484. void fe_pow22523(fe r, const fe a)
  485. {
  486. fe t0, t1, t2;
  487. int i;
  488. /* a ^ (2^255 - 23) */
  489. fe_sq(t0, a); for (i = 1; i < 1; ++i) fe_sq(t0, t0);
  490. fe_sq(t1, t0); for (i = 1; i < 2; ++i) fe_sq(t1, t1); fe_mul(t1, a, t1);
  491. fe_mul(t0, t0, t1);
  492. fe_sq(t0, t0); for (i = 1; i < 1; ++i) fe_sq(t0, t0); fe_mul(t0, t1, t0);
  493. fe_sq(t1, t0); for (i = 1; i < 5; ++i) fe_sq(t1, t1); fe_mul(t0, t1, t0);
  494. fe_sq(t1, t0); for (i = 1; i < 10; ++i) fe_sq(t1, t1); fe_mul(t1, t1, t0);
  495. fe_sq(t2, t1); for (i = 1; i < 20; ++i) fe_sq(t2, t2); fe_mul(t1, t2, t1);
  496. fe_sq(t1, t1); for (i = 1; i < 10; ++i) fe_sq(t1, t1); fe_mul(t0, t1, t0);
  497. fe_sq(t1, t0); for (i = 1; i < 50; ++i) fe_sq(t1, t1); fe_mul(t1, t1, t0);
  498. fe_sq(t2, t1); for (i = 1; i < 100; ++i) fe_sq(t2, t2); fe_mul(t1, t2, t1);
  499. fe_sq(t1, t1); for (i = 1; i < 50; ++i) fe_sq(t1, t1); fe_mul(t0, t1, t0);
  500. fe_sq(t0, t0); for (i = 1; i < 2; ++i) fe_sq(t0, t0); fe_mul( r, t0, a);
  501. return;
  502. }
  503. /* Double the square of a and put result in r. (r = 2 * a * a)
  504. *
  505. * r A field element.
  506. * a A field element.
  507. * b A field element.
  508. */
  509. void fe_sq2(fe r, const fe a)
  510. {
  511. const __int128_t k2 = 2;
  512. const __int128_t k19 = 19;
  513. __int128_t t0 = k2 * (((__int128_t)a[0]) * a[0]);
  514. __int128_t t1 = k2 * (((__int128_t)a[0]) * a[1] * k2);
  515. __int128_t t2 = k2 * (((__int128_t)a[0]) * a[2] * k2
  516. + ((__int128_t)a[1]) * a[1]);
  517. __int128_t t3 = k2 * (((__int128_t)a[0]) * a[3] * k2
  518. + ((__int128_t)a[1]) * a[2] * k2);
  519. __int128_t t4 = k2 * (((__int128_t)a[0]) * a[4] * k2
  520. + ((__int128_t)a[1]) * a[3] * k2
  521. + ((__int128_t)a[2]) * a[2]);
  522. __int128_t t5 = k2 * (((__int128_t)a[1]) * a[4] * k2
  523. + ((__int128_t)a[2]) * a[3] * k2);
  524. __int128_t t6 = k2 * (((__int128_t)a[2]) * a[4] * k2
  525. + ((__int128_t)a[3]) * a[3]);
  526. __int128_t t7 = k2 * (((__int128_t)a[3]) * a[4] * k2);
  527. __int128_t t8 = k2 * (((__int128_t)a[4]) * a[4]);
  528. /* Modulo reduce double long word. */
  529. t0 += t5 * k19;
  530. t1 += t6 * k19;
  531. t2 += t7 * k19;
  532. t3 += t8 * k19;
  533. /* Normalize to 51-bits of data per word. */
  534. t0 += (t4 >> 51) * k19; t4 &= 0x7ffffffffffff;
  535. t1 += t0 >> 51; r[0] = t0 & 0x7ffffffffffff;
  536. t2 += t1 >> 51; r[1] = t1 & 0x7ffffffffffff;
  537. t3 += t2 >> 51; r[2] = t2 & 0x7ffffffffffff;
  538. t4 += t3 >> 51; r[3] = t3 & 0x7ffffffffffff;
  539. r[0] += (t4 >> 51) * k19;
  540. r[4] = t4 & 0x7ffffffffffff;
  541. }
  542. /* Load 3 little endian bytes into a 64-bit word.
  543. *
  544. * in An array of bytes.
  545. * returns a 64-bit word.
  546. */
  547. word64 load_3(const unsigned char *in)
  548. {
  549. word64 result;
  550. result = ((((word64)in[0]) ) |
  551. (((word64)in[1]) << 8) |
  552. (((word64)in[2]) << 16));
  553. return result;
  554. }
  555. /* Load 4 little endian bytes into a 64-bit word.
  556. *
  557. * in An array of bytes.
  558. * returns a 64-bit word.
  559. */
  560. word64 load_4(const unsigned char *in)
  561. {
  562. word64 result;
  563. result = ((((word64)in[0]) ) |
  564. (((word64)in[1]) << 8) |
  565. (((word64)in[2]) << 16) |
  566. (((word64)in[3]) << 24));
  567. return result;
  568. }