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.

275 lines
9.2 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. /*
  2. Copyright 2018 0kims association.
  3. This file is part of zksnark JavaScript library.
  4. zksnark JavaScript library is a free software: you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License as published by the
  6. Free Software Foundation, either version 3 of the License, or (at your option)
  7. any later version.
  8. zksnark JavaScript library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. more details.
  12. You should have received a copy of the GNU General Public License along with
  13. zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. const bigInt = require("./bigint.js");
  16. const BN128 = require("./bn128.js");
  17. const PolField = require("./polfield.js");
  18. const ZqField = require("./zqfield.js");
  19. const RatField = require("./ratfield.js");
  20. const bn128 = new BN128();
  21. const G1 = bn128.G1;
  22. const G2 = bn128.G2;
  23. const PolF = new PolField(new ZqField(bn128.r));
  24. const RatPolF = new PolField(new RatField(new ZqField(bn128.r)));
  25. const F = new ZqField(bn128.r);
  26. module.exports = function setup(circuit) {
  27. const setup = {
  28. vk_proof : {
  29. nVars: circuit.nVars,
  30. nPublic: circuit.nPubInputs + circuit.nOutputs
  31. },
  32. vk_verifier: {
  33. nPublic: circuit.nPubInputs + circuit.nOutputs
  34. },
  35. toxic: {}
  36. };
  37. calculatePolynomials(setup, circuit);
  38. setup.toxic.t = F.random();
  39. calculateEncriptedValuesAtT(setup, circuit);
  40. calculateHexps(setup, circuit);
  41. return setup;
  42. };
  43. function calculatePolynomials(setup, circuit) {
  44. // Calculate the points that must cross each polynomial
  45. /*
  46. setup.toxic.aExtra = [];
  47. setup.toxic.bExtra = [];
  48. setup.toxic.cExtra = [];
  49. const aPoints = [];
  50. const bPoints = [];
  51. const cPoints = [];
  52. for (let s = 0; s<circuit.nVars; s++) {
  53. aPoints[s] = [];
  54. bPoints[s] = [];
  55. cPoints[s] = [];
  56. for (let c=0; c<circuit.nConstraints; c++) {
  57. aPoints[s].push([[bigInt(c), F.one], [circuit.a(c, s), F.one]]);
  58. bPoints[s].push([[bigInt(c), F.one], [circuit.b(c, s), F.one]]);
  59. cPoints[s].push([[bigInt(c), F.one], [circuit.c(c, s), F.one]]);
  60. }
  61. // Add an extra point to avoid constant polinolials.
  62. setup.toxic.aExtra[s] = F.random();
  63. setup.toxic.bExtra[s] = F.random();
  64. setup.toxic.cExtra[s] = F.random();
  65. aPoints[s].push([[bigInt(circuit.nConstraints), F.one], [setup.toxic.aExtra[s], F.one]]);
  66. bPoints[s].push([[bigInt(circuit.nConstraints), F.one], [setup.toxic.bExtra[s], F.one]]);
  67. cPoints[s].push([[bigInt(circuit.nConstraints), F.one], [setup.toxic.cExtra[s], F.one]]);
  68. }
  69. // Calculate the polynomials using Lagrange
  70. setup.vk_proof.polsA = [];
  71. setup.vk_proof.polsB = [];
  72. setup.vk_proof.polsC = [];
  73. for (let s=0; s<circuit.nVars; s++) {
  74. // console.log(`Caclcualte Pol ${s}/${circuit.nVars}`);
  75. const pA = RatPolF.lagrange( aPoints[s] );
  76. const pB = RatPolF.lagrange( bPoints[s] );
  77. const pC = RatPolF.lagrange( cPoints[s] );
  78. setup.vk_proof.polsA.push( unrat(pA) );
  79. setup.vk_proof.polsB.push( unrat(pB) );
  80. setup.vk_proof.polsC.push( unrat(pC) );
  81. }
  82. */
  83. setup.toxic.aExtra = [];
  84. setup.toxic.bExtra = [];
  85. setup.toxic.cExtra = [];
  86. let allZerosPol = [bigInt(1)];
  87. for (let c=0; c<=circuit.nConstraints; c++) {
  88. allZerosPol = PolF.mul(allZerosPol, [F.neg(bigInt(c)), F.one]);
  89. }
  90. setup.vk_proof.polsA = [];
  91. setup.vk_proof.polsB = [];
  92. setup.vk_proof.polsC = [];
  93. for (let s = 0; s<circuit.nVars; s++) {
  94. setup.vk_proof.polsA.push([]);
  95. setup.vk_proof.polsB.push([]);
  96. setup.vk_proof.polsC.push([]);
  97. }
  98. for (let c=0; c<circuit.nConstraints; c++) {
  99. const mpol = PolF.ruffini(allZerosPol, bigInt(c));
  100. const normalizer = PolF.F.inverse(PolF.eval(mpol, bigInt(c)));
  101. for (let s = 0; s<circuit.nVars; s++) {
  102. const factorA = PolF.F.mul(normalizer, circuit.a(c, s));
  103. const spolA = PolF.mulScalar(mpol, factorA);
  104. setup.vk_proof.polsA[s] = PolF.add(setup.vk_proof.polsA[s], spolA);
  105. const factorB = PolF.F.mul(normalizer, circuit.b(c, s));
  106. const spolB = PolF.mulScalar(mpol, factorB);
  107. setup.vk_proof.polsB[s] = PolF.add(setup.vk_proof.polsB[s], spolB);
  108. const factorC = PolF.F.mul(normalizer, circuit.c(c, s));
  109. const spolC = PolF.mulScalar(mpol, factorC);
  110. setup.vk_proof.polsC[s] = PolF.add(setup.vk_proof.polsC[s], spolC);
  111. }
  112. }
  113. const mpol = PolF.ruffini(allZerosPol, bigInt(circuit.nConstraints));
  114. const normalizer = PolF.F.inverse(PolF.eval(mpol, bigInt(circuit.nConstraints)));
  115. for (let s = 0; s<circuit.nVars; s++) {
  116. setup.toxic.aExtra[s] = F.random();
  117. const factorA = PolF.F.mul(normalizer, setup.toxic.aExtra[s]);
  118. const spolA = PolF.mulScalar(mpol, factorA);
  119. setup.vk_proof.polsA[s] = PolF.add(setup.vk_proof.polsA[s], spolA);
  120. setup.toxic.bExtra[s] = F.random();
  121. const factorB = PolF.F.mul(normalizer, setup.toxic.bExtra[s]);
  122. const spolB = PolF.mulScalar(mpol, factorB);
  123. setup.vk_proof.polsB[s] = PolF.add(setup.vk_proof.polsB[s], spolB);
  124. setup.toxic.cExtra[s] = F.random();
  125. const factorC = PolF.F.mul(normalizer, setup.toxic.cExtra[s]);
  126. const spolC = PolF.mulScalar(mpol, factorC);
  127. setup.vk_proof.polsC[s] = PolF.add(setup.vk_proof.polsC[s], spolC);
  128. }
  129. // Calculate Z polynomial
  130. // Z = 1
  131. setup.vk_proof.polZ = [bigInt(1)];
  132. for (let c=0; c<circuit.nConstraints; c++) {
  133. // Z = Z * (x - p_c)
  134. setup.vk_proof.polZ = PolF.mul(
  135. setup.vk_proof.polZ,
  136. [F.neg(bigInt(c)), bigInt(1)] );
  137. }
  138. }
  139. function calculateEncriptedValuesAtT(setup, circuit) {
  140. setup.vk_proof.A = [];
  141. setup.vk_proof.B = [];
  142. setup.vk_proof.C = [];
  143. setup.vk_proof.Ap = [];
  144. setup.vk_proof.Bp = [];
  145. setup.vk_proof.Cp = [];
  146. setup.vk_proof.Kp = [];
  147. setup.vk_verifier.A = [];
  148. setup.toxic.ka = F.random();
  149. setup.toxic.kb = F.random();
  150. setup.toxic.kc = F.random();
  151. setup.toxic.kbeta = F.random();
  152. setup.toxic.kgamma = F.random();
  153. const gb = F.mul(setup.toxic.kbeta, setup.toxic.kgamma);
  154. setup.vk_verifier.vk_a = G2.affine(G2.mulScalar( G2.g, setup.toxic.ka));
  155. setup.vk_verifier.vk_b = G1.affine(G1.mulScalar( G1.g, setup.toxic.kb));
  156. setup.vk_verifier.vk_c = G2.affine(G2.mulScalar( G2.g, setup.toxic.kc));
  157. setup.vk_verifier.vk_gb_1 = G1.affine(G1.mulScalar( G1.g, gb));
  158. setup.vk_verifier.vk_gb_2 = G2.affine(G2.mulScalar( G2.g, gb));
  159. setup.vk_verifier.vk_g = G2.affine(G2.mulScalar( G2.g, setup.toxic.kgamma));
  160. for (let s=0; s<circuit.nVars; s++) {
  161. // A[i] = G1 * polA(t)
  162. const at = F.affine(PolF.eval(setup.vk_proof.polsA[s], setup.toxic.t));
  163. const A = G1.affine(G1.mulScalar(G1.g, at));
  164. setup.vk_proof.A.push(A);
  165. if (s <= setup.vk_proof.nPublic) {
  166. setup.vk_verifier.A.push(A);
  167. }
  168. // B1[i] = G1 * polB(t)
  169. const bt = F.affine(PolF.eval(setup.vk_proof.polsB[s], setup.toxic.t));
  170. const B1 = G1.affine(G1.mulScalar(G1.g, bt));
  171. // B2[i] = G2 * polB(t)
  172. const B2 = G2.affine(G2.mulScalar(G2.g, bt));
  173. setup.vk_proof.B.push(B2);
  174. // C[i] = G1 * polC(t)
  175. const ct = F.affine(PolF.eval(setup.vk_proof.polsC[s], setup.toxic.t));
  176. const C = G1.affine(G1.mulScalar( G1.g, ct));
  177. setup.vk_proof.C.push (C);
  178. // K = G1 * (A+B+C)
  179. const kt = F.affine(F.add(F.add(at, bt), ct));
  180. const K = G1.affine(G1.mulScalar( G1.g, kt));
  181. const Ktest = G1.affine(G1.add(G1.add(A, B1), C));
  182. if (!G1.equals(K, Ktest)) {
  183. console.log ("=====FAIL======");
  184. }
  185. setup.vk_proof.Ap.push(G1.affine(G1.mulScalar(A, setup.toxic.ka)));
  186. setup.vk_proof.Bp.push(G1.affine(G1.mulScalar(B1, setup.toxic.kb)));
  187. setup.vk_proof.Cp.push(G1.affine(G1.mulScalar(C, setup.toxic.kc)));
  188. setup.vk_proof.Kp.push(G1.affine(G1.mulScalar(K, setup.toxic.kbeta)));
  189. }
  190. setup.vk_verifier.vk_z = G2.affine(G2.mulScalar(
  191. G2.g,
  192. PolF.eval(setup.vk_proof.polZ, setup.toxic.t)));
  193. }
  194. function calculateHexps(setup, circuit) {
  195. let maxA = 0;
  196. let maxB = 0;
  197. let maxC = 0;
  198. for (let s=0; s<circuit.nVars; s++) {
  199. maxA = Math.max(maxA, setup.vk_proof.polsA[s].length);
  200. maxB = Math.max(maxB, setup.vk_proof.polsB[s].length);
  201. maxC = Math.max(maxC, setup.vk_proof.polsC[s].length);
  202. }
  203. let maxFull = Math.max(maxA + maxB - 1, maxC);
  204. const maxH = maxFull - setup.vk_proof.polZ.length + 1;
  205. setup.vk_proof.hExps = new Array(maxH);
  206. setup.vk_proof.hExps[0] = G1.g;
  207. let eT = setup.toxic.t;
  208. for (let i=1; i<maxH; i++) {
  209. setup.vk_proof.hExps[i] = G1.affine(G1.mulScalar(G1.g, eT));
  210. eT = F.mul(eT, setup.toxic.t);
  211. }
  212. }
  213. /*
  214. function unrat(p) {
  215. const res = new Array(p.length);
  216. for (let i=0; i<p.length; i++) {
  217. res[i] = RatPolF.F.toF(p[i]);
  218. }
  219. return res;
  220. }
  221. */