You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

868 rivejä
24 KiB

  1. /********************************************************************************************
  2. * SIDH: an efficient supersingular isogeny-based cryptography library for ephemeral
  3. * Diffie-Hellman key exchange.
  4. *
  5. * Copyright (c) Microsoft Corporation. All rights reserved.
  6. *
  7. *
  8. * Abstract: modular arithmetic optimized for x64 platforms
  9. *
  10. *********************************************************************************************/
  11. #include "P751_internal.h"
  12. // Global constants
  13. extern const uint64_t p751[NWORDS_FIELD];
  14. extern const uint64_t p751p1[NWORDS_FIELD];
  15. extern const uint64_t p751x2[NWORDS_FIELD];
  16. __inline void fpadd751(const digit_t *a, const digit_t *b, digit_t *c)
  17. { // Modular addition, c = a+b mod p751.
  18. // Inputs: a, b in [0, 2*p751-1]
  19. // Output: c in [0, 2*p751-1]
  20. #if (OS_TARGET == OS_WIN)
  21. unsigned int i, carry = 0;
  22. digit_t mask;
  23. for (i = 0; i < NWORDS_FIELD; i++)
  24. {
  25. ADDC(carry, a[i], b[i], carry, c[i]);
  26. }
  27. carry = 0;
  28. for (i = 0; i < NWORDS_FIELD; i++)
  29. {
  30. SUBC(carry, c[i], ((digit_t *)p751x2)[i], carry, c[i]);
  31. }
  32. mask = 0 - (digit_t)carry;
  33. carry = 0;
  34. for (i = 0; i < NWORDS_FIELD; i++)
  35. {
  36. ADDC(carry, c[i], ((digit_t *)p751x2)[i] & mask, carry, c[i]);
  37. }
  38. #elif (OS_TARGET == OS_LINUX)
  39. fpadd751_asm(a, b, c);
  40. #endif
  41. }
  42. __inline void fpsub751(const digit_t *a, const digit_t *b, digit_t *c)
  43. { // Modular subtraction, c = a-b mod p751.
  44. // Inputs: a, b in [0, 2*p751-1]
  45. // Output: c in [0, 2*p751-1]
  46. #if (OS_TARGET == OS_WIN)
  47. unsigned int i, borrow = 0;
  48. digit_t mask;
  49. for (i = 0; i < NWORDS_FIELD; i++)
  50. {
  51. SUBC(borrow, a[i], b[i], borrow, c[i]);
  52. }
  53. mask = 0 - (digit_t)borrow;
  54. borrow = 0;
  55. for (i = 0; i < NWORDS_FIELD; i++)
  56. {
  57. ADDC(borrow, c[i], ((digit_t *)p751x2)[i] & mask, borrow, c[i]);
  58. }
  59. #elif (OS_TARGET == OS_LINUX)
  60. fpsub751_asm(a, b, c);
  61. #endif
  62. }
  63. __inline void fpneg751(digit_t *a)
  64. { // Modular negation, a = -a mod p751.
  65. // Input/output: a in [0, 2*p751-1]
  66. unsigned int i, borrow = 0;
  67. for (i = 0; i < NWORDS_FIELD; i++)
  68. {
  69. SUBC(borrow, ((digit_t *)p751x2)[i], a[i], borrow, a[i]);
  70. }
  71. }
  72. void fpdiv2_751(const digit_t *a, digit_t *c)
  73. { // Modular division by two, c = a/2 mod p751.
  74. // Input : a in [0, 2*p751-1]
  75. // Output: c in [0, 2*p751-1]
  76. unsigned int i, carry = 0;
  77. digit_t mask;
  78. mask = 0 - (digit_t)(a[0] & 1); // If a is odd compute a+p751
  79. for (i = 0; i < NWORDS_FIELD; i++)
  80. {
  81. ADDC(carry, a[i], ((digit_t *)p751)[i] & mask, carry, c[i]);
  82. }
  83. mp_shiftr1(c, NWORDS_FIELD);
  84. }
  85. void fpcorrection751(digit_t *a)
  86. { // Modular correction to reduce field element a in [0, 2*p751-1] to [0, p751-1].
  87. unsigned int i, borrow = 0;
  88. digit_t mask;
  89. for (i = 0; i < NWORDS_FIELD; i++)
  90. {
  91. SUBC(borrow, a[i], ((digit_t *)p751)[i], borrow, a[i]);
  92. }
  93. mask = 0 - (digit_t)borrow;
  94. borrow = 0;
  95. for (i = 0; i < NWORDS_FIELD; i++)
  96. {
  97. ADDC(borrow, a[i], ((digit_t *)p751)[i] & mask, borrow, a[i]);
  98. }
  99. }
  100. void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords)
  101. { // Multiprecision multiply, c = a*b, where lng(a) = lng(b) = nwords.
  102. UNREFERENCED_PARAMETER(nwords);
  103. #if (OS_TARGET == OS_WIN)
  104. digit_t t = 0;
  105. uint128_t uv = {0};
  106. unsigned int carry = 0;
  107. MULADD128(a[0], b[0], uv, carry, uv);
  108. t += carry;
  109. c[0] = uv[0];
  110. uv[0] = uv[1];
  111. uv[1] = t;
  112. t = 0;
  113. MULADD128(a[0], b[1], uv, carry, uv);
  114. t += carry;
  115. MULADD128(a[1], b[0], uv, carry, uv);
  116. t += carry;
  117. c[1] = uv[0];
  118. uv[0] = uv[1];
  119. uv[1] = t;
  120. t = 0;
  121. MULADD128(a[0], b[2], uv, carry, uv);
  122. t += carry;
  123. MULADD128(a[1], b[1], uv, carry, uv);
  124. t += carry;
  125. MULADD128(a[2], b[0], uv, carry, uv);
  126. t += carry;
  127. c[2] = uv[0];
  128. uv[0] = uv[1];
  129. uv[1] = t;
  130. t = 0;
  131. MULADD128(a[0], b[3], uv, carry, uv);
  132. t += carry;
  133. MULADD128(a[2], b[1], uv, carry, uv);
  134. t += carry;
  135. MULADD128(a[1], b[2], uv, carry, uv);
  136. t += carry;
  137. MULADD128(a[3], b[0], uv, carry, uv);
  138. t += carry;
  139. c[3] = uv[0];
  140. uv[0] = uv[1];
  141. uv[1] = t;
  142. t = 0;
  143. MULADD128(a[0], b[4], uv, carry, uv);
  144. t += carry;
  145. MULADD128(a[3], b[1], uv, carry, uv);
  146. t += carry;
  147. MULADD128(a[2], b[2], uv, carry, uv);
  148. t += carry;
  149. MULADD128(a[1], b[3], uv, carry, uv);
  150. t += carry;
  151. MULADD128(a[4], b[0], uv, carry, uv);
  152. t += carry;
  153. c[4] = uv[0];
  154. uv[0] = uv[1];
  155. uv[1] = t;
  156. t = 0;
  157. MULADD128(a[0], b[5], uv, carry, uv);
  158. t += carry;
  159. MULADD128(a[4], b[1], uv, carry, uv);
  160. t += carry;
  161. MULADD128(a[3], b[2], uv, carry, uv);
  162. t += carry;
  163. MULADD128(a[2], b[3], uv, carry, uv);
  164. t += carry;
  165. MULADD128(a[1], b[4], uv, carry, uv);
  166. t += carry;
  167. MULADD128(a[5], b[0], uv, carry, uv);
  168. t += carry;
  169. c[5] = uv[0];
  170. uv[0] = uv[1];
  171. uv[1] = t;
  172. t = 0;
  173. MULADD128(a[0], b[6], uv, carry, uv);
  174. t += carry;
  175. MULADD128(a[5], b[1], uv, carry, uv);
  176. t += carry;
  177. MULADD128(a[4], b[2], uv, carry, uv);
  178. t += carry;
  179. MULADD128(a[3], b[3], uv, carry, uv);
  180. t += carry;
  181. MULADD128(a[2], b[4], uv, carry, uv);
  182. t += carry;
  183. MULADD128(a[1], b[5], uv, carry, uv);
  184. t += carry;
  185. MULADD128(a[6], b[0], uv, carry, uv);
  186. t += carry;
  187. c[6] = uv[0];
  188. uv[0] = uv[1];
  189. uv[1] = t;
  190. t = 0;
  191. MULADD128(a[0], b[7], uv, carry, uv);
  192. t += carry;
  193. MULADD128(a[6], b[1], uv, carry, uv);
  194. t += carry;
  195. MULADD128(a[5], b[2], uv, carry, uv);
  196. t += carry;
  197. MULADD128(a[4], b[3], uv, carry, uv);
  198. t += carry;
  199. MULADD128(a[3], b[4], uv, carry, uv);
  200. t += carry;
  201. MULADD128(a[2], b[5], uv, carry, uv);
  202. t += carry;
  203. MULADD128(a[1], b[6], uv, carry, uv);
  204. t += carry;
  205. MULADD128(a[7], b[0], uv, carry, uv);
  206. t += carry;
  207. c[7] = uv[0];
  208. uv[0] = uv[1];
  209. uv[1] = t;
  210. t = 0;
  211. MULADD128(a[0], b[8], uv, carry, uv);
  212. t += carry;
  213. MULADD128(a[7], b[1], uv, carry, uv);
  214. t += carry;
  215. MULADD128(a[6], b[2], uv, carry, uv);
  216. t += carry;
  217. MULADD128(a[5], b[3], uv, carry, uv);
  218. t += carry;
  219. MULADD128(a[4], b[4], uv, carry, uv);
  220. t += carry;
  221. MULADD128(a[3], b[5], uv, carry, uv);
  222. t += carry;
  223. MULADD128(a[2], b[6], uv, carry, uv);
  224. t += carry;
  225. MULADD128(a[1], b[7], uv, carry, uv);
  226. t += carry;
  227. MULADD128(a[8], b[0], uv, carry, uv);
  228. t += carry;
  229. c[8] = uv[0];
  230. uv[0] = uv[1];
  231. uv[1] = t;
  232. t = 0;
  233. MULADD128(a[0], b[9], uv, carry, uv);
  234. t += carry;
  235. MULADD128(a[8], b[1], uv, carry, uv);
  236. t += carry;
  237. MULADD128(a[7], b[2], uv, carry, uv);
  238. t += carry;
  239. MULADD128(a[6], b[3], uv, carry, uv);
  240. t += carry;
  241. MULADD128(a[5], b[4], uv, carry, uv);
  242. t += carry;
  243. MULADD128(a[4], b[5], uv, carry, uv);
  244. t += carry;
  245. MULADD128(a[3], b[6], uv, carry, uv);
  246. t += carry;
  247. MULADD128(a[2], b[7], uv, carry, uv);
  248. t += carry;
  249. MULADD128(a[1], b[8], uv, carry, uv);
  250. t += carry;
  251. MULADD128(a[9], b[0], uv, carry, uv);
  252. t += carry;
  253. c[9] = uv[0];
  254. uv[0] = uv[1];
  255. uv[1] = t;
  256. t = 0;
  257. MULADD128(a[0], b[10], uv, carry, uv);
  258. t += carry;
  259. MULADD128(a[9], b[1], uv, carry, uv);
  260. t += carry;
  261. MULADD128(a[8], b[2], uv, carry, uv);
  262. t += carry;
  263. MULADD128(a[7], b[3], uv, carry, uv);
  264. t += carry;
  265. MULADD128(a[6], b[4], uv, carry, uv);
  266. t += carry;
  267. MULADD128(a[5], b[5], uv, carry, uv);
  268. t += carry;
  269. MULADD128(a[4], b[6], uv, carry, uv);
  270. t += carry;
  271. MULADD128(a[3], b[7], uv, carry, uv);
  272. t += carry;
  273. MULADD128(a[2], b[8], uv, carry, uv);
  274. t += carry;
  275. MULADD128(a[1], b[9], uv, carry, uv);
  276. t += carry;
  277. MULADD128(a[10], b[0], uv, carry, uv);
  278. t += carry;
  279. c[10] = uv[0];
  280. uv[0] = uv[1];
  281. uv[1] = t;
  282. t = 0;
  283. MULADD128(a[0], b[11], uv, carry, uv);
  284. t += carry;
  285. MULADD128(a[10], b[1], uv, carry, uv);
  286. t += carry;
  287. MULADD128(a[9], b[2], uv, carry, uv);
  288. t += carry;
  289. MULADD128(a[8], b[3], uv, carry, uv);
  290. t += carry;
  291. MULADD128(a[7], b[4], uv, carry, uv);
  292. t += carry;
  293. MULADD128(a[6], b[5], uv, carry, uv);
  294. t += carry;
  295. MULADD128(a[5], b[6], uv, carry, uv);
  296. t += carry;
  297. MULADD128(a[4], b[7], uv, carry, uv);
  298. t += carry;
  299. MULADD128(a[3], b[8], uv, carry, uv);
  300. t += carry;
  301. MULADD128(a[2], b[9], uv, carry, uv);
  302. t += carry;
  303. MULADD128(a[1], b[10], uv, carry, uv);
  304. t += carry;
  305. MULADD128(a[11], b[0], uv, carry, uv);
  306. t += carry;
  307. c[11] = uv[0];
  308. uv[0] = uv[1];
  309. uv[1] = t;
  310. t = 0;
  311. MULADD128(a[1], b[11], uv, carry, uv);
  312. t += carry;
  313. MULADD128(a[10], b[2], uv, carry, uv);
  314. t += carry;
  315. MULADD128(a[9], b[3], uv, carry, uv);
  316. t += carry;
  317. MULADD128(a[8], b[4], uv, carry, uv);
  318. t += carry;
  319. MULADD128(a[7], b[5], uv, carry, uv);
  320. t += carry;
  321. MULADD128(a[6], b[6], uv, carry, uv);
  322. t += carry;
  323. MULADD128(a[5], b[7], uv, carry, uv);
  324. t += carry;
  325. MULADD128(a[4], b[8], uv, carry, uv);
  326. t += carry;
  327. MULADD128(a[3], b[9], uv, carry, uv);
  328. t += carry;
  329. MULADD128(a[2], b[10], uv, carry, uv);
  330. t += carry;
  331. MULADD128(a[11], b[1], uv, carry, uv);
  332. t += carry;
  333. c[12] = uv[0];
  334. uv[0] = uv[1];
  335. uv[1] = t;
  336. t = 0;
  337. MULADD128(a[11], b[2], uv, carry, uv);
  338. t += carry;
  339. MULADD128(a[10], b[3], uv, carry, uv);
  340. t += carry;
  341. MULADD128(a[9], b[4], uv, carry, uv);
  342. t += carry;
  343. MULADD128(a[8], b[5], uv, carry, uv);
  344. t += carry;
  345. MULADD128(a[7], b[6], uv, carry, uv);
  346. t += carry;
  347. MULADD128(a[6], b[7], uv, carry, uv);
  348. t += carry;
  349. MULADD128(a[5], b[8], uv, carry, uv);
  350. t += carry;
  351. MULADD128(a[4], b[9], uv, carry, uv);
  352. t += carry;
  353. MULADD128(a[3], b[10], uv, carry, uv);
  354. t += carry;
  355. MULADD128(a[2], b[11], uv, carry, uv);
  356. t += carry;
  357. c[13] = uv[0];
  358. uv[0] = uv[1];
  359. uv[1] = t;
  360. t = 0;
  361. MULADD128(a[11], b[3], uv, carry, uv);
  362. t += carry;
  363. MULADD128(a[10], b[4], uv, carry, uv);
  364. t += carry;
  365. MULADD128(a[9], b[5], uv, carry, uv);
  366. t += carry;
  367. MULADD128(a[8], b[6], uv, carry, uv);
  368. t += carry;
  369. MULADD128(a[7], b[7], uv, carry, uv);
  370. t += carry;
  371. MULADD128(a[6], b[8], uv, carry, uv);
  372. t += carry;
  373. MULADD128(a[5], b[9], uv, carry, uv);
  374. t += carry;
  375. MULADD128(a[4], b[10], uv, carry, uv);
  376. t += carry;
  377. MULADD128(a[3], b[11], uv, carry, uv);
  378. t += carry;
  379. c[14] = uv[0];
  380. uv[0] = uv[1];
  381. uv[1] = t;
  382. t = 0;
  383. MULADD128(a[11], b[4], uv, carry, uv);
  384. t += carry;
  385. MULADD128(a[10], b[5], uv, carry, uv);
  386. t += carry;
  387. MULADD128(a[9], b[6], uv, carry, uv);
  388. t += carry;
  389. MULADD128(a[8], b[7], uv, carry, uv);
  390. t += carry;
  391. MULADD128(a[7], b[8], uv, carry, uv);
  392. t += carry;
  393. MULADD128(a[6], b[9], uv, carry, uv);
  394. t += carry;
  395. MULADD128(a[5], b[10], uv, carry, uv);
  396. t += carry;
  397. MULADD128(a[4], b[11], uv, carry, uv);
  398. t += carry;
  399. c[15] = uv[0];
  400. uv[0] = uv[1];
  401. uv[1] = t;
  402. t = 0;
  403. MULADD128(a[11], b[5], uv, carry, uv);
  404. t += carry;
  405. MULADD128(a[10], b[6], uv, carry, uv);
  406. t += carry;
  407. MULADD128(a[9], b[7], uv, carry, uv);
  408. t += carry;
  409. MULADD128(a[8], b[8], uv, carry, uv);
  410. t += carry;
  411. MULADD128(a[7], b[9], uv, carry, uv);
  412. t += carry;
  413. MULADD128(a[6], b[10], uv, carry, uv);
  414. t += carry;
  415. MULADD128(a[5], b[11], uv, carry, uv);
  416. t += carry;
  417. c[16] = uv[0];
  418. uv[0] = uv[1];
  419. uv[1] = t;
  420. t = 0;
  421. MULADD128(a[11], b[6], uv, carry, uv);
  422. t += carry;
  423. MULADD128(a[10], b[7], uv, carry, uv);
  424. t += carry;
  425. MULADD128(a[9], b[8], uv, carry, uv);
  426. t += carry;
  427. MULADD128(a[8], b[9], uv, carry, uv);
  428. t += carry;
  429. MULADD128(a[7], b[10], uv, carry, uv);
  430. t += carry;
  431. MULADD128(a[6], b[11], uv, carry, uv);
  432. t += carry;
  433. c[17] = uv[0];
  434. uv[0] = uv[1];
  435. uv[1] = t;
  436. t = 0;
  437. MULADD128(a[11], b[7], uv, carry, uv);
  438. t += carry;
  439. MULADD128(a[10], b[8], uv, carry, uv);
  440. t += carry;
  441. MULADD128(a[9], b[9], uv, carry, uv);
  442. t += carry;
  443. MULADD128(a[8], b[10], uv, carry, uv);
  444. t += carry;
  445. MULADD128(a[7], b[11], uv, carry, uv);
  446. t += carry;
  447. c[18] = uv[0];
  448. uv[0] = uv[1];
  449. uv[1] = t;
  450. t = 0;
  451. MULADD128(a[11], b[8], uv, carry, uv);
  452. t += carry;
  453. MULADD128(a[10], b[9], uv, carry, uv);
  454. t += carry;
  455. MULADD128(a[9], b[10], uv, carry, uv);
  456. t += carry;
  457. MULADD128(a[8], b[11], uv, carry, uv);
  458. t += carry;
  459. c[19] = uv[0];
  460. uv[0] = uv[1];
  461. uv[1] = t;
  462. t = 0;
  463. MULADD128(a[11], b[9], uv, carry, uv);
  464. t += carry;
  465. MULADD128(a[10], b[10], uv, carry, uv);
  466. t += carry;
  467. MULADD128(a[9], b[11], uv, carry, uv);
  468. t += carry;
  469. c[20] = uv[0];
  470. uv[0] = uv[1];
  471. uv[1] = t;
  472. t = 0;
  473. MULADD128(a[11], b[10], uv, carry, uv);
  474. t += carry;
  475. MULADD128(a[10], b[11], uv, carry, uv);
  476. t += carry;
  477. c[21] = uv[0];
  478. uv[0] = uv[1];
  479. uv[1] = t;
  480. MULADD128(a[11], b[11], uv, carry, uv);
  481. c[22] = uv[0];
  482. c[23] = uv[1];
  483. #elif (OS_TARGET == OS_LINUX)
  484. mul751_asm(a, b, c);
  485. #endif
  486. }
  487. void rdc_mont(const dfelm_t ma, felm_t mc)
  488. { // Efficient Montgomery reduction using comba and exploiting the special form of the prime p751.
  489. // mc = ma*R^-1 mod p751x2, where R = 2^768.
  490. // If ma < 2^768*p751, the output mc is in the range [0, 2*p751-1].
  491. // ma is assumed to be in Montgomery representation.
  492. #if (OS_TARGET == OS_WIN)
  493. unsigned int carry;
  494. digit_t t = 0;
  495. uint128_t uv = {0};
  496. mc[0] = ma[0];
  497. mc[1] = ma[1];
  498. mc[2] = ma[2];
  499. mc[3] = ma[3];
  500. mc[4] = ma[4];
  501. MUL128(mc[0], ((digit_t *)p751p1)[5], uv);
  502. ADDC(0, uv[0], ma[5], carry, uv[0]);
  503. ADDC(carry, uv[1], 0, carry, uv[1]);
  504. mc[5] = uv[0];
  505. uv[0] = uv[1];
  506. uv[1] = 0;
  507. MULADD128(mc[0], ((digit_t *)p751p1)[6], uv, carry, uv);
  508. MULADD128(mc[1], ((digit_t *)p751p1)[5], uv, carry, uv);
  509. t += carry;
  510. ADDC(0, uv[0], ma[6], carry, uv[0]);
  511. ADDC(carry, uv[1], 0, carry, uv[1]);
  512. t += carry;
  513. mc[6] = uv[0];
  514. uv[0] = uv[1];
  515. uv[1] = t;
  516. t = 0;
  517. MULADD128(mc[0], ((digit_t *)p751p1)[7], uv, carry, uv);
  518. t += carry;
  519. MULADD128(mc[1], ((digit_t *)p751p1)[6], uv, carry, uv);
  520. t += carry;
  521. MULADD128(mc[2], ((digit_t *)p751p1)[5], uv, carry, uv);
  522. t += carry;
  523. ADDC(0, uv[0], ma[7], carry, uv[0]);
  524. ADDC(carry, uv[1], 0, carry, uv[1]);
  525. t += carry;
  526. mc[7] = uv[0];
  527. uv[0] = uv[1];
  528. uv[1] = t;
  529. t = 0;
  530. MULADD128(mc[0], ((digit_t *)p751p1)[8], uv, carry, uv);
  531. t += carry;
  532. MULADD128(mc[1], ((digit_t *)p751p1)[7], uv, carry, uv);
  533. t += carry;
  534. MULADD128(mc[2], ((digit_t *)p751p1)[6], uv, carry, uv);
  535. t += carry;
  536. MULADD128(mc[3], ((digit_t *)p751p1)[5], uv, carry, uv);
  537. t += carry;
  538. ADDC(0, uv[0], ma[8], carry, uv[0]);
  539. ADDC(carry, uv[1], 0, carry, uv[1]);
  540. t += carry;
  541. mc[8] = uv[0];
  542. uv[0] = uv[1];
  543. uv[1] = t;
  544. t = 0;
  545. MULADD128(mc[0], ((digit_t *)p751p1)[9], uv, carry, uv);
  546. t += carry;
  547. MULADD128(mc[1], ((digit_t *)p751p1)[8], uv, carry, uv);
  548. t += carry;
  549. MULADD128(mc[2], ((digit_t *)p751p1)[7], uv, carry, uv);
  550. t += carry;
  551. MULADD128(mc[3], ((digit_t *)p751p1)[6], uv, carry, uv);
  552. t += carry;
  553. MULADD128(mc[4], ((digit_t *)p751p1)[5], uv, carry, uv);
  554. t += carry;
  555. ADDC(0, uv[0], ma[9], carry, uv[0]);
  556. ADDC(carry, uv[1], 0, carry, uv[1]);
  557. t += carry;
  558. mc[9] = uv[0];
  559. uv[0] = uv[1];
  560. uv[1] = t;
  561. t = 0;
  562. MULADD128(mc[0], ((digit_t *)p751p1)[10], uv, carry, uv);
  563. t += carry;
  564. MULADD128(mc[1], ((digit_t *)p751p1)[9], uv, carry, uv);
  565. t += carry;
  566. MULADD128(mc[2], ((digit_t *)p751p1)[8], uv, carry, uv);
  567. t += carry;
  568. MULADD128(mc[3], ((digit_t *)p751p1)[7], uv, carry, uv);
  569. t += carry;
  570. MULADD128(mc[4], ((digit_t *)p751p1)[6], uv, carry, uv);
  571. t += carry;
  572. MULADD128(mc[5], ((digit_t *)p751p1)[5], uv, carry, uv);
  573. t += carry;
  574. ADDC(0, uv[0], ma[10], carry, uv[0]);
  575. ADDC(carry, uv[1], 0, carry, uv[1]);
  576. t += carry;
  577. mc[10] = uv[0];
  578. uv[0] = uv[1];
  579. uv[1] = t;
  580. t = 0;
  581. MULADD128(mc[0], ((digit_t *)p751p1)[11], uv, carry, uv);
  582. t += carry;
  583. MULADD128(mc[1], ((digit_t *)p751p1)[10], uv, carry, uv);
  584. t += carry;
  585. MULADD128(mc[2], ((digit_t *)p751p1)[9], uv, carry, uv);
  586. t += carry;
  587. MULADD128(mc[3], ((digit_t *)p751p1)[8], uv, carry, uv);
  588. t += carry;
  589. MULADD128(mc[4], ((digit_t *)p751p1)[7], uv, carry, uv);
  590. t += carry;
  591. MULADD128(mc[5], ((digit_t *)p751p1)[6], uv, carry, uv);
  592. t += carry;
  593. MULADD128(mc[6], ((digit_t *)p751p1)[5], uv, carry, uv);
  594. t += carry;
  595. ADDC(0, uv[0], ma[11], carry, uv[0]);
  596. ADDC(carry, uv[1], 0, carry, uv[1]);
  597. t += carry;
  598. mc[11] = uv[0];
  599. uv[0] = uv[1];
  600. uv[1] = t;
  601. t = 0;
  602. MULADD128(mc[1], ((digit_t *)p751p1)[11], uv, carry, uv);
  603. t += carry;
  604. MULADD128(mc[2], ((digit_t *)p751p1)[10], uv, carry, uv);
  605. t += carry;
  606. MULADD128(mc[3], ((digit_t *)p751p1)[9], uv, carry, uv);
  607. t += carry;
  608. MULADD128(mc[4], ((digit_t *)p751p1)[8], uv, carry, uv);
  609. t += carry;
  610. MULADD128(mc[5], ((digit_t *)p751p1)[7], uv, carry, uv);
  611. t += carry;
  612. MULADD128(mc[6], ((digit_t *)p751p1)[6], uv, carry, uv);
  613. t += carry;
  614. MULADD128(mc[7], ((digit_t *)p751p1)[5], uv, carry, uv);
  615. t += carry;
  616. ADDC(0, uv[0], ma[12], carry, uv[0]);
  617. ADDC(carry, uv[1], 0, carry, uv[1]);
  618. t += carry;
  619. mc[0] = uv[0];
  620. uv[0] = uv[1];
  621. uv[1] = t;
  622. t = 0;
  623. MULADD128(mc[2], ((digit_t *)p751p1)[11], uv, carry, uv);
  624. t += carry;
  625. MULADD128(mc[3], ((digit_t *)p751p1)[10], uv, carry, uv);
  626. t += carry;
  627. MULADD128(mc[4], ((digit_t *)p751p1)[9], uv, carry, uv);
  628. t += carry;
  629. MULADD128(mc[5], ((digit_t *)p751p1)[8], uv, carry, uv);
  630. t += carry;
  631. MULADD128(mc[6], ((digit_t *)p751p1)[7], uv, carry, uv);
  632. t += carry;
  633. MULADD128(mc[7], ((digit_t *)p751p1)[6], uv, carry, uv);
  634. t += carry;
  635. MULADD128(mc[8], ((digit_t *)p751p1)[5], uv, carry, uv);
  636. t += carry;
  637. ADDC(0, uv[0], ma[13], carry, uv[0]);
  638. ADDC(carry, uv[1], 0, carry, uv[1]);
  639. t += carry;
  640. mc[1] = uv[0];
  641. uv[0] = uv[1];
  642. uv[1] = t;
  643. t = 0;
  644. MULADD128(mc[3], ((digit_t *)p751p1)[11], uv, carry, uv);
  645. t += carry;
  646. MULADD128(mc[4], ((digit_t *)p751p1)[10], uv, carry, uv);
  647. t += carry;
  648. MULADD128(mc[5], ((digit_t *)p751p1)[9], uv, carry, uv);
  649. t += carry;
  650. MULADD128(mc[6], ((digit_t *)p751p1)[8], uv, carry, uv);
  651. t += carry;
  652. MULADD128(mc[7], ((digit_t *)p751p1)[7], uv, carry, uv);
  653. t += carry;
  654. MULADD128(mc[8], ((digit_t *)p751p1)[6], uv, carry, uv);
  655. t += carry;
  656. MULADD128(mc[9], ((digit_t *)p751p1)[5], uv, carry, uv);
  657. t += carry;
  658. ADDC(0, uv[0], ma[14], carry, uv[0]);
  659. ADDC(carry, uv[1], 0, carry, uv[1]);
  660. t += carry;
  661. mc[2] = uv[0];
  662. uv[0] = uv[1];
  663. uv[1] = t;
  664. t = 0;
  665. MULADD128(mc[4], ((digit_t *)p751p1)[11], uv, carry, uv);
  666. t += carry;
  667. MULADD128(mc[5], ((digit_t *)p751p1)[10], uv, carry, uv);
  668. t += carry;
  669. MULADD128(mc[6], ((digit_t *)p751p1)[9], uv, carry, uv);
  670. t += carry;
  671. MULADD128(mc[7], ((digit_t *)p751p1)[8], uv, carry, uv);
  672. t += carry;
  673. MULADD128(mc[8], ((digit_t *)p751p1)[7], uv, carry, uv);
  674. t += carry;
  675. MULADD128(mc[9], ((digit_t *)p751p1)[6], uv, carry, uv);
  676. t += carry;
  677. MULADD128(mc[10], ((digit_t *)p751p1)[5], uv, carry, uv);
  678. t += carry;
  679. ADDC(0, uv[0], ma[15], carry, uv[0]);
  680. ADDC(carry, uv[1], 0, carry, uv[1]);
  681. t += carry;
  682. mc[3] = uv[0];
  683. uv[0] = uv[1];
  684. uv[1] = t;
  685. t = 0;
  686. MULADD128(mc[5], ((digit_t *)p751p1)[11], uv, carry, uv);
  687. t += carry;
  688. MULADD128(mc[6], ((digit_t *)p751p1)[10], uv, carry, uv);
  689. t += carry;
  690. MULADD128(mc[7], ((digit_t *)p751p1)[9], uv, carry, uv);
  691. t += carry;
  692. MULADD128(mc[8], ((digit_t *)p751p1)[8], uv, carry, uv);
  693. t += carry;
  694. MULADD128(mc[9], ((digit_t *)p751p1)[7], uv, carry, uv);
  695. t += carry;
  696. MULADD128(mc[10], ((digit_t *)p751p1)[6], uv, carry, uv);
  697. t += carry;
  698. MULADD128(mc[11], ((digit_t *)p751p1)[5], uv, carry, uv);
  699. t += carry;
  700. ADDC(0, uv[0], ma[16], carry, uv[0]);
  701. ADDC(carry, uv[1], 0, carry, uv[1]);
  702. t += carry;
  703. mc[4] = uv[0];
  704. uv[0] = uv[1];
  705. uv[1] = t;
  706. t = 0;
  707. MULADD128(mc[6], ((digit_t *)p751p1)[11], uv, carry, uv);
  708. t += carry;
  709. MULADD128(mc[7], ((digit_t *)p751p1)[10], uv, carry, uv);
  710. t += carry;
  711. MULADD128(mc[8], ((digit_t *)p751p1)[9], uv, carry, uv);
  712. t += carry;
  713. MULADD128(mc[9], ((digit_t *)p751p1)[8], uv, carry, uv);
  714. t += carry;
  715. MULADD128(mc[10], ((digit_t *)p751p1)[7], uv, carry, uv);
  716. t += carry;
  717. MULADD128(mc[11], ((digit_t *)p751p1)[6], uv, carry, uv);
  718. t += carry;
  719. ADDC(0, uv[0], ma[17], carry, uv[0]);
  720. ADDC(carry, uv[1], 0, carry, uv[1]);
  721. t += carry;
  722. mc[5] = uv[0];
  723. uv[0] = uv[1];
  724. uv[1] = t;
  725. t = 0;
  726. MULADD128(mc[7], ((digit_t *)p751p1)[11], uv, carry, uv);
  727. t += carry;
  728. MULADD128(mc[8], ((digit_t *)p751p1)[10], uv, carry, uv);
  729. t += carry;
  730. MULADD128(mc[9], ((digit_t *)p751p1)[9], uv, carry, uv);
  731. t += carry;
  732. MULADD128(mc[10], ((digit_t *)p751p1)[8], uv, carry, uv);
  733. t += carry;
  734. MULADD128(mc[11], ((digit_t *)p751p1)[7], uv, carry, uv);
  735. t += carry;
  736. ADDC(0, uv[0], ma[18], carry, uv[0]);
  737. ADDC(carry, uv[1], 0, carry, uv[1]);
  738. t += carry;
  739. mc[6] = uv[0];
  740. uv[0] = uv[1];
  741. uv[1] = t;
  742. t = 0;
  743. MULADD128(mc[8], ((digit_t *)p751p1)[11], uv, carry, uv);
  744. t += carry;
  745. MULADD128(mc[9], ((digit_t *)p751p1)[10], uv, carry, uv);
  746. t += carry;
  747. MULADD128(mc[10], ((digit_t *)p751p1)[9], uv, carry, uv);
  748. t += carry;
  749. MULADD128(mc[11], ((digit_t *)p751p1)[8], uv, carry, uv);
  750. t += carry;
  751. ADDC(0, uv[0], ma[19], carry, uv[0]);
  752. ADDC(carry, uv[1], 0, carry, uv[1]);
  753. t += carry;
  754. mc[7] = uv[0];
  755. uv[0] = uv[1];
  756. uv[1] = t;
  757. t = 0;
  758. MULADD128(mc[9], ((digit_t *)p751p1)[11], uv, carry, uv);
  759. t += carry;
  760. MULADD128(mc[10], ((digit_t *)p751p1)[10], uv, carry, uv);
  761. t += carry;
  762. MULADD128(mc[11], ((digit_t *)p751p1)[9], uv, carry, uv);
  763. t += carry;
  764. ADDC(0, uv[0], ma[20], carry, uv[0]);
  765. ADDC(carry, uv[1], 0, carry, uv[1]);
  766. t += carry;
  767. mc[8] = uv[0];
  768. uv[0] = uv[1];
  769. uv[1] = t;
  770. t = 0;
  771. MULADD128(mc[10], ((digit_t *)p751p1)[11], uv, carry, uv);
  772. t += carry;
  773. MULADD128(mc[11], ((digit_t *)p751p1)[10], uv, carry, uv);
  774. t += carry;
  775. ADDC(0, uv[0], ma[21], carry, uv[0]);
  776. ADDC(carry, uv[1], 0, carry, uv[1]);
  777. t += carry;
  778. mc[9] = uv[0];
  779. uv[0] = uv[1];
  780. uv[1] = t;
  781. t = 0;
  782. MULADD128(mc[11], ((digit_t *)p751p1)[11], uv, carry, uv);
  783. t += carry;
  784. ADDC(0, uv[0], ma[22], carry, mc[10]);
  785. ADDC(carry, uv[1], 0, carry, uv[1]);
  786. ADDC(0, uv[1], ma[23], carry, mc[11]);
  787. #elif (OS_TARGET == OS_LINUX)
  788. rdc751_asm(ma, mc);
  789. #endif
  790. }