fe_448.c 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406
  1. /* fe_448.c
  2. *
  3. * Copyright (C) 2006-2023 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. /* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work.
  22. * Small implementation based on Daniel Beer's curve25519 public domain work.
  23. * Reworked for curve448 by Sean Parkinson.
  24. */
  25. #ifdef HAVE_CONFIG_H
  26. #include <config.h>
  27. #endif
  28. #include <wolfssl/wolfcrypt/settings.h>
  29. #if defined(HAVE_CURVE448) || defined(HAVE_ED448)
  30. #include <wolfssl/wolfcrypt/fe_448.h>
  31. #ifdef NO_INLINE
  32. #include <wolfssl/wolfcrypt/misc.h>
  33. #else
  34. #define WOLFSSL_MISC_INCLUDED
  35. #include <wolfcrypt/src/misc.c>
  36. #endif
  37. #if defined(CURVE448_SMALL) || defined(ED448_SMALL)
  38. /* Initialize the field element operations.
  39. */
  40. void fe448_init(void)
  41. {
  42. }
  43. /* Normalize the field element.
  44. * Ensure result is in range: 0..2^448-2^224-2
  45. *
  46. * a [in] Field element in range 0..2^448-1.
  47. */
  48. void fe448_norm(word8* a)
  49. {
  50. int i;
  51. sword16 c = 0;
  52. sword16 o = 0;
  53. for (i = 0; i < 56; i++) {
  54. c += a[i];
  55. if ((i == 0) || (i == 28))
  56. c += 1;
  57. c >>= 8;
  58. }
  59. for (i = 0; i < 56; i++) {
  60. if ((i == 0) || (i == 28)) o += c;
  61. o += a[i];
  62. a[i] = (word8)o;
  63. o >>= 8;
  64. }
  65. }
  66. /* Copy one field element into another: d = a.
  67. *
  68. * d [in] Destination field element.
  69. * a [in] Source field element.
  70. */
  71. void fe448_copy(word8* d, const word8* a)
  72. {
  73. int i;
  74. for (i = 0; i < 56; i++) {
  75. d[i] = a[i];
  76. }
  77. }
  78. /* Conditionally swap the elements.
  79. * Constant time implementation.
  80. *
  81. * a [in] First field element.
  82. * b [in] Second field element.
  83. * c [in] Swap when 1. Valid values: 0, 1.
  84. */
  85. static void fe448_cswap(word8* a, word8* b, int c)
  86. {
  87. int i;
  88. word8 mask = -(word8)c;
  89. word8 t[56];
  90. for (i = 0; i < 56; i++)
  91. t[i] = (a[i] ^ b[i]) & mask;
  92. for (i = 0; i < 56; i++)
  93. a[i] ^= t[i];
  94. for (i = 0; i < 56; i++)
  95. b[i] ^= t[i];
  96. }
  97. /* Add two field elements. r = (a + b) mod (2^448 - 2^224 - 1)
  98. *
  99. * r [in] Field element to hold sum.
  100. * a [in] Field element to add.
  101. * b [in] Field element to add.
  102. */
  103. void fe448_add(word8* r, const word8* a, const word8* b)
  104. {
  105. int i;
  106. sword16 c = 0;
  107. sword16 o = 0;
  108. for (i = 0; i < 56; i++) {
  109. c += a[i];
  110. c += b[i];
  111. r[i] = (word8)c;
  112. c >>= 8;
  113. }
  114. for (i = 0; i < 56; i++) {
  115. if ((i == 0) || (i == 28)) o += c;
  116. o += r[i];
  117. r[i] = (word8)o;
  118. o >>= 8;
  119. }
  120. }
  121. /* Subtract a field element from another. r = (a - b) mod (2^448 - 2^224 - 1)
  122. *
  123. * r [in] Field element to hold difference.
  124. * a [in] Field element to subtract from.
  125. * b [in] Field element to subtract.
  126. */
  127. void fe448_sub(word8* r, const word8* a, const word8* b)
  128. {
  129. int i;
  130. sword16 c = 0;
  131. sword16 o = 0;
  132. for (i = 0; i < 56; i++) {
  133. if (i == 28)
  134. c += 0x1fc;
  135. else
  136. c += 0x1fe;
  137. c += a[i];
  138. c -= b[i];
  139. r[i] = (word8)c;
  140. c >>= 8;
  141. }
  142. for (i = 0; i < 56; i++) {
  143. if ((i == 0) || (i == 28)) o += c;
  144. o += r[i];
  145. r[i] = (word8)o;
  146. o >>= 8;
  147. }
  148. }
  149. /* Multiply a field element by 39081. r = (39081 * a) mod (2^448 - 2^224 - 1)
  150. *
  151. * r [in] Field element to hold result.
  152. * a [in] Field element to multiply.
  153. */
  154. void fe448_mul39081(word8* r, const word8* a)
  155. {
  156. int i;
  157. sword32 c = 0;
  158. sword32 o = 0;
  159. for (i = 0; i < 56; i++) {
  160. c += a[i] * (sword32)39081;
  161. r[i] = (word8)c;
  162. c >>= 8;
  163. }
  164. for (i = 0; i < 56; i++) {
  165. if ((i == 0) || (i == 28)) o += c;
  166. o += r[i];
  167. r[i] = (word8)o;
  168. o >>= 8;
  169. }
  170. }
  171. /* Multiply two field elements. r = (a * b) mod (2^448 - 2^224 - 1)
  172. *
  173. * r [in] Field element to hold result.
  174. * a [in] Field element to multiply.
  175. * b [in] Field element to multiply.
  176. */
  177. void fe448_mul(word8* r, const word8* a, const word8* b)
  178. {
  179. int i, k;
  180. sword32 c = 0;
  181. sword16 o = 0, cc = 0;
  182. word8 t[112];
  183. for (k = 0; k < 56; k++) {
  184. i = 0;
  185. for (; i <= k; i++) {
  186. c += (sword32)a[i] * b[k - i];
  187. }
  188. t[k] = (word8)c;
  189. c >>= 8;
  190. }
  191. for (; k < 111; k++) {
  192. i = k - 55;
  193. for (; i < 56; i++) {
  194. c += (sword32)a[i] * b[k - i];
  195. }
  196. t[k] = (word8)c;
  197. c >>= 8;
  198. }
  199. t[k] = (word8)c;
  200. for (i = 0; i < 28; i++) {
  201. o += t[i];
  202. o += t[i + 56];
  203. o += t[i + 84];
  204. r[i] = (word8)o;
  205. o >>= 8;
  206. }
  207. for (i = 28; i < 56; i++) {
  208. o += t[i];
  209. o += t[i + 56];
  210. o += t[i + 28];
  211. o += t[i + 56];
  212. r[i] = (word8)o;
  213. o >>= 8;
  214. }
  215. for (i = 0; i < 56; i++) {
  216. if ((i == 0) || (i == 28)) cc += o;
  217. cc += r[i];
  218. r[i] = (word8)cc;
  219. cc >>= 8;
  220. }
  221. }
  222. /* Square a field element. r = (a * a) mod (2^448 - 2^224 - 1)
  223. *
  224. * r [in] Field element to hold result.
  225. * a [in] Field element to square.
  226. */
  227. void fe448_sqr(word8* r, const word8* a)
  228. {
  229. int i, k;
  230. sword32 c = 0;
  231. sword32 p;
  232. sword16 o = 0, cc = 0;
  233. word8 t[112];
  234. for (k = 0; k < 56; k++) {
  235. i = 0;
  236. for (; i <= k; i++) {
  237. if (k - i < i)
  238. break;
  239. p = (sword32)a[i] * a[k - i];
  240. if (k - i != i)
  241. p *= 2;
  242. c += p;
  243. }
  244. t[k] = (word8)c;
  245. c >>= 8;
  246. }
  247. for (; k < 111; k++) {
  248. i = k - 55;
  249. for (; i < 56; i++) {
  250. if (k - i < i)
  251. break;
  252. p = (sword32)a[i] * a[k - i];
  253. if (k - i != i)
  254. p *= 2;
  255. c += p;
  256. }
  257. t[k] = (word8)c;
  258. c >>= 8;
  259. }
  260. t[k] = (word8)c;
  261. for (i = 0; i < 28; i++) {
  262. o += t[i];
  263. o += t[i + 56];
  264. o += t[i + 84];
  265. r[i] = (word8)o;
  266. o >>= 8;
  267. }
  268. for (i = 28; i < 56; i++) {
  269. o += t[i];
  270. o += t[i + 56];
  271. o += t[i + 28];
  272. o += t[i + 56];
  273. r[i] = (word8)o;
  274. o >>= 8;
  275. }
  276. for (i = 0; i < 56; i++) {
  277. if ((i == 0) || (i == 28)) cc += o;
  278. cc += r[i];
  279. r[i] = (word8)cc;
  280. cc >>= 8;
  281. }
  282. fe448_norm(r);
  283. }
  284. /* Invert the field element. (r * a) mod (2^448 - 2^224 - 1) = 1
  285. * Constant time implementation - using Fermat's little theorem:
  286. * a^(p-1) mod p = 1 => a^(p-2) mod p = 1/a
  287. * For curve448: p - 2 = 2^448 - 2^224 - 3
  288. *
  289. * r [in] Field element to hold result.
  290. * a [in] Field element to invert.
  291. */
  292. void fe448_invert(word8* r, const word8* a)
  293. {
  294. int i;
  295. word8 t[56];
  296. fe448_sqr(t, a);
  297. fe448_mul(t, t, a);
  298. for (i = 0; i < 221; i++) {
  299. fe448_sqr(t, t);
  300. fe448_mul(t, t, a);
  301. }
  302. fe448_sqr(t, t);
  303. for (i = 0; i < 222; i++) {
  304. fe448_sqr(t, t);
  305. fe448_mul(t, t, a);
  306. }
  307. fe448_sqr(t, t);
  308. fe448_sqr(t, t);
  309. fe448_mul(r, t, a);
  310. }
  311. /* Scalar multiply the point by a number. r = n.a
  312. * Uses Montgomery ladder and only requires the x-ordinate.
  313. *
  314. * r [in] Field element to hold result.
  315. * n [in] Scalar as an array of bytes.
  316. * a [in] Point to multiply - x-ordinate only.
  317. */
  318. int curve448(byte* r, const byte* n, const byte* a)
  319. {
  320. word8 x1[56];
  321. word8 x2[56] = {1};
  322. word8 z2[56] = {0};
  323. word8 x3[56];
  324. word8 z3[56] = {1};
  325. word8 t0[56];
  326. word8 t1[56];
  327. int i;
  328. unsigned int swap;
  329. fe448_copy(x1, a);
  330. fe448_copy(x3, a);
  331. swap = 0;
  332. for (i = 447; i >= 0; --i) {
  333. unsigned int b = (n[i >> 3] >> (i & 7)) & 1;
  334. swap ^= b;
  335. fe448_cswap(x2, x3, swap);
  336. fe448_cswap(z2, z3, swap);
  337. swap = b;
  338. /* Montgomery Ladder - double and add */
  339. fe448_add(t0, x2, z2);
  340. fe448_add(t1, x3, z3);
  341. fe448_sub(x2, x2, z2);
  342. fe448_sub(x3, x3, z3);
  343. fe448_mul(t1, t1, x2);
  344. fe448_mul(z3, x3, t0);
  345. fe448_sqr(t0, t0);
  346. fe448_sqr(x2, x2);
  347. fe448_add(x3, z3, t1);
  348. fe448_sqr(x3, x3);
  349. fe448_sub(z3, z3, t1);
  350. fe448_sqr(z3, z3);
  351. fe448_mul(z3, z3, x1);
  352. fe448_sub(t1, t0, x2);
  353. fe448_mul(x2, t0, x2);
  354. fe448_mul39081(z2, t1);
  355. fe448_add(z2, t0, z2);
  356. fe448_mul(z2, z2, t1);
  357. }
  358. fe448_cswap(x2, x3, swap);
  359. fe448_cswap(z2, z3, swap);
  360. fe448_invert(z2, z2);
  361. fe448_mul(r, x2, z2);
  362. fe448_norm(r);
  363. return 0;
  364. }
  365. #ifdef HAVE_ED448
  366. /* Check whether field element is not 0.
  367. * Field element must have been normalized before call.
  368. *
  369. * a [in] Field element.
  370. * returns 0 when zero, and any other value otherwise.
  371. */
  372. int fe448_isnonzero(const word8* a)
  373. {
  374. int i;
  375. byte c = 0;
  376. for (i = 0; i < 56; i++)
  377. c |= a[i];
  378. return c;
  379. }
  380. /* Negates the field element. r = -a mod (2^448 - 2^224 - 1)
  381. * Add 0x200 to each element and subtract 2 from next.
  382. * Top element overflow handled by subtracting 2 from index 0 and 28.
  383. *
  384. * r [in] Field element to hold result.
  385. * a [in] Field element.
  386. */
  387. void fe448_neg(word8* r, const word8* a)
  388. {
  389. int i;
  390. sword16 c = 0;
  391. sword16 o = 0;
  392. for (i = 0; i < 56; i++) {
  393. if (i == 28)
  394. c += 0x1fc;
  395. else
  396. c += 0x1fe;
  397. c -= a[i];
  398. r[i] = (word8)c;
  399. c >>= 8;
  400. }
  401. for (i = 0; i < 56; i++) {
  402. if ((i == 0) || (i == 28)) o += c;
  403. o += r[i];
  404. r[i] = (word8)o;
  405. o >>= 8;
  406. }
  407. }
  408. /* Raise field element to (p-3) / 4: 2^446 - 2^222 - 1
  409. * Used for calculating y-ordinate from x-ordinate for Ed448.
  410. *
  411. * r [in] Field element to hold result.
  412. * a [in] Field element to exponentiate.
  413. */
  414. void fe448_pow_2_446_222_1(word8* r, const word8* a)
  415. {
  416. int i;
  417. word8 t[56];
  418. fe448_sqr(t, a);
  419. fe448_mul(t, t, a);
  420. for (i = 0; i < 221; i++) {
  421. fe448_sqr(t, t);
  422. fe448_mul(t, t, a);
  423. }
  424. fe448_sqr(t, t);
  425. for (i = 0; i < 221; i++) {
  426. fe448_sqr(t, t);
  427. fe448_mul(t, t, a);
  428. }
  429. fe448_sqr(t, t);
  430. fe448_mul(r, t, a);
  431. }
  432. /* Constant time, conditional move of b into a.
  433. * a is not changed if the condition is 0.
  434. *
  435. * a A field element.
  436. * b A field element.
  437. * c If 1 then copy and if 0 then don't copy.
  438. */
  439. void fe448_cmov(word8* a, const word8* b, int c)
  440. {
  441. int i;
  442. word8 m = -(word8)c;
  443. word8 t[56];
  444. for (i = 0; i < 56; i++)
  445. t[i] = m & (a[i] ^ b[i]);
  446. for (i = 0; i < 56; i++)
  447. a[i] ^= t[i];
  448. }
  449. #endif /* HAVE_ED448 */
  450. #elif defined(CURVED448_128BIT)
  451. /* Initialize the field element operations.
  452. */
  453. void fe448_init(void)
  454. {
  455. }
  456. /* Convert the field element from a byte array to an array of 56-bits.
  457. *
  458. * r [in] Array to encode into.
  459. * b [in] Byte array.
  460. */
  461. void fe448_from_bytes(sword64* r, const unsigned char* b)
  462. {
  463. r[ 0] = ((sword64) (b[ 0]) << 0)
  464. | ((sword64) (b[ 1]) << 8)
  465. | ((sword64) (b[ 2]) << 16)
  466. | ((sword64) (b[ 3]) << 24)
  467. | ((sword64) (b[ 4]) << 32)
  468. | ((sword64) (b[ 5]) << 40)
  469. | ((sword64) (b[ 6]) << 48);
  470. r[ 1] = ((sword64) (b[ 7]) << 0)
  471. | ((sword64) (b[ 8]) << 8)
  472. | ((sword64) (b[ 9]) << 16)
  473. | ((sword64) (b[10]) << 24)
  474. | ((sword64) (b[11]) << 32)
  475. | ((sword64) (b[12]) << 40)
  476. | ((sword64) (b[13]) << 48);
  477. r[ 2] = ((sword64) (b[14]) << 0)
  478. | ((sword64) (b[15]) << 8)
  479. | ((sword64) (b[16]) << 16)
  480. | ((sword64) (b[17]) << 24)
  481. | ((sword64) (b[18]) << 32)
  482. | ((sword64) (b[19]) << 40)
  483. | ((sword64) (b[20]) << 48);
  484. r[ 3] = ((sword64) (b[21]) << 0)
  485. | ((sword64) (b[22]) << 8)
  486. | ((sword64) (b[23]) << 16)
  487. | ((sword64) (b[24]) << 24)
  488. | ((sword64) (b[25]) << 32)
  489. | ((sword64) (b[26]) << 40)
  490. | ((sword64) (b[27]) << 48);
  491. r[ 4] = ((sword64) (b[28]) << 0)
  492. | ((sword64) (b[29]) << 8)
  493. | ((sword64) (b[30]) << 16)
  494. | ((sword64) (b[31]) << 24)
  495. | ((sword64) (b[32]) << 32)
  496. | ((sword64) (b[33]) << 40)
  497. | ((sword64) (b[34]) << 48);
  498. r[ 5] = ((sword64) (b[35]) << 0)
  499. | ((sword64) (b[36]) << 8)
  500. | ((sword64) (b[37]) << 16)
  501. | ((sword64) (b[38]) << 24)
  502. | ((sword64) (b[39]) << 32)
  503. | ((sword64) (b[40]) << 40)
  504. | ((sword64) (b[41]) << 48);
  505. r[ 6] = ((sword64) (b[42]) << 0)
  506. | ((sword64) (b[43]) << 8)
  507. | ((sword64) (b[44]) << 16)
  508. | ((sword64) (b[45]) << 24)
  509. | ((sword64) (b[46]) << 32)
  510. | ((sword64) (b[47]) << 40)
  511. | ((sword64) (b[48]) << 48);
  512. r[ 7] = ((sword64) (b[49]) << 0)
  513. | ((sword64) (b[50]) << 8)
  514. | ((sword64) (b[51]) << 16)
  515. | ((sword64) (b[52]) << 24)
  516. | ((sword64) (b[53]) << 32)
  517. | ((sword64) (b[54]) << 40)
  518. | ((sword64) (b[55]) << 48);
  519. }
  520. /* Convert the field element to a byte array from an array of 56-bits.
  521. *
  522. * b [in] Byte array.
  523. * a [in] Array to encode into.
  524. */
  525. void fe448_to_bytes(unsigned char* b, const sword64* a)
  526. {
  527. sword128 t;
  528. /* Mod */
  529. sword64 in0 = a[0];
  530. sword64 in1 = a[1];
  531. sword64 in2 = a[2];
  532. sword64 in3 = a[3];
  533. sword64 in4 = a[4];
  534. sword64 in5 = a[5];
  535. sword64 in6 = a[6];
  536. sword64 in7 = a[7];
  537. sword64 o = in7 >> 56;
  538. in7 -= o << 56;
  539. in0 += o;
  540. in4 += o;
  541. o = (in0 + 1) >> 56;
  542. o = (o + in1) >> 56;
  543. o = (o + in2) >> 56;
  544. o = (o + in3) >> 56;
  545. o = (o + in4 + 1) >> 56;
  546. o = (o + in5) >> 56;
  547. o = (o + in6) >> 56;
  548. o = (o + in7) >> 56;
  549. in0 += o;
  550. in4 += o;
  551. in7 -= o << 56;
  552. o = (in0 >> 56); in1 += o; t = o << 56; in0 -= (sword64)t;
  553. o = (in1 >> 56); in2 += o; t = o << 56; in1 -= (sword64)t;
  554. o = (in2 >> 56); in3 += o; t = o << 56; in2 -= (sword64)t;
  555. o = (in3 >> 56); in4 += o; t = o << 56; in3 -= (sword64)t;
  556. o = (in4 >> 56); in5 += o; t = o << 56; in4 -= (sword64)t;
  557. o = (in5 >> 56); in6 += o; t = o << 56; in5 -= (sword64)t;
  558. o = (in6 >> 56); in7 += o; t = o << 56; in6 -= (sword64)t;
  559. o = (in7 >> 56); in0 += o;
  560. in4 += o; t = o << 56; in7 -= (sword64)t;
  561. /* Output as bytes */
  562. b[ 0] = (byte)(in0 >> 0);
  563. b[ 1] = (byte)(in0 >> 8);
  564. b[ 2] = (byte)(in0 >> 16);
  565. b[ 3] = (byte)(in0 >> 24);
  566. b[ 4] = (byte)(in0 >> 32);
  567. b[ 5] = (byte)(in0 >> 40);
  568. b[ 6] = (byte)(in0 >> 48);
  569. b[ 7] = (byte)(in1 >> 0);
  570. b[ 8] = (byte)(in1 >> 8);
  571. b[ 9] = (byte)(in1 >> 16);
  572. b[10] = (byte)(in1 >> 24);
  573. b[11] = (byte)(in1 >> 32);
  574. b[12] = (byte)(in1 >> 40);
  575. b[13] = (byte)(in1 >> 48);
  576. b[14] = (byte)(in2 >> 0);
  577. b[15] = (byte)(in2 >> 8);
  578. b[16] = (byte)(in2 >> 16);
  579. b[17] = (byte)(in2 >> 24);
  580. b[18] = (byte)(in2 >> 32);
  581. b[19] = (byte)(in2 >> 40);
  582. b[20] = (byte)(in2 >> 48);
  583. b[21] = (byte)(in3 >> 0);
  584. b[22] = (byte)(in3 >> 8);
  585. b[23] = (byte)(in3 >> 16);
  586. b[24] = (byte)(in3 >> 24);
  587. b[25] = (byte)(in3 >> 32);
  588. b[26] = (byte)(in3 >> 40);
  589. b[27] = (byte)(in3 >> 48);
  590. b[28] = (byte)(in4 >> 0);
  591. b[29] = (byte)(in4 >> 8);
  592. b[30] = (byte)(in4 >> 16);
  593. b[31] = (byte)(in4 >> 24);
  594. b[32] = (byte)(in4 >> 32);
  595. b[33] = (byte)(in4 >> 40);
  596. b[34] = (byte)(in4 >> 48);
  597. b[35] = (byte)(in5 >> 0);
  598. b[36] = (byte)(in5 >> 8);
  599. b[37] = (byte)(in5 >> 16);
  600. b[38] = (byte)(in5 >> 24);
  601. b[39] = (byte)(in5 >> 32);
  602. b[40] = (byte)(in5 >> 40);
  603. b[41] = (byte)(in5 >> 48);
  604. b[42] = (byte)(in6 >> 0);
  605. b[43] = (byte)(in6 >> 8);
  606. b[44] = (byte)(in6 >> 16);
  607. b[45] = (byte)(in6 >> 24);
  608. b[46] = (byte)(in6 >> 32);
  609. b[47] = (byte)(in6 >> 40);
  610. b[48] = (byte)(in6 >> 48);
  611. b[49] = (byte)(in7 >> 0);
  612. b[50] = (byte)(in7 >> 8);
  613. b[51] = (byte)(in7 >> 16);
  614. b[52] = (byte)(in7 >> 24);
  615. b[53] = (byte)(in7 >> 32);
  616. b[54] = (byte)(in7 >> 40);
  617. b[55] = (byte)(in7 >> 48);
  618. }
  619. /* Set the field element to 0.
  620. *
  621. * a [in] Field element.
  622. */
  623. void fe448_1(sword64* a)
  624. {
  625. a[0] = 1;
  626. a[1] = 0;
  627. a[2] = 0;
  628. a[3] = 0;
  629. a[4] = 0;
  630. a[5] = 0;
  631. a[6] = 0;
  632. a[7] = 0;
  633. }
  634. /* Set the field element to 0.
  635. *
  636. * a [in] Field element.
  637. */
  638. void fe448_0(sword64* a)
  639. {
  640. a[0] = 0;
  641. a[1] = 0;
  642. a[2] = 0;
  643. a[3] = 0;
  644. a[4] = 0;
  645. a[5] = 0;
  646. a[6] = 0;
  647. a[7] = 0;
  648. }
  649. /* Copy one field element into another: d = a.
  650. *
  651. * d [in] Destination field element.
  652. * a [in] Source field element.
  653. */
  654. void fe448_copy(sword64* d, const sword64* a)
  655. {
  656. d[0] = a[0];
  657. d[1] = a[1];
  658. d[2] = a[2];
  659. d[3] = a[3];
  660. d[4] = a[4];
  661. d[5] = a[5];
  662. d[6] = a[6];
  663. d[7] = a[7];
  664. }
  665. /* Conditionally swap the elements.
  666. * Constant time implementation.
  667. *
  668. * a [in] First field element.
  669. * b [in] Second field element.
  670. * c [in] Swap when 1. Valid values: 0, 1.
  671. */
  672. static void fe448_cswap(sword64* a, sword64* b, int c)
  673. {
  674. sword64 mask = -(sword64)c;
  675. sword64 t0 = (a[0] ^ b[0]) & mask;
  676. sword64 t1 = (a[1] ^ b[1]) & mask;
  677. sword64 t2 = (a[2] ^ b[2]) & mask;
  678. sword64 t3 = (a[3] ^ b[3]) & mask;
  679. sword64 t4 = (a[4] ^ b[4]) & mask;
  680. sword64 t5 = (a[5] ^ b[5]) & mask;
  681. sword64 t6 = (a[6] ^ b[6]) & mask;
  682. sword64 t7 = (a[7] ^ b[7]) & mask;
  683. a[0] ^= t0;
  684. a[1] ^= t1;
  685. a[2] ^= t2;
  686. a[3] ^= t3;
  687. a[4] ^= t4;
  688. a[5] ^= t5;
  689. a[6] ^= t6;
  690. a[7] ^= t7;
  691. b[0] ^= t0;
  692. b[1] ^= t1;
  693. b[2] ^= t2;
  694. b[3] ^= t3;
  695. b[4] ^= t4;
  696. b[5] ^= t5;
  697. b[6] ^= t6;
  698. b[7] ^= t7;
  699. }
  700. /* Add two field elements. r = (a + b) mod (2^448 - 2^224 - 1)
  701. *
  702. * r [in] Field element to hold sum.
  703. * a [in] Field element to add.
  704. * b [in] Field element to add.
  705. */
  706. void fe448_add(sword64* r, const sword64* a, const sword64* b)
  707. {
  708. r[0] = a[0] + b[0];
  709. r[1] = a[1] + b[1];
  710. r[2] = a[2] + b[2];
  711. r[3] = a[3] + b[3];
  712. r[4] = a[4] + b[4];
  713. r[5] = a[5] + b[5];
  714. r[6] = a[6] + b[6];
  715. r[7] = a[7] + b[7];
  716. }
  717. /* Subtract a field element from another. r = (a - b) mod (2^448 - 2^224 - 1)
  718. *
  719. * r [in] Field element to hold difference.
  720. * a [in] Field element to subtract from.
  721. * b [in] Field element to subtract.
  722. */
  723. void fe448_sub(sword64* r, const sword64* a, const sword64* b)
  724. {
  725. r[0] = a[0] - b[0];
  726. r[1] = a[1] - b[1];
  727. r[2] = a[2] - b[2];
  728. r[3] = a[3] - b[3];
  729. r[4] = a[4] - b[4];
  730. r[5] = a[5] - b[5];
  731. r[6] = a[6] - b[6];
  732. r[7] = a[7] - b[7];
  733. }
  734. /* Multiply a field element by 39081. r = (39081 * a) mod (2^448 - 2^224 - 1)
  735. *
  736. * r [in] Field element to hold result.
  737. * a [in] Field element to multiply.
  738. */
  739. void fe448_mul39081(sword64* r, const sword64* a)
  740. {
  741. sword128 t;
  742. sword64 o;
  743. sword128 t0 = a[0] * (sword128)39081;
  744. sword128 t1 = a[1] * (sword128)39081;
  745. sword128 t2 = a[2] * (sword128)39081;
  746. sword128 t3 = a[3] * (sword128)39081;
  747. sword128 t4 = a[4] * (sword128)39081;
  748. sword128 t5 = a[5] * (sword128)39081;
  749. sword128 t6 = a[6] * (sword128)39081;
  750. sword128 t7 = a[7] * (sword128)39081;
  751. o = (sword64)(t0 >> 56); t1 += o; t = (sword128)o << 56; t0 -= t;
  752. o = (sword64)(t1 >> 56); t2 += o; t = (sword128)o << 56; t1 -= t;
  753. o = (sword64)(t2 >> 56); t3 += o; t = (sword128)o << 56; t2 -= t;
  754. o = (sword64)(t3 >> 56); t4 += o; t = (sword128)o << 56; t3 -= t;
  755. o = (sword64)(t4 >> 56); t5 += o; t = (sword128)o << 56; t4 -= t;
  756. o = (sword64)(t5 >> 56); t6 += o; t = (sword128)o << 56; t5 -= t;
  757. o = (sword64)(t6 >> 56); t7 += o; t = (sword128)o << 56; t6 -= t;
  758. o = (sword64)(t7 >> 56); t0 += o;
  759. t4 += o; t = (sword128)o << 56; t7 -= t;
  760. /* Store */
  761. r[0] = (sword64)t0;
  762. r[1] = (sword64)t1;
  763. r[2] = (sword64)t2;
  764. r[3] = (sword64)t3;
  765. r[4] = (sword64)t4;
  766. r[5] = (sword64)t5;
  767. r[6] = (sword64)t6;
  768. r[7] = (sword64)t7;
  769. }
  770. /* Multiply two field elements. r = (a * b) mod (2^448 - 2^224 - 1)
  771. *
  772. * r [in] Field element to hold result.
  773. * a [in] Field element to multiply.
  774. * b [in] Field element to multiply.
  775. */
  776. void fe448_mul(sword64* r, const sword64* a, const sword64* b)
  777. {
  778. sword64 o;
  779. sword64 a1[4];
  780. sword64 b1[4];
  781. sword128 t0;
  782. sword128 t1;
  783. sword128 t2;
  784. sword128 t3;
  785. sword128 t4;
  786. sword128 t5;
  787. sword128 t6;
  788. sword128 t7;
  789. sword128 t03;
  790. sword128 t04;
  791. sword128 t13;
  792. sword128 t14;
  793. a1[0] = a[0] + a[4];
  794. a1[1] = a[1] + a[5];
  795. a1[2] = a[2] + a[6];
  796. a1[3] = a[3] + a[7];
  797. b1[0] = b[0] + b[4];
  798. b1[1] = b[1] + b[5];
  799. b1[2] = b[2] + b[6];
  800. b1[3] = b[3] + b[7];
  801. t03 = ((sword128)a[0] * b[3]) + ((sword128)a[1] * b[2])
  802. + ((sword128)a[2] * b[1]) + ((sword128)a[3] * b[0]);
  803. t04 = ((sword128)a[1] * b[3]) + ((sword128)a[2] * b[2])
  804. + ((sword128)a[3] * b[1]);
  805. t04 += t03 >> 56;
  806. t03 &= 0xffffffffffffffL;
  807. t13 = ((sword128)a1[0] * b1[3]) + ((sword128)a1[1] * b1[2])
  808. + ((sword128)a1[2] * b1[1]) + ((sword128)a1[3] * b1[0]);
  809. t14 = ((sword128)a1[1] * b1[3]) + ((sword128)a1[2] * b1[2])
  810. + ((sword128)a1[3] * b1[1]);
  811. t14 += t13 >> 56;
  812. t13 &= 0xffffffffffffffL;
  813. t0 = ((sword128)a[0] * b[0]) + ((sword128)a[4] * b[4]) + t14 + -t04;
  814. t1 = ((sword128)a[0] * b[1]) + ((sword128)a[1] * b[0])
  815. + ((sword128)a[4] * b[5]) + ((sword128)a[5] * b[4])
  816. + ((sword128)a1[2] * b1[3]) + ((sword128)a1[3] * b1[2])
  817. - ((sword128)a[2] * b[3]) - ((sword128)a[3] * b[2]);
  818. o = (sword64)(t0 >> 56); t1 += o; t0 &= 0xffffffffffffffL;
  819. t2 = ((sword128)a[0] * b[2]) + ((sword128)a[1] * b[1])
  820. + ((sword128)a[2] * b[0]) + ((sword128)a[4] * b[6])
  821. + ((sword128)a[5] * b[5]) + ((sword128)a[6] * b[4])
  822. + ((sword128)a1[3] * b1[3]) - ((sword128)a[3] * b[3]);
  823. o = (sword64)(t1 >> 56); t2 += o; t1 &= 0xffffffffffffffL;
  824. t3 = t03 + ((sword128)a[4] * b[7]) + ((sword128)a[5] * b[6])
  825. + ((sword128)a[6] * b[5]) + ((sword128)a[7] * b[4]);
  826. o = (sword64)(t2 >> 56); t3 += o; t2 &= 0xffffffffffffffL;
  827. t4 = ((sword128)a[5] * b[7]) + ((sword128)a[6] * b[6])
  828. + ((sword128)a[7] * b[5]) + ((sword128)a1[0] * b1[0])
  829. - ((sword128)a[0] * b[0]) + t14;
  830. o = (sword64)(t3 >> 56); t4 += o; t3 &= 0xffffffffffffffL;
  831. t5 = ((sword128)a[6] * b[7]) + ((sword128)a[7] * b[6])
  832. + ((sword128)a1[0] * b1[1]) + ((sword128)a1[1] * b1[0])
  833. - ((sword128)a[0] * b[1]) - ((sword128)a[1] * b[0])
  834. + ((sword128)a1[2] * b1[3]) + ((sword128)a1[3] * b1[2]);
  835. o = (sword64)(t4 >> 56); t5 += o; t4 &= 0xffffffffffffffL;
  836. t6 = ((sword128)a[7] * b[7]) + ((sword128)a1[0] * b1[2])
  837. + ((sword128)a1[1] * b1[1]) + ((sword128)a1[2] * b1[0])
  838. - ((sword128)a[0] * b[2]) - ((sword128)a[1] * b[1])
  839. - ((sword128)a[2] * b[0]) + ((sword128)a1[3] * b1[3]);
  840. o = (sword64)(t5 >> 56); t6 += o; t5 &= 0xffffffffffffffL;
  841. t7 = t13 + -t03;
  842. o = (sword64)(t6 >> 56); t7 += o; t6 &= 0xffffffffffffffL;
  843. o = (sword64)(t7 >> 56); t0 += o;
  844. t4 += o; t7 &= 0xffffffffffffffL;
  845. /* Store */
  846. r[0] = (sword64)t0;
  847. r[1] = (sword64)t1;
  848. r[2] = (sword64)t2;
  849. r[3] = (sword64)t3;
  850. r[4] = (sword64)t4;
  851. r[5] = (sword64)t5;
  852. r[6] = (sword64)t6;
  853. r[7] = (sword64)t7;
  854. }
  855. /* Square a field element. r = (a * a) mod (2^448 - 2^224 - 1)
  856. *
  857. * r [in] Field element to hold result.
  858. * a [in] Field element to square.
  859. */
  860. void fe448_sqr(sword64* r, const sword64* a)
  861. {
  862. sword64 o;
  863. sword64 a1[4];
  864. sword128 t0;
  865. sword128 t1;
  866. sword128 t2;
  867. sword128 t3;
  868. sword128 t4;
  869. sword128 t5;
  870. sword128 t6;
  871. sword128 t7;
  872. sword128 t03;
  873. sword128 t04;
  874. sword128 t13;
  875. sword128 t14;
  876. a1[0] = a[0] + a[4];
  877. a1[1] = a[1] + a[5];
  878. a1[2] = a[2] + a[6];
  879. a1[3] = a[3] + a[7];
  880. t03 = ((sword128)a[0] * (2 * a[3])) + ((sword128)a[1] * (2 * a[2]));
  881. t04 = ((sword128)a[1] * (2 * a[3])) + ((sword128)a[2] * a[2]);
  882. t04 += t03 >> 56;
  883. t03 &= 0xffffffffffffffL;
  884. t13 = ((sword128)a1[0] * (2 * a1[3])) + ((sword128)a1[1] * (2 * a1[2]));
  885. t14 = ((sword128)a1[1] * (2 * a1[3])) + ((sword128)a1[2] * a1[2]);
  886. t14 += t13 >> 56;
  887. t13 &= 0xffffffffffffffL;
  888. t0 = ((sword128)a[0] * a[0]) + ((sword128)a[4] * a[4]) + t14 + -t04;
  889. t1 = ((sword128)a[0] * (2 * a[1])) + ((sword128)a[4] * (2 * a[5]))
  890. + ((sword128)a1[2] * (2 * a1[3])) - ((sword128)a[2] * (2 * a[3]));
  891. o = (sword64)(t0 >> 56); t1 += o; t0 &= 0xffffffffffffffL;
  892. t2 = ((sword128)a[0] * (2 * a[2])) + ((sword128)a[1] * a[1])
  893. + ((sword128)a[4] * (2 * a[6])) + ((sword128)a[5] * a[5])
  894. + ((sword128)a1[3] * a1[3]) - ((sword128)a[3] * a[3]);
  895. o = (sword64)(t1 >> 56); t2 += o; t1 &= 0xffffffffffffffL;
  896. t3 = t03 + ((sword128)a[4] * (2 * a[7])) + ((sword128)a[5] * (2 * a[6]));
  897. o = (sword64)(t2 >> 56); t3 += o; t2 &= 0xffffffffffffffL;
  898. t4 = ((sword128)a[5] * (2 * a[7])) + ((sword128)a[6] * a[6])
  899. + ((sword128)a1[0] * a1[0]) - ((sword128)a[0] * a[0]) + t14;
  900. o = (sword64)(t3 >> 56); t4 += o; t3 &= 0xffffffffffffffL;
  901. t5 = ((sword128)a[6] * (2 * a[7])) + ((sword128)a1[0] * (2 * a1[1]))
  902. - ((sword128)a[0] * (2 * a[1])) + ((sword128)a1[2] * (2 * a1[3]));
  903. o = (sword64)(t4 >> 56); t5 += o; t4 &= 0xffffffffffffffL;
  904. t6 = ((sword128)a[7] * a[7]) + ((sword128)a1[0] * (2 * a1[2]))
  905. + ((sword128)a1[1] * a1[1]) - ((sword128)a[0] * (2 * a[2]))
  906. - ((sword128)a[1] * a[1]) + ((sword128)a1[3] * a1[3]);
  907. o = (sword64)(t5 >> 56); t6 += o; t5 &= 0xffffffffffffffL;
  908. t7 = t13 + -t03;
  909. o = (sword64)(t6 >> 56); t7 += o; t6 &= 0xffffffffffffffL;
  910. o = (sword64)(t7 >> 56); t0 += o;
  911. t4 += o; t7 &= 0xffffffffffffffL;
  912. /* Store */
  913. r[0] = (sword64)t0;
  914. r[1] = (sword64)t1;
  915. r[2] = (sword64)t2;
  916. r[3] = (sword64)t3;
  917. r[4] = (sword64)t4;
  918. r[5] = (sword64)t5;
  919. r[6] = (sword64)t6;
  920. r[7] = (sword64)t7;
  921. }
  922. /* Invert the field element. (r * a) mod (2^448 - 2^224 - 1) = 1
  923. * Constant time implementation - using Fermat's little theorem:
  924. * a^(p-1) mod p = 1 => a^(p-2) mod p = 1/a
  925. * For curve448: p - 2 = 2^448 - 2^224 - 3
  926. *
  927. * r [in] Field element to hold result.
  928. * a [in] Field element to invert.
  929. */
  930. void fe448_invert(sword64* r, const sword64* a)
  931. {
  932. sword64 t1[8];
  933. sword64 t2[8];
  934. sword64 t3[8];
  935. sword64 t4[8];
  936. int i;
  937. fe448_sqr(t1, a);
  938. /* t1 = 2 */
  939. fe448_mul(t1, t1, a);
  940. /* t1 = 3 */
  941. fe448_sqr(t2, t1); for (i = 1; i < 2; ++i) fe448_sqr(t2, t2);
  942. /* t2 = c */
  943. fe448_mul(t3, t2, a);
  944. /* t3 = d */
  945. fe448_mul(t1, t2, t1);
  946. /* t1 = f */
  947. fe448_sqr(t2, t1);
  948. /* t2 = 1e */
  949. fe448_mul(t4, t2, a);
  950. /* t4 = 1f */
  951. fe448_sqr(t2, t4); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2);
  952. /* t2 = 3e0 */
  953. fe448_mul(t1, t2, t4);
  954. /* t1 = 3ff */
  955. fe448_sqr(t2, t1); for (i = 1; i < 10; ++i) fe448_sqr(t2, t2);
  956. /* t2 = ffc00 */
  957. fe448_mul(t1, t2, t1);
  958. /* t1 = fffff */
  959. fe448_sqr(t2, t1); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2);
  960. /* t2 = 1ffffe0 */
  961. fe448_mul(t1, t2, t4);
  962. /* t1 = 1ffffff */
  963. fe448_sqr(t2, t1); for (i = 1; i < 25; ++i) fe448_sqr(t2, t2);
  964. /* t2 = 3fffffe000000 */
  965. fe448_mul(t1, t2, t1);
  966. /* t1 = 3ffffffffffff */
  967. fe448_sqr(t2, t1); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2);
  968. /* t2 = 7fffffffffffe0 */
  969. fe448_mul(t1, t2, t4);
  970. /* t1 = 7fffffffffffff */
  971. fe448_sqr(t2, t1); for (i = 1; i < 55; ++i) fe448_sqr(t2, t2);
  972. /* t2 = 3fffffffffffff80000000000000 */
  973. fe448_mul(t1, t2, t1);
  974. /* t1 = 3fffffffffffffffffffffffffff */
  975. fe448_sqr(t2, t1); for (i = 1; i < 110; ++i) fe448_sqr(t2, t2);
  976. /* t2 = fffffffffffffffffffffffffffc000000000000000000000000000 */
  977. fe448_mul(t1, t2, t1);
  978. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  979. fe448_sqr(t2, t1); for (i = 1; i < 4; ++i) fe448_sqr(t2, t2);
  980. /* t2 = fffffffffffffffffffffffffffffffffffffffffffffffffffffff0 */
  981. fe448_mul(t3, t3, t2);
  982. /* t3 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffd */
  983. fe448_mul(t1, t3, a);
  984. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe */
  985. fe448_sqr(t1, t1); for (i = 1; i < 224; ++i) fe448_sqr(t1, t1);
  986. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000000000000000000000000000000000000000000000000000 */
  987. fe448_mul(r, t3, t1);
  988. /* r = fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffd */
  989. }
  990. /* Scalar multiply the point by a number. r = n.a
  991. * Uses Montgomery ladder and only requires the x-ordinate.
  992. *
  993. * r [in] Field element to hold result.
  994. * n [in] Scalar as an array of bytes.
  995. * a [in] Point to multiply - x-ordinate only.
  996. */
  997. int curve448(byte* r, const byte* n, const byte* a)
  998. {
  999. sword64 x1[8];
  1000. sword64 x2[8];
  1001. sword64 z2[8];
  1002. sword64 x3[8];
  1003. sword64 z3[8];
  1004. sword64 t0[8];
  1005. sword64 t1[8];
  1006. int i;
  1007. unsigned int swap;
  1008. fe448_from_bytes(x1, a);
  1009. fe448_1(x2);
  1010. fe448_0(z2);
  1011. fe448_copy(x3, x1);
  1012. fe448_1(z3);
  1013. swap = 0;
  1014. for (i = 447; i >= 0; --i) {
  1015. unsigned int b = (n[i >> 3] >> (i & 7)) & 1;
  1016. swap ^= b;
  1017. fe448_cswap(x2, x3, (int)swap);
  1018. fe448_cswap(z2, z3, (int)swap);
  1019. swap = b;
  1020. /* Montgomery Ladder - double and add */
  1021. fe448_add(t0, x2, z2);
  1022. fe448_reduce(t0);
  1023. fe448_add(t1, x3, z3);
  1024. fe448_reduce(t1);
  1025. fe448_sub(x2, x2, z2);
  1026. fe448_sub(x3, x3, z3);
  1027. fe448_mul(t1, t1, x2);
  1028. fe448_mul(z3, x3, t0);
  1029. fe448_sqr(t0, t0);
  1030. fe448_sqr(x2, x2);
  1031. fe448_add(x3, z3, t1);
  1032. fe448_reduce(x3);
  1033. fe448_sqr(x3, x3);
  1034. fe448_sub(z3, z3, t1);
  1035. fe448_sqr(z3, z3);
  1036. fe448_mul(z3, z3, x1);
  1037. fe448_sub(t1, t0, x2);
  1038. fe448_mul(x2, t0, x2);
  1039. fe448_mul39081(z2, t1);
  1040. fe448_add(z2, t0, z2);
  1041. fe448_mul(z2, z2, t1);
  1042. }
  1043. /* Last two bits are 0 - no final swap check required. */
  1044. fe448_invert(z2, z2);
  1045. fe448_mul(x2, x2, z2);
  1046. fe448_to_bytes(r, x2);
  1047. return 0;
  1048. }
  1049. #ifdef HAVE_ED448
  1050. /* Check whether field element is not 0.
  1051. * Must convert to a normalized form before checking.
  1052. *
  1053. * a [in] Field element.
  1054. * returns 0 when zero, and any other value otherwise.
  1055. */
  1056. int fe448_isnonzero(const sword64* a)
  1057. {
  1058. byte b[56];
  1059. int i;
  1060. byte c = 0;
  1061. fe448_to_bytes(b, a);
  1062. for (i = 0; i < 56; i++)
  1063. c |= b[i];
  1064. return c;
  1065. }
  1066. /* Check whether field element is negative.
  1067. * Must convert to a normalized form before checking.
  1068. *
  1069. * a [in] Field element.
  1070. * returns 1 when negative, and 0 otherwise.
  1071. */
  1072. int fe448_isnegative(const sword64* a)
  1073. {
  1074. byte b[56];
  1075. fe448_to_bytes(b, a);
  1076. return b[0] & 1;
  1077. }
  1078. /* Negates the field element. r = -a
  1079. *
  1080. * r [in] Field element to hold result.
  1081. * a [in] Field element.
  1082. */
  1083. void fe448_neg(sword64* r, const sword64* a)
  1084. {
  1085. r[0] = -a[0];
  1086. r[1] = -a[1];
  1087. r[2] = -a[2];
  1088. r[3] = -a[3];
  1089. r[4] = -a[4];
  1090. r[5] = -a[5];
  1091. r[6] = -a[6];
  1092. r[7] = -a[7];
  1093. }
  1094. /* Raise field element to (p-3) / 4: 2^446 - 2^222 - 1
  1095. * Used for calculating y-ordinate from x-ordinate for Ed448.
  1096. *
  1097. * r [in] Field element to hold result.
  1098. * a [in] Field element to exponentiate.
  1099. */
  1100. void fe448_pow_2_446_222_1(sword64* r, const sword64* a)
  1101. {
  1102. sword64 t1[8];
  1103. sword64 t2[8];
  1104. sword64 t3[8];
  1105. sword64 t4[8];
  1106. sword64 t5[8];
  1107. int i;
  1108. fe448_sqr(t3, a);
  1109. /* t3 = 2 */
  1110. fe448_mul(t1, t3, a);
  1111. /* t1 = 3 */
  1112. fe448_sqr(t5, t1);
  1113. /* t5 = 6 */
  1114. fe448_mul(t5, t5, a);
  1115. /* t5 = 7 */
  1116. fe448_sqr(t2, t1); for (i = 1; i < 2; ++i) fe448_sqr(t2, t2);
  1117. /* t2 = c */
  1118. fe448_mul(t3, t2, t3);
  1119. /* t3 = e */
  1120. fe448_mul(t1, t2, t1);
  1121. /* t1 = f */
  1122. fe448_sqr(t2, t1); for (i = 1; i < 3; ++i) fe448_sqr(t2, t2);
  1123. /* t2 = 78 */
  1124. fe448_mul(t5, t2, t5);
  1125. /* t5 = 7f */
  1126. fe448_sqr(t2, t1); for (i = 1; i < 4; ++i) fe448_sqr(t2, t2);
  1127. /* t2 = f0 */
  1128. fe448_mul(t1, t2, t1);
  1129. /* t1 = ff */
  1130. fe448_mul(t3, t3, t2);
  1131. /* t3 = fe */
  1132. fe448_sqr(t2, t1); for (i = 1; i < 7; ++i) fe448_sqr(t2, t2);
  1133. /* t2 = 7f80 */
  1134. fe448_mul(t5, t2, t5);
  1135. /* t5 = 7fff */
  1136. fe448_sqr(t2, t1); for (i = 1; i < 8; ++i) fe448_sqr(t2, t2);
  1137. /* t2 = ff00 */
  1138. fe448_mul(t1, t2, t1);
  1139. /* t1 = ffff */
  1140. fe448_mul(t3, t3, t2);
  1141. /* t3 = fffe */
  1142. fe448_sqr(t2, t5); for (i = 1; i < 15; ++i) fe448_sqr(t2, t2);
  1143. /* t2 = 3fff8000 */
  1144. fe448_mul(t5, t2, t5);
  1145. /* t5 = 3fffffff */
  1146. fe448_sqr(t2, t1); for (i = 1; i < 16; ++i) fe448_sqr(t2, t2);
  1147. /* t2 = ffff0000 */
  1148. fe448_mul(t1, t2, t1);
  1149. /* t1 = ffffffff */
  1150. fe448_mul(t3, t3, t2);
  1151. /* t3 = fffffffe */
  1152. fe448_sqr(t2, t1); for (i = 1; i < 32; ++i) fe448_sqr(t2, t2);
  1153. /* t2 = ffffffff00000000 */
  1154. fe448_mul(t2, t2, t1);
  1155. /* t2 = ffffffffffffffff */
  1156. fe448_sqr(t1, t2); for (i = 1; i < 64; ++i) fe448_sqr(t1, t1);
  1157. /* t1 = ffffffffffffffff0000000000000000 */
  1158. fe448_mul(t1, t1, t2);
  1159. /* t1 = ffffffffffffffffffffffffffffffff */
  1160. fe448_sqr(t1, t1); for (i = 1; i < 64; ++i) fe448_sqr(t1, t1);
  1161. /* t1 = ffffffffffffffffffffffffffffffff0000000000000000 */
  1162. fe448_mul(t4, t1, t2);
  1163. /* t4 = ffffffffffffffffffffffffffffffffffffffffffffffff */
  1164. fe448_sqr(t2, t4); for (i = 1; i < 32; ++i) fe448_sqr(t2, t2);
  1165. /* t2 = ffffffffffffffffffffffffffffffffffffffffffffffff00000000 */
  1166. fe448_mul(t3, t3, t2);
  1167. /* t3 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe */
  1168. fe448_sqr(t1, t3); for (i = 1; i < 192; ++i) fe448_sqr(t1, t1);
  1169. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000 */
  1170. fe448_mul(t1, t1, t4);
  1171. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff */
  1172. fe448_sqr(t1, t1); for (i = 1; i < 30; ++i) fe448_sqr(t1, t1);
  1173. /* t1 = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffc0000000 */
  1174. fe448_mul(r, t5, t1);
  1175. /* r = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  1176. }
  1177. /* Constant time, conditional move of b into a.
  1178. * a is not changed if the condition is 0.
  1179. *
  1180. * a A field element.
  1181. * b A field element.
  1182. * c If 1 then copy and if 0 then don't copy.
  1183. */
  1184. void fe448_cmov(sword64* a, const sword64* b, int c)
  1185. {
  1186. sword64 m = -(sword64)c;
  1187. sword64 t0 = m & (a[0] ^ b[0]);
  1188. sword64 t1 = m & (a[1] ^ b[1]);
  1189. sword64 t2 = m & (a[2] ^ b[2]);
  1190. sword64 t3 = m & (a[3] ^ b[3]);
  1191. sword64 t4 = m & (a[4] ^ b[4]);
  1192. sword64 t5 = m & (a[5] ^ b[5]);
  1193. sword64 t6 = m & (a[6] ^ b[6]);
  1194. sword64 t7 = m & (a[7] ^ b[7]);
  1195. a[0] ^= t0;
  1196. a[1] ^= t1;
  1197. a[2] ^= t2;
  1198. a[3] ^= t3;
  1199. a[4] ^= t4;
  1200. a[5] ^= t5;
  1201. a[6] ^= t6;
  1202. a[7] ^= t7;
  1203. }
  1204. #endif /* HAVE_ED448 */
  1205. #else
  1206. /* Initialize the field element operations.
  1207. */
  1208. void fe448_init(void)
  1209. {
  1210. }
  1211. /* Convert the field element from a byte array to an array of 28-bits.
  1212. *
  1213. * r [in] Array to encode into.
  1214. * b [in] Byte array.
  1215. */
  1216. void fe448_from_bytes(sword32* r, const unsigned char* b)
  1217. {
  1218. r[ 0] = (((sword32)((b[ 0] ) >> 0)) << 0)
  1219. | (((sword32)((b[ 1] ) >> 0)) << 8)
  1220. | (((sword32)((b[ 2] ) >> 0)) << 16)
  1221. | ((((sword32)((b[ 3] & 0xf )) >> 0)) << 24);
  1222. r[ 1] = (((sword32)((b[ 3] ) >> 4)) << 0)
  1223. | (((sword32)((b[ 4] ) >> 0)) << 4)
  1224. | (((sword32)((b[ 5] ) >> 0)) << 12)
  1225. | (((sword32)((b[ 6] ) >> 0)) << 20);
  1226. r[ 2] = (((sword32)((b[ 7] ) >> 0)) << 0)
  1227. | (((sword32)((b[ 8] ) >> 0)) << 8)
  1228. | (((sword32)((b[ 9] ) >> 0)) << 16)
  1229. | ((((sword32)((b[10] & 0xf )) >> 0)) << 24);
  1230. r[ 3] = (((sword32)((b[10] ) >> 4)) << 0)
  1231. | (((sword32)((b[11] ) >> 0)) << 4)
  1232. | (((sword32)((b[12] ) >> 0)) << 12)
  1233. | (((sword32)((b[13] ) >> 0)) << 20);
  1234. r[ 4] = (((sword32)((b[14] ) >> 0)) << 0)
  1235. | (((sword32)((b[15] ) >> 0)) << 8)
  1236. | (((sword32)((b[16] ) >> 0)) << 16)
  1237. | ((((sword32)((b[17] & 0xf )) >> 0)) << 24);
  1238. r[ 5] = (((sword32)((b[17] ) >> 4)) << 0)
  1239. | (((sword32)((b[18] ) >> 0)) << 4)
  1240. | (((sword32)((b[19] ) >> 0)) << 12)
  1241. | (((sword32)((b[20] ) >> 0)) << 20);
  1242. r[ 6] = (((sword32)((b[21] ) >> 0)) << 0)
  1243. | (((sword32)((b[22] ) >> 0)) << 8)
  1244. | (((sword32)((b[23] ) >> 0)) << 16)
  1245. | ((((sword32)((b[24] & 0xf )) >> 0)) << 24);
  1246. r[ 7] = (((sword32)((b[24] ) >> 4)) << 0)
  1247. | (((sword32)((b[25] ) >> 0)) << 4)
  1248. | (((sword32)((b[26] ) >> 0)) << 12)
  1249. | (((sword32)((b[27] ) >> 0)) << 20);
  1250. r[ 8] = (((sword32)((b[28] ) >> 0)) << 0)
  1251. | (((sword32)((b[29] ) >> 0)) << 8)
  1252. | (((sword32)((b[30] ) >> 0)) << 16)
  1253. | ((((sword32)((b[31] & 0xf )) >> 0)) << 24);
  1254. r[ 9] = (((sword32)((b[31] ) >> 4)) << 0)
  1255. | (((sword32)((b[32] ) >> 0)) << 4)
  1256. | (((sword32)((b[33] ) >> 0)) << 12)
  1257. | (((sword32)((b[34] ) >> 0)) << 20);
  1258. r[10] = (((sword32)((b[35] ) >> 0)) << 0)
  1259. | (((sword32)((b[36] ) >> 0)) << 8)
  1260. | (((sword32)((b[37] ) >> 0)) << 16)
  1261. | ((((sword32)((b[38] & 0xf )) >> 0)) << 24);
  1262. r[11] = (((sword32)((b[38] ) >> 4)) << 0)
  1263. | (((sword32)((b[39] ) >> 0)) << 4)
  1264. | (((sword32)((b[40] ) >> 0)) << 12)
  1265. | (((sword32)((b[41] ) >> 0)) << 20);
  1266. r[12] = (((sword32)((b[42] ) >> 0)) << 0)
  1267. | (((sword32)((b[43] ) >> 0)) << 8)
  1268. | (((sword32)((b[44] ) >> 0)) << 16)
  1269. | ((((sword32)((b[45] & 0xf )) >> 0)) << 24);
  1270. r[13] = (((sword32)((b[45] ) >> 4)) << 0)
  1271. | (((sword32)((b[46] ) >> 0)) << 4)
  1272. | (((sword32)((b[47] ) >> 0)) << 12)
  1273. | (((sword32)((b[48] ) >> 0)) << 20);
  1274. r[14] = (((sword32)((b[49] ) >> 0)) << 0)
  1275. | (((sword32)((b[50] ) >> 0)) << 8)
  1276. | (((sword32)((b[51] ) >> 0)) << 16)
  1277. | ((((sword32)((b[52] & 0xf )) >> 0)) << 24);
  1278. r[15] = (((sword32)((b[52] ) >> 4)) << 0)
  1279. | (((sword32)((b[53] ) >> 0)) << 4)
  1280. | (((sword32)((b[54] ) >> 0)) << 12)
  1281. | (((sword32)((b[55] ) >> 0)) << 20);
  1282. }
  1283. /* Convert the field element to a byte array from an array of 28-bits.
  1284. *
  1285. * b [in] Byte array.
  1286. * a [in] Array to encode into.
  1287. */
  1288. void fe448_to_bytes(unsigned char* b, const sword32* a)
  1289. {
  1290. sword64 t;
  1291. /* Mod */
  1292. sword32 in0 = a[0];
  1293. sword32 in1 = a[1];
  1294. sword32 in2 = a[2];
  1295. sword32 in3 = a[3];
  1296. sword32 in4 = a[4];
  1297. sword32 in5 = a[5];
  1298. sword32 in6 = a[6];
  1299. sword32 in7 = a[7];
  1300. sword32 in8 = a[8];
  1301. sword32 in9 = a[9];
  1302. sword32 in10 = a[10];
  1303. sword32 in11 = a[11];
  1304. sword32 in12 = a[12];
  1305. sword32 in13 = a[13];
  1306. sword32 in14 = a[14];
  1307. sword32 in15 = a[15];
  1308. sword32 o = in15 >> 28;
  1309. in15 -= o << 28;
  1310. in0 += o;
  1311. in8 += o;
  1312. o = (in0 + 1) >> 28;
  1313. o = (o + in1) >> 28;
  1314. o = (o + in2) >> 28;
  1315. o = (o + in3) >> 28;
  1316. o = (o + in4) >> 28;
  1317. o = (o + in5) >> 28;
  1318. o = (o + in6) >> 28;
  1319. o = (o + in7) >> 28;
  1320. o = (o + in8 + 1) >> 28;
  1321. o = (o + in9) >> 28;
  1322. o = (o + in10) >> 28;
  1323. o = (o + in11) >> 28;
  1324. o = (o + in12) >> 28;
  1325. o = (o + in13) >> 28;
  1326. o = (o + in14) >> 28;
  1327. o = (o + in15) >> 28;
  1328. in0 += o;
  1329. in8 += o;
  1330. in15 -= o << 28;
  1331. o = (in0 >> 28); in1 += o; t = o << 28; in0 -= (sword32)t;
  1332. o = (in1 >> 28); in2 += o; t = o << 28; in1 -= (sword32)t;
  1333. o = (in2 >> 28); in3 += o; t = o << 28; in2 -= (sword32)t;
  1334. o = (in3 >> 28); in4 += o; t = o << 28; in3 -= (sword32)t;
  1335. o = (in4 >> 28); in5 += o; t = o << 28; in4 -= (sword32)t;
  1336. o = (in5 >> 28); in6 += o; t = o << 28; in5 -= (sword32)t;
  1337. o = (in6 >> 28); in7 += o; t = o << 28; in6 -= (sword32)t;
  1338. o = (in7 >> 28); in8 += o; t = o << 28; in7 -= (sword32)t;
  1339. o = (in8 >> 28); in9 += o; t = o << 28; in8 -= (sword32)t;
  1340. o = (in9 >> 28); in10 += o; t = o << 28; in9 -= (sword32)t;
  1341. o = (in10 >> 28); in11 += o; t = o << 28; in10 -= (sword32)t;
  1342. o = (in11 >> 28); in12 += o; t = o << 28; in11 -= (sword32)t;
  1343. o = (in12 >> 28); in13 += o; t = o << 28; in12 -= (sword32)t;
  1344. o = (in13 >> 28); in14 += o; t = o << 28; in13 -= (sword32)t;
  1345. o = (in14 >> 28); in15 += o; t = o << 28; in14 -= (sword32)t;
  1346. o = (in15 >> 28); in0 += o;
  1347. in8 += o; t = o << 28; in15 -= (sword32)t;
  1348. /* Output as bytes */
  1349. b[ 0] = (byte)(in0 >> 0);
  1350. b[ 1] = (byte)(in0 >> 8);
  1351. b[ 2] = (byte)(in0 >> 16);
  1352. b[ 3] = (byte)(in0 >> 24) + ((in1 >> 0) << 4);
  1353. b[ 4] = (byte)(in1 >> 4);
  1354. b[ 5] = (byte)(in1 >> 12);
  1355. b[ 6] = (byte)(in1 >> 20);
  1356. b[ 7] = (byte)(in2 >> 0);
  1357. b[ 8] = (byte)(in2 >> 8);
  1358. b[ 9] = (byte)(in2 >> 16);
  1359. b[10] = (byte)(in2 >> 24) + ((in3 >> 0) << 4);
  1360. b[11] = (byte)(in3 >> 4);
  1361. b[12] = (byte)(in3 >> 12);
  1362. b[13] = (byte)(in3 >> 20);
  1363. b[14] = (byte)(in4 >> 0);
  1364. b[15] = (byte)(in4 >> 8);
  1365. b[16] = (byte)(in4 >> 16);
  1366. b[17] = (byte)(in4 >> 24) + ((in5 >> 0) << 4);
  1367. b[18] = (byte)(in5 >> 4);
  1368. b[19] = (byte)(in5 >> 12);
  1369. b[20] = (byte)(in5 >> 20);
  1370. b[21] = (byte)(in6 >> 0);
  1371. b[22] = (byte)(in6 >> 8);
  1372. b[23] = (byte)(in6 >> 16);
  1373. b[24] = (byte)(in6 >> 24) + ((in7 >> 0) << 4);
  1374. b[25] = (byte)(in7 >> 4);
  1375. b[26] = (byte)(in7 >> 12);
  1376. b[27] = (byte)(in7 >> 20);
  1377. b[28] = (byte)(in8 >> 0);
  1378. b[29] = (byte)(in8 >> 8);
  1379. b[30] = (byte)(in8 >> 16);
  1380. b[31] = (byte)(in8 >> 24) + ((in9 >> 0) << 4);
  1381. b[32] = (byte)(in9 >> 4);
  1382. b[33] = (byte)(in9 >> 12);
  1383. b[34] = (byte)(in9 >> 20);
  1384. b[35] = (byte)(in10 >> 0);
  1385. b[36] = (byte)(in10 >> 8);
  1386. b[37] = (byte)(in10 >> 16);
  1387. b[38] = (byte)(in10 >> 24) + ((in11 >> 0) << 4);
  1388. b[39] = (byte)(in11 >> 4);
  1389. b[40] = (byte)(in11 >> 12);
  1390. b[41] = (byte)(in11 >> 20);
  1391. b[42] = (byte)(in12 >> 0);
  1392. b[43] = (byte)(in12 >> 8);
  1393. b[44] = (byte)(in12 >> 16);
  1394. b[45] = (byte)(in12 >> 24) + ((in13 >> 0) << 4);
  1395. b[46] = (byte)(in13 >> 4);
  1396. b[47] = (byte)(in13 >> 12);
  1397. b[48] = (byte)(in13 >> 20);
  1398. b[49] = (byte)(in14 >> 0);
  1399. b[50] = (byte)(in14 >> 8);
  1400. b[51] = (byte)(in14 >> 16);
  1401. b[52] = (byte)(in14 >> 24) + ((in15 >> 0) << 4);
  1402. b[53] = (byte)(in15 >> 4);
  1403. b[54] = (byte)(in15 >> 12);
  1404. b[55] = (byte)(in15 >> 20);
  1405. }
  1406. /* Set the field element to 0.
  1407. *
  1408. * a [in] Field element.
  1409. */
  1410. void fe448_1(sword32* a)
  1411. {
  1412. a[0] = 1;
  1413. a[1] = 0;
  1414. a[2] = 0;
  1415. a[3] = 0;
  1416. a[4] = 0;
  1417. a[5] = 0;
  1418. a[6] = 0;
  1419. a[7] = 0;
  1420. a[8] = 0;
  1421. a[9] = 0;
  1422. a[10] = 0;
  1423. a[11] = 0;
  1424. a[12] = 0;
  1425. a[13] = 0;
  1426. a[14] = 0;
  1427. a[15] = 0;
  1428. }
  1429. /* Set the field element to 0.
  1430. *
  1431. * a [in] Field element.
  1432. */
  1433. void fe448_0(sword32* a)
  1434. {
  1435. a[0] = 0;
  1436. a[1] = 0;
  1437. a[2] = 0;
  1438. a[3] = 0;
  1439. a[4] = 0;
  1440. a[5] = 0;
  1441. a[6] = 0;
  1442. a[7] = 0;
  1443. a[8] = 0;
  1444. a[9] = 0;
  1445. a[10] = 0;
  1446. a[11] = 0;
  1447. a[12] = 0;
  1448. a[13] = 0;
  1449. a[14] = 0;
  1450. a[15] = 0;
  1451. }
  1452. /* Copy one field element into another: d = a.
  1453. *
  1454. * d [in] Destination field element.
  1455. * a [in] Source field element.
  1456. */
  1457. void fe448_copy(sword32* d, const sword32* a)
  1458. {
  1459. d[0] = a[0];
  1460. d[1] = a[1];
  1461. d[2] = a[2];
  1462. d[3] = a[3];
  1463. d[4] = a[4];
  1464. d[5] = a[5];
  1465. d[6] = a[6];
  1466. d[7] = a[7];
  1467. d[8] = a[8];
  1468. d[9] = a[9];
  1469. d[10] = a[10];
  1470. d[11] = a[11];
  1471. d[12] = a[12];
  1472. d[13] = a[13];
  1473. d[14] = a[14];
  1474. d[15] = a[15];
  1475. }
  1476. /* Conditionally swap the elements.
  1477. * Constant time implementation.
  1478. *
  1479. * a [in] First field element.
  1480. * b [in] Second field element.
  1481. * c [in] Swap when 1. Valid values: 0, 1.
  1482. */
  1483. static void fe448_cswap(sword32* a, sword32* b, int c)
  1484. {
  1485. sword32 mask = -(sword32)c;
  1486. sword32 t0 = (a[0] ^ b[0]) & mask;
  1487. sword32 t1 = (a[1] ^ b[1]) & mask;
  1488. sword32 t2 = (a[2] ^ b[2]) & mask;
  1489. sword32 t3 = (a[3] ^ b[3]) & mask;
  1490. sword32 t4 = (a[4] ^ b[4]) & mask;
  1491. sword32 t5 = (a[5] ^ b[5]) & mask;
  1492. sword32 t6 = (a[6] ^ b[6]) & mask;
  1493. sword32 t7 = (a[7] ^ b[7]) & mask;
  1494. sword32 t8 = (a[8] ^ b[8]) & mask;
  1495. sword32 t9 = (a[9] ^ b[9]) & mask;
  1496. sword32 t10 = (a[10] ^ b[10]) & mask;
  1497. sword32 t11 = (a[11] ^ b[11]) & mask;
  1498. sword32 t12 = (a[12] ^ b[12]) & mask;
  1499. sword32 t13 = (a[13] ^ b[13]) & mask;
  1500. sword32 t14 = (a[14] ^ b[14]) & mask;
  1501. sword32 t15 = (a[15] ^ b[15]) & mask;
  1502. a[0] ^= t0;
  1503. a[1] ^= t1;
  1504. a[2] ^= t2;
  1505. a[3] ^= t3;
  1506. a[4] ^= t4;
  1507. a[5] ^= t5;
  1508. a[6] ^= t6;
  1509. a[7] ^= t7;
  1510. a[8] ^= t8;
  1511. a[9] ^= t9;
  1512. a[10] ^= t10;
  1513. a[11] ^= t11;
  1514. a[12] ^= t12;
  1515. a[13] ^= t13;
  1516. a[14] ^= t14;
  1517. a[15] ^= t15;
  1518. b[0] ^= t0;
  1519. b[1] ^= t1;
  1520. b[2] ^= t2;
  1521. b[3] ^= t3;
  1522. b[4] ^= t4;
  1523. b[5] ^= t5;
  1524. b[6] ^= t6;
  1525. b[7] ^= t7;
  1526. b[8] ^= t8;
  1527. b[9] ^= t9;
  1528. b[10] ^= t10;
  1529. b[11] ^= t11;
  1530. b[12] ^= t12;
  1531. b[13] ^= t13;
  1532. b[14] ^= t14;
  1533. b[15] ^= t15;
  1534. }
  1535. /* Add two field elements. r = (a + b) mod (2^448 - 2^224 - 1)
  1536. *
  1537. * r [in] Field element to hold sum.
  1538. * a [in] Field element to add.
  1539. * b [in] Field element to add.
  1540. */
  1541. void fe448_add(sword32* r, const sword32* a, const sword32* b)
  1542. {
  1543. r[0] = a[0] + b[0];
  1544. r[1] = a[1] + b[1];
  1545. r[2] = a[2] + b[2];
  1546. r[3] = a[3] + b[3];
  1547. r[4] = a[4] + b[4];
  1548. r[5] = a[5] + b[5];
  1549. r[6] = a[6] + b[6];
  1550. r[7] = a[7] + b[7];
  1551. r[8] = a[8] + b[8];
  1552. r[9] = a[9] + b[9];
  1553. r[10] = a[10] + b[10];
  1554. r[11] = a[11] + b[11];
  1555. r[12] = a[12] + b[12];
  1556. r[13] = a[13] + b[13];
  1557. r[14] = a[14] + b[14];
  1558. r[15] = a[15] + b[15];
  1559. }
  1560. /* Subtract a field element from another. r = (a - b) mod (2^448 - 2^224 - 1)
  1561. *
  1562. * r [in] Field element to hold difference.
  1563. * a [in] Field element to subtract from.
  1564. * b [in] Field element to subtract.
  1565. */
  1566. void fe448_sub(sword32* r, const sword32* a, const sword32* b)
  1567. {
  1568. r[0] = a[0] - b[0];
  1569. r[1] = a[1] - b[1];
  1570. r[2] = a[2] - b[2];
  1571. r[3] = a[3] - b[3];
  1572. r[4] = a[4] - b[4];
  1573. r[5] = a[5] - b[5];
  1574. r[6] = a[6] - b[6];
  1575. r[7] = a[7] - b[7];
  1576. r[8] = a[8] - b[8];
  1577. r[9] = a[9] - b[9];
  1578. r[10] = a[10] - b[10];
  1579. r[11] = a[11] - b[11];
  1580. r[12] = a[12] - b[12];
  1581. r[13] = a[13] - b[13];
  1582. r[14] = a[14] - b[14];
  1583. r[15] = a[15] - b[15];
  1584. }
  1585. void fe448_reduce(sword32* a)
  1586. {
  1587. sword64 o;
  1588. o = a[0 ] >> 28; a[1 ] += (sword32)o; a[0 ] -= (sword32)(o << 28);
  1589. o = a[1 ] >> 28; a[2 ] += (sword32)o; a[1 ] -= (sword32)(o << 28);
  1590. o = a[2 ] >> 28; a[3 ] += (sword32)o; a[2 ] -= (sword32)(o << 28);
  1591. o = a[3 ] >> 28; a[4 ] += (sword32)o; a[3 ] -= (sword32)(o << 28);
  1592. o = a[4 ] >> 28; a[5 ] += (sword32)o; a[4 ] -= (sword32)(o << 28);
  1593. o = a[5 ] >> 28; a[6 ] += (sword32)o; a[5 ] -= (sword32)(o << 28);
  1594. o = a[6 ] >> 28; a[7 ] += (sword32)o; a[6 ] -= (sword32)(o << 28);
  1595. o = a[7 ] >> 28; a[8 ] += (sword32)o; a[7 ] -= (sword32)(o << 28);
  1596. o = a[8 ] >> 28; a[9 ] += (sword32)o; a[8 ] -= (sword32)(o << 28);
  1597. o = a[9 ] >> 28; a[10] += (sword32)o; a[9 ] -= (sword32)(o << 28);
  1598. o = a[10] >> 28; a[11] += (sword32)o; a[10] -= (sword32)(o << 28);
  1599. o = a[11] >> 28; a[12] += (sword32)o; a[11] -= (sword32)(o << 28);
  1600. o = a[12] >> 28; a[13] += (sword32)o; a[12] -= (sword32)(o << 28);
  1601. o = a[13] >> 28; a[14] += (sword32)o; a[13] -= (sword32)(o << 28);
  1602. o = a[14] >> 28; a[15] += (sword32)o; a[14] -= (sword32)(o << 28);
  1603. o = a[15] >> 28; a[0] += (sword32)o;
  1604. a[8] += (sword32)o; a[15] -= (sword32)(o << 28);
  1605. }
  1606. /* Multiply a field element by 39081. r = (39081 * a) mod (2^448 - 2^224 - 1)
  1607. *
  1608. * r [in] Field element to hold result.
  1609. * a [in] Field element to multiply.
  1610. */
  1611. void fe448_mul39081(sword32* r, const sword32* a)
  1612. {
  1613. sword64 t;
  1614. sword32 o;
  1615. sword64 t0 = a[0] * (sword64)39081;
  1616. sword64 t1 = a[1] * (sword64)39081;
  1617. sword64 t2 = a[2] * (sword64)39081;
  1618. sword64 t3 = a[3] * (sword64)39081;
  1619. sword64 t4 = a[4] * (sword64)39081;
  1620. sword64 t5 = a[5] * (sword64)39081;
  1621. sword64 t6 = a[6] * (sword64)39081;
  1622. sword64 t7 = a[7] * (sword64)39081;
  1623. sword64 t8 = a[8] * (sword64)39081;
  1624. sword64 t9 = a[9] * (sword64)39081;
  1625. sword64 t10 = a[10] * (sword64)39081;
  1626. sword64 t11 = a[11] * (sword64)39081;
  1627. sword64 t12 = a[12] * (sword64)39081;
  1628. sword64 t13 = a[13] * (sword64)39081;
  1629. sword64 t14 = a[14] * (sword64)39081;
  1630. sword64 t15 = a[15] * (sword64)39081;
  1631. o = (sword32)(t0 >> 28); t1 += o; t = (sword64)o << 28; t0 -= t;
  1632. o = (sword32)(t1 >> 28); t2 += o; t = (sword64)o << 28; t1 -= t;
  1633. o = (sword32)(t2 >> 28); t3 += o; t = (sword64)o << 28; t2 -= t;
  1634. o = (sword32)(t3 >> 28); t4 += o; t = (sword64)o << 28; t3 -= t;
  1635. o = (sword32)(t4 >> 28); t5 += o; t = (sword64)o << 28; t4 -= t;
  1636. o = (sword32)(t5 >> 28); t6 += o; t = (sword64)o << 28; t5 -= t;
  1637. o = (sword32)(t6 >> 28); t7 += o; t = (sword64)o << 28; t6 -= t;
  1638. o = (sword32)(t7 >> 28); t8 += o; t = (sword64)o << 28; t7 -= t;
  1639. o = (sword32)(t8 >> 28); t9 += o; t = (sword64)o << 28; t8 -= t;
  1640. o = (sword32)(t9 >> 28); t10 += o; t = (sword64)o << 28; t9 -= t;
  1641. o = (sword32)(t10 >> 28); t11 += o; t = (sword64)o << 28; t10 -= t;
  1642. o = (sword32)(t11 >> 28); t12 += o; t = (sword64)o << 28; t11 -= t;
  1643. o = (sword32)(t12 >> 28); t13 += o; t = (sword64)o << 28; t12 -= t;
  1644. o = (sword32)(t13 >> 28); t14 += o; t = (sword64)o << 28; t13 -= t;
  1645. o = (sword32)(t14 >> 28); t15 += o; t = (sword64)o << 28; t14 -= t;
  1646. o = (sword32)(t15 >> 28); t0 += o;
  1647. t8 += o; t = (sword64)o << 28; t15 -= t;
  1648. /* Store */
  1649. r[0] = (sword32)t0;
  1650. r[1] = (sword32)t1;
  1651. r[2] = (sword32)t2;
  1652. r[3] = (sword32)t3;
  1653. r[4] = (sword32)t4;
  1654. r[5] = (sword32)t5;
  1655. r[6] = (sword32)t6;
  1656. r[7] = (sword32)t7;
  1657. r[8] = (sword32)t8;
  1658. r[9] = (sword32)t9;
  1659. r[10] = (sword32)t10;
  1660. r[11] = (sword32)t11;
  1661. r[12] = (sword32)t12;
  1662. r[13] = (sword32)t13;
  1663. r[14] = (sword32)t14;
  1664. r[15] = (sword32)t15;
  1665. }
  1666. /* Multiply two field elements. r = a * b
  1667. *
  1668. * r [in] Field element to hold result.
  1669. * a [in] Field element to multiply.
  1670. * b [in] Field element to multiply.
  1671. */
  1672. static WC_INLINE void fe448_mul_8(sword32* r, const sword32* a, const sword32* b)
  1673. {
  1674. sword64 t;
  1675. sword64 t0 = (sword64)a[ 0] * b[ 0];
  1676. sword64 t1 = (sword64)a[ 0] * b[ 1];
  1677. sword64 t101 = (sword64)a[ 1] * b[ 0];
  1678. sword64 t2 = (sword64)a[ 0] * b[ 2];
  1679. sword64 t102 = (sword64)a[ 1] * b[ 1];
  1680. sword64 t202 = (sword64)a[ 2] * b[ 0];
  1681. sword64 t3 = (sword64)a[ 0] * b[ 3];
  1682. sword64 t103 = (sword64)a[ 1] * b[ 2];
  1683. sword64 t203 = (sword64)a[ 2] * b[ 1];
  1684. sword64 t303 = (sword64)a[ 3] * b[ 0];
  1685. sword64 t4 = (sword64)a[ 0] * b[ 4];
  1686. sword64 t104 = (sword64)a[ 1] * b[ 3];
  1687. sword64 t204 = (sword64)a[ 2] * b[ 2];
  1688. sword64 t304 = (sword64)a[ 3] * b[ 1];
  1689. sword64 t404 = (sword64)a[ 4] * b[ 0];
  1690. sword64 t5 = (sword64)a[ 0] * b[ 5];
  1691. sword64 t105 = (sword64)a[ 1] * b[ 4];
  1692. sword64 t205 = (sword64)a[ 2] * b[ 3];
  1693. sword64 t305 = (sword64)a[ 3] * b[ 2];
  1694. sword64 t405 = (sword64)a[ 4] * b[ 1];
  1695. sword64 t505 = (sword64)a[ 5] * b[ 0];
  1696. sword64 t6 = (sword64)a[ 0] * b[ 6];
  1697. sword64 t106 = (sword64)a[ 1] * b[ 5];
  1698. sword64 t206 = (sword64)a[ 2] * b[ 4];
  1699. sword64 t306 = (sword64)a[ 3] * b[ 3];
  1700. sword64 t406 = (sword64)a[ 4] * b[ 2];
  1701. sword64 t506 = (sword64)a[ 5] * b[ 1];
  1702. sword64 t606 = (sword64)a[ 6] * b[ 0];
  1703. sword64 t7 = (sword64)a[ 0] * b[ 7];
  1704. sword64 t107 = (sword64)a[ 1] * b[ 6];
  1705. sword64 t207 = (sword64)a[ 2] * b[ 5];
  1706. sword64 t307 = (sword64)a[ 3] * b[ 4];
  1707. sword64 t407 = (sword64)a[ 4] * b[ 3];
  1708. sword64 t507 = (sword64)a[ 5] * b[ 2];
  1709. sword64 t607 = (sword64)a[ 6] * b[ 1];
  1710. sword64 t707 = (sword64)a[ 7] * b[ 0];
  1711. sword64 t8 = (sword64)a[ 1] * b[ 7];
  1712. sword64 t108 = (sword64)a[ 2] * b[ 6];
  1713. sword64 t208 = (sword64)a[ 3] * b[ 5];
  1714. sword64 t308 = (sword64)a[ 4] * b[ 4];
  1715. sword64 t408 = (sword64)a[ 5] * b[ 3];
  1716. sword64 t508 = (sword64)a[ 6] * b[ 2];
  1717. sword64 t608 = (sword64)a[ 7] * b[ 1];
  1718. sword64 t9 = (sword64)a[ 2] * b[ 7];
  1719. sword64 t109 = (sword64)a[ 3] * b[ 6];
  1720. sword64 t209 = (sword64)a[ 4] * b[ 5];
  1721. sword64 t309 = (sword64)a[ 5] * b[ 4];
  1722. sword64 t409 = (sword64)a[ 6] * b[ 3];
  1723. sword64 t509 = (sword64)a[ 7] * b[ 2];
  1724. sword64 t10 = (sword64)a[ 3] * b[ 7];
  1725. sword64 t110 = (sword64)a[ 4] * b[ 6];
  1726. sword64 t210 = (sword64)a[ 5] * b[ 5];
  1727. sword64 t310 = (sword64)a[ 6] * b[ 4];
  1728. sword64 t410 = (sword64)a[ 7] * b[ 3];
  1729. sword64 t11 = (sword64)a[ 4] * b[ 7];
  1730. sword64 t111 = (sword64)a[ 5] * b[ 6];
  1731. sword64 t211 = (sword64)a[ 6] * b[ 5];
  1732. sword64 t311 = (sword64)a[ 7] * b[ 4];
  1733. sword64 t12 = (sword64)a[ 5] * b[ 7];
  1734. sword64 t112 = (sword64)a[ 6] * b[ 6];
  1735. sword64 t212 = (sword64)a[ 7] * b[ 5];
  1736. sword64 t13 = (sword64)a[ 6] * b[ 7];
  1737. sword64 t113 = (sword64)a[ 7] * b[ 6];
  1738. sword64 t14 = (sword64)a[ 7] * b[ 7];
  1739. t1 += t101;
  1740. t2 += t102; t2 += t202;
  1741. t3 += t103; t3 += t203; t3 += t303;
  1742. t4 += t104; t4 += t204; t4 += t304; t4 += t404;
  1743. t5 += t105; t5 += t205; t5 += t305; t5 += t405; t5 += t505;
  1744. t6 += t106; t6 += t206; t6 += t306; t6 += t406; t6 += t506;
  1745. t6 += t606;
  1746. t7 += t107; t7 += t207; t7 += t307; t7 += t407; t7 += t507;
  1747. t7 += t607;
  1748. t8 += t108; t8 += t208; t8 += t308; t8 += t408; t8 += t508;
  1749. t8 += t608;
  1750. t9 += t109; t9 += t209; t9 += t309; t9 += t409; t9 += t509;
  1751. t10 += t110; t10 += t210; t10 += t310; t10 += t410;
  1752. t11 += t111; t11 += t211; t11 += t311;
  1753. t12 += t112; t12 += t212;
  1754. t13 += t113;
  1755. sword64 o = t14 >> 28;
  1756. sword64 t15 = o;
  1757. t14 -= o << 28;
  1758. o = (t0 >> 28); t1 += o; t = o << 28; t0 -= t;
  1759. o = (t1 >> 28); t2 += o; t = o << 28; t1 -= t;
  1760. o = (t2 >> 28); t3 += o; t = o << 28; t2 -= t;
  1761. o = (t3 >> 28); t4 += o; t = o << 28; t3 -= t;
  1762. o = (t4 >> 28); t5 += o; t = o << 28; t4 -= t;
  1763. o = (t5 >> 28); t6 += o; t = o << 28; t5 -= t;
  1764. o = (t6 >> 28); t7 += o; t = o << 28; t6 -= t;
  1765. o = (t707>> 28); t8 += o; t = o << 28; t707-= t; t7 += t707;
  1766. o = (t7 >> 28); t8 += o; t = o << 28; t7 -= t;
  1767. o = (t8 >> 28); t9 += o; t = o << 28; t8 -= t;
  1768. o = (t9 >> 28); t10 += o; t = o << 28; t9 -= t;
  1769. o = (t10 >> 28); t11 += o; t = o << 28; t10 -= t;
  1770. o = (t11 >> 28); t12 += o; t = o << 28; t11 -= t;
  1771. o = (t12 >> 28); t13 += o; t = o << 28; t12 -= t;
  1772. o = (t13 >> 28); t14 += o; t = o << 28; t13 -= t;
  1773. o = (t14 >> 28); t15 += o; t = o << 28; t14 -= t;
  1774. o = (t15 >> 28); t0 += o;
  1775. t8 += o; t = o << 28; t15 -= t;
  1776. /* Store */
  1777. r[0] = (sword32)t0;
  1778. r[1] = (sword32)t1;
  1779. r[2] = (sword32)t2;
  1780. r[3] = (sword32)t3;
  1781. r[4] = (sword32)t4;
  1782. r[5] = (sword32)t5;
  1783. r[6] = (sword32)t6;
  1784. r[7] = (sword32)t7;
  1785. r[8] = (sword32)t8;
  1786. r[9] = (sword32)t9;
  1787. r[10] = (sword32)t10;
  1788. r[11] = (sword32)t11;
  1789. r[12] = (sword32)t12;
  1790. r[13] = (sword32)t13;
  1791. r[14] = (sword32)t14;
  1792. r[15] = (sword32)t15;
  1793. }
  1794. /* Multiply two field elements. r = (a * b) mod (2^448 - 2^224 - 1)
  1795. *
  1796. * r [in] Field element to hold result.
  1797. * a [in] Field element to multiply.
  1798. * b [in] Field element to multiply.
  1799. */
  1800. void fe448_mul(sword32* r, const sword32* a, const sword32* b)
  1801. {
  1802. sword32 r0[16];
  1803. sword32 r1[16];
  1804. sword32* a1 = r1;
  1805. sword32 b1[8];
  1806. sword32 r2[16];
  1807. a1[0] = a[0] + a[8];
  1808. a1[1] = a[1] + a[9];
  1809. a1[2] = a[2] + a[10];
  1810. a1[3] = a[3] + a[11];
  1811. a1[4] = a[4] + a[12];
  1812. a1[5] = a[5] + a[13];
  1813. a1[6] = a[6] + a[14];
  1814. a1[7] = a[7] + a[15];
  1815. b1[0] = b[0] + b[8];
  1816. b1[1] = b[1] + b[9];
  1817. b1[2] = b[2] + b[10];
  1818. b1[3] = b[3] + b[11];
  1819. b1[4] = b[4] + b[12];
  1820. b1[5] = b[5] + b[13];
  1821. b1[6] = b[6] + b[14];
  1822. b1[7] = b[7] + b[15];
  1823. fe448_mul_8(r2, a + 8, b + 8);
  1824. fe448_mul_8(r0, a, b);
  1825. fe448_mul_8(r1, a1, b1);
  1826. r[ 0] = r0[ 0] + r2[ 0] + r1[ 8] - r0[ 8];
  1827. r[ 1] = r0[ 1] + r2[ 1] + r1[ 9] - r0[ 9];
  1828. r[ 2] = r0[ 2] + r2[ 2] + r1[10] - r0[10];
  1829. r[ 3] = r0[ 3] + r2[ 3] + r1[11] - r0[11];
  1830. r[ 4] = r0[ 4] + r2[ 4] + r1[12] - r0[12];
  1831. r[ 5] = r0[ 5] + r2[ 5] + r1[13] - r0[13];
  1832. r[ 6] = r0[ 6] + r2[ 6] + r1[14] - r0[14];
  1833. r[ 7] = r0[ 7] + r2[ 7] + r1[15] - r0[15];
  1834. r[ 8] = r2[ 8] + r1[ 0] - r0[ 0] + r1[ 8];
  1835. r[ 9] = r2[ 9] + r1[ 1] - r0[ 1] + r1[ 9];
  1836. r[10] = r2[10] + r1[ 2] - r0[ 2] + r1[10];
  1837. r[11] = r2[11] + r1[ 3] - r0[ 3] + r1[11];
  1838. r[12] = r2[12] + r1[ 4] - r0[ 4] + r1[12];
  1839. r[13] = r2[13] + r1[ 5] - r0[ 5] + r1[13];
  1840. r[14] = r2[14] + r1[ 6] - r0[ 6] + r1[14];
  1841. r[15] = r2[15] + r1[ 7] - r0[ 7] + r1[15];
  1842. }
  1843. /* Square a field element. r = a * a
  1844. *
  1845. * r [in] Field element to hold result.
  1846. * a [in] Field element to square.
  1847. */
  1848. static WC_INLINE void fe448_sqr_8(sword32* r, const sword32* a)
  1849. {
  1850. sword64 o;
  1851. sword64 t15;
  1852. sword64 t;
  1853. sword64 t0 = (sword64)a[ 0] * a[ 0];
  1854. sword64 t1 = 2 * (sword64)a[ 0] * a[ 1];
  1855. sword64 t2 = 2 * (sword64)a[ 0] * a[ 2];
  1856. sword64 t102 = (sword64)a[ 1] * a[ 1];
  1857. sword64 t3 = 2 * (sword64)a[ 0] * a[ 3];
  1858. sword64 t103 = 2 * (sword64)a[ 1] * a[ 2];
  1859. sword64 t4 = 2 * (sword64)a[ 0] * a[ 4];
  1860. sword64 t104 = 2 * (sword64)a[ 1] * a[ 3];
  1861. sword64 t204 = (sword64)a[ 2] * a[ 2];
  1862. sword64 t5 = 2 * (sword64)a[ 0] * a[ 5];
  1863. sword64 t105 = 2 * (sword64)a[ 1] * a[ 4];
  1864. sword64 t205 = 2 * (sword64)a[ 2] * a[ 3];
  1865. sword64 t6 = 2 * (sword64)a[ 0] * a[ 6];
  1866. sword64 t106 = 2 * (sword64)a[ 1] * a[ 5];
  1867. sword64 t206 = 2 * (sword64)a[ 2] * a[ 4];
  1868. sword64 t306 = (sword64)a[ 3] * a[ 3];
  1869. sword64 t7 = 2 * (sword64)a[ 0] * a[ 7];
  1870. sword64 t107 = 2 * (sword64)a[ 1] * a[ 6];
  1871. sword64 t207 = 2 * (sword64)a[ 2] * a[ 5];
  1872. sword64 t307 = 2 * (sword64)a[ 3] * a[ 4];
  1873. sword64 t8 = 2 * (sword64)a[ 1] * a[ 7];
  1874. sword64 t108 = 2 * (sword64)a[ 2] * a[ 6];
  1875. sword64 t208 = 2 * (sword64)a[ 3] * a[ 5];
  1876. sword64 t308 = (sword64)a[ 4] * a[ 4];
  1877. sword64 t9 = 2 * (sword64)a[ 2] * a[ 7];
  1878. sword64 t109 = 2 * (sword64)a[ 3] * a[ 6];
  1879. sword64 t209 = 2 * (sword64)a[ 4] * a[ 5];
  1880. sword64 t10 = 2 * (sword64)a[ 3] * a[ 7];
  1881. sword64 t110 = 2 * (sword64)a[ 4] * a[ 6];
  1882. sword64 t210 = (sword64)a[ 5] * a[ 5];
  1883. sword64 t11 = 2 * (sword64)a[ 4] * a[ 7];
  1884. sword64 t111 = 2 * (sword64)a[ 5] * a[ 6];
  1885. sword64 t12 = 2 * (sword64)a[ 5] * a[ 7];
  1886. sword64 t112 = (sword64)a[ 6] * a[ 6];
  1887. sword64 t13 = 2 * (sword64)a[ 6] * a[ 7];
  1888. sword64 t14 = (sword64)a[ 7] * a[ 7];
  1889. t2 += t102;
  1890. t3 += t103;
  1891. t4 += t104; t4 += t204;
  1892. t5 += t105; t5 += t205;
  1893. t6 += t106; t6 += t206; t6 += t306;
  1894. t7 += t107; t7 += t207;
  1895. t8 += t108; t8 += t208; t8 += t308;
  1896. t9 += t109; t9 += t209;
  1897. t10 += t110; t10 += t210;
  1898. t11 += t111;
  1899. t12 += t112;
  1900. o = t14 >> 28;
  1901. t15 = o;
  1902. t14 -= o << 28;
  1903. o = (t0 >> 28); t1 += o; t = o << 28; t0 -= t;
  1904. o = (t1 >> 28); t2 += o; t = o << 28; t1 -= t;
  1905. o = (t2 >> 28); t3 += o; t = o << 28; t2 -= t;
  1906. o = (t3 >> 28); t4 += o; t = o << 28; t3 -= t;
  1907. o = (t4 >> 28); t5 += o; t = o << 28; t4 -= t;
  1908. o = (t5 >> 28); t6 += o; t = o << 28; t5 -= t;
  1909. o = (t6 >> 28); t7 += o; t = o << 28; t6 -= t;
  1910. o = (t307>> 28); t8 += o; t = o << 28; t307-= t; t7 += t307;
  1911. o = (t7 >> 28); t8 += o; t = o << 28; t7 -= t;
  1912. o = (t8 >> 28); t9 += o; t = o << 28; t8 -= t;
  1913. o = (t9 >> 28); t10 += o; t = o << 28; t9 -= t;
  1914. o = (t10 >> 28); t11 += o; t = o << 28; t10 -= t;
  1915. o = (t11 >> 28); t12 += o; t = o << 28; t11 -= t;
  1916. o = (t12 >> 28); t13 += o; t = o << 28; t12 -= t;
  1917. o = (t13 >> 28); t14 += o; t = o << 28; t13 -= t;
  1918. o = (t14 >> 28); t15 += o; t = o << 28; t14 -= t;
  1919. o = (t15 >> 28); t0 += o;
  1920. t8 += o; t = o << 28; t15 -= t;
  1921. /* Store */
  1922. r[0] = (sword32)t0;
  1923. r[1] = (sword32)t1;
  1924. r[2] = (sword32)t2;
  1925. r[3] = (sword32)t3;
  1926. r[4] = (sword32)t4;
  1927. r[5] = (sword32)t5;
  1928. r[6] = (sword32)t6;
  1929. r[7] = (sword32)t7;
  1930. r[8] = (sword32)t8;
  1931. r[9] = (sword32)t9;
  1932. r[10] = (sword32)t10;
  1933. r[11] = (sword32)t11;
  1934. r[12] = (sword32)t12;
  1935. r[13] = (sword32)t13;
  1936. r[14] = (sword32)t14;
  1937. r[15] = (sword32)t15;
  1938. }
  1939. /* Square a field element. r = (a * a) mod (2^448 - 2^224 - 1)
  1940. *
  1941. * r [in] Field element to hold result.
  1942. * a [in] Field element to square.
  1943. */
  1944. void fe448_sqr(sword32* r, const sword32* a)
  1945. {
  1946. sword32 r0[16];
  1947. sword32 r1[16];
  1948. sword32* a1 = r1;
  1949. sword32 r2[16];
  1950. a1[0] = a[0] + a[8];
  1951. a1[1] = a[1] + a[9];
  1952. a1[2] = a[2] + a[10];
  1953. a1[3] = a[3] + a[11];
  1954. a1[4] = a[4] + a[12];
  1955. a1[5] = a[5] + a[13];
  1956. a1[6] = a[6] + a[14];
  1957. a1[7] = a[7] + a[15];
  1958. fe448_sqr_8(r2, a + 8);
  1959. fe448_sqr_8(r0, a);
  1960. fe448_sqr_8(r1, a1);
  1961. r[ 0] = r0[ 0] + r2[ 0] + r1[ 8] - r0[ 8];
  1962. r[ 1] = r0[ 1] + r2[ 1] + r1[ 9] - r0[ 9];
  1963. r[ 2] = r0[ 2] + r2[ 2] + r1[10] - r0[10];
  1964. r[ 3] = r0[ 3] + r2[ 3] + r1[11] - r0[11];
  1965. r[ 4] = r0[ 4] + r2[ 4] + r1[12] - r0[12];
  1966. r[ 5] = r0[ 5] + r2[ 5] + r1[13] - r0[13];
  1967. r[ 6] = r0[ 6] + r2[ 6] + r1[14] - r0[14];
  1968. r[ 7] = r0[ 7] + r2[ 7] + r1[15] - r0[15];
  1969. r[ 8] = r2[ 8] + r1[ 0] - r0[ 0] + r1[ 8];
  1970. r[ 9] = r2[ 9] + r1[ 1] - r0[ 1] + r1[ 9];
  1971. r[10] = r2[10] + r1[ 2] - r0[ 2] + r1[10];
  1972. r[11] = r2[11] + r1[ 3] - r0[ 3] + r1[11];
  1973. r[12] = r2[12] + r1[ 4] - r0[ 4] + r1[12];
  1974. r[13] = r2[13] + r1[ 5] - r0[ 5] + r1[13];
  1975. r[14] = r2[14] + r1[ 6] - r0[ 6] + r1[14];
  1976. r[15] = r2[15] + r1[ 7] - r0[ 7] + r1[15];
  1977. }
  1978. /* Invert the field element. (r * a) mod (2^448 - 2^224 - 1) = 1
  1979. * Constant time implementation - using Fermat's little theorem:
  1980. * a^(p-1) mod p = 1 => a^(p-2) mod p = 1/a
  1981. * For curve448: p - 2 = 2^448 - 2^224 - 3
  1982. *
  1983. * r [in] Field element to hold result.
  1984. * a [in] Field element to invert.
  1985. */
  1986. void fe448_invert(sword32* r, const sword32* a)
  1987. {
  1988. sword32 t1[16];
  1989. sword32 t2[16];
  1990. sword32 t3[16];
  1991. sword32 t4[16];
  1992. int i;
  1993. fe448_sqr(t1, a);
  1994. /* t1 = 2 */
  1995. fe448_mul(t1, t1, a);
  1996. /* t1 = 3 */
  1997. fe448_sqr(t2, t1); for (i = 1; i < 2; ++i) fe448_sqr(t2, t2);
  1998. /* t2 = c */
  1999. fe448_mul(t3, t2, a);
  2000. /* t3 = d */
  2001. fe448_mul(t1, t2, t1);
  2002. /* t1 = f */
  2003. fe448_sqr(t2, t1);
  2004. /* t2 = 1e */
  2005. fe448_mul(t4, t2, a);
  2006. /* t4 = 1f */
  2007. fe448_sqr(t2, t4); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2);
  2008. /* t2 = 3e0 */
  2009. fe448_mul(t1, t2, t4);
  2010. /* t1 = 3ff */
  2011. fe448_sqr(t2, t1); for (i = 1; i < 10; ++i) fe448_sqr(t2, t2);
  2012. /* t2 = ffc00 */
  2013. fe448_mul(t1, t2, t1);
  2014. /* t1 = fffff */
  2015. fe448_sqr(t2, t1); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2);
  2016. /* t2 = 1ffffe0 */
  2017. fe448_mul(t1, t2, t4);
  2018. /* t1 = 1ffffff */
  2019. fe448_sqr(t2, t1); for (i = 1; i < 25; ++i) fe448_sqr(t2, t2);
  2020. /* t2 = 3fffffe000000 */
  2021. fe448_mul(t1, t2, t1);
  2022. /* t1 = 3ffffffffffff */
  2023. fe448_sqr(t2, t1); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2);
  2024. /* t2 = 7fffffffffffe0 */
  2025. fe448_mul(t1, t2, t4);
  2026. /* t1 = 7fffffffffffff */
  2027. fe448_sqr(t2, t1); for (i = 1; i < 55; ++i) fe448_sqr(t2, t2);
  2028. /* t2 = 3fffffffffffff80000000000000 */
  2029. fe448_mul(t1, t2, t1);
  2030. /* t1 = 3fffffffffffffffffffffffffff */
  2031. fe448_sqr(t2, t1); for (i = 1; i < 110; ++i) fe448_sqr(t2, t2);
  2032. /* t2 = fffffffffffffffffffffffffffc000000000000000000000000000 */
  2033. fe448_mul(t1, t2, t1);
  2034. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  2035. fe448_sqr(t2, t1); for (i = 1; i < 4; ++i) fe448_sqr(t2, t2);
  2036. /* t2 = fffffffffffffffffffffffffffffffffffffffffffffffffffffff0 */
  2037. fe448_mul(t3, t3, t2);
  2038. /* t3 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffd */
  2039. fe448_mul(t1, t3, a);
  2040. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe */
  2041. fe448_sqr(t1, t1); for (i = 1; i < 224; ++i) fe448_sqr(t1, t1);
  2042. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000000000000000000000000000000000000000000000000000 */
  2043. fe448_mul(r, t3, t1);
  2044. /* r = fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffd */
  2045. }
  2046. /* Scalar multiply the point by a number. r = n.a
  2047. * Uses Montgomery ladder and only requires the x-ordinate.
  2048. *
  2049. * r [in] Field element to hold result.
  2050. * n [in] Scalar as an array of bytes.
  2051. * a [in] Point to multiply - x-ordinate only.
  2052. */
  2053. int curve448(byte* r, const byte* n, const byte* a)
  2054. {
  2055. sword32 x1[16];
  2056. sword32 x2[16];
  2057. sword32 z2[16];
  2058. sword32 x3[16];
  2059. sword32 z3[16];
  2060. sword32 t0[16];
  2061. sword32 t1[16];
  2062. int i;
  2063. unsigned int swap;
  2064. fe448_from_bytes(x1, a);
  2065. fe448_1(x2);
  2066. fe448_0(z2);
  2067. fe448_copy(x3, x1);
  2068. fe448_1(z3);
  2069. swap = 0;
  2070. for (i = 447; i >= 0; --i) {
  2071. unsigned int b = (n[i >> 3] >> (i & 7)) & 1;
  2072. swap ^= b;
  2073. fe448_cswap(x2, x3, (int)swap);
  2074. fe448_cswap(z2, z3, (int)swap);
  2075. swap = b;
  2076. /* Montgomery Ladder - double and add */
  2077. fe448_add(t0, x2, z2);
  2078. fe448_reduce(t0);
  2079. fe448_add(t1, x3, z3);
  2080. fe448_reduce(t1);
  2081. fe448_sub(x2, x2, z2);
  2082. fe448_sub(x3, x3, z3);
  2083. fe448_mul(t1, t1, x2);
  2084. fe448_mul(z3, x3, t0);
  2085. fe448_sqr(t0, t0);
  2086. fe448_sqr(x2, x2);
  2087. fe448_add(x3, z3, t1);
  2088. fe448_reduce(x3);
  2089. fe448_sqr(x3, x3);
  2090. fe448_sub(z3, z3, t1);
  2091. fe448_sqr(z3, z3);
  2092. fe448_mul(z3, z3, x1);
  2093. fe448_sub(t1, t0, x2);
  2094. fe448_mul(x2, t0, x2);
  2095. fe448_mul39081(z2, t1);
  2096. fe448_add(z2, t0, z2);
  2097. fe448_mul(z2, z2, t1);
  2098. }
  2099. /* Last two bits are 0 - no final swap check required. */
  2100. fe448_invert(z2, z2);
  2101. fe448_mul(x2, x2, z2);
  2102. fe448_to_bytes(r, x2);
  2103. return 0;
  2104. }
  2105. #ifdef HAVE_ED448
  2106. /* Check whether field element is not 0.
  2107. * Must convert to a normalized form before checking.
  2108. *
  2109. * a [in] Field element.
  2110. * returns 0 when zero, and any other value otherwise.
  2111. */
  2112. int fe448_isnonzero(const sword32* a)
  2113. {
  2114. byte b[56];
  2115. int i;
  2116. byte c = 0;
  2117. fe448_to_bytes(b, a);
  2118. for (i = 0; i < 56; i++)
  2119. c |= b[i];
  2120. return c;
  2121. }
  2122. /* Check whether field element is negative.
  2123. * Must convert to a normalized form before checking.
  2124. *
  2125. * a [in] Field element.
  2126. * returns 1 when negative, and 0 otherwise.
  2127. */
  2128. int fe448_isnegative(const sword32* a)
  2129. {
  2130. byte b[56];
  2131. fe448_to_bytes(b, a);
  2132. return b[0] & 1;
  2133. }
  2134. /* Negates the field element. r = -a
  2135. *
  2136. * r [in] Field element to hold result.
  2137. * a [in] Field element.
  2138. */
  2139. void fe448_neg(sword32* r, const sword32* a)
  2140. {
  2141. r[0] = -a[0];
  2142. r[1] = -a[1];
  2143. r[2] = -a[2];
  2144. r[3] = -a[3];
  2145. r[4] = -a[4];
  2146. r[5] = -a[5];
  2147. r[6] = -a[6];
  2148. r[7] = -a[7];
  2149. r[8] = -a[8];
  2150. r[9] = -a[9];
  2151. r[10] = -a[10];
  2152. r[11] = -a[11];
  2153. r[12] = -a[12];
  2154. r[13] = -a[13];
  2155. r[14] = -a[14];
  2156. r[15] = -a[15];
  2157. }
  2158. /* Raise field element to (p-3) / 4: 2^446 - 2^222 - 1
  2159. * Used for calculating y-ordinate from x-ordinate for Ed448.
  2160. *
  2161. * r [in] Field element to hold result.
  2162. * a [in] Field element to exponentiate.
  2163. */
  2164. void fe448_pow_2_446_222_1(sword32* r, const sword32* a)
  2165. {
  2166. sword32 t1[16];
  2167. sword32 t2[16];
  2168. sword32 t3[16];
  2169. sword32 t4[16];
  2170. sword32 t5[16];
  2171. int i;
  2172. fe448_sqr(t3, a);
  2173. /* t3 = 2 */
  2174. fe448_mul(t1, t3, a);
  2175. /* t1 = 3 */
  2176. fe448_sqr(t5, t1);
  2177. /* t5 = 6 */
  2178. fe448_mul(t5, t5, a);
  2179. /* t5 = 7 */
  2180. fe448_sqr(t2, t1); for (i = 1; i < 2; ++i) fe448_sqr(t2, t2);
  2181. /* t2 = c */
  2182. fe448_mul(t3, t2, t3);
  2183. /* t3 = e */
  2184. fe448_mul(t1, t2, t1);
  2185. /* t1 = f */
  2186. fe448_sqr(t2, t1); for (i = 1; i < 3; ++i) fe448_sqr(t2, t2);
  2187. /* t2 = 78 */
  2188. fe448_mul(t5, t2, t5);
  2189. /* t5 = 7f */
  2190. fe448_sqr(t2, t1); for (i = 1; i < 4; ++i) fe448_sqr(t2, t2);
  2191. /* t2 = f0 */
  2192. fe448_mul(t1, t2, t1);
  2193. /* t1 = ff */
  2194. fe448_mul(t3, t3, t2);
  2195. /* t3 = fe */
  2196. fe448_sqr(t2, t1); for (i = 1; i < 7; ++i) fe448_sqr(t2, t2);
  2197. /* t2 = 7f80 */
  2198. fe448_mul(t5, t2, t5);
  2199. /* t5 = 7fff */
  2200. fe448_sqr(t2, t1); for (i = 1; i < 8; ++i) fe448_sqr(t2, t2);
  2201. /* t2 = ff00 */
  2202. fe448_mul(t1, t2, t1);
  2203. /* t1 = ffff */
  2204. fe448_mul(t3, t3, t2);
  2205. /* t3 = fffe */
  2206. fe448_sqr(t2, t5); for (i = 1; i < 15; ++i) fe448_sqr(t2, t2);
  2207. /* t2 = 3fff8000 */
  2208. fe448_mul(t5, t2, t5);
  2209. /* t5 = 3fffffff */
  2210. fe448_sqr(t2, t1); for (i = 1; i < 16; ++i) fe448_sqr(t2, t2);
  2211. /* t2 = ffff0000 */
  2212. fe448_mul(t1, t2, t1);
  2213. /* t1 = ffffffff */
  2214. fe448_mul(t3, t3, t2);
  2215. /* t3 = fffffffe */
  2216. fe448_sqr(t2, t1); for (i = 1; i < 32; ++i) fe448_sqr(t2, t2);
  2217. /* t2 = ffffffff00000000 */
  2218. fe448_mul(t2, t2, t1);
  2219. /* t2 = ffffffffffffffff */
  2220. fe448_sqr(t1, t2); for (i = 1; i < 64; ++i) fe448_sqr(t1, t1);
  2221. /* t1 = ffffffffffffffff0000000000000000 */
  2222. fe448_mul(t1, t1, t2);
  2223. /* t1 = ffffffffffffffffffffffffffffffff */
  2224. fe448_sqr(t1, t1); for (i = 1; i < 64; ++i) fe448_sqr(t1, t1);
  2225. /* t1 = ffffffffffffffffffffffffffffffff0000000000000000 */
  2226. fe448_mul(t4, t1, t2);
  2227. /* t4 = ffffffffffffffffffffffffffffffffffffffffffffffff */
  2228. fe448_sqr(t2, t4); for (i = 1; i < 32; ++i) fe448_sqr(t2, t2);
  2229. /* t2 = ffffffffffffffffffffffffffffffffffffffffffffffff00000000 */
  2230. fe448_mul(t3, t3, t2);
  2231. /* t3 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe */
  2232. fe448_sqr(t1, t3); for (i = 1; i < 192; ++i) fe448_sqr(t1, t1);
  2233. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000 */
  2234. fe448_mul(t1, t1, t4);
  2235. /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff */
  2236. fe448_sqr(t1, t1); for (i = 1; i < 30; ++i) fe448_sqr(t1, t1);
  2237. /* t1 = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffc0000000 */
  2238. fe448_mul(r, t5, t1);
  2239. /* r = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  2240. }
  2241. /* Constant time, conditional move of b into a.
  2242. * a is not changed if the condition is 0.
  2243. *
  2244. * a A field element.
  2245. * b A field element.
  2246. * c If 1 then copy and if 0 then don't copy.
  2247. */
  2248. void fe448_cmov(sword32* a, const sword32* b, int c)
  2249. {
  2250. sword32 m = -(sword32)c;
  2251. sword32 t0 = m & (a[0] ^ b[0]);
  2252. sword32 t1 = m & (a[1] ^ b[1]);
  2253. sword32 t2 = m & (a[2] ^ b[2]);
  2254. sword32 t3 = m & (a[3] ^ b[3]);
  2255. sword32 t4 = m & (a[4] ^ b[4]);
  2256. sword32 t5 = m & (a[5] ^ b[5]);
  2257. sword32 t6 = m & (a[6] ^ b[6]);
  2258. sword32 t7 = m & (a[7] ^ b[7]);
  2259. sword32 t8 = m & (a[8] ^ b[8]);
  2260. sword32 t9 = m & (a[9] ^ b[9]);
  2261. sword32 t10 = m & (a[10] ^ b[10]);
  2262. sword32 t11 = m & (a[11] ^ b[11]);
  2263. sword32 t12 = m & (a[12] ^ b[12]);
  2264. sword32 t13 = m & (a[13] ^ b[13]);
  2265. sword32 t14 = m & (a[14] ^ b[14]);
  2266. sword32 t15 = m & (a[15] ^ b[15]);
  2267. a[0] ^= t0;
  2268. a[1] ^= t1;
  2269. a[2] ^= t2;
  2270. a[3] ^= t3;
  2271. a[4] ^= t4;
  2272. a[5] ^= t5;
  2273. a[6] ^= t6;
  2274. a[7] ^= t7;
  2275. a[8] ^= t8;
  2276. a[9] ^= t9;
  2277. a[10] ^= t10;
  2278. a[11] ^= t11;
  2279. a[12] ^= t12;
  2280. a[13] ^= t13;
  2281. a[14] ^= t14;
  2282. a[15] ^= t15;
  2283. }
  2284. #endif /* HAVE_ED448 */
  2285. #endif
  2286. #endif /* HAVE_CURVE448 || HAVE_ED448 */