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.

322 lines
10 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. /*
  13. it("bn128r add", async () => {
  14. const tv = buildTestVector2(bn128r, "add");
  15. await tester(bn128r, tv);
  16. });
  17. it("secp256k1q add", async () => {
  18. const tv = buildTestVector2(secp256k1q, "add");
  19. await tester(secp256k1q, tv);
  20. });
  21. it("mnt6753q add", async () => {
  22. const tv = buildTestVector2(mnt6753q, "add");
  23. await tester(mnt6753q, tv);
  24. });
  25. it("bn128r sub", async () => {
  26. const tv = buildTestVector2(bn128r, "sub");
  27. await tester(bn128r, tv);
  28. });
  29. it("secp256k1q sub", async () => {
  30. const tv = buildTestVector2(secp256k1q, "sub");
  31. await tester(secp256k1q, tv);
  32. });
  33. it("mnt6753q sub", async () => {
  34. const tv = buildTestVector2(mnt6753q, "sub");
  35. await tester(mnt6753q, tv);
  36. });
  37. it("bn128r neg", async () => {
  38. const tv = buildTestVector1(bn128r, "neg");
  39. await tester(bn128r, tv);
  40. });
  41. it("secp256k1q neg", async () => {
  42. const tv = buildTestVector1(secp256k1q, "neg");
  43. await tester(secp256k1q, tv);
  44. });
  45. it("mnt6753q neg", async () => {
  46. const tv = buildTestVector1(mnt6753q, "neg");
  47. await tester(mnt6753q, tv);
  48. });
  49. it("bn128r mul", async () => {
  50. const tv = buildTestVector2(bn128r, "mul");
  51. await tester(bn128r, tv);
  52. });
  53. it("secp256k1q mul", async () => {
  54. const tv = buildTestVector2(secp256k1q, "mul");
  55. await tester(secp256k1q, tv);
  56. });
  57. it("mnt6753q mul", async () => {
  58. const tv = buildTestVector2(mnt6753q, "mul");
  59. await tester(mnt6753q, tv);
  60. });
  61. it("bn128r binary and", async () => {
  62. const tv = buildTestVector2(bn128r, "band");
  63. await tester(bn128r, tv);
  64. });
  65. it("secp256k1q binary and", async () => {
  66. const tv = buildTestVector2(secp256k1q, "band");
  67. await tester(secp256k1q, tv);
  68. });
  69. it("mnt6753q binary and", async () => {
  70. const tv = buildTestVector2(mnt6753q, "band");
  71. await tester(mnt6753q, tv);
  72. });
  73. it("bn128r binary or", async () => {
  74. const tv = buildTestVector2(bn128r, "bor");
  75. await tester(bn128r, tv);
  76. });
  77. it("secp256k1q binary or", async () => {
  78. const tv = buildTestVector2(secp256k1q, "bor");
  79. await tester(secp256k1q, tv);
  80. });
  81. it("mnt6753q binary or", async () => {
  82. const tv = buildTestVector2(mnt6753q, "bor");
  83. await tester(mnt6753q, tv);
  84. });
  85. it("bn128r binary xor", async () => {
  86. const tv = buildTestVector2(bn128r, "bxor");
  87. await tester(bn128r, tv);
  88. });
  89. it("secp256k1q binary xor", async () => {
  90. const tv = buildTestVector2(secp256k1q, "bxor");
  91. await tester(secp256k1q, tv);
  92. });
  93. it("mnt6753q binary xor", async () => {
  94. const tv = buildTestVector2(mnt6753q, "bxor");
  95. await tester(mnt6753q, tv);
  96. });
  97. it("bn128r eq", async () => {
  98. const tv = buildTestVector2(bn128r, "eq");
  99. await tester(bn128r, tv);
  100. });
  101. it("secp256k1q eq", async () => {
  102. const tv = buildTestVector2(secp256k1q, "eq");
  103. await tester(secp256k1q, tv);
  104. });
  105. */
  106. it("mnt6753q eq", async () => {
  107. const tv = buildTestVector2(mnt6753q, "eq");
  108. await tester(mnt6753q, tv);
  109. });
  110. /*
  111. it("bn128r neq", async () => {
  112. const tv = buildTestVector2(bn128r, "neq");
  113. await tester(bn128r, tv);
  114. });
  115. it("secp256k1q neq", async () => {
  116. const tv = buildTestVector2(secp256k1q, "neq");
  117. await tester(secp256k1q, tv);
  118. });
  119. */
  120. it("mnt6753q neq", async () => {
  121. const tv = buildTestVector2(mnt6753q, "neq");
  122. await tester(mnt6753q, tv);
  123. });
  124. /*
  125. it("bn128r lt", async () => {
  126. const tv = buildTestVector2(bn128r, "lt");
  127. await tester(bn128r, tv);
  128. });
  129. it("secp256k1q lt", async () => {
  130. const tv = buildTestVector2(secp256k1q, "lt");
  131. await tester(secp256k1q, tv);
  132. });
  133. */
  134. it("mnt6753q lt", async () => {
  135. const tv = buildTestVector2(mnt6753q, "lt");
  136. await tester(mnt6753q, tv);
  137. });
  138. /*
  139. it("bn128r gt", async () => {
  140. const tv = buildTestVector2(bn128r, "gt");
  141. await tester(bn128r, tv);
  142. });
  143. it("secp256k1q gt", async () => {
  144. const tv = buildTestVector2(secp256k1q, "gt");
  145. await tester(secp256k1q, tv);
  146. });
  147. */
  148. it("mnt6753q gt", async () => {
  149. const tv = buildTestVector2(mnt6753q, "gt");
  150. await tester(mnt6753q, tv);
  151. });
  152. /*
  153. it("bn128r leq", async () => {
  154. const tv = buildTestVector2(bn128r, "leq");
  155. await tester(bn128r, tv);
  156. });
  157. it("secp256k1q leq", async () => {
  158. const tv = buildTestVector2(secp256k1q, "leq");
  159. await tester(secp256k1q, tv);
  160. });
  161. */
  162. it("mnt6753q leq", async () => {
  163. const tv = buildTestVector2(mnt6753q, "leq");
  164. await tester(mnt6753q, tv);
  165. });
  166. /*
  167. it("bn128r geq", async () => {
  168. const tv = buildTestVector2(bn128r, "geq");
  169. await tester(bn128r, tv);
  170. });
  171. it("secp256k1q geq", async () => {
  172. const tv = buildTestVector2(secp256k1q, "geq");
  173. await tester(secp256k1q, tv);
  174. });
  175. */
  176. it("mnt6753q geq", async () => {
  177. const tv = buildTestVector2(mnt6753q, "geq");
  178. await tester(mnt6753q, tv);
  179. });
  180. });
  181. function buildTestVector2(p, op) {
  182. const F = new ZqField(p);
  183. const tv = [];
  184. const nums = getCriticalNumbers(p, 2);
  185. const excludeZero = ["div", "mod"].indexOf(op) >= 0;
  186. for (let i=0; i<nums.length; i++) {
  187. for (let j=0; j<nums.length; j++) {
  188. if ((excludeZero)&&(nums[j][0].isZero())) continue;
  189. tv.push([
  190. [nums[i][1], nums[j][1], op],
  191. F[op](nums[i][0], nums[j][0])
  192. ]);
  193. }
  194. }
  195. return tv;
  196. }
  197. function buildTestVector1(p, op) {
  198. const F = new ZqField(p);
  199. const tv = [];
  200. const nums = getCriticalNumbers(p, 2);
  201. const excludeZero = ["inv"].indexOf(op) >= 0;
  202. for (let i=0; i<nums.length; i++) {
  203. if ((excludeZero)&&(nums[i][0].isZero())) continue;
  204. tv.push([
  205. [nums[i][1], op],
  206. F[op](nums[i][0])
  207. ]);
  208. }
  209. return tv;
  210. }
  211. function getCriticalNumbers(p, lim) {
  212. const numbers = [];
  213. addFrontier(0);
  214. addFrontier(bigInt.one.shiftLeft(31));
  215. addFrontier(p.minus(bigInt.one.shiftLeft(31)));
  216. addFrontier(bigInt.one.shiftLeft(32));
  217. addFrontier(p.minus(bigInt.one.shiftLeft(32)));
  218. addFrontier(bigInt.one.shiftLeft(63));
  219. addFrontier(p.minus(bigInt.one.shiftLeft(63)));
  220. addFrontier(bigInt.one.shiftLeft(64));
  221. addFrontier(p.minus(bigInt.one.shiftLeft(64)));
  222. addFrontier(bigInt.one.shiftLeft(p.bitLength()-1));
  223. addFrontier(p.shiftRight(1));
  224. function addFrontier(f) {
  225. for (let i=-lim; i<=lim; i++) {
  226. let n = bigInt(f).add(bigInt(i));
  227. n = n.mod(p);
  228. if (n.isNegative()) n = p.add(n);
  229. addNumber(n);
  230. }
  231. }
  232. return numbers;
  233. function addNumber(n) {
  234. if (n.lt(bigInt("80000000", 16)) ) {
  235. addShortPositive(n);
  236. addShortMontgomeryPositive(n);
  237. }
  238. if (n.geq(p.minus(bigInt("80000000", 16))) ) {
  239. addShortNegative(n);
  240. addShortMontgomeryNegative(n);
  241. }
  242. addLongNormal(n);
  243. addLongMontgomery(n);
  244. function addShortPositive(a) {
  245. numbers.push([a, "0x"+a.toString(16)]);
  246. }
  247. function addShortMontgomeryPositive(a) {
  248. let S = "0x" + bigInt("40", 16).shiftLeft(56).add(a).toString(16);
  249. S = S + "," + getLongString(toMontgomery(a));
  250. numbers.push([a, S]);
  251. }
  252. function addShortNegative(a) {
  253. const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
  254. numbers.push([a, "0x"+b.toString(16)]);
  255. }
  256. function addShortMontgomeryNegative(a) {
  257. const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
  258. let S = "0x" + bigInt("40", 16).shiftLeft(56).add(b).toString(16);
  259. S = S + "," + getLongString(toMontgomery(a));
  260. numbers.push([a, S]);
  261. }
  262. function addLongNormal(a) {
  263. let S = "0x" + bigInt("80", 16).shiftLeft(56).toString(16);
  264. S = S + "," + getLongString(a);
  265. numbers.push([a, S]);
  266. }
  267. function addLongMontgomery(a) {
  268. let S = "0x" + bigInt("C0", 16).shiftLeft(56).toString(16);
  269. S = S + "," + getLongString(toMontgomery(a));
  270. numbers.push([a, S]);
  271. }
  272. function getLongString(a) {
  273. if (a.isZero()) {
  274. return "0x0";
  275. }
  276. let r = a;
  277. let S = "";
  278. while (!r.isZero()) {
  279. if (S!= "") S = S+",";
  280. S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16);
  281. r = r.shiftRight(64);
  282. }
  283. return S;
  284. }
  285. function toMontgomery(a) {
  286. const n64 = Math.floor((p.bitLength() - 1) / 64)+1;
  287. const R = bigInt.one.shiftLeft(n64*64);
  288. return a.times(R).mod(p);
  289. }
  290. }
  291. }