@aztec/blob-lib 0.0.1-fake-ceab37513c → 0.0.6-commit.a2d1860fe9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dest/batched_blob.d.ts +31 -0
  2. package/dest/batched_blob.d.ts.map +1 -0
  3. package/dest/batched_blob.js +20 -0
  4. package/dest/blob.d.ts +56 -102
  5. package/dest/blob.d.ts.map +1 -1
  6. package/dest/blob.js +77 -170
  7. package/dest/blob_batching.d.ts +41 -111
  8. package/dest/blob_batching.d.ts.map +1 -1
  9. package/dest/blob_batching.js +129 -203
  10. package/dest/blob_utils.d.ts +40 -0
  11. package/dest/blob_utils.d.ts.map +1 -0
  12. package/dest/blob_utils.js +69 -0
  13. package/dest/circuit_types/blob_accumulator.d.ts +23 -0
  14. package/dest/circuit_types/blob_accumulator.d.ts.map +1 -0
  15. package/dest/circuit_types/blob_accumulator.js +62 -0
  16. package/dest/circuit_types/final_blob_accumulator.d.ts +23 -0
  17. package/dest/circuit_types/final_blob_accumulator.d.ts.map +1 -0
  18. package/dest/circuit_types/final_blob_accumulator.js +66 -0
  19. package/dest/circuit_types/final_blob_batching_challenges.d.ts +16 -0
  20. package/dest/circuit_types/final_blob_batching_challenges.d.ts.map +1 -0
  21. package/dest/circuit_types/final_blob_batching_challenges.js +26 -0
  22. package/dest/circuit_types/index.d.ts +4 -0
  23. package/dest/circuit_types/index.d.ts.map +1 -0
  24. package/dest/circuit_types/index.js +4 -0
  25. package/dest/encoding/block_blob_data.d.ts +30 -0
  26. package/dest/encoding/block_blob_data.d.ts.map +1 -0
  27. package/dest/encoding/block_blob_data.js +75 -0
  28. package/dest/encoding/block_end_marker.d.ts +11 -0
  29. package/dest/encoding/block_end_marker.d.ts.map +1 -0
  30. package/dest/encoding/block_end_marker.js +41 -0
  31. package/dest/encoding/block_end_state_field.d.ts +12 -0
  32. package/dest/encoding/block_end_state_field.d.ts.map +1 -0
  33. package/dest/encoding/block_end_state_field.js +39 -0
  34. package/dest/encoding/checkpoint_blob_data.d.ts +15 -0
  35. package/dest/encoding/checkpoint_blob_data.d.ts.map +1 -0
  36. package/dest/encoding/checkpoint_blob_data.js +67 -0
  37. package/dest/encoding/checkpoint_end_marker.d.ts +8 -0
  38. package/dest/encoding/checkpoint_end_marker.d.ts.map +1 -0
  39. package/dest/encoding/checkpoint_end_marker.js +28 -0
  40. package/dest/encoding/fixtures.d.ts +41 -0
  41. package/dest/encoding/fixtures.d.ts.map +1 -0
  42. package/dest/encoding/fixtures.js +140 -0
  43. package/dest/encoding/index.d.ts +10 -0
  44. package/dest/encoding/index.d.ts.map +1 -0
  45. package/dest/encoding/index.js +9 -0
  46. package/dest/encoding/tx_blob_data.d.ts +19 -0
  47. package/dest/encoding/tx_blob_data.d.ts.map +1 -0
  48. package/dest/encoding/tx_blob_data.js +79 -0
  49. package/dest/encoding/tx_start_marker.d.ts +16 -0
  50. package/dest/encoding/tx_start_marker.d.ts.map +1 -0
  51. package/dest/encoding/tx_start_marker.js +77 -0
  52. package/dest/errors.d.ts +1 -1
  53. package/dest/errors.d.ts.map +1 -1
  54. package/dest/hash.d.ts +43 -0
  55. package/dest/hash.d.ts.map +1 -0
  56. package/dest/hash.js +80 -0
  57. package/dest/index.d.ts +7 -4
  58. package/dest/index.d.ts.map +1 -1
  59. package/dest/index.js +6 -16
  60. package/dest/interface.d.ts +1 -2
  61. package/dest/interface.d.ts.map +1 -1
  62. package/dest/kzg_context.d.ts +8 -0
  63. package/dest/kzg_context.d.ts.map +1 -0
  64. package/dest/kzg_context.js +14 -0
  65. package/dest/sponge_blob.d.ts +13 -13
  66. package/dest/sponge_blob.d.ts.map +1 -1
  67. package/dest/sponge_blob.js +26 -30
  68. package/dest/testing.d.ts +10 -23
  69. package/dest/testing.d.ts.map +1 -1
  70. package/dest/testing.js +37 -53
  71. package/dest/types.d.ts +4 -1
  72. package/dest/types.d.ts.map +1 -1
  73. package/dest/types.js +3 -0
  74. package/package.json +9 -7
  75. package/src/batched_blob.ts +26 -0
  76. package/src/blob.ts +80 -201
  77. package/src/blob_batching.ts +168 -231
  78. package/src/blob_utils.ts +84 -0
  79. package/src/circuit_types/blob_accumulator.ts +96 -0
  80. package/src/circuit_types/final_blob_accumulator.ts +76 -0
  81. package/src/circuit_types/final_blob_batching_challenges.ts +30 -0
  82. package/src/circuit_types/index.ts +4 -0
  83. package/src/encoding/block_blob_data.ts +114 -0
  84. package/src/encoding/block_end_marker.ts +55 -0
  85. package/src/encoding/block_end_state_field.ts +59 -0
  86. package/src/encoding/checkpoint_blob_data.ts +102 -0
  87. package/src/encoding/checkpoint_end_marker.ts +40 -0
  88. package/src/encoding/fixtures.ts +210 -0
  89. package/src/encoding/index.ts +9 -0
  90. package/src/encoding/tx_blob_data.ts +116 -0
  91. package/src/encoding/tx_start_marker.ts +97 -0
  92. package/src/hash.ts +89 -0
  93. package/src/index.ts +6 -19
  94. package/src/interface.ts +0 -1
  95. package/src/kzg_context.ts +16 -0
  96. package/src/sponge_blob.ts +28 -31
  97. package/src/testing.ts +48 -59
  98. package/src/types.ts +3 -2
  99. package/dest/blob_batching_public_inputs.d.ts +0 -71
  100. package/dest/blob_batching_public_inputs.d.ts.map +0 -1
  101. package/dest/blob_batching_public_inputs.js +0 -168
  102. package/dest/encoding.d.ts +0 -66
  103. package/dest/encoding.d.ts.map +0 -1
  104. package/dest/encoding.js +0 -113
  105. package/src/blob_batching_public_inputs.ts +0 -252
  106. package/src/encoding.ts +0 -138
