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.

212 lines
4.6 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
  1. const bigInt = require("big-integer");
  2. const assert = require("assert");
  3. function writeUint32(h, val) {
  4. h.dataView.setUint32(h.offset, val, true);
  5. h.offset += 4;
  6. }
  7. function writeUint32ToPointer(h, p, val) {
  8. h.dataView.setUint32(p, val, true);
  9. }
  10. function alloc(h, n) {
  11. const o = h.offset;
  12. h.offset += n;
  13. return o;
  14. }
  15. function writeBigInt(h, bi) {
  16. for (let i=0; i<8; i++) {
  17. const v = bi.shiftRight(i*32).and(0xFFFFFFFF).toJSNumber();
  18. writeUint32(h, v);
  19. }
  20. }
  21. function toMontgomeryQ(p) {
  22. const q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
  23. return p.times(bigInt.one.shiftLeft(256)).mod(q);
  24. }
  25. function toMontgomeryR(p) {
  26. const r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  27. return p.times(bigInt.one.shiftLeft(256)).mod(r);
  28. }
  29. function writePoint(h, p) {
  30. writeBigInt(h, toMontgomeryQ(p[0]));
  31. writeBigInt(h, toMontgomeryQ(p[1]));
  32. }
  33. function writePoint2(h, p) {
  34. writeBigInt(h, toMontgomeryQ(p[0][0]));
  35. writeBigInt(h, toMontgomeryQ(p[0][1]));
  36. writeBigInt(h, toMontgomeryQ(p[1][0]));
  37. writeBigInt(h, toMontgomeryQ(p[1][1]));
  38. }
  39. function writeTransformedPolynomial(h, p) {
  40. const keys = Object.keys(p);
  41. writeUint32(h, keys.length);
  42. for (let i=0; i<keys.length; i++) {
  43. writeUint32(h, keys[i]);
  44. writeBigInt(h, toMontgomeryR(p[keys[i]]));
  45. }
  46. }
  47. function calculateBuffLen(provingKey) {
  48. function polSize(pol) {
  49. const l= Object.keys(pol).length;
  50. return 36*l + 4;
  51. }
  52. let size = 40;
  53. // alfa1, beta1, delta1
  54. size += 3 * (32*2);
  55. // beta2, delta2
  56. size += 2 * (32*4);
  57. for (let i=0; i<provingKey.nVars; i++) {
  58. size += polSize(provingKey.polsA[i]);
  59. size += polSize(provingKey.polsB[i]);
  60. }
  61. size += provingKey.nVars* (32*2);
  62. size += provingKey.nVars* (32*2);
  63. size += provingKey.nVars* (32*4);
  64. size += (provingKey.nVars - provingKey.nPublic - 1)* (32*2);
  65. size += provingKey.domainSize * (32*2);
  66. return size;
  67. }
  68. function buildPKey(provingKey) {
  69. const buffLen = calculateBuffLen(provingKey);
  70. const buff = new ArrayBuffer(buffLen);
  71. const h = {
  72. dataView: new DataView(buff),
  73. offset: 0
  74. };
  75. writeUint32(h, provingKey.nVars);
  76. writeUint32(h, provingKey.nPublic);
  77. writeUint32(h, provingKey.domainSize);
  78. const pPolsA = alloc(h, 4);
  79. const pPolsB = alloc(h, 4);
  80. const pPointsA = alloc(h, 4);
  81. const pPointsB1 = alloc(h, 4);
  82. const pPointsB2 = alloc(h, 4);
  83. const pPointsC = alloc(h, 4);
  84. const pPointsHExps = alloc(h, 4);
  85. writePoint(h, provingKey.vk_alfa_1);
  86. writePoint(h, provingKey.vk_beta_1);
  87. writePoint(h, provingKey.vk_delta_1);
  88. writePoint2(h, provingKey.vk_beta_2);
  89. writePoint2(h, provingKey.vk_delta_2);
  90. writeUint32ToPointer(h, pPolsA, h.offset);
  91. for (let i=0; i<provingKey.nVars; i++) {
  92. writeTransformedPolynomial(h, provingKey.polsA[i]);
  93. }
  94. writeUint32ToPointer(h, pPolsB, h.offset);
  95. for (let i=0; i<provingKey.nVars; i++) {
  96. writeTransformedPolynomial(h, provingKey.polsB[i]);
  97. }
  98. writeUint32ToPointer(h, pPointsA, h.offset);
  99. for (let i=0; i<provingKey.nVars; i++) {
  100. writePoint(h, provingKey.A[i]);
  101. }
  102. writeUint32ToPointer(h, pPointsB1, h.offset);
  103. for (let i=0; i<provingKey.nVars; i++) {
  104. writePoint(h, provingKey.B1[i]);
  105. }
  106. writeUint32ToPointer(h, pPointsB2, h.offset);
  107. for (let i=0; i<provingKey.nVars; i++) {
  108. writePoint2(h, provingKey.B2[i]);
  109. }
  110. writeUint32ToPointer(h, pPointsC, h.offset);
  111. for (let i=provingKey.nPublic+1; i<provingKey.nVars; i++) {
  112. writePoint(h, provingKey.C[i]);
  113. }
  114. writeUint32ToPointer(h, pPointsHExps, h.offset);
  115. for (let i=0; i<provingKey.domainSize; i++) {
  116. writePoint(h, provingKey.hExps[i]);
  117. }
  118. assert.equal(h.offset, buffLen);
  119. return Buffer.from(buff);
  120. }
  121. module.exports = buildPKey;
  122. /*
  123. NSignals
  124. NPublic
  125. DomainSize (2 multiple)
  126. pPolsA
  127. pPolsB
  128. pPointsA
  129. pPointsB1
  130. pPointsB2
  131. pPointsC
  132. pPointsHExps
  133. Alfa1
  134. Beta1
  135. Delta1
  136. Beta2
  137. Delta2
  138. PolinomialA_0
  139. PolinomialA_1
  140. PolinomialA_2
  141. ...
  142. PolinomialA_NVars-1
  143. PolinomialB_0
  144. PolinomialB_1
  145. PolinomialB_2
  146. ...
  147. PolinomialB_NVars-1
  148. PointA_0
  149. PointA_1
  150. ...
  151. PointA_NVars-1
  152. PointB1_0
  153. PointB1_1
  154. ...
  155. PointB1_NVars-1
  156. PointB2_0
  157. PointB2_1
  158. ...
  159. PointB2_NVars-1
  160. PointC_nPublics+1
  161. PointC_nPublics+2
  162. ...
  163. PointC_nPublics+NVars
  164. PointHExp_0
  165. PointHExp_1
  166. ...
  167. PointHExp_DomainSize-1
  168. */