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.

343 lines
10 KiB

  1. const path = require("path");
  2. const bigInt = require("big-integer");
  3. const c_tester = require("../index.js").c_tester;
  4. const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  5. function normalize(o) {
  6. if ((typeof(o) == "bigint") || o.isZero !== undefined) {
  7. const res = bigInt(o);
  8. return norm(res);
  9. } else if (Array.isArray(o)) {
  10. return o.map(normalize);
  11. } else if (typeof o == "object") {
  12. const res = {};
  13. for (let k in o) {
  14. res[k] = normalize(o[k]);
  15. }
  16. return res;
  17. } else {
  18. const res = bigInt(o);
  19. return norm(res);
  20. }
  21. function norm(n) {
  22. let res = n.mod(__P__);
  23. if (res.isNegative()) res = __P__.add(res);
  24. return res;
  25. }
  26. }
  27. async function doTest(circuit, testVectors) {
  28. const cir = await c_tester(path.join(__dirname, "circuits", circuit));
  29. for (let i=0; i<testVectors.length; i++) {
  30. const w = await cir.calculateWitness(normalize(testVectors[i][0]));
  31. await cir.assertOut(w, normalize(testVectors[i][1]) );
  32. }
  33. await cir.release();
  34. }
  35. describe("basic cases", function () {
  36. this.timeout(100000);
  37. it("inout", async () => {
  38. await doTest(
  39. "inout.circom",
  40. [
  41. [{in1: 1, in2: [2,3], in3:[[4,5], [6,7], [8,9]]}, {out1: 1, out2: [2,3], out3: [[4,5], [6,7],[8,9]]}],
  42. ]
  43. );
  44. });
  45. it("add", async () => {
  46. await doTest(
  47. "add.circom",
  48. [
  49. [{in: [0,0]}, {out: 0}],
  50. [{in: [0,1]}, {out: 1}],
  51. [{in: [1,2]}, {out: 3}],
  52. [{in: [__P__.minus(1),1]}, {out: 0}],
  53. ]
  54. );
  55. });
  56. it("add constant", async () => {
  57. await doTest(
  58. "addconst1.circom",
  59. [
  60. [{in: 0}, {out: 15}],
  61. [{in: 10}, {out: 25}],
  62. [{in: __P__.minus(2)}, {out: 13}],
  63. ]
  64. );
  65. });
  66. it("for unrolled", async () => {
  67. await doTest(
  68. "forunrolled.circom",
  69. [
  70. [{in: 0}, {out: [0,1,2]}],
  71. [{in: 10}, {out: [10, 11, 12]}],
  72. [{in: __P__.minus(2)}, {out: [__P__.minus(2), __P__.minus(1), 0]}],
  73. ]
  74. );
  75. });
  76. it("for rolled", async () => {
  77. await doTest(
  78. "forrolled.circom",
  79. [
  80. [{in: 0}, {out: 0}],
  81. [{in: 10}, {out: 10}],
  82. ]
  83. );
  84. });
  85. it("while unrolled", async () => {
  86. await doTest(
  87. "whileunrolled.circom",
  88. [
  89. [{in: 0}, {out: [0,1,2]}],
  90. [{in: 10}, {out: [10, 11, 12]}],
  91. [{in: __P__.minus(2)}, {out: [__P__.minus(2), __P__.minus(1), 0]}],
  92. ]
  93. );
  94. });
  95. it("while rolled", async () => {
  96. await doTest(
  97. "whilerolled.circom",
  98. [
  99. [{in: 0}, {out: 0}],
  100. [{in: 10}, {out: 10}],
  101. ]
  102. );
  103. });
  104. it("function1", async () => {
  105. await doTest(
  106. "function1.circom",
  107. [
  108. [{in: 0}, {out: 3}],
  109. [{in: 10}, {out: 13}],
  110. [{in: __P__.minus(2)}, {out: 1}],
  111. ]
  112. );
  113. });
  114. it("function2", async () => {
  115. await doTest(
  116. "function2.circom",
  117. [
  118. [{in: 0}, {out: 3}],
  119. [{in: 10}, {out: 13}],
  120. [{in: __P__.minus(2)}, {out: 1}],
  121. ]
  122. );
  123. });
  124. it("constants1", async () => {
  125. await doTest(
  126. "constants1.circom",
  127. [
  128. [{in: 0}, {out: 42}],
  129. [{in: 10}, {out: 52}],
  130. [{in: __P__.minus(2)}, {out: 40}],
  131. ]
  132. );
  133. });
  134. it("arrays", async () => {
  135. await doTest(
  136. "arrays.circom",
  137. [
  138. [{in: 0}, {out: [1, 8, 51]}],
  139. [{in: 10}, {out: [11, 28, 111]}],
  140. [{in: __P__.minus(2)}, {out: [__P__.minus(1), 4, 39]}],
  141. ]
  142. );
  143. });
  144. it("if unrolled", async () => {
  145. await doTest(
  146. "ifunrolled.circom",
  147. [
  148. [{in: 0}, {out: [1, 3, 6]}],
  149. [{in: 10}, {out: [11, 13, 16]}],
  150. [{in: __P__.minus(2)}, {out: [__P__.minus(1), 1, 4]}],
  151. ]
  152. );
  153. });
  154. it("if rolled", async () => {
  155. await doTest(
  156. "ifrolled.circom",
  157. [
  158. [{in: 0}, {out: [1, 0, 0]}],
  159. [{in: 1}, {out: [0, 1, 0]}],
  160. [{in: 2}, {out: [0, 0, 1]}],
  161. [{in: 3}, {out: [0, 0, 0]}],
  162. [{in: __P__.minus(2)}, {out: [0,0,0]}],
  163. ]
  164. );
  165. });
  166. it("inc", async () => {
  167. await doTest(
  168. "inc.circom",
  169. [
  170. [{in: 0}, {out: [5, 2]}],
  171. [{in: 1}, {out: [6, 4]}],
  172. [{in: 2}, {out: [7, 6]}],
  173. [{in: 3}, {out: [8, 8]}],
  174. [{in: __P__.minus(2)}, {out: [3,__P__.minus(2)]}],
  175. ]
  176. );
  177. });
  178. it("dec", async () => {
  179. await doTest(
  180. "dec.circom",
  181. [
  182. [{in: 0}, {out: [1, __P__.minus(2)]}],
  183. [{in: 1}, {out: [2, 0]}],
  184. [{in: 2}, {out: [3, 2]}],
  185. [{in: 3}, {out: [4, 4]}],
  186. [{in: __P__.minus(2)}, {out: [__P__.minus(1),__P__.minus(6)]}],
  187. ]
  188. );
  189. });
  190. it("ops", async () => {
  191. await doTest(
  192. "ops.circom",
  193. [
  194. [{in: [-2, 2]}, {add: 0, sub: -4, mul: -4}],
  195. [{in: [-1, 1]}, {add: 0, sub: -2, mul: -1}],
  196. [{in: [ 0, 0]}, {add: 0, sub: 0, mul: 0}],
  197. [{in: [ 1,-1]}, {add: 0, sub: 2, mul: -1}],
  198. [{in: [ 2,-2]}, {add: 0, sub: 4, mul: -4}],
  199. [{in: [-2,-3]}, {add: -5, sub: 1, mul: 6}],
  200. [{in: [ 2, 3]}, {add: 5, sub: -1, mul: 6}],
  201. ]
  202. );
  203. });
  204. it("ops2", async () => {
  205. await doTest(
  206. "ops2.circom",
  207. [
  208. [{in: [-2, 2]}, {div: -1, idiv: bigInt("10944121435919637611123202872628637544274182200208017171849102093287904247807"), mod: 1}],
  209. [{in: [-1, 1]}, {div: -1, idiv: -1, mod: 0}],
  210. [{in: [ 1,-1]}, {div: -1, idiv: 0, mod: 1}],
  211. ]
  212. );
  213. });
  214. it("ops3", async () => {
  215. await doTest(
  216. "ops3.circom",
  217. [
  218. [{in: [-2, 2]}, {neg1: 2,neg2: -2, pow: 4}],
  219. [{in: [0, 1]}, {neg1: 0, neg2: -1, pow: 0}],
  220. [{in: [ 1,-1]}, {neg1: -1, neg2: 1, pow: 1}],
  221. ]
  222. );
  223. });
  224. it("Comparation ops", async () => {
  225. await doTest(
  226. "opscmp.circom",
  227. [
  228. [{in: [ 8, 9]}, {lt: 1, leq: 1, eq:0, neq:1, geq: 0, gt:0}],
  229. [{in: [-2,-2]}, {lt: 0, leq: 1, eq:1, neq:0, geq: 1, gt:0}],
  230. [{in: [-1,-2]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}],
  231. [{in: [ 1,-1]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}], // In mod, negative values are higher than positive.
  232. ]
  233. );
  234. });
  235. it("Bit ops", async () => {
  236. const mask = bigInt("14474011154664524427946373126085988481658748083205070504932198000989141204991");
  237. const m1m = bigInt("7414231717174750794300032619171286606889616317210963838766006185586667290624");
  238. await doTest(
  239. "opsbit.circom",
  240. [
  241. [{in: [ 5, 3]}, {and: 1, or: 7, xor:6, not1:mask.minus(5), shl: 40, shr:0}],
  242. [{in: [ 0, 0]}, {and: 0, or: 0, xor:0, not1:mask, shl: 0, shr:0}],
  243. [{in: [-1, 1]}, {and: 0, or: m1m.add(bigInt.one), xor:m1m.add(bigInt.one), not1:mask.minus(m1m), shl: m1m.shiftLeft(1).and(mask), shr:__P__.shiftRight(1).and(mask)}],
  244. ]
  245. );
  246. });
  247. it("Logical ops", async () => {
  248. await doTest(
  249. "opslog.circom",
  250. [
  251. [{in: [ 5, 0]}, {and: 0, or: 1, not1:0}],
  252. [{in: [ 0, 1]}, {and: 0, or: 1, not1:1}],
  253. [{in: [-1, 9]}, {and: 1, or: 1, not1:0}],
  254. [{in: [ 0, 0]}, {and: 0, or: 0, not1:1}],
  255. ]
  256. );
  257. });
  258. it("Conditional Ternary operator", async () => {
  259. await doTest(
  260. "condternary.circom",
  261. [
  262. [{in: 0}, {out: 21}],
  263. [{in: 1}, {out: 1}],
  264. [{in: 2}, {out: 23}],
  265. [{in:-1}, {out: 20}],
  266. ]
  267. );
  268. });
  269. it("Compute block", async () => {
  270. await doTest(
  271. "compute.circom",
  272. [
  273. [{x: 1}, {y: 7}],
  274. [{x: 2}, {y: 7}],
  275. [{x: 3}, {y: 11}],
  276. [{x:-1}, {y: -5}],
  277. ]
  278. );
  279. });
  280. it("Component array ", async () => {
  281. await doTest(
  282. "componentarray.circom",
  283. [
  284. [{in: 1}, {out: 1}],
  285. [{in: 2}, {out: 256}],
  286. [{in: 3}, {out: 6561}],
  287. [{in:-1}, {out: 1}],
  288. ]
  289. );
  290. });
  291. it("Component array 2d", async () => {
  292. await doTest(
  293. "componentarray2.circom",
  294. [
  295. [{in: [1,2]}, {out: [1, 256]}],
  296. [{in: [0,3]}, {out: [0, 6561]}],
  297. ]
  298. );
  299. });
  300. it("Constant circuit", async () => {
  301. await doTest(
  302. "constantcircuit.circom",
  303. [
  304. // 0xbb67ae85
  305. [{}, {out: [1,0,1,0, 0,0,0,1, 0,1,1,1, 0,1,0,1, 1,1,1,0, 0,1,1,0, 1,1,0,1, 1,1,0,1]}],
  306. ]
  307. );
  308. });
  309. it("Constant internal circuit", async () => {
  310. await doTest(
  311. "constantinternalcircuit.circom",
  312. [
  313. [{in: 1}, {out: 5}],
  314. [{in: 0}, {out: 4}],
  315. [{in: -2}, {out: 2}],
  316. [{in: 10}, {out: 14}]
  317. ]
  318. );
  319. });
  320. it("include", async () => {
  321. await doTest(
  322. "include.circom",
  323. [
  324. [{in: 3}, {out: 6}],
  325. [{in: 6}, {out: 15}],
  326. ]
  327. );
  328. });
  329. });