package/src/blob.ts CHANGED
@@ -1,259 +1,173 @@
1
- import { poseidon2Hash, sha256 } from '@aztec/foundation/crypto';
2
- import { Fr } from '@aztec/foundation/fields';
1
+ import { FIELDS_PER_BLOB } from '@aztec/constants';
2
+ import { BLS12Fr } from '@aztec/foundation/curves/bls12';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
4
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
4
5
 
5
- // Importing directly from 'c-kzg' does not work:
6
- import cKzg from 'c-kzg';
7
- import type { Blob as BlobBuffer } from 'c-kzg';
8
-
9
- import { deserializeEncodedBlobToFields, extractBlobFieldsFromBuffer } from './encoding.js';
10
- import { BlobDeserializationError } from './errors.js';
6
+ import { computeBlobCommitment, computeChallengeZ, computeEthVersionedBlobHash } from './hash.js';
11
7
  import type { BlobJson } from './interface.js';
8
+ import { BYTES_PER_BLOB, BYTES_PER_COMMITMENT, getKzg } from './kzg_context.js';
12
9
 
13
- const { BYTES_PER_BLOB, FIELD_ELEMENTS_PER_BLOB, blobToKzgCommitment, computeKzgProof, verifyKzgProof } = cKzg;
14
-
15
- // The prefix to the EVM blobHash, defined here: https://eips.ethereum.org/EIPS/eip-4844#specification
16
- export const VERSIONED_HASH_VERSION_KZG = 0x01;
17
-
18
- /** Versioned blob hash for an empty blob */
19
- export const EMPTY_BLOB_VERSIONED_HASH = Buffer.from(
20
- `010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014`,
21
- 'hex',
22
- );
10
+ export { FIELDS_PER_BLOB };
23
11
 
