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

407 lines
14 KiB

  1. const tester = require("../c/buildasm/buildzqfieldtester.js");
  2. const ZqField = require("fflib").ZqField;
  3. const bigInt = require("big-integer");
  4. const bn128q = new bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
  5. const bn128r = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  6. const secp256k1q = new bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
  7. const secp256k1r = new bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
  8. const mnt6753q = new bigInt("41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001");
  9. const mnt6753r = new bigInt("41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689601");
  10. describe("field asm test", function () {
  11. this.timeout(1000000000);
  12. it("bn128r add", async () => {
  13. const tv = buildTestVector2(bn128r, "add");
  14. await tester(bn128r, tv);
  15. });
  16. it("secp256k1q add", async () => {
  17. const tv = buildTestVector2(secp256k1q, "add");
  18. await tester(secp256k1q, tv);
  19. });
  20. it("mnt6753q add", async () => {
  21. const tv = buildTestVector2(mnt6753q, "add");
  22. await tester(mnt6753q, tv);
  23. });
  24. it("bn128r sub", async () => {
  25. const tv = buildTestVector2(bn128r, "sub");
  26. await tester(bn128r, tv);
  27. });
  28. it("secp256k1q sub", async () => {
  29. const tv = buildTestVector2(secp256k1q, "sub");
  30. await tester(secp256k1q, tv);
  31. });
  32. it("mnt6753q sub", async () => {
  33. const tv = buildTestVector2(mnt6753q, "sub");
  34. await tester(mnt6753q, tv);
  35. });
  36. it("bn128r neg", async () => {
  37. const tv = buildTestVector1(bn128r, "neg");
  38. await tester(bn128r, tv);
  39. });
  40. it("secp256k1q neg", async () => {
  41. const tv = buildTestVector1(secp256k1q, "neg");
  42. await tester(secp256k1q, tv);
  43. });
  44. it("mnt6753q neg", async () => {
  45. const tv = buildTestVector1(mnt6753q, "neg");
  46. await tester(mnt6753q, tv);
  47. });
  48. it("bn128r mul", async () => {
  49. const tv = buildTestVector2(bn128r, "mul");
  50. await tester(bn128r, tv);
  51. });
  52. it("secp256k1q mul", async () => {
  53. const tv = buildTestVector2(secp256k1q, "mul");
  54. await tester(secp256k1q, tv);
  55. });
  56. it("mnt6753q mul", async () => {
  57. const tv = buildTestVector2(mnt6753q, "mul");
  58. await tester(mnt6753q, tv);
  59. });
  60. it("bn128r binary and", async () => {
  61. const tv = buildTestVector2(bn128r, "band");
  62. await tester(bn128r, tv);
  63. });
  64. it("secp256k1q binary and", async () => {
  65. const tv = buildTestVector2(secp256k1q, "band");
  66. await tester(secp256k1q, tv);
  67. });
  68. it("mnt6753q binary and", async () => {
  69. const tv = buildTestVector2(mnt6753q, "band");
  70. await tester(mnt6753q, tv);
  71. });
  72. it("bn128r binary or", async () => {
  73. const tv = buildTestVector2(bn128r, "bor");
  74. await tester(bn128r, tv);
  75. });
  76. it("secp256k1q binary or", async () => {
  77. const tv = buildTestVector2(secp256k1q, "bor");
  78. await tester(secp256k1q, tv);
  79. });
  80. it("mnt6753q binary or", async () => {
  81. const tv = buildTestVector2(mnt6753q, "bor");
  82. await tester(mnt6753q, tv);
  83. });
  84. it("bn128r binary xor", async () => {
  85. const tv = buildTestVector2(bn128r, "bxor");
  86. await tester(bn128r, tv);
  87. });
  88. it("secp256k1q binary xor", async () => {
  89. const tv = buildTestVector2(secp256k1q, "bxor");
  90. await tester(secp256k1q, tv);
  91. });
  92. it("mnt6753q binary xor", async () => {
  93. const tv = buildTestVector2(mnt6753q, "bxor");
  94. await tester(mnt6753q, tv);
  95. });
  96. it("bn128r binary not", async () => {
  97. const tv = buildTestVector1(bn128r, "bnot");
  98. await tester(bn128r, tv);
  99. });
  100. it("secp256k1q binary not", async () => {
  101. const tv = buildTestVector1(secp256k1q, "bnot");
  102. await tester(secp256k1q, tv);
  103. });
  104. it("mnt6753q binary not", async () => {
  105. const tv = buildTestVector1(mnt6753q, "bnot");
  106. await tester(mnt6753q, tv);
  107. });
  108. it("bn128r eq", async () => {
  109. const tv = buildTestVector2(bn128r, "eq");
  110. await tester(bn128r, tv);
  111. });
  112. it("secp256k1q eq", async () => {
  113. const tv = buildTestVector2(secp256k1q, "eq");
  114. await tester(secp256k1q, tv);
  115. });
  116. it("mnt6753q eq", async () => {
  117. const tv = buildTestVector2(mnt6753q, "eq");
  118. await tester(mnt6753q, tv);
  119. });
  120. it("bn128r neq", async () => {
  121. const tv = buildTestVector2(bn128r, "neq");
  122. await tester(bn128r, tv);
  123. });
  124. it("secp256k1q neq", async () => {
  125. const tv = buildTestVector2(secp256k1q, "neq");
  126. await tester(secp256k1q, tv);
  127. });
  128. it("mnt6753q neq", async () => {
  129. const tv = buildTestVector2(mnt6753q, "neq");
  130. await tester(mnt6753q, tv);
  131. });
  132. it("bn128r lt", async () => {
  133. const tv = buildTestVector2(bn128r, "lt");
  134. await tester(bn128r, tv);
  135. });
  136. it("secp256k1q lt", async () => {
  137. const tv = buildTestVector2(secp256k1q, "lt");
  138. await tester(secp256k1q, tv);
  139. });
  140. it("mnt6753q lt", async () => {
  141. const tv = buildTestVector2(mnt6753q, "lt");
  142. await tester(mnt6753q, tv);
  143. });
  144. it("bn128r gt", async () => {
  145. const tv = buildTestVector2(bn128r, "gt");
  146. await tester(bn128r, tv);
  147. });
  148. it("secp256k1q gt", async () => {
  149. const tv = buildTestVector2(secp256k1q, "gt");
  150. await tester(secp256k1q, tv);
  151. });
  152. it("mnt6753q gt", async () => {
  153. const tv = buildTestVector2(mnt6753q, "gt");
  154. await tester(mnt6753q, tv);
  155. });
  156. it("bn128r leq", async () => {
  157. const tv = buildTestVector2(bn128r, "leq");
  158. await tester(bn128r, tv);
  159. });
  160. it("secp256k1q leq", async () => {
  161. const tv = buildTestVector2(secp256k1q, "leq");
  162. await tester(secp256k1q, tv);
  163. });
  164. it("mnt6753q leq", async () => {
  165. const tv = buildTestVector2(mnt6753q, "leq");
  166. await tester(mnt6753q, tv);
  167. });
  168. it("bn128r geq", async () => {
  169. const tv = buildTestVector2(bn128r, "geq");
  170. await tester(bn128r, tv);
  171. });
  172. it("secp256k1q geq", async () => {
  173. const tv = buildTestVector2(secp256k1q, "geq");
  174. await tester(secp256k1q, tv);
  175. });
  176. it("mnt6753q geq", async () => {
  177. const tv = buildTestVector2(mnt6753q, "geq");
  178. await tester(mnt6753q, tv);
  179. });
  180. it("bn128r logical and", async () => {
  181. const tv = buildTestVector2(bn128r, "land");
  182. await tester(bn128r, tv);
  183. });
  184. it("secp256k1q logical and", async () => {
  185. const tv = buildTestVector2(secp256k1q, "land");
  186. await tester(secp256k1q, tv);
  187. });
  188. it("mnt6753q logical and", async () => {
  189. const tv = buildTestVector2(mnt6753q, "land");
  190. await tester(mnt6753q, tv);
  191. });
  192. it("bn128r logical or", async () => {
  193. const tv = buildTestVector2(bn128r, "lor");
  194. await tester(bn128r, tv);
  195. });
  196. it("secp256k1q logical or", async () => {
  197. const tv = buildTestVector2(secp256k1q, "lor");
  198. await tester(secp256k1q, tv);
  199. });
  200. it("mnt6753q logical or", async () => {
  201. const tv = buildTestVector2(mnt6753q, "lor");
  202. await tester(mnt6753q, tv);
  203. });
  204. it("bn128r logical not", async () => {
  205. const tv = buildTestVector1(bn128r, "lnot");
  206. await tester(bn128r, tv);
  207. });
  208. it("secp256k1q logical not", async () => {
  209. const tv = buildTestVector1(secp256k1q, "lnot");
  210. await tester(secp256k1q, tv);
  211. });
  212. it("mnt6753q logical not", async () => {
  213. const tv = buildTestVector1(mnt6753q, "lnot");
  214. await tester(mnt6753q, tv);
  215. });
  216. it("bn128r idiv", async () => {
  217. const tv = buildTestVector2(bn128r, "idiv");
  218. await tester(bn128r, tv);
  219. });
  220. it("secp256k1q idiv", async () => {
  221. const tv = buildTestVector2(secp256k1q, "idiv");
  222. await tester(secp256k1q, tv);
  223. });
  224. it("mnt6753q idiv", async () => {
  225. const tv = buildTestVector2(mnt6753q, "idiv");
  226. await tester(mnt6753q, tv);
  227. });
  228. it("bn128r inv", async () => {
  229. const tv = buildTestVector1(bn128r, "inv");
  230. await tester(bn128r, tv);
  231. });
  232. it("secp256k1q inv", async () => {
  233. const tv = buildTestVector1(secp256k1q, "inv");
  234. await tester(secp256k1q, tv);
  235. });
  236. it("mnt6753q inv", async () => {
  237. const tv = buildTestVector1(mnt6753q, "inv");
  238. await tester(mnt6753q, tv);
  239. });
  240. it("bn128r div", async () => {
  241. const tv = buildTestVector2(bn128r, "div");
  242. await tester(bn128r, tv);
  243. });
  244. it("secp256k1q div", async () => {
  245. const tv = buildTestVector2(secp256k1q, "div");
  246. await tester(secp256k1q, tv);
  247. });
  248. it("mnt6753q div", async () => {
  249. const tv = buildTestVector2(mnt6753q, "div");
  250. await tester(mnt6753q, tv);
  251. });
  252. it("bn128r square", async () => {
  253. const tv = buildTestVector1(bn128r, "square");
  254. await tester(bn128r, tv);
  255. });
  256. it("secp256k1q square", async () => {
  257. const tv = buildTestVector1(secp256k1q, "square");
  258. await tester(secp256k1q, tv);
  259. });
  260. it("mnt6753q square", async () => {
  261. const tv = buildTestVector1(mnt6753q, "square");
  262. await tester(mnt6753q, tv);
  263. });
  264. });
  265. function buildTestVector2(p, op) {
  266. const F = new ZqField(p);
  267. const tv = [];
  268. const nums = getCriticalNumbers(p, 2);
  269. const excludeZero = ["div", "mod", "idiv"].indexOf(op) >= 0;
  270. for (let i=0; i<nums.length; i++) {
  271. for (let j=0; j<nums.length; j++) {
  272. if ((excludeZero)&&(nums[j][0].isZero())) continue;
  273. tv.push([
  274. [nums[i][1], nums[j][1], op],
  275. F[op](nums[i][0], nums[j][0])
  276. ]);
  277. }
  278. }
  279. return tv;
  280. }
  281. function buildTestVector1(p, op) {
  282. const F = new ZqField(p);
  283. const tv = [];
  284. const nums = getCriticalNumbers(p, 2);
  285. const excludeZero = ["inv"].indexOf(op) >= 0;
  286. for (let i=0; i<nums.length; i++) {
  287. if ((excludeZero)&&(nums[i][0].isZero())) continue;
  288. tv.push([
  289. [nums[i][1], op],
  290. F[op](nums[i][0])
  291. ]);
  292. }
  293. return tv;
  294. }
  295. function getCriticalNumbers(p, lim) {
  296. const numbers = [];
  297. addFrontier(0);
  298. addFrontier(bigInt.one.shiftLeft(31));
  299. addFrontier(p.minus(bigInt.one.shiftLeft(31)));
  300. addFrontier(bigInt.one.shiftLeft(32));
  301. addFrontier(p.minus(bigInt.one.shiftLeft(32)));
  302. addFrontier(bigInt.one.shiftLeft(63));
  303. addFrontier(p.minus(bigInt.one.shiftLeft(63)));
  304. addFrontier(bigInt.one.shiftLeft(64));
  305. addFrontier(p.minus(bigInt.one.shiftLeft(64)));
  306. addFrontier(bigInt.one.shiftLeft(p.bitLength()-1));
  307. addFrontier(p.shiftRight(1));
  308. function addFrontier(f) {
  309. for (let i=-lim; i<=lim; i++) {
  310. let n = bigInt(f).add(bigInt(i));
  311. n = n.mod(p);
  312. if (n.isNegative()) n = p.add(n);
  313. addNumber(n);
  314. }
  315. }
  316. return numbers;
  317. function addNumber(n) {
  318. if (n.lt(bigInt("80000000", 16)) ) {
  319. addShortPositive(n);
  320. addShortMontgomeryPositive(n);
  321. }
  322. if (n.geq(p.minus(bigInt("80000000", 16))) ) {
  323. addShortNegative(n);
  324. addShortMontgomeryNegative(n);
  325. }
  326. addLongNormal(n);
  327. addLongMontgomery(n);
  328. function addShortPositive(a) {
  329. numbers.push([a, "0x"+a.toString(16)]);
  330. }
  331. function addShortMontgomeryPositive(a) {
  332. let S = "0x" + bigInt("40", 16).shiftLeft(56).add(a).toString(16);
  333. S = S + "," + getLongString(toMontgomery(a));
  334. numbers.push([a, S]);
  335. }
  336. function addShortNegative(a) {
  337. const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
  338. numbers.push([a, "0x"+b.toString(16)]);
  339. }
  340. function addShortMontgomeryNegative(a) {
  341. const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
  342. let S = "0x" + bigInt("40", 16).shiftLeft(56).add(b).toString(16);
  343. S = S + "," + getLongString(toMontgomery(a));
  344. numbers.push([a, S]);
  345. }
  346. function addLongNormal(a) {
  347. let S = "0x" + bigInt("80", 16).shiftLeft(56).toString(16);
  348. S = S + "," + getLongString(a);
  349. numbers.push([a, S]);
  350. }
  351. function addLongMontgomery(a) {
  352. let S = "0x" + bigInt("C0", 16).shiftLeft(56).toString(16);
  353. S = S + "," + getLongString(toMontgomery(a));
  354. numbers.push([a, S]);
  355. }
  356. function getLongString(a) {
  357. if (a.isZero()) {
  358. return "0x0";
  359. }
  360. let r = a;
  361. let S = "";
  362. while (!r.isZero()) {
  363. if (S!= "") S = S+",";
  364. S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16);
  365. r = r.shiftRight(64);
  366. }
  367. return S;
  368. }
  369. function toMontgomery(a) {
  370. const n64 = Math.floor((p.bitLength() - 1) / 64)+1;
  371. const R = bigInt.one.shiftLeft(n64*64);
  372. return a.times(R).mod(p);
  373. }
  374. }
  375. }