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.

240 lines
5.3 KiB

5 years ago
  1. const {unstringifyBigInts} = require("./stringifybigint.js");
  2. const fs = require("fs");
  3. const bigInt = require("big-integer");
  4. const assert = require("assert");
  5. const version = require("../package").version;
  6. const argv = require("yargs")
  7. .version(version)
  8. .usage(`node buildpkey.js -i "proving_key.json" -o "proving_key.bin"
  9. Default: circuit.json
  10. `)
  11. .alias("i", "input")
  12. .alias("o", "output")
  13. .help("h")
  14. .alias("h", "help")
  15. .epilogue(`Copyright (C) 2018 0kims association
  16. This program comes with ABSOLUTELY NO WARRANTY;
  17. This is free software, and you are welcome to redistribute it
  18. under certain conditions; see the COPYING file in the official
  19. repo directory at https://github.com/iden3/circom `)
  20. .argv;
  21. const inputName = (argv.input) ? argv.input : "proving_key.json";
  22. const outputName = (argv.output) ? argv.output : "proving_key.bin";
  23. const provingKey = unstringifyBigInts(JSON.parse(fs.readFileSync(inputName, "utf8")));
  24. function writeUint32(h, val) {
  25. h.dataView.setUint32(h.offset, val, true);
  26. h.offset += 4;
  27. }
  28. function writeUint32ToPointer(h, p, val) {
  29. h.dataView.setUint32(p, val, true);
  30. }
  31. function alloc(h, n) {
  32. const o = h.offset;
  33. h.offset += n;
  34. return o;
  35. }
  36. function writeBigInt(h, bi) {
  37. for (let i=0; i<8; i++) {
  38. const v = bi.shiftRight(i*32).and(0xFFFFFFFF).toJSNumber();
  39. writeUint32(h, v);
  40. }
  41. }
  42. function toMontgomeryQ(p) {
  43. const q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
  44. return p.times(bigInt.one.shiftLeft(256)).mod(q);
  45. }
  46. function toMontgomeryR(p) {
  47. const r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  48. return p.times(bigInt.one.shiftLeft(256)).mod(r);
  49. }
  50. function writePoint(h, p) {
  51. writeBigInt(h, toMontgomeryQ(p[0]));
  52. writeBigInt(h, toMontgomeryQ(p[1]));
  53. }
  54. function writePoint2(h, p) {
  55. writeBigInt(h, toMontgomeryQ(p[0][0]));
  56. writeBigInt(h, toMontgomeryQ(p[0][1]));
  57. writeBigInt(h, toMontgomeryQ(p[1][0]));
  58. writeBigInt(h, toMontgomeryQ(p[1][1]));
  59. }
  60. function writeTransformedPolynomial(h, p) {
  61. const keys = Object.keys(p);
  62. writeUint32(h, keys.length);
  63. for (let i=0; i<keys.length; i++) {
  64. writeUint32(h, keys[i]);
  65. writeBigInt(h, toMontgomeryR(p[keys[i]]));
  66. }
  67. }
  68. function calculateBuffLen(provingKey) {
  69. function polSize(pol) {
  70. const l= Object.keys(pol).length;
  71. return 36*l + 4;
  72. }
  73. let size = 40;
  74. // alfa1, beta1, delta1
  75. size += 3 * (32*2);
  76. // beta2, delta2
  77. size += 2 * (32*4);
  78. for (let i=0; i<provingKey.nVars; i++) {
  79. size += polSize(provingKey.polsA[i]);
  80. size += polSize(provingKey.polsB[i]);
  81. }
  82. size += provingKey.nVars* (32*2);
  83. size += provingKey.nVars* (32*2);
  84. size += provingKey.nVars* (32*4);
  85. size += (provingKey.nVars - provingKey.nPublic - 1)* (32*2);
  86. size += provingKey.domainSize * (32*2);
  87. return size;
  88. }
  89. const buffLen = calculateBuffLen(provingKey);
  90. const buff = new ArrayBuffer(buffLen);
  91. const h = {
  92. dataView: new DataView(buff),
  93. offset: 0
  94. };
  95. writeUint32(h, provingKey.nVars);
  96. writeUint32(h, provingKey.nPublic);
  97. writeUint32(h, provingKey.domainSize);
  98. const pPolsA = alloc(h, 4);
  99. const pPolsB = alloc(h, 4);
  100. const pPointsA = alloc(h, 4);
  101. const pPointsB1 = alloc(h, 4);
  102. const pPointsB2 = alloc(h, 4);
  103. const pPointsC = alloc(h, 4);
  104. const pPointsHExps = alloc(h, 4);
  105. writePoint(h, provingKey.vk_alfa_1);
  106. writePoint(h, provingKey.vk_beta_1);
  107. writePoint(h, provingKey.vk_delta_1);
  108. writePoint2(h, provingKey.vk_beta_2);
  109. writePoint2(h, provingKey.vk_delta_2);
  110. writeUint32ToPointer(h, pPolsA, h.offset);
  111. for (let i=0; i<provingKey.nVars; i++) {
  112. writeTransformedPolynomial(h, provingKey.polsA[i]);
  113. }
  114. writeUint32ToPointer(h, pPolsB, h.offset);
  115. for (let i=0; i<provingKey.nVars; i++) {
  116. writeTransformedPolynomial(h, provingKey.polsB[i]);
  117. }
  118. writeUint32ToPointer(h, pPointsA, h.offset);
  119. for (let i=0; i<provingKey.nVars; i++) {
  120. writePoint(h, provingKey.A[i]);
  121. }
  122. writeUint32ToPointer(h, pPointsB1, h.offset);
  123. for (let i=0; i<provingKey.nVars; i++) {
  124. writePoint(h, provingKey.B1[i]);
  125. }
  126. writeUint32ToPointer(h, pPointsB2, h.offset);
  127. for (let i=0; i<provingKey.nVars; i++) {
  128. writePoint2(h, provingKey.B2[i]);
  129. }
  130. writeUint32ToPointer(h, pPointsC, h.offset);
  131. for (let i=provingKey.nPublic+1; i<provingKey.nVars; i++) {
  132. writePoint(h, provingKey.C[i]);
  133. }
  134. writeUint32ToPointer(h, pPointsHExps, h.offset);
  135. for (let i=0; i<provingKey.domainSize; i++) {
  136. writePoint(h, provingKey.hExps[i]);
  137. }
  138. assert.equal(h.offset, buffLen);
  139. var wstream = fs.createWriteStream(outputName);
  140. wstream.write(Buffer.from(buff));
  141. wstream.end();
  142. /*
  143. NSignals
  144. NPublic
  145. DomainSize (2 multiple)
  146. pPolsA
  147. pPolsB
  148. pPointsA
  149. pPointsB1
  150. pPointsB2
  151. pPointsC
  152. pPointsHExps
  153. Alfa1
  154. Beta1
  155. Delta1
  156. Beta2
  157. Delta2
  158. PolinomialA_0
  159. PolinomialA_1
  160. PolinomialA_2
  161. ...
  162. PolinomialA_NVars-1
  163. PolinomialB_0
  164. PolinomialB_1
  165. PolinomialB_2
  166. ...
  167. PolinomialB_NVars-1
  168. PointA_0
  169. PointA_1
  170. ...
  171. PointA_NVars-1
  172. PointB1_0
  173. PointB1_1
  174. ...
  175. PointB1_NVars-1
  176. PointB2_0
  177. PointB2_1
  178. ...
  179. PointB2_NVars-1
  180. PointC_nPublics+1
  181. PointC_nPublics+2
  182. ...
  183. PointC_nPublics+NVars
  184. PointHExp_0
  185. PointHExp_1
  186. ...
  187. PointHExp_DomainSize-1
  188. */