24
12
  /**
25
13
  * A class to create, manage, and prove EVM blobs.
14
+ *
15
+ * @dev Note: All methods in this class do not check the encoding of the given data. It's the responsibility of other
16
+ * components to ensure that the blob data (which might spread across multiple blobs) was created following the protocol
17
+ * and is correctly encoded.
26
18
  */
27
19
  export class Blob {
28
20
  constructor(
29
- /** The blob to be broadcast on L1 in bytes form. */
30
- public readonly data: BlobBuffer,
31
- /** The hash of all tx effects inside the blob. Used in generating the challenge z and proving that we have included all required effects. */
32
- public readonly fieldsHash: Fr,
33
- /** Challenge point z (= H(H(tx_effects), kzgCommmitment). Used such that p(z) = y for a single blob, used as z_i in batching (see ./blob_batching.ts). */
34
- public readonly challengeZ: Fr,
35
- /** Commitment to the blob C. Used in compressed BLS12 point format (48 bytes). */
21
+ /**
22
+ * The data to be broadcast on L1 in bytes form.
23
+ */
24
+ public readonly data: Uint8Array,
25
+ /**
26
+ * Commitment to the blob data. Used in compressed BLS12 point format (48 bytes).
27
+ */
36
28
  public readonly commitment: Buffer,
37
- ) {}
29
+ ) {
30
+ if (data.length !== BYTES_PER_BLOB) {
31
+ throw new Error(`Blob data must be ${BYTES_PER_BLOB} bytes. Got ${data.length}.`);
32
+ }
33
+ if (commitment.length !== BYTES_PER_COMMITMENT) {
34
+ throw new Error(`Blob commitment must be ${BYTES_PER_COMMITMENT} bytes. Got ${commitment.length}.`);
35
+ }
36
+ }
38
37
 
39
38
  /**
40
- * The encoded version of the blob will determine the end of the blob based on the transaction encoding.
41
- * This is required when the fieldsHash of a blob will contain trailing zeros.
42
- *
43
- * See `./encoding.ts` for more details.
44
- *
45
- * This method is used to create a Blob from a buffer.
46
- * @param blob - The buffer to create the Blob from.
47
- * @param multiBlobFieldsHash - The fields hash to use for the Blob.
39
+ * Create a Blob from a buffer.
40
+ * @param data - The buffer of the Blob.
48
41
  * @returns A Blob created from the buffer.
49
42
  *
50
- * @throws If unable to deserialize the blob.
43
+ * @throws If data does not match the expected length (BYTES_PER_BLOB).
51
44
  */
