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.

208 lines
6.3 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
  1. /*
  2. Copyright 2018 0kims association.
  3. This file is part of snarkjs.
  4. snarkjs 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. snarkjs 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. snarkjs. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. const BN128 = require("./bn128.js");
  16. const PolField = require("./polfield.js");
  17. const ZqField = require("./zqfield.js");
  18. const bn128 = new BN128();
  19. const PolF = new PolField(new ZqField(bn128.r));
  20. const G1 = bn128.G1;
  21. const G2 = bn128.G2;
  22. module.exports = function genProof(vk_proof, witness) {
  23. const proof = {};
  24. const d1 = PolF.F.random();
  25. const d2 = PolF.F.random();
  26. const d3 = PolF.F.random();
  27. proof.pi_a = G1.zero;
  28. proof.pi_ap = G1.zero;
  29. proof.pi_b = G2.zero;
  30. proof.pi_bp = G1.zero;
  31. proof.pi_c = G1.zero;
  32. proof.pi_cp = G1.zero;
  33. proof.pi_kp = G1.zero;
  34. proof.pi_h = G1.zero;
  35. // Skip public entries and the "1" signal that are forced by the verifier
  36. for (let s= vk_proof.nPublic+1; s< vk_proof.nVars; s++) {
  37. // pi_a = pi_a + A[s] * witness[s];
  38. proof.pi_a = G1.add( proof.pi_a, G1.mulScalar( vk_proof.A[s], witness[s]));
  39. // pi_ap = pi_ap + Ap[s] * witness[s];
  40. proof.pi_ap = G1.add( proof.pi_ap, G1.mulScalar( vk_proof.Ap[s], witness[s]));
  41. }
  42. for (let s= 0; s< vk_proof.nVars; s++) {
  43. // pi_a = pi_a + A[s] * witness[s];
  44. proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( vk_proof.B[s], witness[s]));
  45. // pi_ap = pi_ap + Ap[s] * witness[s];
  46. proof.pi_bp = G1.add( proof.pi_bp, G1.mulScalar( vk_proof.Bp[s], witness[s]));
  47. // pi_a = pi_a + A[s] * witness[s];
  48. proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.C[s], witness[s]));
  49. // pi_ap = pi_ap + Ap[s] * witness[s];
  50. proof.pi_cp = G1.add( proof.pi_cp, G1.mulScalar( vk_proof.Cp[s], witness[s]));
  51. // pi_ap = pi_ap + Ap[s] * witness[s];
  52. proof.pi_kp = G1.add( proof.pi_kp, G1.mulScalar( vk_proof.Kp[s], witness[s]));
  53. }
  54. proof.pi_a = G1.add( proof.pi_a, G1.mulScalar( vk_proof.A[vk_proof.nVars], d1));
  55. proof.pi_ap = G1.add( proof.pi_ap, G1.mulScalar( vk_proof.Ap[vk_proof.nVars], d1));
  56. proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( vk_proof.B[vk_proof.nVars], d2));
  57. proof.pi_bp = G1.add( proof.pi_bp, G1.mulScalar( vk_proof.Bp[vk_proof.nVars], d2));
  58. proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.C[vk_proof.nVars], d3));
  59. proof.pi_cp = G1.add( proof.pi_cp, G1.mulScalar( vk_proof.Cp[vk_proof.nVars], d3));
  60. proof.pi_kp = G1.add( proof.pi_kp, G1.mulScalar( vk_proof.Kp[vk_proof.nVars ], d1));
  61. proof.pi_kp = G1.add( proof.pi_kp, G1.mulScalar( vk_proof.Kp[vk_proof.nVars+1], d2));
  62. proof.pi_kp = G1.add( proof.pi_kp, G1.mulScalar( vk_proof.Kp[vk_proof.nVars+2], d3));
  63. /*
  64. let polA = [];
  65. let polB = [];
  66. let polC = [];
  67. for (let s= 0; s< vk_proof.nVars; s++) {
  68. polA = PolF.add(
  69. polA,
  70. PolF.mul(
  71. vk_proof.polsA[s],
  72. [witness[s]] ));
  73. polB = PolF.add(
  74. polB,
  75. PolF.mul(
  76. vk_proof.polsB[s],
  77. [witness[s]] ));
  78. polC = PolF.add(
  79. polC,
  80. PolF.mul(
  81. vk_proof.polsC[s],
  82. [witness[s]] ));
  83. }
  84. let polFull = PolF.sub(PolF.mul( polA, polB), polC);
  85. const h = PolF.div(polFull, vk_proof.polZ );
  86. */
  87. const h = calculateH(vk_proof, witness, d1, d2, d3);
  88. // console.log(h.length + "/" + vk_proof.hExps.length);
  89. for (let i = 0; i < h.length; i++) {
  90. proof.pi_h = G1.add( proof.pi_h, G1.mulScalar( vk_proof.hExps[i], h[i]));
  91. }
  92. proof.pi_a = G1.affine(proof.pi_a);
  93. proof.pi_b = G2.affine(proof.pi_b);
  94. proof.pi_c = G1.affine(proof.pi_c);
  95. proof.pi_ap = G1.affine(proof.pi_ap);
  96. proof.pi_bp = G1.affine(proof.pi_bp);
  97. proof.pi_cp = G1.affine(proof.pi_cp);
  98. proof.pi_kp = G1.affine(proof.pi_kp);
  99. proof.pi_h = G1.affine(proof.pi_h);
  100. // proof.h=h;
  101. const publicSignals = witness.slice(1, vk_proof.nPublic+1);
  102. return {proof, publicSignals};
  103. };
  104. function calculateH(vk_proof, witness, d1, d2, d3) {
  105. const F = PolF.F;
  106. const m = vk_proof.domainSize;
  107. const polA_T = new Array(m).fill(PolF.F.zero);
  108. const polB_T = new Array(m).fill(PolF.F.zero);
  109. const polC_T = new Array(m).fill(PolF.F.zero);
  110. for (let s=0; s<vk_proof.nVars; s++) {
  111. for (let c in vk_proof.polsA[s]) {
  112. polA_T[c] = F.add(polA_T[c], F.mul(witness[s], vk_proof.polsA[s][c]));
  113. }
  114. for (let c in vk_proof.polsB[s]) {
  115. polB_T[c] = F.add(polB_T[c], F.mul(witness[s], vk_proof.polsB[s][c]));
  116. }
  117. for (let c in vk_proof.polsC[s]) {
  118. polC_T[c] = F.add(polC_T[c], F.mul(witness[s], vk_proof.polsC[s][c]));
  119. }
  120. }
  121. const polA_S = PolF.ifft(polA_T);
  122. const polB_S = PolF.ifft(polB_T);
  123. const polAB_S = PolF.mul(polA_S, polB_S);
  124. const polC_S = PolF.ifft(polC_T);
  125. const polABC_S = PolF.sub(polAB_S, polC_S);
  126. const polZ_S = new Array(m+1).fill(F.zero);
  127. polZ_S[m] = F.one;
  128. polZ_S[0] = F.neg(F.one);
  129. let H_S = PolF.div(polABC_S, polZ_S);
  130. /*
  131. const H2S = PolF.mul(H_S, polZ_S);
  132. if (PolF.equals(H2S, polABC_S)) {
  133. console.log("Is Divisible!");
  134. } else {
  135. console.log("ERROR: Not divisible!");
  136. }
  137. */
  138. /* add coefficients of the polynomial (d2*A + d1*B - d3) + d1*d2*Z */
  139. H_S = PolF.extend(H_S, m+1);
  140. for (let i=0; i<m; i++) {
  141. const d2A = PolF.F.mul(d2, polA_S[i]);
  142. const d1B = PolF.F.mul(d1, polB_S[i]);
  143. H_S[i] = PolF.F.add(H_S[i], PolF.F.add(d2A, d1B));
  144. }
  145. H_S[0] = PolF.F.sub(H_S[0], d3);
  146. // Z = x^m -1
  147. const d1d2 = PolF.F.mul(d1, d2);
  148. H_S[m] = PolF.F.add(H_S[m], d1d2);
  149. H_S[0] = PolF.F.sub(H_S[0], d1d2);
  150. H_S = PolF.reduce(PolF.affine(H_S));
  151. return H_S;
  152. }