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.

485 lines
15 KiB

5 years ago
  1. const assert = require("assert");
  2. const bigInt = require("big-integer");
  3. const buildF1 = require("../index.js").buildF1;
  4. describe("Basic tests for Zq", () => {
  5. it("It should do a basic addition", async () => {
  6. const f1 = await buildF1(101);
  7. const pA = f1.allocInt(3);
  8. const pB = f1.allocInt(4);
  9. const pC = f1.allocInt();
  10. f1.f1_add(pA, pB, pC);
  11. const c = f1.getInt(pC);
  12. assert.equal(c, 7);
  13. });
  14. it("Should add with 2 chunks", async () => {
  15. const f1 = await buildF1(bigInt("100000000000000000001", 16));
  16. const pA = f1.allocInt(bigInt("FFFFFFFFFFFFFFFF", 16));
  17. const pB = f1.allocInt(1);
  18. const pC = f1.allocInt();
  19. f1.f1_add(pA, pB, pC);
  20. const c = f1.getInt(pC);
  21. assert(c.equals(bigInt("10000000000000000", 16)));
  22. });
  23. it("Should add with 2 chunks overflow", async () => {
  24. const q = bigInt("10000000000000001", 16);
  25. const f1 = await buildF1(q);
  26. const pA = f1.allocInt(bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16).mod(q));
  27. const pB = f1.allocInt(1);
  28. const pC = f1.allocInt();
  29. f1.f1_add(pA, pB, pC);
  30. const c = f1.getInt(pC);
  31. assert(c.equals(1));
  32. });
  33. it("Should add with double overflow", async () => {
  34. const q = bigInt(1).shiftLeft(255).add(1);
  35. const a = bigInt(1).shiftLeft(256).minus(1).mod(q);
  36. const f1 = await buildF1(q);
  37. const pA = f1.allocInt(a);
  38. const pC = f1.allocInt();
  39. f1.f1_add(pA, pA, pC);
  40. const c = f1.getInt(pC);
  41. assert(c.equals(a.add(a).mod(q)));
  42. });
  43. it("It should do a basic substraction", async () => {
  44. const f1 = await buildF1(101);
  45. const pA = f1.allocInt(5);
  46. const pB = f1.allocInt(3);
  47. const pC = f1.allocInt();
  48. f1.f1_sub(pA, pB, pC);
  49. const c = f1.getInt(pC);
  50. assert.equal(c, 2);
  51. });
  52. it("It should do a basic substraction with negative result", async () => {
  53. const f1 = await buildF1(101);
  54. const pA = f1.allocInt(3);
  55. const pB = f1.allocInt(5);
  56. const pC = f1.allocInt();
  57. f1.f1_sub(pA, pB, pC);
  58. const c = f1.getInt(pC);
  59. assert.equal(c.mod(101), 99);
  60. });
  61. it("Should substract with 2 chunks overflow", async () => {
  62. const q = bigInt("10000000000000001", 16);
  63. const a = bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16).mod(q);
  64. const f1 = await buildF1(q);
  65. const pA = f1.allocInt(1);
  66. const pB = f1.allocInt(a);
  67. const pC = f1.allocInt();
  68. f1.f1_sub(pA, pB, pC);
  69. const c = f1.getInt(pC);
  70. let d = bigInt.one.minus(a).mod(q);
  71. if (d.isNegative()) d = d.add(q);
  72. assert(c.equals(d));
  73. });
  74. it("It should Substract a big number", async () => {
  75. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  76. const f1 = await buildF1(q);
  77. const a = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808495617");
  78. const b = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808234523");
  79. const pA = f1.allocInt(a);
  80. const pB = f1.allocInt(b);
  81. const pC = f1.allocInt();
  82. f1.f1_sub(pA, pB, pC);
  83. const c = f1.getInt(pC);
  84. let cc = a.minus(b).mod(q);
  85. if (cc.isNegative()) cc = cc.add(q);
  86. assert(cc.equals(c.mod(q)));
  87. const pAA = f1.allocInt(b);
  88. const pBB = f1.allocInt(a);
  89. const pCC = f1.allocInt();
  90. f1.f1_sub(pAA, pBB, pCC);
  91. const d = f1.getInt(pCC);
  92. let dd = b.minus(a).mod(q);
  93. if (dd.isNegative()) dd = dd.add(q);
  94. assert(dd.equals(d.mod(q)));
  95. });
  96. it("It should do a basic multiplication", async () => {
  97. const f1 = await buildF1(101);
  98. const pA = f1.allocInt(3);
  99. const pB = f1.allocInt(4);
  100. const pC = f1.allocInt2();
  101. f1.int_mul(pA, pB, pC);
  102. const c = f1.getInt2(pC);
  103. assert.equal(c, 12);
  104. });
  105. it("It should do a basic division", async () => {
  106. const f1 = await buildF1(101);
  107. const pA = f1.allocInt(12);
  108. const pB = f1.allocInt(6);
  109. const pC = f1.allocInt();
  110. f1.int_div(pA, pB, pC);
  111. const c = f1.getInt(pC);
  112. assert.equal(c, 2);
  113. });
  114. it("It should do a more complex division", async () => {
  115. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  116. const f1 = await buildF1(q);
  117. const pA = f1.allocInt(bigInt("FFFF00000000", 16));
  118. const pB = f1.allocInt(bigInt("100000000", 16));
  119. const pC = f1.allocInt();
  120. f1.int_div(pA, pB, pC);
  121. const c = f1.getInt(pC);
  122. assert(c.equals(bigInt("FFFF", 16)));
  123. });
  124. it("It should do a division by zero", async () => {
  125. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  126. const f1 = await buildF1(q);
  127. const pA = f1.allocInt(bigInt("FFFF00000000", 16));
  128. const pB = f1.allocInt(0);
  129. const pC = f1.allocInt();
  130. try {
  131. f1.int_div(pA, pB, pC);
  132. assert(false, "Didn't throw...");
  133. } catch (err) {
  134. assert.equal(err.toString(), "RuntimeError: divide by zero");
  135. }
  136. });
  137. it("It should do a various division", async () => {
  138. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  139. const f1 = await buildF1(q);
  140. const v= [
  141. bigInt.zero,
  142. q.minus(1),
  143. q.minus(2),
  144. q.minus(1).shiftRight(1),
  145. q.minus(1).shiftRight(1).add(1),
  146. q.minus(1).shiftRight(1).add(2),
  147. q.minus(1).shiftRight(1).minus(1),
  148. q.minus(1).shiftRight(1).minus(2),
  149. bigInt(bigInt("F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0", 16)),
  150. bigInt(bigInt("10101010101010101010101010101010", 16)),
  151. bigInt(bigInt("FF00FF00FF00FF00FF00FF00FF00FF00", 16)),
  152. bigInt(bigInt("11001100110011001100110011001100", 16)),
  153. bigInt(bigInt("F0F0F0F0F0F0F0F0", 16)),
  154. bigInt(bigInt("1010101010101010", 16)),
  155. bigInt(bigInt("FF00FF00FF00FF00", 16)),
  156. bigInt(bigInt("1100110011001100", 16)),
  157. bigInt(2),
  158. bigInt.one,
  159. ];
  160. const pA = f1.allocInt();
  161. const pB = f1.allocInt();
  162. const pC = f1.allocInt();
  163. const pR = f1.allocInt();
  164. for (let i=0; i<v.length; i++) {
  165. for (let j=1; j<v.length; j++) {
  166. const expected_c = v[i].divide(v[j]);
  167. const expected_r = v[i].mod(v[j]);
  168. f1.putInt(pA, v[i]);
  169. f1.putInt(pB, v[j]);
  170. f1.int_div(pA, pB, pC, pR);
  171. const c = f1.getInt(pC);
  172. const r = f1.getInt(pR);
  173. assert(expected_r.equals(r));
  174. assert(expected_c.equals(c));
  175. }
  176. }
  177. });
  178. it("It should do a basic reduction 1", async () => {
  179. const f1 = await buildF1(bigInt("FFFFFFFFFFFFFFFF",16));
  180. const pA = f1.allocInt2(bigInt(0x10000000000000000));
  181. const pC = f1.allocInt();
  182. f1.f1m_mReduct(pA, pC);
  183. const c = f1.getInt(pC);
  184. assert.equal(c, 1);
  185. });
  186. it("It should do a basic reduction 2", async () => {
  187. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  188. const f1 = await buildF1(q);
  189. const a = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808495617");
  190. const b = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808234523");
  191. const pA = f1.allocInt(a);
  192. const pB = f1.allocInt(b);
  193. const pC = f1.allocInt2();
  194. const pD = f1.allocInt();
  195. f1.int_mul(pA, pB, pC);
  196. const c = f1.getInt2(pC);
  197. f1.f1m_mReduct(pC, pD);
  198. const d = f1.getInt(pD);
  199. const r = bigInt.one.shiftLeft(256).mod(q);
  200. const r2 = r.times(r).mod(q);
  201. const pR2 = f1.allocInt(r2);
  202. const pE = f1.allocInt2();
  203. f1.int_mul(pD, pR2, pE);
  204. const pF = f1.allocInt();
  205. f1.f1m_mReduct(pE, pF);
  206. const f = f1.getInt2(pF);
  207. assert(a.times(b).mod(q).equals(f.mod(q)));
  208. });
  209. it("It should do a basic reduction 3", async () => {
  210. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  211. const f1 = await buildF1(q);
  212. const a = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808495617");
  213. const b = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808234523");
  214. const pA = f1.allocInt(a);
  215. const pB = f1.allocInt(b);
  216. const pC = f1.allocInt();
  217. f1.f1_mul(pA, pB, pC);
  218. const c = f1.getInt2(pC);
  219. assert(a.times(b).mod(q).equals(c.mod(q)));
  220. });
  221. it("It should do various test in zq Snarks modules", async () => {
  222. const q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
  223. const f1 = await buildF1(q);
  224. const v= [
  225. q.minus(1),
  226. q.minus(2),
  227. q.minus(1).shiftRight(1),
  228. q.minus(1).shiftRight(1).add(1),
  229. q.minus(1).shiftRight(1).add(2),
  230. q.minus(1).shiftRight(1).minus(1),
  231. q.minus(1).shiftRight(1).minus(2),
  232. bigInt(2),
  233. bigInt.one,
  234. bigInt.zero
  235. ];
  236. const pA = f1.allocInt();
  237. const pB = f1.allocInt();
  238. const pC = f1.allocInt();
  239. let c;
  240. for (let i=0; i<v.length; i++) {
  241. for (let j=0; j<5; j++) {
  242. f1.putInt(pA, v[i]);
  243. f1.putInt(pB, v[j]);
  244. // eq
  245. assert.equal( f1.int_eq(pA,pB), (i==j));
  246. // add
  247. f1.f1_add(pA, pB, pC);
  248. c = f1.getInt2(pC);
  249. assert(c.equals(v[i].add(v[j]).mod(q)));
  250. // sub
  251. f1.f1_sub(pA, pB, pC);
  252. c = f1.getInt2(pC);
  253. let s = v[i].minus(v[j]).mod(q);
  254. if (s.isNegative()) s=s.add(q);
  255. assert(c.equals(s));
  256. // mul
  257. f1.f1_mul(pA, pB, pC);
  258. c = f1.getInt2(pC);
  259. assert(c.equals(v[i].times(v[j]).mod(q)));
  260. }
  261. }
  262. });
  263. it("It should do a test", async () => {
  264. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  265. const f1 = await buildF1(q);
  266. const t = f1.test_F1(1000000);
  267. console.log(t);
  268. }).timeout(10000000);
  269. it("Should test to montgomery", async () => {
  270. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  271. const f1 = await buildF1(q);
  272. const r = bigInt(11);
  273. const pR = f1.allocInt(r);
  274. const pRes = f1.allocInt();
  275. const pRes2 = f1.allocInt();
  276. f1.f1m_toMontgomery(pR, pRes);
  277. const res = f1.getInt(pRes);
  278. f1.f1m_fromMontgomery(pRes, pRes2);
  279. const res2 = f1.getInt(pRes2);
  280. assert(res.equals(r.times( bigInt.one.shiftLeft(256)).mod(q)));
  281. assert(res2.equals(r));
  282. });
  283. it("Should convert back and forth montgomery", async () => {
  284. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  285. const v= [
  286. q.minus(1),
  287. q.minus(2),
  288. q.minus(1).shiftRight(1),
  289. q.minus(1).shiftRight(1).add(1),
  290. q.minus(1).shiftRight(1).add(2),
  291. q.minus(1).shiftRight(1).minus(1),
  292. q.minus(1).shiftRight(1).minus(2),
  293. bigInt(2),
  294. bigInt.one,
  295. bigInt.zero
  296. ];
  297. const f1 = await buildF1(q);
  298. const pA = f1.allocInt();
  299. for (let i=0; i<v.length; i++) {
  300. f1.putInt(pA, v[i]);
  301. f1.f1m_toMontgomery(pA, pA);
  302. f1.f1m_fromMontgomery(pA, pA);
  303. const a = f1.getInt(pA);
  304. assert(v[i].equals(a));
  305. }
  306. });
  307. it("Should do inverse", async () => {
  308. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  309. const v= [
  310. bigInt.one,
  311. q.minus(1),
  312. q.minus(2),
  313. q.minus(1).shiftRight(1),
  314. q.minus(1).shiftRight(1).add(1),
  315. q.minus(1).shiftRight(1).add(2),
  316. q.minus(1).shiftRight(1).minus(1),
  317. q.minus(1).shiftRight(1).minus(2),
  318. bigInt(2),
  319. ];
  320. const f1 = await buildF1(q);
  321. const pA = f1.allocInt();
  322. const pB = f1.allocInt();
  323. const pQ = f1.allocInt();
  324. f1.putInt(pQ, q);
  325. for (let i=0; i<v.length; i++) {
  326. f1.putInt(pA, v[i]);
  327. f1.int_inverseMod(pA, pQ, pB);
  328. const b = f1.getInt(pB);
  329. assert(b.equals(v[i].modInv(q)));
  330. }
  331. });
  332. it("Should do inverse in montgomery", async () => {
  333. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  334. const v= [
  335. bigInt.one,
  336. q.minus(1),
  337. q.minus(2),
  338. q.minus(1).shiftRight(1),
  339. q.minus(1).shiftRight(1).add(1),
  340. q.minus(1).shiftRight(1).add(2),
  341. q.minus(1).shiftRight(1).minus(1),
  342. q.minus(1).shiftRight(1).minus(2),
  343. bigInt(2),
  344. ];
  345. const f1 = await buildF1(q);
  346. const pA = f1.allocInt();
  347. const pB = f1.allocInt();
  348. const pC = f1.allocInt();
  349. for (let i=0; i<v.length; i++) {
  350. f1.putInt(pA, v[i]);
  351. f1.f1m_toMontgomery(pA, pA);
  352. f1.f1m_inverse(pA, pB);
  353. f1.f1m_mul(pA, pB, pC);
  354. f1.f1m_fromMontgomery(pC, pC);
  355. const c = f1.getInt(pC);
  356. assert(c.equals(1));
  357. }
  358. });
  359. it("Test Neg", async () => {
  360. const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  361. const v= [
  362. bigInt.one,
  363. q.minus(1),
  364. q.minus(2),
  365. q.minus(1).shiftRight(1),
  366. q.minus(1).shiftRight(1).add(1),
  367. q.minus(1).shiftRight(1).add(2),
  368. q.minus(1).shiftRight(1).minus(1),
  369. q.minus(1).shiftRight(1).minus(2),
  370. bigInt(2),
  371. ];
  372. const f1 = await buildF1(q);
  373. const pA = f1.allocInt();
  374. for (let i=0; i<v.length; i++) {
  375. f1.putInt(pA, v[i]);
  376. f1.f1m_neg(pA);
  377. f1.f1m_neg(pA);
  378. const a = f1.getInt(pA);
  379. assert(a.equals(v[i]));
  380. }
  381. });
  382. });