ClpNat256.pas 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781
  1. { *********************************************************************************** }
  2. { * CryptoLib Library * }
  3. { * Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe * }
  4. { * Github Repository <https://github.com/Xor-el> * }
  5. { * Distributed under the MIT software license, see the accompanying file LICENSE * }
  6. { * or visit http://www.opensource.org/licenses/mit-license.php. * }
  7. { * Acknowledgements: * }
  8. { * * }
  9. { * Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring * }
  10. { * development of this library * }
  11. { * ******************************************************************************* * }
  12. (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
  13. unit ClpNat256;
  14. {$I CryptoLib.inc}
  15. interface
  16. uses
  17. ClpNat,
  18. ClpConverters,
  19. ClpBits,
  20. ClpBigInteger,
  21. ClpArrayUtils,
  22. ClpCryptoLibTypes;
  23. type
  24. TNat256 = class abstract(TObject)
  25. strict private
  26. const
  27. M = UInt64($FFFFFFFF);
  28. public
  29. class function Add(const x, y, z: TCryptoLibUInt32Array): UInt32;
  30. overload; static;
  31. class function Add(const x: TCryptoLibUInt32Array; xOff: Int32;
  32. const y: TCryptoLibUInt32Array; yOff: Int32;
  33. const z: TCryptoLibUInt32Array; zOff: Int32): UInt32; overload; static;
  34. class function AddBothTo(const x, y, z: TCryptoLibUInt32Array): UInt32;
  35. overload; static;
  36. class function AddBothTo(const x: TCryptoLibUInt32Array; xOff: Int32;
  37. const y: TCryptoLibUInt32Array; yOff: Int32;
  38. const z: TCryptoLibUInt32Array; zOff: Int32): UInt32; overload; static;
  39. class function AddTo(const x, z: TCryptoLibUInt32Array): UInt32;
  40. overload; static;
  41. class function AddTo(const x: TCryptoLibUInt32Array; xOff: Int32;
  42. const z: TCryptoLibUInt32Array; zOff: Int32; cIn: UInt32): UInt32;
  43. overload; static;
  44. class function AddToEachOther(const u: TCryptoLibUInt32Array; uOff: Int32;
  45. const v: TCryptoLibUInt32Array; vOff: Int32): UInt32; static;
  46. class procedure Copy(const x, z: TCryptoLibUInt32Array); overload;
  47. static; inline;
  48. class procedure Copy(const x: TCryptoLibUInt32Array; xOff: Int32;
  49. const z: TCryptoLibUInt32Array; zOff: Int32); overload; static; inline;
  50. class procedure Copy64(const x, z: TCryptoLibUInt64Array); overload;
  51. static; inline;
  52. class procedure Copy64(const x: TCryptoLibUInt64Array; xOff: Int32;
  53. const z: TCryptoLibUInt64Array; zOff: Int32); overload; static; inline;
  54. class function Create(): TCryptoLibUInt32Array; static; inline;
  55. class function Create64(): TCryptoLibUInt64Array; static; inline;
  56. class function CreateExt(): TCryptoLibUInt32Array; static; inline;
  57. class function CreateExt64(): TCryptoLibUInt64Array; static; inline;
  58. class function Diff(const x: TCryptoLibUInt32Array; xOff: Int32;
  59. const y: TCryptoLibUInt32Array; yOff: Int32;
  60. const z: TCryptoLibUInt32Array; zOff: Int32): Boolean; static; inline;
  61. class function Eq(const x, y: TCryptoLibUInt32Array): Boolean; static;
  62. class function Eq64(const x, y: TCryptoLibUInt64Array): Boolean; static;
  63. class function FromBigInteger(const x: TBigInteger)
  64. : TCryptoLibUInt32Array; static;
  65. class function FromBigInteger64(const x: TBigInteger)
  66. : TCryptoLibUInt64Array; static;
  67. class function GetBit(const x: TCryptoLibUInt32Array; bit: Int32): UInt32;
  68. static; inline;
  69. class function Gte(const x, y: TCryptoLibUInt32Array): Boolean;
  70. overload; static;
  71. class function Gte(const x: TCryptoLibUInt32Array; xOff: Int32;
  72. const y: TCryptoLibUInt32Array; yOff: Int32): Boolean; overload; static;
  73. class function IsOne(const x: TCryptoLibUInt32Array): Boolean; static;
  74. class function IsOne64(const x: TCryptoLibUInt64Array): Boolean; static;
  75. class function IsZero(const x: TCryptoLibUInt32Array): Boolean; static;
  76. class function IsZero64(const x: TCryptoLibUInt64Array): Boolean; static;
  77. class procedure Mul(const x, y, zz: TCryptoLibUInt32Array);
  78. overload; static;
  79. class procedure Mul(const x: TCryptoLibUInt32Array; xOff: Int32;
  80. const y: TCryptoLibUInt32Array; yOff: Int32;
  81. const zz: TCryptoLibUInt32Array; zzOff: Int32); overload; static;
  82. class function MulAddTo(const x, y, zz: TCryptoLibUInt32Array): UInt32;
  83. overload; static;
  84. class function MulAddTo(const x: TCryptoLibUInt32Array; xOff: Int32;
  85. const y: TCryptoLibUInt32Array; yOff: Int32;
  86. const zz: TCryptoLibUInt32Array; zzOff: Int32): UInt32; overload; static;
  87. class function Mul33Add(w: UInt32; const x: TCryptoLibUInt32Array;
  88. xOff: Int32; const y: TCryptoLibUInt32Array; yOff: Int32;
  89. const z: TCryptoLibUInt32Array; zOff: Int32): UInt64; static;
  90. class function MulByWord(x: UInt32; const z: TCryptoLibUInt32Array)
  91. : UInt32; static;
  92. class function MulByWordAddTo(x: UInt32; const y, z: TCryptoLibUInt32Array)
  93. : UInt32; static;
  94. class function MulWordAddTo(x: UInt32; const y: TCryptoLibUInt32Array;
  95. yOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32): UInt32; static;
  96. class function Mul33DWordAdd(x: UInt32; y: UInt64;
  97. const z: TCryptoLibUInt32Array; zOff: Int32): UInt32; static;
  98. class function Mul33WordAdd(x, y: UInt32; const z: TCryptoLibUInt32Array;
  99. zOff: Int32): UInt32; static;
  100. class function MulWordDwordAdd(x: UInt32; y: UInt64;
  101. const z: TCryptoLibUInt32Array; zOff: Int32): UInt32; static;
  102. class function MulWord(x: UInt32; const y, z: TCryptoLibUInt32Array;
  103. zOff: Int32): UInt32; static;
  104. class procedure Square(const x, zz: TCryptoLibUInt32Array);
  105. overload; static;
  106. class procedure Square(const x: TCryptoLibUInt32Array; xOff: Int32;
  107. const zz: TCryptoLibUInt32Array; zzOff: Int32); overload; static;
  108. class function Sub(const x, y, z: TCryptoLibUInt32Array): Int32;
  109. overload; static;
  110. class function Sub(const x: TCryptoLibUInt32Array; xOff: Int32;
  111. const y: TCryptoLibUInt32Array; yOff: Int32;
  112. const z: TCryptoLibUInt32Array; zOff: Int32): Int32; overload; static;
  113. class function SubBothFrom(const x, y, z: TCryptoLibUInt32Array)
  114. : Int32; static;
  115. class function SubFrom(const x, z: TCryptoLibUInt32Array): Int32;
  116. overload; static;
  117. class function SubFrom(const x: TCryptoLibUInt32Array; xOff: Int32;
  118. const z: TCryptoLibUInt32Array; zOff: Int32): Int32; overload; static;
  119. class function ToBigInteger(const x: TCryptoLibUInt32Array)
  120. : TBigInteger; static;
  121. class function ToBigInteger64(const x: TCryptoLibUInt64Array)
  122. : TBigInteger; static;
  123. class procedure Zero(const z: TCryptoLibUInt32Array); static; inline;
  124. end;
  125. implementation
  126. { TNat256 }
  127. class function TNat256.Add(const x, y, z: TCryptoLibUInt32Array): UInt32;
  128. var
  129. c: UInt64;
  130. begin
  131. c := 0;
  132. c := c + (UInt64(x[0]) + y[0]);
  133. z[0] := UInt32(c);
  134. c := c shr 32;
  135. c := c + (UInt64(x[1]) + y[1]);
  136. z[1] := UInt32(c);
  137. c := c shr 32;
  138. c := c + (UInt64(x[2]) + y[2]);
  139. z[2] := UInt32(c);
  140. c := c shr 32;
  141. c := c + (UInt64(x[3]) + y[3]);
  142. z[3] := UInt32(c);
  143. c := c shr 32;
  144. c := c + (UInt64(x[4]) + y[4]);
  145. z[4] := UInt32(c);
  146. c := c shr 32;
  147. c := c + (UInt64(x[5]) + y[5]);
  148. z[5] := UInt32(c);
  149. c := c shr 32;
  150. c := c + (UInt64(x[6]) + y[6]);
  151. z[6] := UInt32(c);
  152. c := c shr 32;
  153. c := c + (UInt64(x[7]) + y[7]);
  154. z[7] := UInt32(c);
  155. c := c shr 32;
  156. result := UInt32(c);
  157. end;
  158. class function TNat256.Add(const x: TCryptoLibUInt32Array; xOff: Int32;
  159. const y: TCryptoLibUInt32Array; yOff: Int32; const z: TCryptoLibUInt32Array;
  160. zOff: Int32): UInt32;
  161. var
  162. c: UInt64;
  163. begin
  164. c := 0;
  165. c := c + (UInt64(x[xOff + 0]) + y[yOff + 0]);
  166. z[zOff + 0] := UInt32(c);
  167. c := c shr 32;
  168. c := c + (UInt64(x[xOff + 1]) + y[yOff + 1]);
  169. z[zOff + 1] := UInt32(c);
  170. c := c shr 32;
  171. c := c + (UInt64(x[xOff + 2]) + y[yOff + 2]);
  172. z[zOff + 2] := UInt32(c);
  173. c := c shr 32;
  174. c := c + (UInt64(x[xOff + 3]) + y[yOff + 3]);
  175. z[zOff + 3] := UInt32(c);
  176. c := c shr 32;
  177. c := c + (UInt64(x[xOff + 4]) + y[yOff + 4]);
  178. z[zOff + 4] := UInt32(c);
  179. c := c shr 32;
  180. c := c + (UInt64(x[xOff + 5]) + y[yOff + 5]);
  181. z[zOff + 5] := UInt32(c);
  182. c := c shr 32;
  183. c := c + (UInt64(x[xOff + 6]) + y[yOff + 6]);
  184. z[zOff + 6] := UInt32(c);
  185. c := c shr 32;
  186. c := c + (UInt64(x[xOff + 7]) + y[yOff + 7]);
  187. z[zOff + 7] := UInt32(c);
  188. c := c shr 32;
  189. result := UInt32(c);
  190. end;
  191. class function TNat256.AddBothTo(const x, y, z: TCryptoLibUInt32Array): UInt32;
  192. var
  193. c: UInt64;
  194. begin
  195. c := 0;
  196. c := c + (UInt64(x[0]) + y[0] + z[0]);
  197. z[0] := UInt32(c);
  198. c := c shr 32;
  199. c := c + (UInt64(x[1]) + y[1] + z[1]);
  200. z[1] := UInt32(c);
  201. c := c shr 32;
  202. c := c + (UInt64(x[2]) + y[2] + z[2]);
  203. z[2] := UInt32(c);
  204. c := c shr 32;
  205. c := c + (UInt64(x[3]) + y[3] + z[3]);
  206. z[3] := UInt32(c);
  207. c := c shr 32;
  208. c := c + (UInt64(x[4]) + y[4] + z[4]);
  209. z[4] := UInt32(c);
  210. c := c shr 32;
  211. c := c + (UInt64(x[5]) + y[5] + z[5]);
  212. z[5] := UInt32(c);
  213. c := c shr 32;
  214. c := c + (UInt64(x[6]) + y[6] + z[6]);
  215. z[6] := UInt32(c);
  216. c := c shr 32;
  217. c := c + (UInt64(x[7]) + y[7] + z[7]);
  218. z[7] := UInt32(c);
  219. c := c shr 32;
  220. result := UInt32(c);
  221. end;
  222. class function TNat256.AddBothTo(const x: TCryptoLibUInt32Array; xOff: Int32;
  223. const y: TCryptoLibUInt32Array; yOff: Int32; const z: TCryptoLibUInt32Array;
  224. zOff: Int32): UInt32;
  225. var
  226. c: UInt64;
  227. begin
  228. c := 0;
  229. c := c + (UInt64(x[xOff + 0]) + y[yOff + 0] + z[zOff + 0]);
  230. z[zOff + 0] := UInt32(c);
  231. c := c shr 32;
  232. c := c + (UInt64(x[xOff + 1]) + y[yOff + 1] + z[zOff + 1]);
  233. z[zOff + 1] := UInt32(c);
  234. c := c shr 32;
  235. c := c + (UInt64(x[xOff + 2]) + y[yOff + 2] + z[zOff + 2]);
  236. z[zOff + 2] := UInt32(c);
  237. c := c shr 32;
  238. c := c + (UInt64(x[xOff + 3]) + y[yOff + 3] + z[zOff + 3]);
  239. z[zOff + 3] := UInt32(c);
  240. c := c shr 32;
  241. c := c + (UInt64(x[xOff + 4]) + y[yOff + 4] + z[zOff + 4]);
  242. z[zOff + 4] := UInt32(c);
  243. c := c shr 32;
  244. c := c + (UInt64(x[xOff + 5]) + y[yOff + 5] + z[zOff + 5]);
  245. z[zOff + 5] := UInt32(c);
  246. c := c shr 32;
  247. c := c + (UInt64(x[xOff + 6]) + y[yOff + 6] + z[zOff + 6]);
  248. z[zOff + 6] := UInt32(c);
  249. c := c shr 32;
  250. c := c + (UInt64(x[xOff + 7]) + y[yOff + 7] + z[zOff + 7]);
  251. z[zOff + 7] := UInt32(c);
  252. c := c shr 32;
  253. result := UInt32(c);
  254. end;
  255. class function TNat256.AddTo(const x, z: TCryptoLibUInt32Array): UInt32;
  256. var
  257. c: UInt64;
  258. begin
  259. c := 0;
  260. c := c + (UInt64(x[0]) + z[0]);
  261. z[0] := UInt32(c);
  262. c := c shr 32;
  263. c := c + (UInt64(x[1]) + z[1]);
  264. z[1] := UInt32(c);
  265. c := c shr 32;
  266. c := c + (UInt64(x[2]) + z[2]);
  267. z[2] := UInt32(c);
  268. c := c shr 32;
  269. c := c + (UInt64(x[3]) + z[3]);
  270. z[3] := UInt32(c);
  271. c := c shr 32;
  272. c := c + (UInt64(x[4]) + z[4]);
  273. z[4] := UInt32(c);
  274. c := c shr 32;
  275. c := c + (UInt64(x[5]) + z[5]);
  276. z[5] := UInt32(c);
  277. c := c shr 32;
  278. c := c + (UInt64(x[6]) + z[6]);
  279. z[6] := UInt32(c);
  280. c := c shr 32;
  281. c := c + (UInt64(x[7]) + z[7]);
  282. z[7] := UInt32(c);
  283. c := c shr 32;
  284. result := UInt32(c);
  285. end;
  286. class function TNat256.AddTo(const x: TCryptoLibUInt32Array; xOff: Int32;
  287. const z: TCryptoLibUInt32Array; zOff: Int32; cIn: UInt32): UInt32;
  288. var
  289. c: UInt64;
  290. begin
  291. c := cIn;
  292. c := c + (UInt64(x[xOff + 0]) + z[zOff + 0]);
  293. z[zOff + 0] := UInt32(c);
  294. c := c shr 32;
  295. c := c + (UInt64(x[xOff + 1]) + z[zOff + 1]);
  296. z[zOff + 1] := UInt32(c);
  297. c := c shr 32;
  298. c := c + (UInt64(x[xOff + 2]) + z[zOff + 2]);
  299. z[zOff + 2] := UInt32(c);
  300. c := c shr 32;
  301. c := c + (UInt64(x[xOff + 3]) + z[zOff + 3]);
  302. z[zOff + 3] := UInt32(c);
  303. c := c shr 32;
  304. c := c + (UInt64(x[xOff + 4]) + z[zOff + 4]);
  305. z[zOff + 4] := UInt32(c);
  306. c := c shr 32;
  307. c := c + (UInt64(x[xOff + 5]) + z[zOff + 5]);
  308. z[zOff + 5] := UInt32(c);
  309. c := c shr 32;
  310. c := c + (UInt64(x[xOff + 6]) + z[zOff + 6]);
  311. z[zOff + 6] := UInt32(c);
  312. c := c shr 32;
  313. c := c + (UInt64(x[xOff + 7]) + z[zOff + 7]);
  314. z[zOff + 7] := UInt32(c);
  315. c := c shr 32;
  316. result := UInt32(c);
  317. end;
  318. class function TNat256.AddToEachOther(const u: TCryptoLibUInt32Array;
  319. uOff: Int32; const v: TCryptoLibUInt32Array; vOff: Int32): UInt32;
  320. var
  321. c: UInt64;
  322. begin
  323. c := 0;
  324. c := c + (UInt64(u[uOff + 0]) + v[vOff + 0]);
  325. u[uOff + 0] := UInt32(c);
  326. v[vOff + 0] := UInt32(c);
  327. c := c shr 32;
  328. c := c + (UInt64(u[uOff + 1]) + v[vOff + 1]);
  329. u[uOff + 1] := UInt32(c);
  330. v[vOff + 1] := UInt32(c);
  331. c := c shr 32;
  332. c := c + (UInt64(u[uOff + 2]) + v[vOff + 2]);
  333. u[uOff + 2] := UInt32(c);
  334. v[vOff + 2] := UInt32(c);
  335. c := c shr 32;
  336. c := c + (UInt64(u[uOff + 3]) + v[vOff + 3]);
  337. u[uOff + 3] := UInt32(c);
  338. v[vOff + 3] := UInt32(c);
  339. c := c shr 32;
  340. c := c + (UInt64(u[uOff + 4]) + v[vOff + 4]);
  341. u[uOff + 4] := UInt32(c);
  342. v[vOff + 4] := UInt32(c);
  343. c := c shr 32;
  344. c := c + (UInt64(u[uOff + 5]) + v[vOff + 5]);
  345. u[uOff + 5] := UInt32(c);
  346. v[vOff + 5] := UInt32(c);
  347. c := c shr 32;
  348. c := c + (UInt64(u[uOff + 6]) + v[vOff + 6]);
  349. u[uOff + 6] := UInt32(c);
  350. v[vOff + 6] := UInt32(c);
  351. c := c shr 32;
  352. c := c + (UInt64(u[uOff + 7]) + v[vOff + 7]);
  353. u[uOff + 7] := UInt32(c);
  354. v[vOff + 7] := UInt32(c);
  355. c := c shr 32;
  356. result := UInt32(c);
  357. end;
  358. class procedure TNat256.Copy(const x, z: TCryptoLibUInt32Array);
  359. begin
  360. System.Move(x[0], z[0], 8 * System.SizeOf(UInt32));
  361. end;
  362. class procedure TNat256.Copy(const x: TCryptoLibUInt32Array; xOff: Int32;
  363. const z: TCryptoLibUInt32Array; zOff: Int32);
  364. begin
  365. System.Move(x[xOff], z[zOff], 8 * System.SizeOf(UInt32));
  366. end;
  367. class procedure TNat256.Copy64(const x, z: TCryptoLibUInt64Array);
  368. begin
  369. System.Move(x[0], z[0], 4 * System.SizeOf(UInt64));
  370. end;
  371. class procedure TNat256.Copy64(const x: TCryptoLibUInt64Array; xOff: Int32;
  372. const z: TCryptoLibUInt64Array; zOff: Int32);
  373. begin
  374. System.Move(x[xOff], z[zOff], 4 * System.SizeOf(UInt64));
  375. end;
  376. class function TNat256.Create: TCryptoLibUInt32Array;
  377. begin
  378. System.SetLength(result, 8);
  379. end;
  380. class function TNat256.Create64: TCryptoLibUInt64Array;
  381. begin
  382. System.SetLength(result, 4);
  383. end;
  384. class function TNat256.CreateExt: TCryptoLibUInt32Array;
  385. begin
  386. System.SetLength(result, 16);
  387. end;
  388. class function TNat256.CreateExt64: TCryptoLibUInt64Array;
  389. begin
  390. System.SetLength(result, 8);
  391. end;
  392. class function TNat256.Diff(const x: TCryptoLibUInt32Array; xOff: Int32;
  393. const y: TCryptoLibUInt32Array; yOff: Int32; const z: TCryptoLibUInt32Array;
  394. zOff: Int32): Boolean;
  395. var
  396. pos: Boolean;
  397. begin
  398. pos := Gte(x, xOff, y, yOff);
  399. if (pos) then
  400. begin
  401. Sub(x, xOff, y, yOff, z, zOff);
  402. end
  403. else
  404. begin
  405. Sub(y, yOff, x, xOff, z, zOff);
  406. end;
  407. result := pos;
  408. end;
  409. class function TNat256.Eq(const x, y: TCryptoLibUInt32Array): Boolean;
  410. var
  411. i: Int32;
  412. begin
  413. i := 7;
  414. while i >= 0 do
  415. begin
  416. if (x[i] <> y[i]) then
  417. begin
  418. result := false;
  419. Exit;
  420. end;
  421. System.Dec(i);
  422. end;
  423. result := true;
  424. end;
  425. class function TNat256.Eq64(const x, y: TCryptoLibUInt64Array): Boolean;
  426. var
  427. i: Int32;
  428. begin
  429. i := 3;
  430. while i >= 0 do
  431. begin
  432. if (x[i] <> y[i]) then
  433. begin
  434. result := false;
  435. Exit;
  436. end;
  437. System.Dec(i);
  438. end;
  439. result := true;
  440. end;
  441. class function TNat256.FromBigInteger(const x: TBigInteger)
  442. : TCryptoLibUInt32Array;
  443. var
  444. i: Int32;
  445. Lx: TBigInteger;
  446. begin
  447. Lx := x;
  448. if ((Lx.SignValue < 0) or (Lx.BitLength > 256)) then
  449. begin
  450. raise EArgumentCryptoLibException.Create('');
  451. end;
  452. result := Create();
  453. i := 0;
  454. while (Lx.SignValue <> 0) do
  455. begin
  456. result[i] := UInt32(Lx.Int32Value);
  457. System.Inc(i);
  458. Lx := Lx.ShiftRight(32);
  459. end;
  460. end;
  461. class function TNat256.FromBigInteger64(const x: TBigInteger)
  462. : TCryptoLibUInt64Array;
  463. var
  464. i: Int32;
  465. Lx: TBigInteger;
  466. begin
  467. Lx := x;
  468. if ((Lx.SignValue < 0) or (Lx.BitLength > 256)) then
  469. begin
  470. raise EArgumentCryptoLibException.Create('');
  471. end;
  472. result := Create64();
  473. i := 0;
  474. while (Lx.SignValue <> 0) do
  475. begin
  476. result[i] := UInt64(Lx.Int64Value);
  477. System.Inc(i);
  478. Lx := Lx.ShiftRight(64);
  479. end;
  480. end;
  481. class function TNat256.GetBit(const x: TCryptoLibUInt32Array;
  482. bit: Int32): UInt32;
  483. var
  484. w, b: Int32;
  485. begin
  486. if (bit = 0) then
  487. begin
  488. result := x[0] and 1;
  489. Exit;
  490. end;
  491. if ((bit and 255) <> bit) then
  492. begin
  493. result := 0;
  494. Exit;
  495. end;
  496. w := TBits.Asr32(bit, 5);
  497. b := bit and 31;
  498. result := (x[w] shr b) and 1;
  499. end;
  500. class function TNat256.Gte(const x, y: TCryptoLibUInt32Array): Boolean;
  501. var
  502. i: Int32;
  503. x_i, y_i: UInt32;
  504. begin
  505. i := 7;
  506. while i >= 0 do
  507. begin
  508. x_i := x[i];
  509. y_i := y[i];
  510. if (x_i < y_i) then
  511. begin
  512. result := false;
  513. Exit;
  514. end;
  515. if (x_i > y_i) then
  516. begin
  517. result := true;
  518. Exit;
  519. end;
  520. System.Dec(i);
  521. end;
  522. result := true;
  523. end;
  524. class function TNat256.Gte(const x: TCryptoLibUInt32Array; xOff: Int32;
  525. const y: TCryptoLibUInt32Array; yOff: Int32): Boolean;
  526. var
  527. i: Int32;
  528. x_i, y_i: UInt32;
  529. begin
  530. i := 7;
  531. while i >= 0 do
  532. begin
  533. x_i := x[xOff + i];
  534. y_i := y[yOff + i];
  535. if (x_i < y_i) then
  536. begin
  537. result := false;
  538. Exit;
  539. end;
  540. if (x_i > y_i) then
  541. begin
  542. result := true;
  543. Exit;
  544. end;
  545. System.Dec(i);
  546. end;
  547. result := true;
  548. end;
  549. class function TNat256.IsOne(const x: TCryptoLibUInt32Array): Boolean;
  550. var
  551. i: Int32;
  552. begin
  553. if (x[0] <> 1) then
  554. begin
  555. result := false;
  556. Exit;
  557. end;
  558. i := 1;
  559. while i < 8 do
  560. begin
  561. if (x[i] <> 0) then
  562. begin
  563. result := false;
  564. Exit;
  565. end;
  566. System.Inc(i);
  567. end;
  568. result := true;
  569. end;
  570. class function TNat256.IsOne64(const x: TCryptoLibUInt64Array): Boolean;
  571. var
  572. i: Int32;
  573. begin
  574. if (x[0] <> UInt64(1)) then
  575. begin
  576. result := false;
  577. Exit;
  578. end;
  579. i := 1;
  580. while i < 4 do
  581. begin
  582. if (x[i] <> UInt64(0)) then
  583. begin
  584. result := false;
  585. Exit;
  586. end;
  587. System.Inc(i);
  588. end;
  589. result := true;
  590. end;
  591. class function TNat256.IsZero(const x: TCryptoLibUInt32Array): Boolean;
  592. var
  593. i: Int32;
  594. begin
  595. i := 0;
  596. while i < 8 do
  597. begin
  598. if (x[i] <> 0) then
  599. begin
  600. result := false;
  601. Exit;
  602. end;
  603. System.Inc(i);
  604. end;
  605. result := true;
  606. end;
  607. class function TNat256.IsZero64(const x: TCryptoLibUInt64Array): Boolean;
  608. var
  609. i: Int32;
  610. begin
  611. i := 0;
  612. while i < 4 do
  613. begin
  614. if (x[i] <> UInt64(0)) then
  615. begin
  616. result := false;
  617. Exit;
  618. end;
  619. System.Inc(i);
  620. end;
  621. result := true;
  622. end;
  623. class procedure TNat256.Mul(const x, y, zz: TCryptoLibUInt32Array);
  624. var
  625. c, x_0, x_i, y_0, y_1, y_2, y_3, y_4, y_5, y_6, y_7: UInt64;
  626. i: Int32;
  627. begin
  628. y_0 := y[0];
  629. y_1 := y[1];
  630. y_2 := y[2];
  631. y_3 := y[3];
  632. y_4 := y[4];
  633. y_5 := y[5];
  634. y_6 := y[6];
  635. y_7 := y[7];
  636. c := 0;
  637. x_0 := x[0];
  638. c := c + (x_0 * y_0);
  639. zz[0] := UInt32(c);
  640. c := c shr 32;
  641. c := c + (x_0 * y_1);
  642. zz[1] := UInt32(c);
  643. c := c shr 32;
  644. c := c + (x_0 * y_2);
  645. zz[2] := UInt32(c);
  646. c := c shr 32;
  647. c := c + (x_0 * y_3);
  648. zz[3] := UInt32(c);
  649. c := c shr 32;
  650. c := c + (x_0 * y_4);
  651. zz[4] := UInt32(c);
  652. c := c shr 32;
  653. c := c + (x_0 * y_5);
  654. zz[5] := UInt32(c);
  655. c := c shr 32;
  656. c := c + (x_0 * y_6);
  657. zz[6] := UInt32(c);
  658. c := c shr 32;
  659. c := c + (x_0 * y_7);
  660. zz[7] := UInt32(c);
  661. c := c shr 32;
  662. zz[8] := UInt32(c);
  663. for i := 1 to System.Pred(8) do
  664. begin
  665. c := 0;
  666. x_i := x[i];
  667. c := c + (x_i * y_0 + zz[i + 0]);
  668. zz[i + 0] := UInt32(c);
  669. c := c shr 32;
  670. c := c + (x_i * y_1 + zz[i + 1]);
  671. zz[i + 1] := UInt32(c);
  672. c := c shr 32;
  673. c := c + (x_i * y_2 + zz[i + 2]);
  674. zz[i + 2] := UInt32(c);
  675. c := c shr 32;
  676. c := c + (x_i * y_3 + zz[i + 3]);
  677. zz[i + 3] := UInt32(c);
  678. c := c shr 32;
  679. c := c + (x_i * y_4 + zz[i + 4]);
  680. zz[i + 4] := UInt32(c);
  681. c := c shr 32;
  682. c := c + (x_i * y_5 + zz[i + 5]);
  683. zz[i + 5] := UInt32(c);
  684. c := c shr 32;
  685. c := c + (x_i * y_6 + zz[i + 6]);
  686. zz[i + 6] := UInt32(c);
  687. c := c shr 32;
  688. c := c + (x_i * y_7 + zz[i + 7]);
  689. zz[i + 7] := UInt32(c);
  690. c := c shr 32;
  691. zz[i + 8] := UInt32(c);
  692. end;
  693. end;
  694. class procedure TNat256.Mul(const x: TCryptoLibUInt32Array; xOff: Int32;
  695. const y: TCryptoLibUInt32Array; yOff: Int32; const zz: TCryptoLibUInt32Array;
  696. zzOff: Int32);
  697. var
  698. c, x_0, x_i, y_0, y_1, y_2, y_3, y_4, y_5, y_6, y_7: UInt64;
  699. i: Int32;
  700. begin
  701. y_0 := y[yOff + 0];
  702. y_1 := y[yOff + 1];
  703. y_2 := y[yOff + 2];
  704. y_3 := y[yOff + 3];
  705. y_4 := y[yOff + 4];
  706. y_5 := y[yOff + 5];
  707. y_6 := y[yOff + 6];
  708. y_7 := y[yOff + 7];
  709. c := 0;
  710. x_0 := x[xOff + 0];
  711. c := c + (x_0 * y_0);
  712. zz[zzOff + 0] := UInt32(c);
  713. c := c shr 32;
  714. c := c + (x_0 * y_1);
  715. zz[zzOff + 1] := UInt32(c);
  716. c := c shr 32;
  717. c := c + (x_0 * y_2);
  718. zz[zzOff + 2] := UInt32(c);
  719. c := c shr 32;
  720. c := c + (x_0 * y_3);
  721. zz[zzOff + 3] := UInt32(c);
  722. c := c shr 32;
  723. c := c + (x_0 * y_4);
  724. zz[zzOff + 4] := UInt32(c);
  725. c := c shr 32;
  726. c := c + (x_0 * y_5);
  727. zz[zzOff + 5] := UInt32(c);
  728. c := c shr 32;
  729. c := c + (x_0 * y_6);
  730. zz[zzOff + 6] := UInt32(c);
  731. c := c shr 32;
  732. c := c + (x_0 * y_7);
  733. zz[zzOff + 7] := UInt32(c);
  734. c := c shr 32;
  735. zz[zzOff + 8] := UInt32(c);
  736. for i := 1 to System.Pred(8) do
  737. begin
  738. System.Inc(zzOff);
  739. c := 0;
  740. x_i := x[xOff + i];
  741. c := c + (x_i * y_0 + zz[zzOff + 0]);
  742. zz[zzOff + 0] := UInt32(c);
  743. c := c shr 32;
  744. c := c + (x_i * y_1 + zz[zzOff + 1]);
  745. zz[zzOff + 1] := UInt32(c);
  746. c := c shr 32;
  747. c := c + (x_i * y_2 + zz[zzOff + 2]);
  748. zz[zzOff + 2] := UInt32(c);
  749. c := c shr 32;
  750. c := c + (x_i * y_3 + zz[zzOff + 3]);
  751. zz[zzOff + 3] := UInt32(c);
  752. c := c shr 32;
  753. c := c + (x_i * y_4 + zz[zzOff + 4]);
  754. zz[zzOff + 4] := UInt32(c);
  755. c := c shr 32;
  756. c := c + (x_i * y_5 + zz[zzOff + 5]);
  757. zz[zzOff + 5] := UInt32(c);
  758. c := c shr 32;
  759. c := c + (x_i * y_6 + zz[zzOff + 6]);
  760. zz[zzOff + 6] := UInt32(c);
  761. c := c shr 32;
  762. c := c + (x_i * y_7 + zz[zzOff + 7]);
  763. zz[zzOff + 7] := UInt32(c);
  764. c := c shr 32;
  765. zz[zzOff + 8] := UInt32(c);
  766. end;
  767. end;
  768. class function TNat256.MulAddTo(const x, y, zz: TCryptoLibUInt32Array): UInt32;
  769. var
  770. c, x_i, y_0, y_1, y_2, y_3, y_4, y_5, y_6, y_7, zc: UInt64;
  771. i: Int32;
  772. begin
  773. y_0 := y[0];
  774. y_1 := y[1];
  775. y_2 := y[2];
  776. y_3 := y[3];
  777. y_4 := y[4];
  778. y_5 := y[5];
  779. y_6 := y[6];
  780. y_7 := y[7];
  781. zc := 0;
  782. for i := 0 to System.Pred(8) do
  783. begin
  784. c := 0;
  785. x_i := x[i];
  786. c := c + (x_i * y_0 + zz[i + 0]);
  787. zz[i + 0] := UInt32(c);
  788. c := c shr 32;
  789. c := c + (x_i * y_1 + zz[i + 1]);
  790. zz[i + 1] := UInt32(c);
  791. c := c shr 32;
  792. c := c + (x_i * y_2 + zz[i + 2]);
  793. zz[i + 2] := UInt32(c);
  794. c := c shr 32;
  795. c := c + (x_i * y_3 + zz[i + 3]);
  796. zz[i + 3] := UInt32(c);
  797. c := c shr 32;
  798. c := c + (x_i * y_4 + zz[i + 4]);
  799. zz[i + 4] := UInt32(c);
  800. c := c shr 32;
  801. c := c + (x_i * y_5 + zz[i + 5]);
  802. zz[i + 5] := UInt32(c);
  803. c := c shr 32;
  804. c := c + (x_i * y_6 + zz[i + 6]);
  805. zz[i + 6] := UInt32(c);
  806. c := c shr 32;
  807. c := c + (x_i * y_7 + zz[i + 7]);
  808. zz[i + 7] := UInt32(c);
  809. c := c shr 32;
  810. zc := zc + (c + (zz[i + 8] and M));
  811. zz[i + 8] := UInt32(zc);
  812. zc := zc shr 32;
  813. end;
  814. result := UInt32(zc);
  815. end;
  816. class function TNat256.MulAddTo(const x: TCryptoLibUInt32Array; xOff: Int32;
  817. const y: TCryptoLibUInt32Array; yOff: Int32; const zz: TCryptoLibUInt32Array;
  818. zzOff: Int32): UInt32;
  819. var
  820. c, x_i, y_0, y_1, y_2, y_3, y_4, y_5, y_6, y_7, zc: UInt64;
  821. i: Int32;
  822. begin
  823. y_0 := y[yOff + 0];
  824. y_1 := y[yOff + 1];
  825. y_2 := y[yOff + 2];
  826. y_3 := y[yOff + 3];
  827. y_4 := y[yOff + 4];
  828. y_5 := y[yOff + 5];
  829. y_6 := y[yOff + 6];
  830. y_7 := y[yOff + 7];
  831. zc := 0;
  832. for i := 0 to System.Pred(8) do
  833. begin
  834. c := 0;
  835. x_i := x[xOff + i];
  836. c := c + (x_i * y_0 + zz[zzOff + 0]);
  837. zz[zzOff + 0] := UInt32(c);
  838. c := c shr 32;
  839. c := c + (x_i * y_1 + zz[zzOff + 1]);
  840. zz[zzOff + 1] := UInt32(c);
  841. c := c shr 32;
  842. c := c + (x_i * y_2 + zz[zzOff + 2]);
  843. zz[zzOff + 2] := UInt32(c);
  844. c := c shr 32;
  845. c := c + (x_i * y_3 + zz[zzOff + 3]);
  846. zz[zzOff + 3] := UInt32(c);
  847. c := c shr 32;
  848. c := c + (x_i * y_4 + zz[zzOff + 4]);
  849. zz[zzOff + 4] := UInt32(c);
  850. c := c shr 32;
  851. c := c + (x_i * y_5 + zz[zzOff + 5]);
  852. zz[zzOff + 5] := UInt32(c);
  853. c := c shr 32;
  854. c := c + (x_i * y_6 + zz[zzOff + 6]);
  855. zz[zzOff + 6] := UInt32(c);
  856. c := c shr 32;
  857. c := c + (x_i * y_7 + zz[zzOff + 7]);
  858. zz[zzOff + 7] := UInt32(c);
  859. c := c shr 32;
  860. zc := zc + (c + (zz[zzOff + 8] and M));
  861. zz[zzOff + 8] := UInt32(zc);
  862. zc := zc shr 32;
  863. System.Inc(zzOff);
  864. end;
  865. result := UInt32(zc);
  866. end;
  867. class function TNat256.Mul33Add(w: UInt32; const x: TCryptoLibUInt32Array;
  868. xOff: Int32; const y: TCryptoLibUInt32Array; yOff: Int32;
  869. const z: TCryptoLibUInt32Array; zOff: Int32): UInt64;
  870. var
  871. c, wVal, x0, x1, x2, x3, x4, x5, x6, x7: UInt64;
  872. begin
  873. {$IFDEF DEBUG}
  874. System.Assert(w shr 31 = 0);
  875. {$ENDIF DEBUG}
  876. c := 0;
  877. wVal := w;
  878. x0 := x[xOff + 0];
  879. c := c + (wVal * x0 + y[yOff + 0]);
  880. z[zOff + 0] := UInt32(c);
  881. c := c shr 32;
  882. x1 := x[xOff + 1];
  883. c := c + (wVal * x1 + x0 + y[yOff + 1]);
  884. z[zOff + 1] := UInt32(c);
  885. c := c shr 32;
  886. x2 := x[xOff + 2];
  887. c := c + (wVal * x2 + x1 + y[yOff + 2]);
  888. z[zOff + 2] := UInt32(c);
  889. c := c shr 32;
  890. x3 := x[xOff + 3];
  891. c := c + (wVal * x3 + x2 + y[yOff + 3]);
  892. z[zOff + 3] := UInt32(c);
  893. c := c shr 32;
  894. x4 := x[xOff + 4];
  895. c := c + (wVal * x4 + x3 + y[yOff + 4]);
  896. z[zOff + 4] := UInt32(c);
  897. c := c shr 32;
  898. x5 := x[xOff + 5];
  899. c := c + (wVal * x5 + x4 + y[yOff + 5]);
  900. z[zOff + 5] := UInt32(c);
  901. c := c shr 32;
  902. x6 := x[xOff + 6];
  903. c := c + (wVal * x6 + x5 + y[yOff + 6]);
  904. z[zOff + 6] := UInt32(c);
  905. c := c shr 32;
  906. x7 := x[xOff + 7];
  907. c := c + (wVal * x7 + x6 + y[yOff + 7]);
  908. z[zOff + 7] := UInt32(c);
  909. c := c shr 32;
  910. c := c + x7;
  911. result := c;
  912. end;
  913. class function TNat256.MulByWord(x: UInt32;
  914. const z: TCryptoLibUInt32Array): UInt32;
  915. var
  916. c, xVal: UInt64;
  917. begin
  918. c := 0;
  919. xVal := x;
  920. c := c + (xVal * UInt64(z[0]));
  921. z[0] := UInt32(c);
  922. c := c shr 32;
  923. c := c + (xVal * UInt64(z[1]));
  924. z[1] := UInt32(c);
  925. c := c shr 32;
  926. c := c + (xVal * UInt64(z[2]));
  927. z[2] := UInt32(c);
  928. c := c shr 32;
  929. c := c + (xVal * UInt64(z[3]));
  930. z[3] := UInt32(c);
  931. c := c shr 32;
  932. c := c + (xVal * UInt64(z[4]));
  933. z[4] := UInt32(c);
  934. c := c shr 32;
  935. c := c + (xVal * UInt64(z[5]));
  936. z[5] := UInt32(c);
  937. c := c shr 32;
  938. c := c + (xVal * UInt64(z[6]));
  939. z[6] := UInt32(c);
  940. c := c shr 32;
  941. c := c + (xVal * UInt64(z[7]));
  942. z[7] := UInt32(c);
  943. c := c shr 32;
  944. result := UInt32(c);
  945. end;
  946. class function TNat256.MulByWordAddTo(x: UInt32;
  947. const y, z: TCryptoLibUInt32Array): UInt32;
  948. var
  949. c, xVal: UInt64;
  950. begin
  951. c := 0;
  952. xVal := x;
  953. c := c + (xVal * UInt64(z[0]) + y[0]);
  954. z[0] := UInt32(c);
  955. c := c shr 32;
  956. c := c + (xVal * UInt64(z[1]) + y[1]);
  957. z[1] := UInt32(c);
  958. c := c shr 32;
  959. c := c + (xVal * UInt64(z[2]) + y[2]);
  960. z[2] := UInt32(c);
  961. c := c shr 32;
  962. c := c + (xVal * UInt64(z[3]) + y[3]);
  963. z[3] := UInt32(c);
  964. c := c shr 32;
  965. c := c + (xVal * UInt64(z[4]) + y[4]);
  966. z[4] := UInt32(c);
  967. c := c shr 32;
  968. c := c + (xVal * UInt64(z[5]) + y[5]);
  969. z[5] := UInt32(c);
  970. c := c shr 32;
  971. c := c + (xVal * UInt64(z[6]) + y[6]);
  972. z[6] := UInt32(c);
  973. c := c shr 32;
  974. c := c + (xVal * UInt64(z[7]) + y[7]);
  975. z[7] := UInt32(c);
  976. c := c shr 32;
  977. result := UInt32(c);
  978. end;
  979. class function TNat256.MulWordAddTo(x: UInt32; const y: TCryptoLibUInt32Array;
  980. yOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32): UInt32;
  981. var
  982. c, xVal: UInt64;
  983. begin
  984. c := 0;
  985. xVal := x;
  986. c := c + (xVal * y[yOff + 0] + z[zOff + 0]);
  987. z[zOff + 0] := UInt32(c);
  988. c := c shr 32;
  989. c := c + (xVal * y[yOff + 1] + z[zOff + 1]);
  990. z[zOff + 1] := UInt32(c);
  991. c := c shr 32;
  992. c := c + (xVal * y[yOff + 2] + z[zOff + 2]);
  993. z[zOff + 2] := UInt32(c);
  994. c := c shr 32;
  995. c := c + (xVal * y[yOff + 3] + z[zOff + 3]);
  996. z[zOff + 3] := UInt32(c);
  997. c := c shr 32;
  998. c := c + (xVal * y[yOff + 4] + z[zOff + 4]);
  999. z[zOff + 4] := UInt32(c);
  1000. c := c shr 32;
  1001. c := c + (xVal * y[yOff + 5] + z[zOff + 5]);
  1002. z[zOff + 5] := UInt32(c);
  1003. c := c shr 32;
  1004. c := c + (xVal * y[yOff + 6] + z[zOff + 6]);
  1005. z[zOff + 6] := UInt32(c);
  1006. c := c shr 32;
  1007. c := c + (xVal * y[yOff + 7] + z[zOff + 7]);
  1008. z[zOff + 7] := UInt32(c);
  1009. c := c shr 32;
  1010. result := UInt32(c);
  1011. end;
  1012. class function TNat256.Mul33DWordAdd(x: UInt32; y: UInt64;
  1013. const z: TCryptoLibUInt32Array; zOff: Int32): UInt32;
  1014. var
  1015. c, xVal, y00, y01: UInt64;
  1016. begin
  1017. {$IFDEF DEBUG}
  1018. System.Assert(x shr 31 = 0);
  1019. System.Assert(zOff <= 4);
  1020. {$ENDIF DEBUG}
  1021. c := 0;
  1022. xVal := x;
  1023. y00 := y and M;
  1024. c := c + (xVal * y00 + z[zOff + 0]);
  1025. z[zOff + 0] := UInt32(c);
  1026. c := c shr 32;
  1027. y01 := y shr 32;
  1028. c := c + (xVal * y01 + y00 + z[zOff + 1]);
  1029. z[zOff + 1] := UInt32(c);
  1030. c := c shr 32;
  1031. c := c + (y01 + z[zOff + 2]);
  1032. z[zOff + 2] := UInt32(c);
  1033. c := c shr 32;
  1034. c := c + (z[zOff + 3]);
  1035. z[zOff + 3] := UInt32(c);
  1036. c := c shr 32;
  1037. if c = 0 then
  1038. begin
  1039. result := 0;
  1040. end
  1041. else
  1042. begin
  1043. result := TNat.IncAt(8, z, zOff, 4);
  1044. end;
  1045. end;
  1046. class function TNat256.Mul33WordAdd(x, y: UInt32;
  1047. const z: TCryptoLibUInt32Array; zOff: Int32): UInt32;
  1048. var
  1049. c, yVal: UInt64;
  1050. begin
  1051. {$IFDEF DEBUG}
  1052. System.Assert(x shr 31 = 0);
  1053. System.Assert(zOff <= 5);
  1054. {$ENDIF DEBUG}
  1055. c := 0;
  1056. yVal := y;
  1057. c := c + (yVal * x + z[zOff + 0]);
  1058. z[zOff + 0] := UInt32(c);
  1059. c := c shr 32;
  1060. c := c + (yVal + z[zOff + 1]);
  1061. z[zOff + 1] := UInt32(c);
  1062. c := c shr 32;
  1063. c := c + (z[zOff + 2]);
  1064. z[zOff + 2] := UInt32(c);
  1065. c := c shr 32;
  1066. if c = 0 then
  1067. begin
  1068. result := 0;
  1069. end
  1070. else
  1071. begin
  1072. result := TNat.IncAt(8, z, zOff, 3);
  1073. end;
  1074. end;
  1075. class function TNat256.MulWordDwordAdd(x: UInt32; y: UInt64;
  1076. const z: TCryptoLibUInt32Array; zOff: Int32): UInt32;
  1077. var
  1078. c, xVal: UInt64;
  1079. begin
  1080. {$IFDEF DEBUG}
  1081. System.Assert(zOff <= 5);
  1082. {$ENDIF DEBUG}
  1083. c := 0;
  1084. xVal := x;
  1085. c := c + (xVal * y + z[zOff + 0]);
  1086. z[zOff + 0] := UInt32(c);
  1087. c := c shr 32;
  1088. c := c + (xVal * (y shr 32) + z[zOff + 1]);
  1089. z[zOff + 1] := UInt32(c);
  1090. c := c shr 32;
  1091. c := c + (z[zOff + 2]);
  1092. z[zOff + 2] := UInt32(c);
  1093. c := c shr 32;
  1094. if c = 0 then
  1095. begin
  1096. result := 0;
  1097. end
  1098. else
  1099. begin
  1100. result := TNat.IncAt(8, z, zOff, 3);
  1101. end;
  1102. end;
  1103. class function TNat256.MulWord(x: UInt32; const y, z: TCryptoLibUInt32Array;
  1104. zOff: Int32): UInt32;
  1105. var
  1106. c, xVal: UInt64;
  1107. i: Int32;
  1108. begin
  1109. c := 0;
  1110. xVal := x;
  1111. i := 0;
  1112. repeat
  1113. c := c + (xVal * y[i]);
  1114. z[zOff + i] := UInt32(c);
  1115. c := c shr 32;
  1116. System.Inc(i);
  1117. until not(i < 8);
  1118. result := UInt32(c);
  1119. end;
  1120. class procedure TNat256.Square(const x, zz: TCryptoLibUInt32Array);
  1121. var
  1122. x_0, zz_1, xVal, p, x_1, zz_2, x_2, zz_3, zz_4, x_3, zz_5, zz_6, x_4, zz_7,
  1123. zz_8, x_5, zz_9, zz_10, x_6, zz_11, zz_12, x_7, zz_13, zz_14: UInt64;
  1124. c, w: UInt32;
  1125. i, j: Int32;
  1126. begin
  1127. x_0 := x[0];
  1128. c := 0;
  1129. i := 7;
  1130. j := 16;
  1131. repeat
  1132. xVal := x[i];
  1133. System.Dec(i);
  1134. p := xVal * xVal;
  1135. System.Dec(j);
  1136. zz[j] := (c shl 31) or UInt32(p shr 33);
  1137. System.Dec(j);
  1138. zz[j] := UInt32(p shr 1);
  1139. c := UInt32(p);
  1140. until not(i > 0);
  1141. p := x_0 * x_0;
  1142. zz_1 := UInt64(c shl 31) or (p shr 33);
  1143. zz[0] := UInt32(p);
  1144. c := UInt32(p shr 32) and 1;
  1145. x_1 := x[1];
  1146. zz_2 := zz[2];
  1147. zz_1 := zz_1 + (x_1 * x_0);
  1148. w := UInt32(zz_1);
  1149. zz[1] := (w shl 1) or c;
  1150. c := w shr 31;
  1151. zz_2 := zz_2 + (zz_1 shr 32);
  1152. x_2 := x[2];
  1153. zz_3 := zz[3];
  1154. zz_4 := zz[4];
  1155. zz_2 := zz_2 + (x_2 * x_0);
  1156. w := UInt32(zz_2);
  1157. zz[2] := (w shl 1) or c;
  1158. c := w shr 31;
  1159. zz_3 := zz_3 + ((zz_2 shr 32) + x_2 * x_1);
  1160. zz_4 := zz_4 + (zz_3 shr 32);
  1161. zz_3 := zz_3 and M;
  1162. x_3 := x[3];
  1163. zz_5 := zz[5] + (zz_4 shr 32);
  1164. zz_4 := zz_4 and M;
  1165. zz_6 := zz[6] + (zz_5 shr 32);
  1166. zz_5 := zz_5 and M;
  1167. zz_3 := zz_3 + (x_3 * x_0);
  1168. w := UInt32(zz_3);
  1169. zz[3] := (w shl 1) or c;
  1170. c := w shr 31;
  1171. zz_4 := zz_4 + ((zz_3 shr 32) + x_3 * x_1);
  1172. zz_5 := zz_5 + ((zz_4 shr 32) + x_3 * x_2);
  1173. zz_4 := zz_4 and M;
  1174. zz_6 := zz_6 + (zz_5 shr 32);
  1175. zz_5 := zz_5 and M;
  1176. x_4 := x[4];
  1177. zz_7 := zz[7] + (zz_6 shr 32);
  1178. zz_6 := zz_6 and M;
  1179. zz_8 := zz[8] + (zz_7 shr 32);
  1180. zz_7 := zz_7 and M;
  1181. zz_4 := zz_4 + (x_4 * x_0);
  1182. w := UInt32(zz_4);
  1183. zz[4] := (w shl 1) or c;
  1184. c := w shr 31;
  1185. zz_5 := zz_5 + ((zz_4 shr 32) + x_4 * x_1);
  1186. zz_6 := zz_6 + ((zz_5 shr 32) + x_4 * x_2);
  1187. zz_5 := zz_5 and M;
  1188. zz_7 := zz_7 + ((zz_6 shr 32) + x_4 * x_3);
  1189. zz_6 := zz_6 and M;
  1190. zz_8 := zz_8 + (zz_7 shr 32);
  1191. zz_7 := zz_7 and M;
  1192. x_5 := x[5];
  1193. zz_9 := zz[9] + (zz_8 shr 32);
  1194. zz_8 := zz_8 and M;
  1195. zz_10 := zz[10] + (zz_9 shr 32);
  1196. zz_9 := zz_9 and M;
  1197. zz_5 := zz_5 + (x_5 * x_0);
  1198. w := UInt32(zz_5);
  1199. zz[5] := (w shl 1) or c;
  1200. c := w shr 31;
  1201. zz_6 := zz_6 + ((zz_5 shr 32) + x_5 * x_1);
  1202. zz_7 := zz_7 + ((zz_6 shr 32) + x_5 * x_2);
  1203. zz_6 := zz_6 and M;
  1204. zz_8 := zz_8 + ((zz_7 shr 32) + x_5 * x_3);
  1205. zz_7 := zz_7 and M;
  1206. zz_9 := zz_9 + ((zz_8 shr 32) + x_5 * x_4);
  1207. zz_8 := zz_8 and M;
  1208. zz_10 := zz_10 + (zz_9 shr 32);
  1209. zz_9 := zz_9 and M;
  1210. x_6 := x[6];
  1211. zz_11 := zz[11] + (zz_10 shr 32);
  1212. zz_10 := zz_10 and M;
  1213. zz_12 := zz[12] + (zz_11 shr 32);
  1214. zz_11 := zz_11 and M;
  1215. zz_6 := zz_6 + (x_6 * x_0);
  1216. w := UInt32(zz_6);
  1217. zz[6] := (w shl 1) or c;
  1218. c := w shr 31;
  1219. zz_7 := zz_7 + ((zz_6 shr 32) + x_6 * x_1);
  1220. zz_8 := zz_8 + ((zz_7 shr 32) + x_6 * x_2);
  1221. zz_7 := zz_7 and M;
  1222. zz_9 := zz_9 + ((zz_8 shr 32) + x_6 * x_3);
  1223. zz_8 := zz_8 and M;
  1224. zz_10 := zz_10 + ((zz_9 shr 32) + x_6 * x_4);
  1225. zz_9 := zz_9 and M;
  1226. zz_11 := zz_11 + ((zz_10 shr 32) + x_6 * x_5);
  1227. zz_10 := zz_10 and M;
  1228. zz_12 := zz_12 + (zz_11 shr 32);
  1229. zz_11 := zz_11 and M;
  1230. x_7 := x[7];
  1231. zz_13 := zz[13] + (zz_12 shr 32);
  1232. zz_12 := zz_12 and M;
  1233. zz_14 := zz[14] + (zz_13 shr 32);
  1234. zz_13 := zz_13 and M;
  1235. zz_7 := zz_7 + (x_7 * x_0);
  1236. w := UInt32(zz_7);
  1237. zz[7] := (w shl 1) or c;
  1238. c := w shr 31;
  1239. zz_8 := zz_8 + ((zz_7 shr 32) + x_7 * x_1);
  1240. zz_9 := zz_9 + ((zz_8 shr 32) + x_7 * x_2);
  1241. zz_10 := zz_10 + ((zz_9 shr 32) + x_7 * x_3);
  1242. zz_11 := zz_11 + ((zz_10 shr 32) + x_7 * x_4);
  1243. zz_12 := zz_12 + ((zz_11 shr 32) + x_7 * x_5);
  1244. zz_13 := zz_13 + ((zz_12 shr 32) + x_7 * x_6);
  1245. zz_14 := zz_14 + (zz_13 shr 32);
  1246. w := UInt32(zz_8);
  1247. zz[8] := (w shl 1) or c;
  1248. c := w shr 31;
  1249. w := UInt32(zz_9);
  1250. zz[9] := (w shl 1) or c;
  1251. c := w shr 31;
  1252. w := UInt32(zz_10);
  1253. zz[10] := (w shl 1) or c;
  1254. c := w shr 31;
  1255. w := UInt32(zz_11);
  1256. zz[11] := (w shl 1) or c;
  1257. c := w shr 31;
  1258. w := UInt32(zz_12);
  1259. zz[12] := (w shl 1) or c;
  1260. c := w shr 31;
  1261. w := UInt32(zz_13);
  1262. zz[13] := (w shl 1) or c;
  1263. c := w shr 31;
  1264. w := UInt32(zz_14);
  1265. zz[14] := (w shl 1) or c;
  1266. c := w shr 31;
  1267. w := zz[15] + UInt32(zz_14 shr 32);
  1268. zz[15] := (w shl 1) or c;
  1269. end;
  1270. class procedure TNat256.Square(const x: TCryptoLibUInt32Array; xOff: Int32;
  1271. const zz: TCryptoLibUInt32Array; zzOff: Int32);
  1272. var
  1273. x_0, zz_1, xVal, p, x_1, zz_2, x_2, zz_3, zz_4, x_3, zz_5, zz_6, x_4, zz_7,
  1274. zz_8, x_5, zz_9, zz_10, x_6, zz_11, zz_12, x_7, zz_13, zz_14: UInt64;
  1275. c, w: UInt32;
  1276. i, j: Int32;
  1277. begin
  1278. x_0 := x[xOff + 0];
  1279. c := 0;
  1280. i := 7;
  1281. j := 16;
  1282. repeat
  1283. xVal := x[xOff + i];
  1284. System.Dec(i);
  1285. p := xVal * xVal;
  1286. System.Dec(j);
  1287. zz[zzOff + j] := (c shl 31) or UInt32(p shr 33);
  1288. System.Dec(j);
  1289. zz[zzOff + j] := UInt32(p shr 1);
  1290. c := UInt32(p);
  1291. until not(i > 0);
  1292. p := x_0 * x_0;
  1293. zz_1 := UInt64(c shl 31) or (p shr 33);
  1294. zz[zzOff + 0] := UInt32(p);
  1295. c := UInt32(p shr 32) and 1;
  1296. x_1 := x[xOff + 1];
  1297. zz_2 := zz[zzOff + 2];
  1298. zz_1 := zz_1 + (x_1 * x_0);
  1299. w := UInt32(zz_1);
  1300. zz[zzOff + 1] := (w shl 1) or c;
  1301. c := w shr 31;
  1302. zz_2 := zz_2 + (zz_1 shr 32);
  1303. x_2 := x[xOff + 2];
  1304. zz_3 := zz[zzOff + 3];
  1305. zz_4 := zz[zzOff + 4];
  1306. zz_2 := zz_2 + (x_2 * x_0);
  1307. w := UInt32(zz_2);
  1308. zz[zzOff + 2] := (w shl 1) or c;
  1309. c := w shr 31;
  1310. zz_3 := zz_3 + ((zz_2 shr 32) + x_2 * x_1);
  1311. zz_4 := zz_4 + (zz_3 shr 32);
  1312. zz_3 := zz_3 and M;
  1313. x_3 := x[xOff + 3];
  1314. zz_5 := zz[zzOff + 5] + (zz_4 shr 32);
  1315. zz_4 := zz_4 and M;
  1316. zz_6 := zz[zzOff + 6] + (zz_5 shr 32);
  1317. zz_5 := zz_5 and M;
  1318. zz_3 := zz_3 + (x_3 * x_0);
  1319. w := UInt32(zz_3);
  1320. zz[zzOff + 3] := (w shl 1) or c;
  1321. c := w shr 31;
  1322. zz_4 := zz_4 + ((zz_3 shr 32) + x_3 * x_1);
  1323. zz_5 := zz_5 + ((zz_4 shr 32) + x_3 * x_2);
  1324. zz_4 := zz_4 and M;
  1325. zz_6 := zz_6 + (zz_5 shr 32);
  1326. zz_5 := zz_5 and M;
  1327. x_4 := x[xOff + 4];
  1328. zz_7 := zz[zzOff + 7] + (zz_6 shr 32);
  1329. zz_6 := zz_6 and M;
  1330. zz_8 := zz[zzOff + 8] + (zz_7 shr 32);
  1331. zz_7 := zz_7 and M;
  1332. zz_4 := zz_4 + (x_4 * x_0);
  1333. w := UInt32(zz_4);
  1334. zz[zzOff + 4] := (w shl 1) or c;
  1335. c := w shr 31;
  1336. zz_5 := zz_5 + ((zz_4 shr 32) + x_4 * x_1);
  1337. zz_6 := zz_6 + ((zz_5 shr 32) + x_4 * x_2);
  1338. zz_5 := zz_5 and M;
  1339. zz_7 := zz_7 + ((zz_6 shr 32) + x_4 * x_3);
  1340. zz_6 := zz_6 and M;
  1341. zz_8 := zz_8 + (zz_7 shr 32);
  1342. zz_7 := zz_7 and M;
  1343. x_5 := x[xOff + 5];
  1344. zz_9 := zz[zzOff + 9] + (zz_8 shr 32);
  1345. zz_8 := zz_8 and M;
  1346. zz_10 := zz[zzOff + 10] + (zz_9 shr 32);
  1347. zz_9 := zz_9 and M;
  1348. zz_5 := zz_5 + (x_5 * x_0);
  1349. w := UInt32(zz_5);
  1350. zz[zzOff + 5] := (w shl 1) or c;
  1351. c := w shr 31;
  1352. zz_6 := zz_6 + ((zz_5 shr 32) + x_5 * x_1);
  1353. zz_7 := zz_7 + ((zz_6 shr 32) + x_5 * x_2);
  1354. zz_6 := zz_6 and M;
  1355. zz_8 := zz_8 + ((zz_7 shr 32) + x_5 * x_3);
  1356. zz_7 := zz_7 and M;
  1357. zz_9 := zz_9 + ((zz_8 shr 32) + x_5 * x_4);
  1358. zz_8 := zz_8 and M;
  1359. zz_10 := zz_10 + (zz_9 shr 32);
  1360. zz_9 := zz_9 and M;
  1361. x_6 := x[xOff + 6];
  1362. zz_11 := zz[zzOff + 11] + (zz_10 shr 32);
  1363. zz_10 := zz_10 and M;
  1364. zz_12 := zz[zzOff + 12] + (zz_11 shr 32);
  1365. zz_11 := zz_11 and M;
  1366. zz_6 := zz_6 + (x_6 * x_0);
  1367. w := UInt32(zz_6);
  1368. zz[zzOff + 6] := (w shl 1) or c;
  1369. c := w shr 31;
  1370. zz_7 := zz_7 + ((zz_6 shr 32) + x_6 * x_1);
  1371. zz_8 := zz_8 + ((zz_7 shr 32) + x_6 * x_2);
  1372. zz_7 := zz_7 and M;
  1373. zz_9 := zz_9 + ((zz_8 shr 32) + x_6 * x_3);
  1374. zz_8 := zz_8 and M;
  1375. zz_10 := zz_10 + ((zz_9 shr 32) + x_6 * x_4);
  1376. zz_9 := zz_9 and M;
  1377. zz_11 := zz_11 + ((zz_10 shr 32) + x_6 * x_5);
  1378. zz_10 := zz_10 and M;
  1379. zz_12 := zz_12 + (zz_11 shr 32);
  1380. zz_11 := zz_11 and M;
  1381. x_7 := x[xOff + 7];
  1382. zz_13 := zz[zzOff + 13] + (zz_12 shr 32);
  1383. zz_12 := zz_12 and M;
  1384. zz_14 := zz[zzOff + 14] + (zz_13 shr 32);
  1385. zz_13 := zz_13 and M;
  1386. zz_7 := zz_7 + (x_7 * x_0);
  1387. w := UInt32(zz_7);
  1388. zz[zzOff + 7] := (w shl 1) or c;
  1389. c := w shr 31;
  1390. zz_8 := zz_8 + ((zz_7 shr 32) + x_7 * x_1);
  1391. zz_9 := zz_9 + ((zz_8 shr 32) + x_7 * x_2);
  1392. zz_10 := zz_10 + ((zz_9 shr 32) + x_7 * x_3);
  1393. zz_11 := zz_11 + ((zz_10 shr 32) + x_7 * x_4);
  1394. zz_12 := zz_12 + ((zz_11 shr 32) + x_7 * x_5);
  1395. zz_13 := zz_13 + ((zz_12 shr 32) + x_7 * x_6);
  1396. zz_14 := zz_14 + (zz_13 shr 32);
  1397. w := UInt32(zz_8);
  1398. zz[zzOff + 8] := (w shl 1) or c;
  1399. c := w shr 31;
  1400. w := UInt32(zz_9);
  1401. zz[zzOff + 9] := (w shl 1) or c;
  1402. c := w shr 31;
  1403. w := UInt32(zz_10);
  1404. zz[zzOff + 10] := (w shl 1) or c;
  1405. c := w shr 31;
  1406. w := UInt32(zz_11);
  1407. zz[zzOff + 11] := (w shl 1) or c;
  1408. c := w shr 31;
  1409. w := UInt32(zz_12);
  1410. zz[zzOff + 12] := (w shl 1) or c;
  1411. c := w shr 31;
  1412. w := UInt32(zz_13);
  1413. zz[zzOff + 13] := (w shl 1) or c;
  1414. c := w shr 31;
  1415. w := UInt32(zz_14);
  1416. zz[zzOff + 14] := (w shl 1) or c;
  1417. c := w shr 31;
  1418. w := zz[zzOff + 15] + UInt32(zz_14 shr 32);
  1419. zz[zzOff + 15] := (w shl 1) or c;
  1420. end;
  1421. class function TNat256.Sub(const x, y, z: TCryptoLibUInt32Array): Int32;
  1422. var
  1423. c: Int64;
  1424. begin
  1425. c := 0;
  1426. c := c + (Int64(x[0]) - y[0]);
  1427. z[0] := UInt32(c);
  1428. c := TBits.Asr64(c, 32);
  1429. c := c + (Int64(x[1]) - y[1]);
  1430. z[1] := UInt32(c);
  1431. c := TBits.Asr64(c, 32);
  1432. c := c + (Int64(x[2]) - y[2]);
  1433. z[2] := UInt32(c);
  1434. c := TBits.Asr64(c, 32);
  1435. c := c + (Int64(x[3]) - y[3]);
  1436. z[3] := UInt32(c);
  1437. c := TBits.Asr64(c, 32);
  1438. c := c + (Int64(x[4]) - y[4]);
  1439. z[4] := UInt32(c);
  1440. c := TBits.Asr64(c, 32);
  1441. c := c + (Int64(x[5]) - y[5]);
  1442. z[5] := UInt32(c);
  1443. c := TBits.Asr64(c, 32);
  1444. c := c + (Int64(x[6]) - y[6]);
  1445. z[6] := UInt32(c);
  1446. c := TBits.Asr64(c, 32);
  1447. c := c + (Int64(x[7]) - y[7]);
  1448. z[7] := UInt32(c);
  1449. c := TBits.Asr64(c, 32);
  1450. result := Int32(c);
  1451. end;
  1452. class function TNat256.Sub(const x: TCryptoLibUInt32Array; xOff: Int32;
  1453. const y: TCryptoLibUInt32Array; yOff: Int32; const z: TCryptoLibUInt32Array;
  1454. zOff: Int32): Int32;
  1455. var
  1456. c: Int64;
  1457. begin
  1458. c := 0;
  1459. c := c + (Int64(x[xOff + 0]) - y[yOff + 0]);
  1460. z[zOff + 0] := UInt32(c);
  1461. c := TBits.Asr64(c, 32);
  1462. c := c + (Int64(x[xOff + 1]) - y[yOff + 1]);
  1463. z[zOff + 1] := UInt32(c);
  1464. c := TBits.Asr64(c, 32);
  1465. c := c + (Int64(x[xOff + 2]) - y[yOff + 2]);
  1466. z[zOff + 2] := UInt32(c);
  1467. c := TBits.Asr64(c, 32);
  1468. c := c + (Int64(x[xOff + 3]) - y[yOff + 3]);
  1469. z[zOff + 3] := UInt32(c);
  1470. c := TBits.Asr64(c, 32);
  1471. c := c + (Int64(x[xOff + 4]) - y[yOff + 4]);
  1472. z[zOff + 4] := UInt32(c);
  1473. c := TBits.Asr64(c, 32);
  1474. c := c + (Int64(x[xOff + 5]) - y[yOff + 5]);
  1475. z[zOff + 5] := UInt32(c);
  1476. c := TBits.Asr64(c, 32);
  1477. c := c + (Int64(x[xOff + 6]) - y[yOff + 6]);
  1478. z[zOff + 6] := UInt32(c);
  1479. c := TBits.Asr64(c, 32);
  1480. c := c + (Int64(x[xOff + 7]) - y[yOff + 7]);
  1481. z[zOff + 7] := UInt32(c);
  1482. c := TBits.Asr64(c, 32);
  1483. result := Int32(c);
  1484. end;
  1485. class function TNat256.SubBothFrom(const x, y, z: TCryptoLibUInt32Array): Int32;
  1486. var
  1487. c: Int64;
  1488. begin
  1489. c := 0;
  1490. c := c + (Int64(z[0]) - x[0] - y[0]);
  1491. z[0] := UInt32(c);
  1492. c := TBits.Asr64(c, 32);
  1493. c := c + (Int64(z[1]) - x[1] - y[1]);
  1494. z[1] := UInt32(c);
  1495. c := TBits.Asr64(c, 32);
  1496. c := c + (Int64(z[2]) - x[2] - y[2]);
  1497. z[2] := UInt32(c);
  1498. c := TBits.Asr64(c, 32);
  1499. c := c + (Int64(z[3]) - x[3] - y[3]);
  1500. z[3] := UInt32(c);
  1501. c := TBits.Asr64(c, 32);
  1502. c := c + (Int64(z[4]) - x[4] - y[4]);
  1503. z[4] := UInt32(c);
  1504. c := TBits.Asr64(c, 32);
  1505. c := c + (Int64(z[5]) - x[5] - y[5]);
  1506. z[5] := UInt32(c);
  1507. c := TBits.Asr64(c, 32);
  1508. c := c + (Int64(z[6]) - x[6] - y[6]);
  1509. z[6] := UInt32(c);
  1510. c := TBits.Asr64(c, 32);
  1511. c := c + (Int64(z[7]) - x[7] - y[7]);
  1512. z[7] := UInt32(c);
  1513. c := TBits.Asr64(c, 32);
  1514. result := Int32(c);
  1515. end;
  1516. class function TNat256.SubFrom(const x, z: TCryptoLibUInt32Array): Int32;
  1517. var
  1518. c: Int64;
  1519. begin
  1520. c := 0;
  1521. c := c + (Int64(z[0]) - x[0]);
  1522. z[0] := UInt32(c);
  1523. c := TBits.Asr64(c, 32);
  1524. c := c + (Int64(z[1]) - x[1]);
  1525. z[1] := UInt32(c);
  1526. c := TBits.Asr64(c, 32);
  1527. c := c + (Int64(z[2]) - x[2]);
  1528. z[2] := UInt32(c);
  1529. c := TBits.Asr64(c, 32);
  1530. c := c + (Int64(z[3]) - x[3]);
  1531. z[3] := UInt32(c);
  1532. c := TBits.Asr64(c, 32);
  1533. c := c + (Int64(z[4]) - x[4]);
  1534. z[4] := UInt32(c);
  1535. c := TBits.Asr64(c, 32);
  1536. c := c + (Int64(z[5]) - x[5]);
  1537. z[5] := UInt32(c);
  1538. c := TBits.Asr64(c, 32);
  1539. c := c + (Int64(z[6]) - x[6]);
  1540. z[6] := UInt32(c);
  1541. c := TBits.Asr64(c, 32);
  1542. c := c + (Int64(z[7]) - x[7]);
  1543. z[7] := UInt32(c);
  1544. c := TBits.Asr64(c, 32);
  1545. result := Int32(c);
  1546. end;
  1547. class function TNat256.SubFrom(const x: TCryptoLibUInt32Array; xOff: Int32;
  1548. const z: TCryptoLibUInt32Array; zOff: Int32): Int32;
  1549. var
  1550. c: Int64;
  1551. begin
  1552. c := 0;
  1553. c := c + (Int64(z[zOff + 0]) - x[xOff + 0]);
  1554. z[zOff + 0] := UInt32(c);
  1555. c := TBits.Asr64(c, 32);
  1556. c := c + (Int64(z[zOff + 1]) - x[xOff + 1]);
  1557. z[zOff + 1] := UInt32(c);
  1558. c := TBits.Asr64(c, 32);
  1559. c := c + (Int64(z[zOff + 2]) - x[xOff + 2]);
  1560. z[zOff + 2] := UInt32(c);
  1561. c := TBits.Asr64(c, 32);
  1562. c := c + (Int64(z[zOff + 3]) - x[xOff + 3]);
  1563. z[zOff + 3] := UInt32(c);
  1564. c := TBits.Asr64(c, 32);
  1565. c := c + (Int64(z[zOff + 4]) - x[xOff + 4]);
  1566. z[zOff + 4] := UInt32(c);
  1567. c := TBits.Asr64(c, 32);
  1568. c := c + (Int64(z[zOff + 5]) - x[xOff + 5]);
  1569. z[zOff + 5] := UInt32(c);
  1570. c := TBits.Asr64(c, 32);
  1571. c := c + (Int64(z[zOff + 6]) - x[xOff + 6]);
  1572. z[zOff + 6] := UInt32(c);
  1573. c := TBits.Asr64(c, 32);
  1574. c := c + (Int64(z[zOff + 7]) - x[xOff + 7]);
  1575. z[zOff + 7] := UInt32(c);
  1576. c := TBits.Asr64(c, 32);
  1577. result := Int32(c);
  1578. end;
  1579. class function TNat256.ToBigInteger(const x: TCryptoLibUInt32Array)
  1580. : TBigInteger;
  1581. var
  1582. bs, temp: TCryptoLibByteArray;
  1583. i: Int32;
  1584. x_i: UInt32;
  1585. begin
  1586. System.SetLength(bs, 32);
  1587. for i := 0 to System.Pred(8) do
  1588. begin
  1589. x_i := x[i];
  1590. if (x_i <> 0) then
  1591. begin
  1592. temp := TConverters.ReadUInt32AsBytesBE(x_i);
  1593. System.Move(temp[0], bs[(7 - i) shl 2], System.Length(temp) *
  1594. System.SizeOf(Byte))
  1595. end;
  1596. end;
  1597. result := TBigInteger.Create(1, bs);
  1598. end;
  1599. class function TNat256.ToBigInteger64(const x: TCryptoLibUInt64Array)
  1600. : TBigInteger;
  1601. var
  1602. bs, temp: TCryptoLibByteArray;
  1603. i: Int32;
  1604. x_i: UInt64;
  1605. begin
  1606. System.SetLength(bs, 32);
  1607. for i := 0 to System.Pred(4) do
  1608. begin
  1609. x_i := x[i];
  1610. if (x_i <> Int64(0)) then
  1611. begin
  1612. temp := TConverters.ReadUInt64AsBytesBE(x_i);
  1613. System.Move(temp[0], bs[(3 - i) shl 3], System.Length(temp) *
  1614. System.SizeOf(Byte))
  1615. end;
  1616. end;
  1617. result := TBigInteger.Create(1, bs);
  1618. end;
  1619. class procedure TNat256.Zero(const z: TCryptoLibUInt32Array);
  1620. begin
  1621. TArrayUtils.Fill(z, 0, 8, UInt32(0));
  1622. end;
  1623. end.