Nat256.cs 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using System.Diagnostics;
  4. using Org.BouncyCastle.Crypto.Utilities;
  5. namespace Org.BouncyCastle.Math.Raw
  6. {
  7. internal abstract class Nat256
  8. {
  9. private const ulong M = 0xFFFFFFFFUL;
  10. public static uint Add(uint[] x, uint[] y, uint[] z)
  11. {
  12. ulong c = 0;
  13. c += (ulong)x[0] + y[0];
  14. z[0] = (uint)c;
  15. c >>= 32;
  16. c += (ulong)x[1] + y[1];
  17. z[1] = (uint)c;
  18. c >>= 32;
  19. c += (ulong)x[2] + y[2];
  20. z[2] = (uint)c;
  21. c >>= 32;
  22. c += (ulong)x[3] + y[3];
  23. z[3] = (uint)c;
  24. c >>= 32;
  25. c += (ulong)x[4] + y[4];
  26. z[4] = (uint)c;
  27. c >>= 32;
  28. c += (ulong)x[5] + y[5];
  29. z[5] = (uint)c;
  30. c >>= 32;
  31. c += (ulong)x[6] + y[6];
  32. z[6] = (uint)c;
  33. c >>= 32;
  34. c += (ulong)x[7] + y[7];
  35. z[7] = (uint)c;
  36. c >>= 32;
  37. return (uint)c;
  38. }
  39. public static uint Add(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
  40. {
  41. ulong c = 0;
  42. c += (ulong)x[xOff + 0] + y[yOff + 0];
  43. z[zOff + 0] = (uint)c;
  44. c >>= 32;
  45. c += (ulong)x[xOff + 1] + y[yOff + 1];
  46. z[zOff + 1] = (uint)c;
  47. c >>= 32;
  48. c += (ulong)x[xOff + 2] + y[yOff + 2];
  49. z[zOff + 2] = (uint)c;
  50. c >>= 32;
  51. c += (ulong)x[xOff + 3] + y[yOff + 3];
  52. z[zOff + 3] = (uint)c;
  53. c >>= 32;
  54. c += (ulong)x[xOff + 4] + y[yOff + 4];
  55. z[zOff + 4] = (uint)c;
  56. c >>= 32;
  57. c += (ulong)x[xOff + 5] + y[yOff + 5];
  58. z[zOff + 5] = (uint)c;
  59. c >>= 32;
  60. c += (ulong)x[xOff + 6] + y[yOff + 6];
  61. z[zOff + 6] = (uint)c;
  62. c >>= 32;
  63. c += (ulong)x[xOff + 7] + y[yOff + 7];
  64. z[zOff + 7] = (uint)c;
  65. c >>= 32;
  66. return (uint)c;
  67. }
  68. public static uint AddBothTo(uint[] x, uint[] y, uint[] z)
  69. {
  70. ulong c = 0;
  71. c += (ulong)x[0] + y[0] + z[0];
  72. z[0] = (uint)c;
  73. c >>= 32;
  74. c += (ulong)x[1] + y[1] + z[1];
  75. z[1] = (uint)c;
  76. c >>= 32;
  77. c += (ulong)x[2] + y[2] + z[2];
  78. z[2] = (uint)c;
  79. c >>= 32;
  80. c += (ulong)x[3] + y[3] + z[3];
  81. z[3] = (uint)c;
  82. c >>= 32;
  83. c += (ulong)x[4] + y[4] + z[4];
  84. z[4] = (uint)c;
  85. c >>= 32;
  86. c += (ulong)x[5] + y[5] + z[5];
  87. z[5] = (uint)c;
  88. c >>= 32;
  89. c += (ulong)x[6] + y[6] + z[6];
  90. z[6] = (uint)c;
  91. c >>= 32;
  92. c += (ulong)x[7] + y[7] + z[7];
  93. z[7] = (uint)c;
  94. c >>= 32;
  95. return (uint)c;
  96. }
  97. public static uint AddBothTo(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
  98. {
  99. ulong c = 0;
  100. c += (ulong)x[xOff + 0] + y[yOff + 0] + z[zOff + 0];
  101. z[zOff + 0] = (uint)c;
  102. c >>= 32;
  103. c += (ulong)x[xOff + 1] + y[yOff + 1] + z[zOff + 1];
  104. z[zOff + 1] = (uint)c;
  105. c >>= 32;
  106. c += (ulong)x[xOff + 2] + y[yOff + 2] + z[zOff + 2];
  107. z[zOff + 2] = (uint)c;
  108. c >>= 32;
  109. c += (ulong)x[xOff + 3] + y[yOff + 3] + z[zOff + 3];
  110. z[zOff + 3] = (uint)c;
  111. c >>= 32;
  112. c += (ulong)x[xOff + 4] + y[yOff + 4] + z[zOff + 4];
  113. z[zOff + 4] = (uint)c;
  114. c >>= 32;
  115. c += (ulong)x[xOff + 5] + y[yOff + 5] + z[zOff + 5];
  116. z[zOff + 5] = (uint)c;
  117. c >>= 32;
  118. c += (ulong)x[xOff + 6] + y[yOff + 6] + z[zOff + 6];
  119. z[zOff + 6] = (uint)c;
  120. c >>= 32;
  121. c += (ulong)x[xOff + 7] + y[yOff + 7] + z[zOff + 7];
  122. z[zOff + 7] = (uint)c;
  123. c >>= 32;
  124. return (uint)c;
  125. }
  126. public static uint AddTo(uint[] x, uint[] z)
  127. {
  128. ulong c = 0;
  129. c += (ulong)x[0] + z[0];
  130. z[0] = (uint)c;
  131. c >>= 32;
  132. c += (ulong)x[1] + z[1];
  133. z[1] = (uint)c;
  134. c >>= 32;
  135. c += (ulong)x[2] + z[2];
  136. z[2] = (uint)c;
  137. c >>= 32;
  138. c += (ulong)x[3] + z[3];
  139. z[3] = (uint)c;
  140. c >>= 32;
  141. c += (ulong)x[4] + z[4];
  142. z[4] = (uint)c;
  143. c >>= 32;
  144. c += (ulong)x[5] + z[5];
  145. z[5] = (uint)c;
  146. c >>= 32;
  147. c += (ulong)x[6] + z[6];
  148. z[6] = (uint)c;
  149. c >>= 32;
  150. c += (ulong)x[7] + z[7];
  151. z[7] = (uint)c;
  152. c >>= 32;
  153. return (uint)c;
  154. }
  155. public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn)
  156. {
  157. ulong c = cIn;
  158. c += (ulong)x[xOff + 0] + z[zOff + 0];
  159. z[zOff + 0] = (uint)c;
  160. c >>= 32;
  161. c += (ulong)x[xOff + 1] + z[zOff + 1];
  162. z[zOff + 1] = (uint)c;
  163. c >>= 32;
  164. c += (ulong)x[xOff + 2] + z[zOff + 2];
  165. z[zOff + 2] = (uint)c;
  166. c >>= 32;
  167. c += (ulong)x[xOff + 3] + z[zOff + 3];
  168. z[zOff + 3] = (uint)c;
  169. c >>= 32;
  170. c += (ulong)x[xOff + 4] + z[zOff + 4];
  171. z[zOff + 4] = (uint)c;
  172. c >>= 32;
  173. c += (ulong)x[xOff + 5] + z[zOff + 5];
  174. z[zOff + 5] = (uint)c;
  175. c >>= 32;
  176. c += (ulong)x[xOff + 6] + z[zOff + 6];
  177. z[zOff + 6] = (uint)c;
  178. c >>= 32;
  179. c += (ulong)x[xOff + 7] + z[zOff + 7];
  180. z[zOff + 7] = (uint)c;
  181. c >>= 32;
  182. return (uint)c;
  183. }
  184. public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff)
  185. {
  186. ulong c = 0;
  187. c += (ulong)u[uOff + 0] + v[vOff + 0];
  188. u[uOff + 0] = (uint)c;
  189. v[vOff + 0] = (uint)c;
  190. c >>= 32;
  191. c += (ulong)u[uOff + 1] + v[vOff + 1];
  192. u[uOff + 1] = (uint)c;
  193. v[vOff + 1] = (uint)c;
  194. c >>= 32;
  195. c += (ulong)u[uOff + 2] + v[vOff + 2];
  196. u[uOff + 2] = (uint)c;
  197. v[vOff + 2] = (uint)c;
  198. c >>= 32;
  199. c += (ulong)u[uOff + 3] + v[vOff + 3];
  200. u[uOff + 3] = (uint)c;
  201. v[vOff + 3] = (uint)c;
  202. c >>= 32;
  203. c += (ulong)u[uOff + 4] + v[vOff + 4];
  204. u[uOff + 4] = (uint)c;
  205. v[vOff + 4] = (uint)c;
  206. c >>= 32;
  207. c += (ulong)u[uOff + 5] + v[vOff + 5];
  208. u[uOff + 5] = (uint)c;
  209. v[vOff + 5] = (uint)c;
  210. c >>= 32;
  211. c += (ulong)u[uOff + 6] + v[vOff + 6];
  212. u[uOff + 6] = (uint)c;
  213. v[vOff + 6] = (uint)c;
  214. c >>= 32;
  215. c += (ulong)u[uOff + 7] + v[vOff + 7];
  216. u[uOff + 7] = (uint)c;
  217. v[vOff + 7] = (uint)c;
  218. c >>= 32;
  219. return (uint)c;
  220. }
  221. public static void Copy(uint[] x, uint[] z)
  222. {
  223. z[0] = x[0];
  224. z[1] = x[1];
  225. z[2] = x[2];
  226. z[3] = x[3];
  227. z[4] = x[4];
  228. z[5] = x[5];
  229. z[6] = x[6];
  230. z[7] = x[7];
  231. }
  232. public static void Copy64(ulong[] x, ulong[] z)
  233. {
  234. z[0] = x[0];
  235. z[1] = x[1];
  236. z[2] = x[2];
  237. z[3] = x[3];
  238. }
  239. public static uint[] Create()
  240. {
  241. return new uint[8];
  242. }
  243. public static ulong[] Create64()
  244. {
  245. return new ulong[4];
  246. }
  247. public static uint[] CreateExt()
  248. {
  249. return new uint[16];
  250. }
  251. public static ulong[] CreateExt64()
  252. {
  253. return new ulong[8];
  254. }
  255. public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
  256. {
  257. bool pos = Gte(x, xOff, y, yOff);
  258. if (pos)
  259. {
  260. Sub(x, xOff, y, yOff, z, zOff);
  261. }
  262. else
  263. {
  264. Sub(y, yOff, x, xOff, z, zOff);
  265. }
  266. return pos;
  267. }
  268. public static bool Eq(uint[] x, uint[] y)
  269. {
  270. for (int i = 7; i >= 0; --i)
  271. {
  272. if (x[i] != y[i])
  273. return false;
  274. }
  275. return true;
  276. }
  277. public static bool Eq64(ulong[] x, ulong[] y)
  278. {
  279. for (int i = 3; i >= 0; --i)
  280. {
  281. if (x[i] != y[i])
  282. {
  283. return false;
  284. }
  285. }
  286. return true;
  287. }
  288. public static uint[] FromBigInteger(BigInteger x)
  289. {
  290. if (x.SignValue < 0 || x.BitLength > 256)
  291. throw new ArgumentException();
  292. uint[] z = Create();
  293. int i = 0;
  294. while (x.SignValue != 0)
  295. {
  296. z[i++] = (uint)x.IntValue;
  297. x = x.ShiftRight(32);
  298. }
  299. return z;
  300. }
  301. public static ulong[] FromBigInteger64(BigInteger x)
  302. {
  303. if (x.SignValue < 0 || x.BitLength > 256)
  304. throw new ArgumentException();
  305. ulong[] z = Create64();
  306. int i = 0;
  307. while (x.SignValue != 0)
  308. {
  309. z[i++] = (ulong)x.LongValue;
  310. x = x.ShiftRight(64);
  311. }
  312. return z;
  313. }
  314. public static uint GetBit(uint[] x, int bit)
  315. {
  316. if (bit == 0)
  317. {
  318. return x[0] & 1;
  319. }
  320. if ((bit & 255) != bit)
  321. {
  322. return 0;
  323. }
  324. int w = bit >> 5;
  325. int b = bit & 31;
  326. return (x[w] >> b) & 1;
  327. }
  328. public static bool Gte(uint[] x, uint[] y)
  329. {
  330. for (int i = 7; i >= 0; --i)
  331. {
  332. uint x_i = x[i], y_i = y[i];
  333. if (x_i < y_i)
  334. return false;
  335. if (x_i > y_i)
  336. return true;
  337. }
  338. return true;
  339. }
  340. public static bool Gte(uint[] x, int xOff, uint[] y, int yOff)
  341. {
  342. for (int i = 7; i >= 0; --i)
  343. {
  344. uint x_i = x[xOff + i], y_i = y[yOff + i];
  345. if (x_i < y_i)
  346. return false;
  347. if (x_i > y_i)
  348. return true;
  349. }
  350. return true;
  351. }
  352. public static bool IsOne(uint[] x)
  353. {
  354. if (x[0] != 1)
  355. {
  356. return false;
  357. }
  358. for (int i = 1; i < 8; ++i)
  359. {
  360. if (x[i] != 0)
  361. {
  362. return false;
  363. }
  364. }
  365. return true;
  366. }
  367. public static bool IsOne64(ulong[] x)
  368. {
  369. if (x[0] != 1UL)
  370. {
  371. return false;
  372. }
  373. for (int i = 1; i < 4; ++i)
  374. {
  375. if (x[i] != 0UL)
  376. {
  377. return false;
  378. }
  379. }
  380. return true;
  381. }
  382. public static bool IsZero(uint[] x)
  383. {
  384. for (int i = 0; i < 8; ++i)
  385. {
  386. if (x[i] != 0)
  387. {
  388. return false;
  389. }
  390. }
  391. return true;
  392. }
  393. public static bool IsZero64(ulong[] x)
  394. {
  395. for (int i = 0; i < 4; ++i)
  396. {
  397. if (x[i] != 0UL)
  398. {
  399. return false;
  400. }
  401. }
  402. return true;
  403. }
  404. public static void Mul(uint[] x, uint[] y, uint[] zz)
  405. {
  406. ulong y_0 = y[0];
  407. ulong y_1 = y[1];
  408. ulong y_2 = y[2];
  409. ulong y_3 = y[3];
  410. ulong y_4 = y[4];
  411. ulong y_5 = y[5];
  412. ulong y_6 = y[6];
  413. ulong y_7 = y[7];
  414. {
  415. ulong c = 0, x_0 = x[0];
  416. c += x_0 * y_0;
  417. zz[0] = (uint)c;
  418. c >>= 32;
  419. c += x_0 * y_1;
  420. zz[1] = (uint)c;
  421. c >>= 32;
  422. c += x_0 * y_2;
  423. zz[2] = (uint)c;
  424. c >>= 32;
  425. c += x_0 * y_3;
  426. zz[3] = (uint)c;
  427. c >>= 32;
  428. c += x_0 * y_4;
  429. zz[4] = (uint)c;
  430. c >>= 32;
  431. c += x_0 * y_5;
  432. zz[5] = (uint)c;
  433. c >>= 32;
  434. c += x_0 * y_6;
  435. zz[6] = (uint)c;
  436. c >>= 32;
  437. c += x_0 * y_7;
  438. zz[7] = (uint)c;
  439. c >>= 32;
  440. zz[8] = (uint)c;
  441. }
  442. for (int i = 1; i < 8; ++i)
  443. {
  444. ulong c = 0, x_i = x[i];
  445. c += x_i * y_0 + zz[i + 0];
  446. zz[i + 0] = (uint)c;
  447. c >>= 32;
  448. c += x_i * y_1 + zz[i + 1];
  449. zz[i + 1] = (uint)c;
  450. c >>= 32;
  451. c += x_i * y_2 + zz[i + 2];
  452. zz[i + 2] = (uint)c;
  453. c >>= 32;
  454. c += x_i * y_3 + zz[i + 3];
  455. zz[i + 3] = (uint)c;
  456. c >>= 32;
  457. c += x_i * y_4 + zz[i + 4];
  458. zz[i + 4] = (uint)c;
  459. c >>= 32;
  460. c += x_i * y_5 + zz[i + 5];
  461. zz[i + 5] = (uint)c;
  462. c >>= 32;
  463. c += x_i * y_6 + zz[i + 6];
  464. zz[i + 6] = (uint)c;
  465. c >>= 32;
  466. c += x_i * y_7 + zz[i + 7];
  467. zz[i + 7] = (uint)c;
  468. c >>= 32;
  469. zz[i + 8] = (uint)c;
  470. }
  471. }
  472. public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff)
  473. {
  474. ulong y_0 = y[yOff + 0];
  475. ulong y_1 = y[yOff + 1];
  476. ulong y_2 = y[yOff + 2];
  477. ulong y_3 = y[yOff + 3];
  478. ulong y_4 = y[yOff + 4];
  479. ulong y_5 = y[yOff + 5];
  480. ulong y_6 = y[yOff + 6];
  481. ulong y_7 = y[yOff + 7];
  482. {
  483. ulong c = 0, x_0 = x[xOff + 0];
  484. c += x_0 * y_0;
  485. zz[zzOff + 0] = (uint)c;
  486. c >>= 32;
  487. c += x_0 * y_1;
  488. zz[zzOff + 1] = (uint)c;
  489. c >>= 32;
  490. c += x_0 * y_2;
  491. zz[zzOff + 2] = (uint)c;
  492. c >>= 32;
  493. c += x_0 * y_3;
  494. zz[zzOff + 3] = (uint)c;
  495. c >>= 32;
  496. c += x_0 * y_4;
  497. zz[zzOff + 4] = (uint)c;
  498. c >>= 32;
  499. c += x_0 * y_5;
  500. zz[zzOff + 5] = (uint)c;
  501. c >>= 32;
  502. c += x_0 * y_6;
  503. zz[zzOff + 6] = (uint)c;
  504. c >>= 32;
  505. c += x_0 * y_7;
  506. zz[zzOff + 7] = (uint)c;
  507. c >>= 32;
  508. zz[zzOff + 8] = (uint)c;
  509. }
  510. for (int i = 1; i < 8; ++i)
  511. {
  512. ++zzOff;
  513. ulong c = 0, x_i = x[xOff + i];
  514. c += x_i * y_0 + zz[zzOff + 0];
  515. zz[zzOff + 0] = (uint)c;
  516. c >>= 32;
  517. c += x_i * y_1 + zz[zzOff + 1];
  518. zz[zzOff + 1] = (uint)c;
  519. c >>= 32;
  520. c += x_i * y_2 + zz[zzOff + 2];
  521. zz[zzOff + 2] = (uint)c;
  522. c >>= 32;
  523. c += x_i * y_3 + zz[zzOff + 3];
  524. zz[zzOff + 3] = (uint)c;
  525. c >>= 32;
  526. c += x_i * y_4 + zz[zzOff + 4];
  527. zz[zzOff + 4] = (uint)c;
  528. c >>= 32;
  529. c += x_i * y_5 + zz[zzOff + 5];
  530. zz[zzOff + 5] = (uint)c;
  531. c >>= 32;
  532. c += x_i * y_6 + zz[zzOff + 6];
  533. zz[zzOff + 6] = (uint)c;
  534. c >>= 32;
  535. c += x_i * y_7 + zz[zzOff + 7];
  536. zz[zzOff + 7] = (uint)c;
  537. c >>= 32;
  538. zz[zzOff + 8] = (uint)c;
  539. }
  540. }
  541. public static uint MulAddTo(uint[] x, uint[] y, uint[] zz)
  542. {
  543. ulong y_0 = y[0];
  544. ulong y_1 = y[1];
  545. ulong y_2 = y[2];
  546. ulong y_3 = y[3];
  547. ulong y_4 = y[4];
  548. ulong y_5 = y[5];
  549. ulong y_6 = y[6];
  550. ulong y_7 = y[7];
  551. ulong zc = 0;
  552. for (int i = 0; i < 8; ++i)
  553. {
  554. ulong c = 0, x_i = x[i];
  555. c += x_i * y_0 + zz[i + 0];
  556. zz[i + 0] = (uint)c;
  557. c >>= 32;
  558. c += x_i * y_1 + zz[i + 1];
  559. zz[i + 1] = (uint)c;
  560. c >>= 32;
  561. c += x_i * y_2 + zz[i + 2];
  562. zz[i + 2] = (uint)c;
  563. c >>= 32;
  564. c += x_i * y_3 + zz[i + 3];
  565. zz[i + 3] = (uint)c;
  566. c >>= 32;
  567. c += x_i * y_4 + zz[i + 4];
  568. zz[i + 4] = (uint)c;
  569. c >>= 32;
  570. c += x_i * y_5 + zz[i + 5];
  571. zz[i + 5] = (uint)c;
  572. c >>= 32;
  573. c += x_i * y_6 + zz[i + 6];
  574. zz[i + 6] = (uint)c;
  575. c >>= 32;
  576. c += x_i * y_7 + zz[i + 7];
  577. zz[i + 7] = (uint)c;
  578. c >>= 32;
  579. c += zc + zz[i + 8];
  580. zz[i + 8] = (uint)c;
  581. zc = c >> 32;
  582. }
  583. return (uint)zc;
  584. }
  585. public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff)
  586. {
  587. ulong y_0 = y[yOff + 0];
  588. ulong y_1 = y[yOff + 1];
  589. ulong y_2 = y[yOff + 2];
  590. ulong y_3 = y[yOff + 3];
  591. ulong y_4 = y[yOff + 4];
  592. ulong y_5 = y[yOff + 5];
  593. ulong y_6 = y[yOff + 6];
  594. ulong y_7 = y[yOff + 7];
  595. ulong zc = 0;
  596. for (int i = 0; i < 8; ++i)
  597. {
  598. ulong c = 0, x_i = x[xOff + i];
  599. c += x_i * y_0 + zz[zzOff + 0];
  600. zz[zzOff + 0] = (uint)c;
  601. c >>= 32;
  602. c += x_i * y_1 + zz[zzOff + 1];
  603. zz[zzOff + 1] = (uint)c;
  604. c >>= 32;
  605. c += x_i * y_2 + zz[zzOff + 2];
  606. zz[zzOff + 2] = (uint)c;
  607. c >>= 32;
  608. c += x_i * y_3 + zz[zzOff + 3];
  609. zz[zzOff + 3] = (uint)c;
  610. c >>= 32;
  611. c += x_i * y_4 + zz[zzOff + 4];
  612. zz[zzOff + 4] = (uint)c;
  613. c >>= 32;
  614. c += x_i * y_5 + zz[zzOff + 5];
  615. zz[zzOff + 5] = (uint)c;
  616. c >>= 32;
  617. c += x_i * y_6 + zz[zzOff + 6];
  618. zz[zzOff + 6] = (uint)c;
  619. c >>= 32;
  620. c += x_i * y_7 + zz[zzOff + 7];
  621. zz[zzOff + 7] = (uint)c;
  622. c >>= 32;
  623. c += zc + zz[zzOff + 8];
  624. zz[zzOff + 8] = (uint)c;
  625. zc = c >> 32;
  626. ++zzOff;
  627. }
  628. return (uint)zc;
  629. }
  630. public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
  631. {
  632. Debug.Assert(w >> 31 == 0);
  633. ulong c = 0, wVal = w;
  634. ulong x0 = x[xOff + 0];
  635. c += wVal * x0 + y[yOff + 0];
  636. z[zOff + 0] = (uint)c;
  637. c >>= 32;
  638. ulong x1 = x[xOff + 1];
  639. c += wVal * x1 + x0 + y[yOff + 1];
  640. z[zOff + 1] = (uint)c;
  641. c >>= 32;
  642. ulong x2 = x[xOff + 2];
  643. c += wVal * x2 + x1 + y[yOff + 2];
  644. z[zOff + 2] = (uint)c;
  645. c >>= 32;
  646. ulong x3 = x[xOff + 3];
  647. c += wVal * x3 + x2 + y[yOff + 3];
  648. z[zOff + 3] = (uint)c;
  649. c >>= 32;
  650. ulong x4 = x[xOff + 4];
  651. c += wVal * x4 + x3 + y[yOff + 4];
  652. z[zOff + 4] = (uint)c;
  653. c >>= 32;
  654. ulong x5 = x[xOff + 5];
  655. c += wVal * x5 + x4 + y[yOff + 5];
  656. z[zOff + 5] = (uint)c;
  657. c >>= 32;
  658. ulong x6 = x[xOff + 6];
  659. c += wVal * x6 + x5 + y[yOff + 6];
  660. z[zOff + 6] = (uint)c;
  661. c >>= 32;
  662. ulong x7 = x[xOff + 7];
  663. c += wVal * x7 + x6 + y[yOff + 7];
  664. z[zOff + 7] = (uint)c;
  665. c >>= 32;
  666. c += x7;
  667. return c;
  668. }
  669. public static uint MulByWord(uint x, uint[] z)
  670. {
  671. ulong c = 0, xVal = x;
  672. c += xVal * (ulong)z[0];
  673. z[0] = (uint)c;
  674. c >>= 32;
  675. c += xVal * (ulong)z[1];
  676. z[1] = (uint)c;
  677. c >>= 32;
  678. c += xVal * (ulong)z[2];
  679. z[2] = (uint)c;
  680. c >>= 32;
  681. c += xVal * (ulong)z[3];
  682. z[3] = (uint)c;
  683. c >>= 32;
  684. c += xVal * (ulong)z[4];
  685. z[4] = (uint)c;
  686. c >>= 32;
  687. c += xVal * (ulong)z[5];
  688. z[5] = (uint)c;
  689. c >>= 32;
  690. c += xVal * (ulong)z[6];
  691. z[6] = (uint)c;
  692. c >>= 32;
  693. c += xVal * (ulong)z[7];
  694. z[7] = (uint)c;
  695. c >>= 32;
  696. return (uint)c;
  697. }
  698. public static uint MulByWordAddTo(uint x, uint[] y, uint[] z)
  699. {
  700. ulong c = 0, xVal = x;
  701. c += xVal * (ulong)z[0] + y[0];
  702. z[0] = (uint)c;
  703. c >>= 32;
  704. c += xVal * (ulong)z[1] + y[1];
  705. z[1] = (uint)c;
  706. c >>= 32;
  707. c += xVal * (ulong)z[2] + y[2];
  708. z[2] = (uint)c;
  709. c >>= 32;
  710. c += xVal * (ulong)z[3] + y[3];
  711. z[3] = (uint)c;
  712. c >>= 32;
  713. c += xVal * (ulong)z[4] + y[4];
  714. z[4] = (uint)c;
  715. c >>= 32;
  716. c += xVal * (ulong)z[5] + y[5];
  717. z[5] = (uint)c;
  718. c >>= 32;
  719. c += xVal * (ulong)z[6] + y[6];
  720. z[6] = (uint)c;
  721. c >>= 32;
  722. c += xVal * (ulong)z[7] + y[7];
  723. z[7] = (uint)c;
  724. c >>= 32;
  725. return (uint)c;
  726. }
  727. public static uint MulWordAddTo(uint x, uint[] y, int yOff, uint[] z, int zOff)
  728. {
  729. ulong c = 0, xVal = x;
  730. c += xVal * y[yOff + 0] + z[zOff + 0];
  731. z[zOff + 0] = (uint)c;
  732. c >>= 32;
  733. c += xVal * y[yOff + 1] + z[zOff + 1];
  734. z[zOff + 1] = (uint)c;
  735. c >>= 32;
  736. c += xVal * y[yOff + 2] + z[zOff + 2];
  737. z[zOff + 2] = (uint)c;
  738. c >>= 32;
  739. c += xVal * y[yOff + 3] + z[zOff + 3];
  740. z[zOff + 3] = (uint)c;
  741. c >>= 32;
  742. c += xVal * y[yOff + 4] + z[zOff + 4];
  743. z[zOff + 4] = (uint)c;
  744. c >>= 32;
  745. c += xVal * y[yOff + 5] + z[zOff + 5];
  746. z[zOff + 5] = (uint)c;
  747. c >>= 32;
  748. c += xVal * y[yOff + 6] + z[zOff + 6];
  749. z[zOff + 6] = (uint)c;
  750. c >>= 32;
  751. c += xVal * y[yOff + 7] + z[zOff + 7];
  752. z[zOff + 7] = (uint)c;
  753. c >>= 32;
  754. return (uint)c;
  755. }
  756. public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff)
  757. {
  758. Debug.Assert(x >> 31 == 0);
  759. Debug.Assert(zOff <= 4);
  760. ulong c = 0, xVal = x;
  761. ulong y00 = y & M;
  762. c += xVal * y00 + z[zOff + 0];
  763. z[zOff + 0] = (uint)c;
  764. c >>= 32;
  765. ulong y01 = y >> 32;
  766. c += xVal * y01 + y00 + z[zOff + 1];
  767. z[zOff + 1] = (uint)c;
  768. c >>= 32;
  769. c += y01 + z[zOff + 2];
  770. z[zOff + 2] = (uint)c;
  771. c >>= 32;
  772. c += z[zOff + 3];
  773. z[zOff + 3] = (uint)c;
  774. c >>= 32;
  775. return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 4);
  776. }
  777. public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff)
  778. {
  779. Debug.Assert(x >> 31 == 0);
  780. Debug.Assert(zOff <= 5);
  781. ulong c = 0, yVal = y;
  782. c += yVal * x + z[zOff + 0];
  783. z[zOff + 0] = (uint)c;
  784. c >>= 32;
  785. c += yVal + z[zOff + 1];
  786. z[zOff + 1] = (uint)c;
  787. c >>= 32;
  788. c += z[zOff + 2];
  789. z[zOff + 2] = (uint)c;
  790. c >>= 32;
  791. return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 3);
  792. }
  793. public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff)
  794. {
  795. Debug.Assert(zOff <= 5);
  796. ulong c = 0, xVal = x;
  797. c += xVal * y + z[zOff + 0];
  798. z[zOff + 0] = (uint)c;
  799. c >>= 32;
  800. c += xVal * (y >> 32) + z[zOff + 1];
  801. z[zOff + 1] = (uint)c;
  802. c >>= 32;
  803. c += z[zOff + 2];
  804. z[zOff + 2] = (uint)c;
  805. c >>= 32;
  806. return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 3);
  807. }
  808. public static uint MulWord(uint x, uint[] y, uint[] z, int zOff)
  809. {
  810. ulong c = 0, xVal = x;
  811. int i = 0;
  812. do
  813. {
  814. c += xVal * y[i];
  815. z[zOff + i] = (uint)c;
  816. c >>= 32;
  817. }
  818. while (++i < 8);
  819. return (uint)c;
  820. }
  821. public static void Square(uint[] x, uint[] zz)
  822. {
  823. ulong x_0 = x[0];
  824. ulong zz_1;
  825. uint c = 0, w;
  826. {
  827. int i = 7, j = 16;
  828. do
  829. {
  830. ulong xVal = x[i--];
  831. ulong p = xVal * xVal;
  832. zz[--j] = (c << 31) | (uint)(p >> 33);
  833. zz[--j] = (uint)(p >> 1);
  834. c = (uint)p;
  835. }
  836. while (i > 0);
  837. {
  838. ulong p = x_0 * x_0;
  839. zz_1 = (ulong)(c << 31) | (p >> 33);
  840. zz[0] = (uint)p;
  841. c = (uint)(p >> 32) & 1;
  842. }
  843. }
  844. ulong x_1 = x[1];
  845. ulong zz_2 = zz[2];
  846. {
  847. zz_1 += x_1 * x_0;
  848. w = (uint)zz_1;
  849. zz[1] = (w << 1) | c;
  850. c = w >> 31;
  851. zz_2 += zz_1 >> 32;
  852. }
  853. ulong x_2 = x[2];
  854. ulong zz_3 = zz[3];
  855. ulong zz_4 = zz[4];
  856. {
  857. zz_2 += x_2 * x_0;
  858. w = (uint)zz_2;
  859. zz[2] = (w << 1) | c;
  860. c = w >> 31;
  861. zz_3 += (zz_2 >> 32) + x_2 * x_1;
  862. zz_4 += zz_3 >> 32;
  863. zz_3 &= M;
  864. }
  865. ulong x_3 = x[3];
  866. ulong zz_5 = zz[5];
  867. ulong zz_6 = zz[6];
  868. {
  869. zz_3 += x_3 * x_0;
  870. w = (uint)zz_3;
  871. zz[3] = (w << 1) | c;
  872. c = w >> 31;
  873. zz_4 += (zz_3 >> 32) + x_3 * x_1;
  874. zz_5 += (zz_4 >> 32) + x_3 * x_2;
  875. zz_4 &= M;
  876. zz_6 += zz_5 >> 32;
  877. zz_5 &= M;
  878. }
  879. ulong x_4 = x[4];
  880. ulong zz_7 = zz[7];
  881. ulong zz_8 = zz[8];
  882. {
  883. zz_4 += x_4 * x_0;
  884. w = (uint)zz_4;
  885. zz[4] = (w << 1) | c;
  886. c = w >> 31;
  887. zz_5 += (zz_4 >> 32) + x_4 * x_1;
  888. zz_6 += (zz_5 >> 32) + x_4 * x_2;
  889. zz_5 &= M;
  890. zz_7 += (zz_6 >> 32) + x_4 * x_3;
  891. zz_6 &= M;
  892. zz_8 += zz_7 >> 32;
  893. zz_7 &= M;
  894. }
  895. ulong x_5 = x[5];
  896. ulong zz_9 = zz[9];
  897. ulong zz_10 = zz[10];
  898. {
  899. zz_5 += x_5 * x_0;
  900. w = (uint)zz_5;
  901. zz[5] = (w << 1) | c;
  902. c = w >> 31;
  903. zz_6 += (zz_5 >> 32) + x_5 * x_1;
  904. zz_7 += (zz_6 >> 32) + x_5 * x_2;
  905. zz_6 &= M;
  906. zz_8 += (zz_7 >> 32) + x_5 * x_3;
  907. zz_7 &= M;
  908. zz_9 += (zz_8 >> 32) + x_5 * x_4;
  909. zz_8 &= M;
  910. zz_10 += zz_9 >> 32;
  911. zz_9 &= M;
  912. }
  913. ulong x_6 = x[6];
  914. ulong zz_11 = zz[11];
  915. ulong zz_12 = zz[12];
  916. {
  917. zz_6 += x_6 * x_0;
  918. w = (uint)zz_6;
  919. zz[6] = (w << 1) | c;
  920. c = w >> 31;
  921. zz_7 += (zz_6 >> 32) + x_6 * x_1;
  922. zz_8 += (zz_7 >> 32) + x_6 * x_2;
  923. zz_7 &= M;
  924. zz_9 += (zz_8 >> 32) + x_6 * x_3;
  925. zz_8 &= M;
  926. zz_10 += (zz_9 >> 32) + x_6 * x_4;
  927. zz_9 &= M;
  928. zz_11 += (zz_10 >> 32) + x_6 * x_5;
  929. zz_10 &= M;
  930. zz_12 += zz_11 >> 32;
  931. zz_11 &= M;
  932. }
  933. ulong x_7 = x[7];
  934. ulong zz_13 = zz[13];
  935. ulong zz_14 = zz[14];
  936. {
  937. zz_7 += x_7 * x_0;
  938. w = (uint)zz_7;
  939. zz[7] = (w << 1) | c;
  940. c = w >> 31;
  941. zz_8 += (zz_7 >> 32) + x_7 * x_1;
  942. zz_9 += (zz_8 >> 32) + x_7 * x_2;
  943. zz_10 += (zz_9 >> 32) + x_7 * x_3;
  944. zz_11 += (zz_10 >> 32) + x_7 * x_4;
  945. zz_12 += (zz_11 >> 32) + x_7 * x_5;
  946. zz_13 += (zz_12 >> 32) + x_7 * x_6;
  947. zz_14 += zz_13 >> 32;
  948. }
  949. w = (uint)zz_8;
  950. zz[8] = (w << 1) | c;
  951. c = w >> 31;
  952. w = (uint)zz_9;
  953. zz[9] = (w << 1) | c;
  954. c = w >> 31;
  955. w = (uint)zz_10;
  956. zz[10] = (w << 1) | c;
  957. c = w >> 31;
  958. w = (uint)zz_11;
  959. zz[11] = (w << 1) | c;
  960. c = w >> 31;
  961. w = (uint)zz_12;
  962. zz[12] = (w << 1) | c;
  963. c = w >> 31;
  964. w = (uint)zz_13;
  965. zz[13] = (w << 1) | c;
  966. c = w >> 31;
  967. w = (uint)zz_14;
  968. zz[14] = (w << 1) | c;
  969. c = w >> 31;
  970. w = zz[15] + (uint)(zz_14 >> 32);
  971. zz[15] = (w << 1) | c;
  972. }
  973. public static void Square(uint[] x, int xOff, uint[] zz, int zzOff)
  974. {
  975. ulong x_0 = x[xOff + 0];
  976. ulong zz_1;
  977. uint c = 0, w;
  978. {
  979. int i = 7, j = 16;
  980. do
  981. {
  982. ulong xVal = x[xOff + i--];
  983. ulong p = xVal * xVal;
  984. zz[zzOff + --j] = (c << 31) | (uint)(p >> 33);
  985. zz[zzOff + --j] = (uint)(p >> 1);
  986. c = (uint)p;
  987. }
  988. while (i > 0);
  989. {
  990. ulong p = x_0 * x_0;
  991. zz_1 = (ulong)(c << 31) | (p >> 33);
  992. zz[zzOff + 0] = (uint)p;
  993. c = (uint)(p >> 32) & 1;
  994. }
  995. }
  996. ulong x_1 = x[xOff + 1];
  997. ulong zz_2 = zz[zzOff + 2];
  998. {
  999. zz_1 += x_1 * x_0;
  1000. w = (uint)zz_1;
  1001. zz[zzOff + 1] = (w << 1) | c;
  1002. c = w >> 31;
  1003. zz_2 += zz_1 >> 32;
  1004. }
  1005. ulong x_2 = x[xOff + 2];
  1006. ulong zz_3 = zz[zzOff + 3];
  1007. ulong zz_4 = zz[zzOff + 4];
  1008. {
  1009. zz_2 += x_2 * x_0;
  1010. w = (uint)zz_2;
  1011. zz[zzOff + 2] = (w << 1) | c;
  1012. c = w >> 31;
  1013. zz_3 += (zz_2 >> 32) + x_2 * x_1;
  1014. zz_4 += zz_3 >> 32;
  1015. zz_3 &= M;
  1016. }
  1017. ulong x_3 = x[xOff + 3];
  1018. ulong zz_5 = zz[zzOff + 5];
  1019. ulong zz_6 = zz[zzOff + 6];
  1020. {
  1021. zz_3 += x_3 * x_0;
  1022. w = (uint)zz_3;
  1023. zz[zzOff + 3] = (w << 1) | c;
  1024. c = w >> 31;
  1025. zz_4 += (zz_3 >> 32) + x_3 * x_1;
  1026. zz_5 += (zz_4 >> 32) + x_3 * x_2;
  1027. zz_4 &= M;
  1028. zz_6 += zz_5 >> 32;
  1029. zz_5 &= M;
  1030. }
  1031. ulong x_4 = x[xOff + 4];
  1032. ulong zz_7 = zz[zzOff + 7];
  1033. ulong zz_8 = zz[zzOff + 8];
  1034. {
  1035. zz_4 += x_4 * x_0;
  1036. w = (uint)zz_4;
  1037. zz[zzOff + 4] = (w << 1) | c;
  1038. c = w >> 31;
  1039. zz_5 += (zz_4 >> 32) + x_4 * x_1;
  1040. zz_6 += (zz_5 >> 32) + x_4 * x_2;
  1041. zz_5 &= M;
  1042. zz_7 += (zz_6 >> 32) + x_4 * x_3;
  1043. zz_6 &= M;
  1044. zz_8 += zz_7 >> 32;
  1045. zz_7 &= M;
  1046. }
  1047. ulong x_5 = x[xOff + 5];
  1048. ulong zz_9 = zz[zzOff + 9];
  1049. ulong zz_10 = zz[zzOff + 10];
  1050. {
  1051. zz_5 += x_5 * x_0;
  1052. w = (uint)zz_5;
  1053. zz[zzOff + 5] = (w << 1) | c;
  1054. c = w >> 31;
  1055. zz_6 += (zz_5 >> 32) + x_5 * x_1;
  1056. zz_7 += (zz_6 >> 32) + x_5 * x_2;
  1057. zz_6 &= M;
  1058. zz_8 += (zz_7 >> 32) + x_5 * x_3;
  1059. zz_7 &= M;
  1060. zz_9 += (zz_8 >> 32) + x_5 * x_4;
  1061. zz_8 &= M;
  1062. zz_10 += zz_9 >> 32;
  1063. zz_9 &= M;
  1064. }
  1065. ulong x_6 = x[xOff + 6];
  1066. ulong zz_11 = zz[zzOff + 11];
  1067. ulong zz_12 = zz[zzOff + 12];
  1068. {
  1069. zz_6 += x_6 * x_0;
  1070. w = (uint)zz_6;
  1071. zz[zzOff + 6] = (w << 1) | c;
  1072. c = w >> 31;
  1073. zz_7 += (zz_6 >> 32) + x_6 * x_1;
  1074. zz_8 += (zz_7 >> 32) + x_6 * x_2;
  1075. zz_7 &= M;
  1076. zz_9 += (zz_8 >> 32) + x_6 * x_3;
  1077. zz_8 &= M;
  1078. zz_10 += (zz_9 >> 32) + x_6 * x_4;
  1079. zz_9 &= M;
  1080. zz_11 += (zz_10 >> 32) + x_6 * x_5;
  1081. zz_10 &= M;
  1082. zz_12 += zz_11 >> 32;
  1083. zz_11 &= M;
  1084. }
  1085. ulong x_7 = x[xOff + 7];
  1086. ulong zz_13 = zz[zzOff + 13];
  1087. ulong zz_14 = zz[zzOff + 14];
  1088. {
  1089. zz_7 += x_7 * x_0;
  1090. w = (uint)zz_7;
  1091. zz[zzOff + 7] = (w << 1) | c;
  1092. c = w >> 31;
  1093. zz_8 += (zz_7 >> 32) + x_7 * x_1;
  1094. zz_9 += (zz_8 >> 32) + x_7 * x_2;
  1095. zz_10 += (zz_9 >> 32) + x_7 * x_3;
  1096. zz_11 += (zz_10 >> 32) + x_7 * x_4;
  1097. zz_12 += (zz_11 >> 32) + x_7 * x_5;
  1098. zz_13 += (zz_12 >> 32) + x_7 * x_6;
  1099. zz_14 += zz_13 >> 32;
  1100. }
  1101. w = (uint)zz_8;
  1102. zz[zzOff + 8] = (w << 1) | c;
  1103. c = w >> 31;
  1104. w = (uint)zz_9;
  1105. zz[zzOff + 9] = (w << 1) | c;
  1106. c = w >> 31;
  1107. w = (uint)zz_10;
  1108. zz[zzOff + 10] = (w << 1) | c;
  1109. c = w >> 31;
  1110. w = (uint)zz_11;
  1111. zz[zzOff + 11] = (w << 1) | c;
  1112. c = w >> 31;
  1113. w = (uint)zz_12;
  1114. zz[zzOff + 12] = (w << 1) | c;
  1115. c = w >> 31;
  1116. w = (uint)zz_13;
  1117. zz[zzOff + 13] = (w << 1) | c;
  1118. c = w >> 31;
  1119. w = (uint)zz_14;
  1120. zz[zzOff + 14] = (w << 1) | c;
  1121. c = w >> 31;
  1122. w = zz[zzOff + 15] + (uint)(zz_14 >> 32);
  1123. zz[zzOff + 15] = (w << 1) | c;
  1124. }
  1125. public static int Sub(uint[] x, uint[] y, uint[] z)
  1126. {
  1127. long c = 0;
  1128. c += (long)x[0] - y[0];
  1129. z[0] = (uint)c;
  1130. c >>= 32;
  1131. c += (long)x[1] - y[1];
  1132. z[1] = (uint)c;
  1133. c >>= 32;
  1134. c += (long)x[2] - y[2];
  1135. z[2] = (uint)c;
  1136. c >>= 32;
  1137. c += (long)x[3] - y[3];
  1138. z[3] = (uint)c;
  1139. c >>= 32;
  1140. c += (long)x[4] - y[4];
  1141. z[4] = (uint)c;
  1142. c >>= 32;
  1143. c += (long)x[5] - y[5];
  1144. z[5] = (uint)c;
  1145. c >>= 32;
  1146. c += (long)x[6] - y[6];
  1147. z[6] = (uint)c;
  1148. c >>= 32;
  1149. c += (long)x[7] - y[7];
  1150. z[7] = (uint)c;
  1151. c >>= 32;
  1152. return (int)c;
  1153. }
  1154. public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
  1155. {
  1156. long c = 0;
  1157. c += (long)x[xOff + 0] - y[yOff + 0];
  1158. z[zOff + 0] = (uint)c;
  1159. c >>= 32;
  1160. c += (long)x[xOff + 1] - y[yOff + 1];
  1161. z[zOff + 1] = (uint)c;
  1162. c >>= 32;
  1163. c += (long)x[xOff + 2] - y[yOff + 2];
  1164. z[zOff + 2] = (uint)c;
  1165. c >>= 32;
  1166. c += (long)x[xOff + 3] - y[yOff + 3];
  1167. z[zOff + 3] = (uint)c;
  1168. c >>= 32;
  1169. c += (long)x[xOff + 4] - y[yOff + 4];
  1170. z[zOff + 4] = (uint)c;
  1171. c >>= 32;
  1172. c += (long)x[xOff + 5] - y[yOff + 5];
  1173. z[zOff + 5] = (uint)c;
  1174. c >>= 32;
  1175. c += (long)x[xOff + 6] - y[yOff + 6];
  1176. z[zOff + 6] = (uint)c;
  1177. c >>= 32;
  1178. c += (long)x[xOff + 7] - y[yOff + 7];
  1179. z[zOff + 7] = (uint)c;
  1180. c >>= 32;
  1181. return (int)c;
  1182. }
  1183. public static int SubBothFrom(uint[] x, uint[] y, uint[] z)
  1184. {
  1185. long c = 0;
  1186. c += (long)z[0] - x[0] - y[0];
  1187. z[0] = (uint)c;
  1188. c >>= 32;
  1189. c += (long)z[1] - x[1] - y[1];
  1190. z[1] = (uint)c;
  1191. c >>= 32;
  1192. c += (long)z[2] - x[2] - y[2];
  1193. z[2] = (uint)c;
  1194. c >>= 32;
  1195. c += (long)z[3] - x[3] - y[3];
  1196. z[3] = (uint)c;
  1197. c >>= 32;
  1198. c += (long)z[4] - x[4] - y[4];
  1199. z[4] = (uint)c;
  1200. c >>= 32;
  1201. c += (long)z[5] - x[5] - y[5];
  1202. z[5] = (uint)c;
  1203. c >>= 32;
  1204. c += (long)z[6] - x[6] - y[6];
  1205. z[6] = (uint)c;
  1206. c >>= 32;
  1207. c += (long)z[7] - x[7] - y[7];
  1208. z[7] = (uint)c;
  1209. c >>= 32;
  1210. return (int)c;
  1211. }
  1212. public static int SubFrom(uint[] x, uint[] z)
  1213. {
  1214. long c = 0;
  1215. c += (long)z[0] - x[0];
  1216. z[0] = (uint)c;
  1217. c >>= 32;
  1218. c += (long)z[1] - x[1];
  1219. z[1] = (uint)c;
  1220. c >>= 32;
  1221. c += (long)z[2] - x[2];
  1222. z[2] = (uint)c;
  1223. c >>= 32;
  1224. c += (long)z[3] - x[3];
  1225. z[3] = (uint)c;
  1226. c >>= 32;
  1227. c += (long)z[4] - x[4];
  1228. z[4] = (uint)c;
  1229. c >>= 32;
  1230. c += (long)z[5] - x[5];
  1231. z[5] = (uint)c;
  1232. c >>= 32;
  1233. c += (long)z[6] - x[6];
  1234. z[6] = (uint)c;
  1235. c >>= 32;
  1236. c += (long)z[7] - x[7];
  1237. z[7] = (uint)c;
  1238. c >>= 32;
  1239. return (int)c;
  1240. }
  1241. public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff)
  1242. {
  1243. long c = 0;
  1244. c += (long)z[zOff + 0] - x[xOff + 0];
  1245. z[zOff + 0] = (uint)c;
  1246. c >>= 32;
  1247. c += (long)z[zOff + 1] - x[xOff + 1];
  1248. z[zOff + 1] = (uint)c;
  1249. c >>= 32;
  1250. c += (long)z[zOff + 2] - x[xOff + 2];
  1251. z[zOff + 2] = (uint)c;
  1252. c >>= 32;
  1253. c += (long)z[zOff + 3] - x[xOff + 3];
  1254. z[zOff + 3] = (uint)c;
  1255. c >>= 32;
  1256. c += (long)z[zOff + 4] - x[xOff + 4];
  1257. z[zOff + 4] = (uint)c;
  1258. c >>= 32;
  1259. c += (long)z[zOff + 5] - x[xOff + 5];
  1260. z[zOff + 5] = (uint)c;
  1261. c >>= 32;
  1262. c += (long)z[zOff + 6] - x[xOff + 6];
  1263. z[zOff + 6] = (uint)c;
  1264. c >>= 32;
  1265. c += (long)z[zOff + 7] - x[xOff + 7];
  1266. z[zOff + 7] = (uint)c;
  1267. c >>= 32;
  1268. return (int)c;
  1269. }
  1270. public static BigInteger ToBigInteger(uint[] x)
  1271. {
  1272. byte[] bs = new byte[32];
  1273. for (int i = 0; i < 8; ++i)
  1274. {
  1275. uint x_i = x[i];
  1276. if (x_i != 0)
  1277. {
  1278. Pack.UInt32_To_BE(x_i, bs, (7 - i) << 2);
  1279. }
  1280. }
  1281. return new BigInteger(1, bs);
  1282. }
  1283. public static BigInteger ToBigInteger64(ulong[] x)
  1284. {
  1285. byte[] bs = new byte[32];
  1286. for (int i = 0; i < 4; ++i)
  1287. {
  1288. ulong x_i = x[i];
  1289. if (x_i != 0L)
  1290. {
  1291. Pack.UInt64_To_BE(x_i, bs, (3 - i) << 3);
  1292. }
  1293. }
  1294. return new BigInteger(1, bs);
  1295. }
  1296. public static void Zero(uint[] z)
  1297. {
  1298. z[0] = 0;
  1299. z[1] = 0;
  1300. z[2] = 0;
  1301. z[3] = 0;
  1302. z[4] = 0;
  1303. z[5] = 0;
  1304. z[6] = 0;
  1305. z[7] = 0;
  1306. }
  1307. }
  1308. }
  1309. #endif