52
- static fromEncodedBlobBuffer(blob: BlobBuffer, multiBlobFieldsHash?: Fr): Promise<Blob> {
53
- try {
54
- const fields: Fr[] = deserializeEncodedBlobToFields(blob);
55
- return Blob.fromFields(fields, multiBlobFieldsHash);
56
- } catch {
57
- throw new BlobDeserializationError(
58
- `Failed to create Blob from encoded blob buffer, this blob was likely not created by us`,
59
- );
60
- }
45
+ static async fromBlobBuffer(data: Uint8Array): Promise<Blob> {
46
+ const commitment = await computeBlobCommitment(data);
47
+ return new Blob(data, commitment);
61
48
  }
62
49
 
63
50
  /**
64
51
  * Create a Blob from an array of fields.
65
52
  *
53
+ * @dev This method pads 0s to the data, extending it to the size of a full blob.
54
+ *
66
55
  * @param fields - The array of fields to create the Blob from.
67
- * @param multiBlobFieldsHash - The fields hash to use for the Blob.
68
56
  * @returns A Blob created from the array of fields.
69
57
  */
70
- static async fromFields(fields: Fr[], multiBlobFieldsHash?: Fr): Promise<Blob> {
71
- if (fields.length > FIELD_ELEMENTS_PER_BLOB) {
72
- throw new Error(
73
- `Attempted to overfill blob with ${fields.length} elements. The maximum is ${FIELD_ELEMENTS_PER_BLOB}`,
74
- );
58
+ static async fromFields(fields: Fr[]): Promise<Blob> {
59
+ if (fields.length > FIELDS_PER_BLOB) {
60
+ throw new Error(`Attempted to overfill blob with ${fields.length} fields. The maximum is ${FIELDS_PER_BLOB}.`);
75
61
  }
76
62
 
77
63
  const data = Buffer.concat([serializeToBuffer(fields)], BYTES_PER_BLOB);
64
+ const commitment = await computeBlobCommitment(data);
65
+ return new Blob(data, commitment);
66
+ }
78
67
 
79
- // This matches the output of SpongeBlob.squeeze() in the blob circuit
80
- const fieldsHash = multiBlobFieldsHash ? multiBlobFieldsHash : await poseidon2Hash(fields);
81
- const commitment = Buffer.from(blobToKzgCommitment(data));
82
- const challengeZ = await poseidon2Hash([fieldsHash, ...commitmentToFields(commitment)]);
83
-
84
- return new Blob(data, fieldsHash, challengeZ, commitment);
68
+ /**
69
+ * Get the fields from the blob data.
70
+ *
71
+ * @dev WARNING: this method returns all fields
72
+ *
73
+ * @returns The fields from the blob.
74
+ */
75
+ toFields(): Fr[] {
76
+ const reader = BufferReader.asReader(this.data);
77
+ const numTotalFields = this.data.length / Fr.SIZE_IN_BYTES;
78
+ return reader.readArray(numTotalFields, Fr);
85
79
  }
86
80
 
87
81
  /**
88
82
  * Create a Blob from a JSON object.
89
83
  *
90
- * Blobs will be in this form when requested from the blob sink, or from
84
+ * Blobs will be in this form when requested from the blob client, or from
91
85
  * the beacon chain via `getBlobSidecars`
92
86
  * https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getBlobSidecars
93
87
  *
94
- * @dev WARNING: by default json deals with encoded buffers
95
- *
96
88
  * @param json - The JSON object to create the Blob from.
97
89
  * @returns A Blob created from the JSON object.
98
90
  */
99
91
  static async fromJson(json: BlobJson): Promise<Blob> {
100
92
  const blobBuffer = Buffer.from(json.blob.slice(2), 'hex');
101
-
102
- const blob = await Blob.fromEncodedBlobBuffer(blobBuffer);
93
+ const blob = await Blob.fromBlobBuffer(blobBuffer);
103
94
 
104
95
  if (blob.commitment.toString('hex') !== json.kzg_commitment.slice(2)) {
105
96
  throw new Error('KZG commitment does not match');
106
97
  }
107
98
 
108
- // We do not check the proof, as it will be different if the challenge is shared
109
- // across multiple blobs
110
-
111
99
  return blob;
112
100
  }
113
101
 
114
102
  /**
115
103
  * Get the JSON representation of the blob.
116
104
  *
117
- * @dev WARNING: by default json deals with encoded buffers
118
- * @param index - optional - The index of the blob in the block.
119
105
  * @returns The JSON representation of the blob.
120
106
  */
121
- toJson(index: number): BlobJson {
107
+ toJSON(): BlobJson {
122
108
  return {
123
109
  blob: `0x${Buffer.from(this.data).toString('hex')}`,
124
- index: index.toString(),
125
110
  // eslint-disable-next-line camelcase
126
111
  kzg_commitment: `0x${this.commitment.toString('hex')}`,
127
112
  };
128
113
  }
129
114
 
130
- /**
131
- * Get the fields from the blob.
132
- *
133
- * @dev WARNING: this method does not take into account trailing zeros
134
- *
135
- * @returns The fields from the blob.
136
- */
137
- toFields(): Fr[] {
138
- return extractBlobFieldsFromBuffer(this.data);
139
- }
140
-
141
- /**
142
- * Get the encoded fields from the blob.
143
- *
144
- * @dev This method takes into account trailing zeros
145
- *
146
- * @returns The encoded fields from the blob.
147
- *
148
- * @throws If unable to deserialize the blob.
149
- */
150
- toEncodedFields(): Fr[] {
151
- try {
152
- return deserializeEncodedBlobToFields(this.data);
153
- } catch {
154
- throw new BlobDeserializationError(
155
- `Failed to deserialize encoded blob fields, this blob was likely not created by us`,
156
- );
157
- }
158
- }
159
-
160
- /**
161
- * Get the encoded fields from multiple blobs.
162
- *
163
- * @dev This method takes into account trailing zeros
164
- *
165
- * @returns The encoded fields from the blobs.
166
- */
167
- static toEncodedFields(blobs: Blob[]): Fr[] {
168
- try {
169
- return deserializeEncodedBlobToFields(Buffer.concat(blobs.map(b => b.data)));
170
- } catch {
171
- throw new BlobDeserializationError(
172
- `Failed to deserialize encoded blob fields, this blob was likely not created by us`,
173
- );
174
- }
115
+ getEthVersionedBlobHash(): Buffer {
116
+ return computeEthVersionedBlobHash(this.commitment);
175
117
  }
176
118
 
177
119
  /**
178
- * Get the commitment fields from the blob.
179
- *
180
- * The 48-byte commitment is encoded into two field elements:
181
- * +------------------+------------------+
182
- * | Field Element 1 | Field Element 2 |
183
- * | [bytes 0-31] | [bytes 32-47] |
184
- * +------------------+------------------+
185
- * | 32 bytes | 16 bytes |
186
- * +------------------+------------------+
187
- * @returns The commitment fields from the blob.
120
+ * Challenge point z (= H(H(tx_effects), kzgCommitment)).
121
+ * Used such that p(z) = y for a single blob, used as z_i in batching (see ./blob_batching.ts).
188
122
  */
189
- commitmentToFields(): [Fr, Fr] {
190
- return commitmentToFields(this.commitment);
191
- }
192
-
193
- // Returns ethereum's versioned blob hash, following kzg_to_versioned_hash: https://eips.ethereum.org/EIPS/eip-4844#helpers
194
- getEthVersionedBlobHash(): Buffer {
195
- const hash = sha256(this.commitment);
196
- hash[0] = VERSIONED_HASH_VERSION_KZG;
197
- return hash;
198
- }
199
-
200
- static getEthVersionedBlobHash(commitment: Buffer): Buffer {
201
- const hash = sha256(commitment);
202
- hash[0] = VERSIONED_HASH_VERSION_KZG;
203
- return hash;
123
+ async computeChallengeZ(blobFieldsHash: Fr): Promise<Fr> {
124
+ return await computeChallengeZ(blobFieldsHash, this.commitment);
204
125
  }
205
126
 
206
127
  /**
207
128
  * Evaluate the blob at a given challenge and return the evaluation and KZG proof.
208
129
  *
209
- * @param challengeZ - The challenge z at which to evaluate the blob. If not given, assume we want to evaluate at the individual blob's z.
130
+ * @param challengeZ - The challenge z at which to evaluate the blob.
131
+ * @param verifyProof - Whether to verify the KZG proof.
210
132
  *
211
- * @returns -
212
- * y: Buffer - Evaluation y = p(z), where p() is the blob polynomial. BLS12 field element, rep. as BigNum in nr, bigint in ts
133
+ * @returns
134
+ * y: BLS12Fr - Evaluation y = p(z), where p() is the blob polynomial. BLS12 field element, rep. as BigNum in nr, bigint in ts.
213
135
  * proof: Buffer - KZG opening proof for y = p(z). The commitment to quotient polynomial Q, used in compressed BLS12 point format (48 bytes).
214
136
  */
215
- evaluate(challengeZ?: Fr) {
216
- const z = challengeZ || this.challengeZ;
217
- const res = computeKzgProof(this.data, z.toBuffer());
218
- if (!verifyKzgProof(this.commitment, z.toBuffer(), res[1], res[0])) {
137
+ async evaluate(challengeZ: Fr, verifyProof = false) {
138
+ const kzg = getKzg();
139
+ const res = await kzg.asyncComputeKzgProof(this.data, challengeZ.toBuffer());
140
+ if (verifyProof && !kzg.verifyKzgProof(this.commitment, challengeZ.toBuffer(), res[1], res[0])) {
219
141
  throw new Error(`KZG proof did not verify.`);
220
142
  }
143
+
221
144
  const proof = Buffer.from(res[0]);
222
- const y = Buffer.from(res[1]);
145
+ const y = BLS12Fr.fromBuffer(Buffer.from(res[1]));
223
146
  return { y, proof };
224
147
  }
225
148
 
226
149
  /**
227
150
  * Get the buffer representation of the ENTIRE blob.
228
151
  *
229
- * @dev WARNING: this buffer contains all metadata aswell as the data itself
152
+ * @dev WARNING: this buffer contains all metadata as well as the data itself.
230
153
  *
231
154
  * @returns The buffer representation of the blob.
232
155
  */
233
156
  toBuffer(): Buffer {
234
- return Buffer.from(
235
- serializeToBuffer(
236
- this.data.length,
237
- this.data,
238
- this.fieldsHash,
239
- this.challengeZ,
240
- this.commitment.length,
241
- this.commitment,
242
- ),
243
- );
157
+ return Buffer.from(serializeToBuffer(this.data.length, this.data, this.commitment.length, this.commitment));
244
158
  }
245
159
 
246
160
  /**
247
161
  * Create a Blob from a buffer.
248
162
  *
249
- * @dev WARNING: this method contains all metadata aswell as the data itself
163
+ * @dev WARNING: this method contains all metadata as well as the data itself.
250
164
  *
251
165
  * @param buf - The buffer to create the Blob from.
252
166
  * @returns A Blob created from the buffer.
253
167
  */
254
168
  static fromBuffer(buf: Buffer | BufferReader): Blob {
255
169
  const reader = BufferReader.asReader(buf);
256
- return new Blob(reader.readUint8Array(), reader.readObject(Fr), reader.readObject(Fr), reader.readBuffer());
170
+ return new Blob(reader.readUint8Array(), reader.readBuffer());
257
171
  }
258
172
 
259
173
  /**
@@ -263,50 +177,15 @@ export class Blob {
263
177
  return this.data.length;
264
178
  }
265
179
 
266
- /**
267
- * @param blobs - The blobs to emit
268
- * @returns The blobs' compressed commitments in hex prefixed by the number of blobs
269
- * @dev Used for proposing blocks to validate injected blob commitments match real broadcast blobs:
270
- * One byte for the number blobs + 48 bytes per blob commitment
271
- */
272
- static getPrefixedEthBlobCommitments(blobs: Blob[]): `0x${string}` {
273
- let buf = Buffer.alloc(0);
274
- blobs.forEach(blob => {
275
- buf = Buffer.concat([buf, blob.commitment]);
276
- });
277
- // We prefix the number of blobs:
278
- const lenBuf = Buffer.alloc(1);
279
- lenBuf.writeUint8(blobs.length);
280
- buf = Buffer.concat([lenBuf, buf]);
281
- return `0x${buf.toString('hex')}`;
282
- }
283
-
284
180
  static getViemKzgInstance() {
181
+ const kzg = getKzg();
285
182
  return {
286
- blobToKzgCommitment: cKzg.blobToKzgCommitment,
287
- computeBlobKzgProof: cKzg.computeBlobKzgProof,
288
- computeCellsAndKzgProofs: cKzg.computeCellsAndKzgProofs,
183
+ blobToKzgCommitment: kzg.blobToKzgCommitment.bind(kzg),
184
+ computeBlobKzgProof: kzg.computeBlobKzgProof.bind(kzg),
185
+ computeCellsAndKzgProofs: (b: Uint8Array): [Uint8Array[], Uint8Array[]] => {
186
+ const result = kzg.computeCellsAndKzgProofs(b);
187
+ return [result.cells, result.proofs];
188
+ },
289
189
  };
290
190
  }
291
-
292
- /**
293
- * @param fields - Fields to broadcast in the blob(s)
294
- * @returns As many blobs as we require to broadcast the given fields for a block
295
- * @dev Assumes we share the fields hash between all blobs which can only be done for ONE BLOCK because the hash is calculated in block root.
296
- */
297
- static async getBlobsPerBlock(fields: Fr[]): Promise<Blob[]> {
298
- const numBlobs = Math.max(Math.ceil(fields.length / FIELD_ELEMENTS_PER_BLOB), 1);
299
- const multiBlobFieldsHash = await poseidon2Hash(fields);
300
- const res = [];
301
- for (let i = 0; i < numBlobs; i++) {
302
- const end = fields.length < (i + 1) * FIELD_ELEMENTS_PER_BLOB ? fields.length : (i + 1) * FIELD_ELEMENTS_PER_BLOB;
303
- res.push(await Blob.fromFields(fields.slice(i * FIELD_ELEMENTS_PER_BLOB, end), multiBlobFieldsHash));
304
- }
305
- return res;
306
- }
307
- }
308
-
309
- // 48 bytes encoded in fields as [Fr, Fr] = [0->31, 31->48]
310
- function commitmentToFields(commitment: Buffer): [Fr, Fr] {
311
- return [new Fr(commitment.subarray(0, 31)), new Fr(commitment.subarray(31, 48))];
312
191
  }