@aztec/blob-lib 3.0.0-nightly.20251025 → 3.0.0-nightly.20251030-2
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.
- package/dest/blob.d.ts +47 -89
- package/dest/blob.d.ts.map +1 -1
- package/dest/blob.js +62 -160
- package/dest/blob_batching.d.ts +14 -46
- package/dest/blob_batching.d.ts.map +1 -1
- package/dest/blob_batching.js +80 -100
- package/dest/blob_utils.d.ts +30 -0
- package/dest/blob_utils.d.ts.map +1 -0
- package/dest/blob_utils.js +60 -0
- package/dest/circuit_types/blob_accumulator.d.ts +21 -0
- package/dest/circuit_types/blob_accumulator.d.ts.map +1 -0
- package/dest/circuit_types/blob_accumulator.js +58 -0
- package/dest/circuit_types/final_blob_accumulator.d.ts +22 -0
- package/dest/circuit_types/final_blob_accumulator.d.ts.map +1 -0
- package/dest/circuit_types/final_blob_accumulator.js +63 -0
- package/dest/circuit_types/final_blob_batching_challenges.d.ts +15 -0
- package/dest/circuit_types/final_blob_batching_challenges.d.ts.map +1 -0
- package/dest/circuit_types/final_blob_batching_challenges.js +25 -0
- package/dest/circuit_types/index.d.ts +4 -0
- package/dest/circuit_types/index.d.ts.map +1 -0
- package/dest/circuit_types/index.js +4 -0
- package/dest/deserialize.d.ts +7 -41
- package/dest/deserialize.d.ts.map +1 -1
- package/dest/deserialize.js +25 -73
- package/dest/encoding.d.ts +5 -0
- package/dest/encoding.d.ts.map +1 -1
- package/dest/encoding.js +35 -0
- package/dest/hash.d.ts +35 -0
- package/dest/hash.d.ts.map +1 -0
- package/dest/hash.js +69 -0
- package/dest/index.d.ts +4 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +4 -2
- package/dest/sponge_blob.d.ts +13 -9
- package/dest/sponge_blob.d.ts.map +1 -1
- package/dest/sponge_blob.js +28 -17
- package/dest/testing.d.ts +7 -2
- package/dest/testing.d.ts.map +1 -1
- package/dest/testing.js +47 -14
- package/dest/types.d.ts +2 -0
- package/dest/types.d.ts.map +1 -1
- package/dest/types.js +2 -0
- package/package.json +4 -4
- package/src/blob.ts +67 -180
- package/src/blob_batching.ts +109 -119
- package/src/blob_utils.ts +71 -0
- package/src/circuit_types/blob_accumulator.ts +84 -0
- package/src/circuit_types/final_blob_accumulator.ts +75 -0
- package/src/circuit_types/final_blob_batching_challenges.ts +29 -0
- package/src/circuit_types/index.ts +4 -0
- package/src/deserialize.ts +24 -79
- package/src/encoding.ts +45 -0
- package/src/hash.ts +77 -0
- package/src/index.ts +4 -2
- package/src/sponge_blob.ts +24 -14
- package/src/testing.ts +53 -16
- package/src/types.ts +2 -2
- package/dest/blob_batching_public_inputs.d.ts +0 -57
- package/dest/blob_batching_public_inputs.d.ts.map +0 -1
- package/dest/blob_batching_public_inputs.js +0 -144
- package/src/blob_batching_public_inputs.ts +0 -211
package/dest/blob.d.ts
CHANGED
|
@@ -1,50 +1,58 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FIELDS_PER_BLOB } from '@aztec/constants';
|
|
2
|
+
import { BLS12Fr, Fr } from '@aztec/foundation/fields';
|
|
2
3
|
import { BufferReader } from '@aztec/foundation/serialize';
|
|
3
4
|
import type { BlobJson } from './interface.js';
|
|
4
|
-
export
|
|
5
|
+
export { FIELDS_PER_BLOB };
|
|
5
6
|
/**
|
|
6
7
|
* A class to create, manage, and prove EVM blobs.
|
|
8
|
+
*
|
|
9
|
+
* @dev Note: All methods in this class do not check the encoding of the given data. It's the responsibility of other
|
|
10
|
+
* components to ensure that the blob data (which might spread across multiple blobs) was created following the protocol
|
|
11
|
+
* and is correctly encoded.
|
|
7
12
|
*/
|
|
8
13
|
export declare class Blob {
|
|
9
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* The data to be broadcast on L1 in bytes form.
|
|
16
|
+
*/
|
|
10
17
|
readonly data: Uint8Array;
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
readonly challengeZ: Fr;
|
|
15
|
-
/** Commitment to the blob C. Used in compressed BLS12 point format (48 bytes). */
|
|
18
|
+
/**
|
|
19
|
+
* Commitment to the blob data. Used in compressed BLS12 point format (48 bytes).
|
|
20
|
+
*/
|
|
16
21
|
readonly commitment: Buffer;
|
|
17
22
|
constructor(
|
|
18
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* The data to be broadcast on L1 in bytes form.
|
|
25
|
+
*/
|
|
19
26
|
data: Uint8Array,
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
challengeZ: Fr,
|
|
24
|
-
/** Commitment to the blob C. Used in compressed BLS12 point format (48 bytes). */
|
|
27
|
+
/**
|
|
28
|
+
* Commitment to the blob data. Used in compressed BLS12 point format (48 bytes).
|
|
29
|
+
*/
|
|
25
30
|
commitment: Buffer);
|
|
26
31
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* See `./encoding.ts` for more details.
|
|
31
|
-
*
|
|
32
|
-
* This method is used to create a Blob from a buffer.
|
|
33
|
-
* @param blob - The buffer to create the Blob from.
|
|
34
|
-
* @param multiBlobFieldsHash - The fields hash to use for the Blob.
|
|
32
|
+
* Create a Blob from a buffer.
|
|
33
|
+
* @param data - The buffer of the Blob.
|
|
35
34
|
* @returns A Blob created from the buffer.
|
|
36
35
|
*
|
|
37
|
-
* @throws If
|
|
36
|
+
* @throws If data does not match the expected length (BYTES_PER_BLOB).
|
|
38
37
|
*/
|
|
39
|
-
static
|
|
38
|
+
static fromBlobBuffer(data: Uint8Array): Blob;
|
|
40
39
|
/**
|
|
41
40
|
* Create a Blob from an array of fields.
|
|
42
41
|
*
|
|
42
|
+
* @dev This method pads 0s to the data, extending it to the size of a full blob.
|
|
43
|
+
*
|
|
43
44
|
* @param fields - The array of fields to create the Blob from.
|
|
44
|
-
* @param multiBlobFieldsHash - The fields hash to use for the Blob.
|
|
45
45
|
* @returns A Blob created from the array of fields.
|
|
46
46
|
*/
|
|
47
|
-
static fromFields(fields: Fr[]
|
|
47
|
+
static fromFields(fields: Fr[]): Blob;
|
|
48
|
+
/**
|
|
49
|
+
* Get the fields from the blob data.
|
|
50
|
+
*
|
|
51
|
+
* @dev WARNING: this method returns all fields
|
|
52
|
+
*
|
|
53
|
+
* @returns The fields from the blob.
|
|
54
|
+
*/
|
|
55
|
+
toFields(): Fr[];
|
|
48
56
|
/**
|
|
49
57
|
* Create a Blob from a JSON object.
|
|
50
58
|
*
|
|
@@ -52,78 +60,41 @@ export declare class Blob {
|
|
|
52
60
|
* the beacon chain via `getBlobSidecars`
|
|
53
61
|
* https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getBlobSidecars
|
|
54
62
|
*
|
|
55
|
-
* @dev WARNING: by default json deals with encoded buffers
|
|
56
|
-
*
|
|
57
63
|
* @param json - The JSON object to create the Blob from.
|
|
58
64
|
* @returns A Blob created from the JSON object.
|
|
59
65
|
*/
|
|
60
|
-
static fromJson(json: BlobJson):
|
|
66
|
+
static fromJson(json: BlobJson): Blob;
|
|
61
67
|
/**
|
|
62
68
|
* Get the JSON representation of the blob.
|
|
63
69
|
*
|
|
64
|
-
* @dev WARNING: by default json deals with encoded buffers
|
|
65
70
|
* @param index - optional - The index of the blob in the block.
|
|
66
71
|
* @returns The JSON representation of the blob.
|
|
67
72
|
*/
|
|
68
73
|
toJson(index: number): BlobJson;
|
|
74
|
+
getEthVersionedBlobHash(): Buffer;
|
|
69
75
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* @dev WARNING: this method does not take into account trailing zeros
|
|
73
|
-
*
|
|
74
|
-
* @returns The fields from the blob.
|
|
75
|
-
*/
|
|
76
|
-
toFields(): Fr[];
|
|
77
|
-
/**
|
|
78
|
-
* Get the encoded fields from the blob.
|
|
79
|
-
*
|
|
80
|
-
* @dev This method takes into account trailing zeros
|
|
81
|
-
*
|
|
82
|
-
* @returns The encoded fields from the blob.
|
|
83
|
-
*
|
|
84
|
-
* @throws If unable to deserialize the blob.
|
|
85
|
-
*/
|
|
86
|
-
toEncodedFields(): Fr[];
|
|
87
|
-
/**
|
|
88
|
-
* Get the encoded fields from multiple blobs.
|
|
89
|
-
*
|
|
90
|
-
* @dev This method takes into account trailing zeros
|
|
91
|
-
*
|
|
92
|
-
* @returns The encoded fields from the blobs.
|
|
93
|
-
*/
|
|
94
|
-
static toEncodedFields(blobs: Blob[]): Fr[];
|
|
95
|
-
/**
|
|
96
|
-
* Get the commitment fields from the blob.
|
|
97
|
-
*
|
|
98
|
-
* The 48-byte commitment is encoded into two field elements:
|
|
99
|
-
* +------------------+------------------+
|
|
100
|
-
* | Field Element 1 | Field Element 2 |
|
|
101
|
-
* | [bytes 0-31] | [bytes 32-47] |
|
|
102
|
-
* +------------------+------------------+
|
|
103
|
-
* | 32 bytes | 16 bytes |
|
|
104
|
-
* +------------------+------------------+
|
|
105
|
-
* @returns The commitment fields from the blob.
|
|
76
|
+
* Challenge point z (= H(H(tx_effects), kzgCommitment)).
|
|
77
|
+
* Used such that p(z) = y for a single blob, used as z_i in batching (see ./blob_batching.ts).
|
|
106
78
|
*/
|
|
107
|
-
|
|
108
|
-
getEthVersionedBlobHash(): Buffer;
|
|
109
|
-
static getEthVersionedBlobHash(commitment: Buffer): Buffer;
|
|
79
|
+
computeChallengeZ(blobFieldsHash: Fr): Promise<Fr>;
|
|
110
80
|
/**
|
|
111
81
|
* Evaluate the blob at a given challenge and return the evaluation and KZG proof.
|
|
112
82
|
*
|
|
113
|
-
* @param challengeZ - The challenge z at which to evaluate the blob.
|
|
83
|
+
* @param challengeZ - The challenge z at which to evaluate the blob.
|
|
84
|
+
* @param verifyProof - Whether to verify the KZG proof.
|
|
114
85
|
*
|
|
115
|
-
* @returns
|
|
116
|
-
* y:
|
|
86
|
+
* @returns
|
|
87
|
+
* y: BLS12Fr - Evaluation y = p(z), where p() is the blob polynomial. BLS12 field element, rep. as BigNum in nr, bigint in ts.
|
|
117
88
|
* proof: Buffer - KZG opening proof for y = p(z). The commitment to quotient polynomial Q, used in compressed BLS12 point format (48 bytes).
|
|
118
89
|
*/
|
|
119
|
-
evaluate(challengeZ?:
|
|
120
|
-
y:
|
|
90
|
+
evaluate(challengeZ: Fr, verifyProof?: boolean): {
|
|
91
|
+
y: BLS12Fr;
|
|
121
92
|
proof: Buffer<ArrayBuffer>;
|
|
122
93
|
};
|
|
123
94
|
/**
|
|
124
95
|
* Get the buffer representation of the ENTIRE blob.
|
|
125
96
|
*
|
|
126
|
-
* @dev WARNING: this buffer contains all metadata
|
|
97
|
+
* @dev WARNING: this buffer contains all metadata as well as the data itself.
|
|
127
98
|
*
|
|
128
99
|
* @returns The buffer representation of the blob.
|
|
129
100
|
*/
|
|
@@ -131,7 +102,7 @@ export declare class Blob {
|
|
|
131
102
|
/**
|
|
132
103
|
* Create a Blob from a buffer.
|
|
133
104
|
*
|
|
134
|
-
* @dev WARNING: this method contains all metadata
|
|
105
|
+
* @dev WARNING: this method contains all metadata as well as the data itself.
|
|
135
106
|
*
|
|
136
107
|
* @param buf - The buffer to create the Blob from.
|
|
137
108
|
* @returns A Blob created from the buffer.
|
|
@@ -141,23 +112,10 @@ export declare class Blob {
|
|
|
141
112
|
* Get the size of the blob in bytes
|
|
142
113
|
*/
|
|
143
114
|
getSize(): number;
|
|
144
|
-
/**
|
|
145
|
-
* @param blobs - The blobs to emit
|
|
146
|
-
* @returns The blobs' compressed commitments in hex prefixed by the number of blobs
|
|
147
|
-
* @dev Used for proposing blocks to validate injected blob commitments match real broadcast blobs:
|
|
148
|
-
* One byte for the number blobs + 48 bytes per blob commitment
|
|
149
|
-
*/
|
|
150
|
-
static getPrefixedEthBlobCommitments(blobs: Blob[]): `0x${string}`;
|
|
151
115
|
static getViemKzgInstance(): {
|
|
152
116
|
blobToKzgCommitment: (blob: Uint8Array) => Uint8Array;
|
|
153
117
|
computeBlobKzgProof: (blob: Uint8Array, commitment: Uint8Array) => Uint8Array;
|
|
154
118
|
computeCellsAndKzgProofs: (b: Uint8Array) => [Uint8Array[], Uint8Array[]];
|
|
155
119
|
};
|
|
156
|
-
/**
|
|
157
|
-
* @param fields - Fields to broadcast in the blob(s)
|
|
158
|
-
* @returns As many blobs as we require to broadcast the given fields for a block
|
|
159
|
-
* @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.
|
|
160
|
-
*/
|
|
161
|
-
static getBlobsPerBlock(fields: Fr[]): Promise<Blob[]>;
|
|
162
120
|
}
|
|
163
121
|
//# sourceMappingURL=blob.d.ts.map
|
package/dest/blob.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAG9E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B;;;;;;GAMG;AACH,qBAAa,IAAI;IAEb;;OAEG;aACa,IAAI,EAAE,UAAU;IAChC;;OAEG;aACa,UAAU,EAAE,MAAM;;IAPlC;;OAEG;IACa,IAAI,EAAE,UAAU;IAChC;;OAEG;IACa,UAAU,EAAE,MAAM;IAUpC;;;;;;OAMG;IACH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAK7C;;;;;;;OAOG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI;IAUrC;;;;;;OAMG;IACH,QAAQ,IAAI,EAAE,EAAE;IAMhB;;;;;;;;;OASG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAWrC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;IAS/B,uBAAuB,IAAI,MAAM;IAIjC;;;OAGG;IACG,iBAAiB,CAAC,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;IAIxD;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,EAAE,EAAE,EAAE,WAAW,UAAQ;;;;IAW5C;;;;;;OAMG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;;;;OAOG;IACH,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAKnD;;OAEG;IACH,OAAO;IAIP,MAAM,CAAC,kBAAkB;;;sCAIS,UAAU,KAAG,CAAC,UAAU,EAAE,EAAE,UAAU,EAAE,CAAC;;CAM5E"}
|
package/dest/blob.js
CHANGED
|
@@ -1,66 +1,69 @@
|
|
|
1
1
|
import { FIELDS_PER_BLOB } from '@aztec/constants';
|
|
2
|
-
import {
|
|
3
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { BLS12Fr, Fr } from '@aztec/foundation/fields';
|
|
4
3
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
// The prefix to the EVM blobHash, defined here: https://eips.ethereum.org/EIPS/eip-4844#specification
|
|
9
|
-
export const VERSIONED_HASH_VERSION_KZG = 0x01;
|
|
4
|
+
import { computeBlobCommitment, computeChallengeZ, computeEthVersionedBlobHash } from './hash.js';
|
|
5
|
+
import { BYTES_PER_BLOB, BYTES_PER_COMMITMENT, kzg } from './kzg_context.js';
|
|
6
|
+
export { FIELDS_PER_BLOB };
|
|
10
7
|
/**
|
|
11
8
|
* A class to create, manage, and prove EVM blobs.
|
|
9
|
+
*
|
|
10
|
+
* @dev Note: All methods in this class do not check the encoding of the given data. It's the responsibility of other
|
|
11
|
+
* components to ensure that the blob data (which might spread across multiple blobs) was created following the protocol
|
|
12
|
+
* and is correctly encoded.
|
|
12
13
|
*/ export class Blob {
|
|
13
14
|
data;
|
|
14
|
-
fieldsHash;
|
|
15
|
-
challengeZ;
|
|
16
15
|
commitment;
|
|
17
|
-
constructor(/**
|
|
16
|
+
constructor(/**
|
|
17
|
+
* The data to be broadcast on L1 in bytes form.
|
|
18
|
+
*/ data, /**
|
|
19
|
+
* Commitment to the blob data. Used in compressed BLS12 point format (48 bytes).
|
|
20
|
+
*/ commitment){
|
|
18
21
|
this.data = data;
|
|
19
|
-
this.fieldsHash = fieldsHash;
|
|
20
|
-
this.challengeZ = challengeZ;
|
|
21
22
|
this.commitment = commitment;
|
|
23
|
+
if (data.length !== BYTES_PER_BLOB) {
|
|
24
|
+
throw new Error(`Blob data must be ${BYTES_PER_BLOB} bytes. Got ${data.length}.`);
|
|
25
|
+
}
|
|
26
|
+
if (commitment.length !== BYTES_PER_COMMITMENT) {
|
|
27
|
+
throw new Error(`Blob commitment must be ${BYTES_PER_COMMITMENT} bytes. Got ${commitment.length}.`);
|
|
28
|
+
}
|
|
22
29
|
}
|
|
23
30
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* See `./encoding.ts` for more details.
|
|
28
|
-
*
|
|
29
|
-
* This method is used to create a Blob from a buffer.
|
|
30
|
-
* @param blob - The buffer to create the Blob from.
|
|
31
|
-
* @param multiBlobFieldsHash - The fields hash to use for the Blob.
|
|
31
|
+
* Create a Blob from a buffer.
|
|
32
|
+
* @param data - The buffer of the Blob.
|
|
32
33
|
* @returns A Blob created from the buffer.
|
|
33
34
|
*
|
|
34
|
-
* @throws If
|
|
35
|
-
*/ static
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return Blob.fromFields(fields, multiBlobFieldsHash);
|
|
39
|
-
} catch {
|
|
40
|
-
throw new BlobDeserializationError(`Failed to create Blob from encoded blob buffer, this blob was likely not created by us`);
|
|
41
|
-
}
|
|
35
|
+
* @throws If data does not match the expected length (BYTES_PER_BLOB).
|
|
36
|
+
*/ static fromBlobBuffer(data) {
|
|
37
|
+
const commitment = computeBlobCommitment(data);
|
|
38
|
+
return new Blob(data, commitment);
|
|
42
39
|
}
|
|
43
40
|
/**
|
|
44
41
|
* Create a Blob from an array of fields.
|
|
45
42
|
*
|
|
43
|
+
* @dev This method pads 0s to the data, extending it to the size of a full blob.
|
|
44
|
+
*
|
|
46
45
|
* @param fields - The array of fields to create the Blob from.
|
|
47
|
-
* @param multiBlobFieldsHash - The fields hash to use for the Blob.
|
|
48
46
|
* @returns A Blob created from the array of fields.
|
|
49
|
-
*/ static
|
|
47
|
+
*/ static fromFields(fields) {
|
|
50
48
|
if (fields.length > FIELDS_PER_BLOB) {
|
|
51
|
-
throw new Error(`Attempted to overfill blob with ${fields.length}
|
|
49
|
+
throw new Error(`Attempted to overfill blob with ${fields.length} fields. The maximum is ${FIELDS_PER_BLOB}.`);
|
|
52
50
|
}
|
|
53
51
|
const data = Buffer.concat([
|
|
54
52
|
serializeToBuffer(fields)
|
|
55
53
|
], BYTES_PER_BLOB);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
const commitment = computeBlobCommitment(data);
|
|
55
|
+
return new Blob(data, commitment);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the fields from the blob data.
|
|
59
|
+
*
|
|
60
|
+
* @dev WARNING: this method returns all fields
|
|
61
|
+
*
|
|
62
|
+
* @returns The fields from the blob.
|
|
63
|
+
*/ toFields() {
|
|
64
|
+
const reader = BufferReader.asReader(this.data);
|
|
65
|
+
const numTotalFields = this.data.length / Fr.SIZE_IN_BYTES;
|
|
66
|
+
return reader.readArray(numTotalFields, Fr);
|
|
64
67
|
}
|
|
65
68
|
/**
|
|
66
69
|
* Create a Blob from a JSON object.
|
|
@@ -69,24 +72,19 @@ export const VERSIONED_HASH_VERSION_KZG = 0x01;
|
|
|
69
72
|
* the beacon chain via `getBlobSidecars`
|
|
70
73
|
* https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getBlobSidecars
|
|
71
74
|
*
|
|
72
|
-
* @dev WARNING: by default json deals with encoded buffers
|
|
73
|
-
*
|
|
74
75
|
* @param json - The JSON object to create the Blob from.
|
|
75
76
|
* @returns A Blob created from the JSON object.
|
|
76
|
-
*/ static
|
|
77
|
+
*/ static fromJson(json) {
|
|
77
78
|
const blobBuffer = Buffer.from(json.blob.slice(2), 'hex');
|
|
78
|
-
const blob =
|
|
79
|
+
const blob = Blob.fromBlobBuffer(blobBuffer);
|
|
79
80
|
if (blob.commitment.toString('hex') !== json.kzg_commitment.slice(2)) {
|
|
80
81
|
throw new Error('KZG commitment does not match');
|
|
81
82
|
}
|
|
82
|
-
// We do not check the proof, as it will be different if the challenge is shared
|
|
83
|
-
// across multiple blobs
|
|
84
83
|
return blob;
|
|
85
84
|
}
|
|
86
85
|
/**
|
|
87
86
|
* Get the JSON representation of the blob.
|
|
88
87
|
*
|
|
89
|
-
* @dev WARNING: by default json deals with encoded buffers
|
|
90
88
|
* @param index - optional - The index of the blob in the block.
|
|
91
89
|
* @returns The JSON representation of the blob.
|
|
92
90
|
*/ toJson(index) {
|
|
@@ -97,84 +95,31 @@ export const VERSIONED_HASH_VERSION_KZG = 0x01;
|
|
|
97
95
|
kzg_commitment: `0x${this.commitment.toString('hex')}`
|
|
98
96
|
};
|
|
99
97
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Get the fields from the blob.
|
|
102
|
-
*
|
|
103
|
-
* @dev WARNING: this method does not take into account trailing zeros
|
|
104
|
-
*
|
|
105
|
-
* @returns The fields from the blob.
|
|
106
|
-
*/ toFields() {
|
|
107
|
-
return extractBlobFieldsFromBuffer(this.data);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Get the encoded fields from the blob.
|
|
111
|
-
*
|
|
112
|
-
* @dev This method takes into account trailing zeros
|
|
113
|
-
*
|
|
114
|
-
* @returns The encoded fields from the blob.
|
|
115
|
-
*
|
|
116
|
-
* @throws If unable to deserialize the blob.
|
|
117
|
-
*/ toEncodedFields() {
|
|
118
|
-
try {
|
|
119
|
-
return deserializeEncodedBlobToFields(this.data);
|
|
120
|
-
} catch {
|
|
121
|
-
throw new BlobDeserializationError(`Failed to deserialize encoded blob fields, this blob was likely not created by us`);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Get the encoded fields from multiple blobs.
|
|
126
|
-
*
|
|
127
|
-
* @dev This method takes into account trailing zeros
|
|
128
|
-
*
|
|
129
|
-
* @returns The encoded fields from the blobs.
|
|
130
|
-
*/ static toEncodedFields(blobs) {
|
|
131
|
-
try {
|
|
132
|
-
return deserializeEncodedBlobToFields(Buffer.concat(blobs.map((b)=>b.data)));
|
|
133
|
-
} catch {
|
|
134
|
-
throw new BlobDeserializationError(`Failed to deserialize encoded blob fields, this blob was likely not created by us`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Get the commitment fields from the blob.
|
|
139
|
-
*
|
|
140
|
-
* The 48-byte commitment is encoded into two field elements:
|
|
141
|
-
* +------------------+------------------+
|
|
142
|
-
* | Field Element 1 | Field Element 2 |
|
|
143
|
-
* | [bytes 0-31] | [bytes 32-47] |
|
|
144
|
-
* +------------------+------------------+
|
|
145
|
-
* | 32 bytes | 16 bytes |
|
|
146
|
-
* +------------------+------------------+
|
|
147
|
-
* @returns The commitment fields from the blob.
|
|
148
|
-
*/ commitmentToFields() {
|
|
149
|
-
return commitmentToFields(this.commitment);
|
|
150
|
-
}
|
|
151
|
-
// Returns ethereum's versioned blob hash, following kzg_to_versioned_hash: https://eips.ethereum.org/EIPS/eip-4844#helpers
|
|
152
98
|
getEthVersionedBlobHash() {
|
|
153
|
-
|
|
154
|
-
hash[0] = VERSIONED_HASH_VERSION_KZG;
|
|
155
|
-
return hash;
|
|
99
|
+
return computeEthVersionedBlobHash(this.commitment);
|
|
156
100
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Challenge point z (= H(H(tx_effects), kzgCommitment)).
|
|
103
|
+
* Used such that p(z) = y for a single blob, used as z_i in batching (see ./blob_batching.ts).
|
|
104
|
+
*/ async computeChallengeZ(blobFieldsHash) {
|
|
105
|
+
return await computeChallengeZ(blobFieldsHash, this.commitment);
|
|
161
106
|
}
|
|
162
107
|
/**
|
|
163
108
|
* Evaluate the blob at a given challenge and return the evaluation and KZG proof.
|
|
164
109
|
*
|
|
165
|
-
* @param challengeZ - The challenge z at which to evaluate the blob.
|
|
110
|
+
* @param challengeZ - The challenge z at which to evaluate the blob.
|
|
111
|
+
* @param verifyProof - Whether to verify the KZG proof.
|
|
166
112
|
*
|
|
167
|
-
* @returns
|
|
168
|
-
* y:
|
|
113
|
+
* @returns
|
|
114
|
+
* y: BLS12Fr - Evaluation y = p(z), where p() is the blob polynomial. BLS12 field element, rep. as BigNum in nr, bigint in ts.
|
|
169
115
|
* proof: Buffer - KZG opening proof for y = p(z). The commitment to quotient polynomial Q, used in compressed BLS12 point format (48 bytes).
|
|
170
|
-
*/ evaluate(challengeZ) {
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
if (!kzg.verifyKzgProof(this.commitment, z.toBuffer(), res[1], res[0])) {
|
|
116
|
+
*/ evaluate(challengeZ, verifyProof = false) {
|
|
117
|
+
const res = kzg.computeKzgProof(this.data, challengeZ.toBuffer());
|
|
118
|
+
if (verifyProof && !kzg.verifyKzgProof(this.commitment, challengeZ.toBuffer(), res[1], res[0])) {
|
|
174
119
|
throw new Error(`KZG proof did not verify.`);
|
|
175
120
|
}
|
|
176
121
|
const proof = Buffer.from(res[0]);
|
|
177
|
-
const y = Buffer.from(res[1]);
|
|
122
|
+
const y = BLS12Fr.fromBuffer(Buffer.from(res[1]));
|
|
178
123
|
return {
|
|
179
124
|
y,
|
|
180
125
|
proof
|
|
@@ -183,50 +128,28 @@ export const VERSIONED_HASH_VERSION_KZG = 0x01;
|
|
|
183
128
|
/**
|
|
184
129
|
* Get the buffer representation of the ENTIRE blob.
|
|
185
130
|
*
|
|
186
|
-
* @dev WARNING: this buffer contains all metadata
|
|
131
|
+
* @dev WARNING: this buffer contains all metadata as well as the data itself.
|
|
187
132
|
*
|
|
188
133
|
* @returns The buffer representation of the blob.
|
|
189
134
|
*/ toBuffer() {
|
|
190
|
-
return Buffer.from(serializeToBuffer(this.data.length, this.data, this.
|
|
135
|
+
return Buffer.from(serializeToBuffer(this.data.length, this.data, this.commitment.length, this.commitment));
|
|
191
136
|
}
|
|
192
137
|
/**
|
|
193
138
|
* Create a Blob from a buffer.
|
|
194
139
|
*
|
|
195
|
-
* @dev WARNING: this method contains all metadata
|
|
140
|
+
* @dev WARNING: this method contains all metadata as well as the data itself.
|
|
196
141
|
*
|
|
197
142
|
* @param buf - The buffer to create the Blob from.
|
|
198
143
|
* @returns A Blob created from the buffer.
|
|
199
144
|
*/ static fromBuffer(buf) {
|
|
200
145
|
const reader = BufferReader.asReader(buf);
|
|
201
|
-
return new Blob(reader.readUint8Array(), reader.
|
|
146
|
+
return new Blob(reader.readUint8Array(), reader.readBuffer());
|
|
202
147
|
}
|
|
203
148
|
/**
|
|
204
149
|
* Get the size of the blob in bytes
|
|
205
150
|
*/ getSize() {
|
|
206
151
|
return this.data.length;
|
|
207
152
|
}
|
|
208
|
-
/**
|
|
209
|
-
* @param blobs - The blobs to emit
|
|
210
|
-
* @returns The blobs' compressed commitments in hex prefixed by the number of blobs
|
|
211
|
-
* @dev Used for proposing blocks to validate injected blob commitments match real broadcast blobs:
|
|
212
|
-
* One byte for the number blobs + 48 bytes per blob commitment
|
|
213
|
-
*/ static getPrefixedEthBlobCommitments(blobs) {
|
|
214
|
-
let buf = Buffer.alloc(0);
|
|
215
|
-
blobs.forEach((blob)=>{
|
|
216
|
-
buf = Buffer.concat([
|
|
217
|
-
buf,
|
|
218
|
-
blob.commitment
|
|
219
|
-
]);
|
|
220
|
-
});
|
|
221
|
-
// We prefix the number of blobs:
|
|
222
|
-
const lenBuf = Buffer.alloc(1);
|
|
223
|
-
lenBuf.writeUint8(blobs.length);
|
|
224
|
-
buf = Buffer.concat([
|
|
225
|
-
lenBuf,
|
|
226
|
-
buf
|
|
227
|
-
]);
|
|
228
|
-
return `0x${buf.toString('hex')}`;
|
|
229
|
-
}
|
|
230
153
|
static getViemKzgInstance() {
|
|
231
154
|
return {
|
|
232
155
|
blobToKzgCommitment: kzg.blobToKzgCommitment.bind(kzg),
|
|
@@ -240,25 +163,4 @@ export const VERSIONED_HASH_VERSION_KZG = 0x01;
|
|
|
240
163
|
}
|
|
241
164
|
};
|
|
242
165
|
}
|
|
243
|
-
/**
|
|
244
|
-
* @param fields - Fields to broadcast in the blob(s)
|
|
245
|
-
* @returns As many blobs as we require to broadcast the given fields for a block
|
|
246
|
-
* @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.
|
|
247
|
-
*/ static async getBlobsPerBlock(fields) {
|
|
248
|
-
const numBlobs = Math.max(Math.ceil(fields.length / FIELDS_PER_BLOB), 1);
|
|
249
|
-
const multiBlobFieldsHash = await poseidon2Hash(fields);
|
|
250
|
-
const res = [];
|
|
251
|
-
for(let i = 0; i < numBlobs; i++){
|
|
252
|
-
const end = fields.length < (i + 1) * FIELDS_PER_BLOB ? fields.length : (i + 1) * FIELDS_PER_BLOB;
|
|
253
|
-
res.push(await Blob.fromFields(fields.slice(i * FIELDS_PER_BLOB, end), multiBlobFieldsHash));
|
|
254
|
-
}
|
|
255
|
-
return res;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
// 48 bytes encoded in fields as [Fr, Fr] = [0->31, 31->48]
|
|
259
|
-
function commitmentToFields(commitment) {
|
|
260
|
-
return [
|
|
261
|
-
new Fr(commitment.subarray(0, 31)),
|
|
262
|
-
new Fr(commitment.subarray(31, 48))
|
|
263
|
-
];
|
|
264
166
|
}
|
package/dest/blob_batching.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BLS12Fr, BLS12Point, Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import { BufferReader } from '@aztec/foundation/serialize';
|
|
3
2
|
import { Blob } from './blob.js';
|
|
3
|
+
import { BlobAccumulator, FinalBlobAccumulator, FinalBlobBatchingChallenges } from './circuit_types/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* A class to create, manage, and prove batched EVM blobs.
|
|
6
6
|
*/
|
|
@@ -33,13 +33,13 @@ export declare class BatchedBlob {
|
|
|
33
33
|
*
|
|
34
34
|
* @returns A batched blob.
|
|
35
35
|
*/
|
|
36
|
-
static batch(blobs: Blob[]): Promise<BatchedBlob>;
|
|
36
|
+
static batch(blobs: Blob[][]): Promise<BatchedBlob>;
|
|
37
37
|
/**
|
|
38
38
|
* Returns an empty BatchedBlobAccumulator with precomputed challenges from all blobs in the epoch.
|
|
39
39
|
* @dev MUST input all blobs to be broadcast. Does not work in multiple calls because z and gamma are calculated
|
|
40
40
|
* beforehand from ALL blobs.
|
|
41
41
|
*/
|
|
42
|
-
static newAccumulator(blobs: Blob[]): Promise<BatchedBlobAccumulator>;
|
|
42
|
+
static newAccumulator(blobs: Blob[][]): Promise<BatchedBlobAccumulator>;
|
|
43
43
|
/**
|
|
44
44
|
* Gets the final challenges based on all blobs and their elements to perform a multi opening proof.
|
|
45
45
|
* Used in BatchedBlobAccumulator as 'finalZ' and finalGamma':
|
|
@@ -48,11 +48,13 @@ export declare class BatchedBlob {
|
|
|
48
48
|
* - used such that p_i(z) = y_i = Blob.evaluationY for all n blob polynomials p_i().
|
|
49
49
|
* - gamma = H(H(...H(H(y_0, y_1) y_2)..y_n), z)
|
|
50
50
|
* - used such that y = sum_i { gamma^i * y_i }, and C = sum_i { gamma^i * C_i }, for all blob evaluations y_i (see above) and commitments C_i.
|
|
51
|
+
*
|
|
52
|
+
* @param blobs - The blobs to precompute the challenges for. Each sub-array is the blobs for an L1 block.
|
|
51
53
|
* @returns Challenges z and gamma.
|
|
52
54
|
*/
|
|
53
|
-
static precomputeBatchedBlobChallenges(blobs: Blob[]): Promise<FinalBlobBatchingChallenges>;
|
|
55
|
+
static precomputeBatchedBlobChallenges(blobs: Blob[][]): Promise<FinalBlobBatchingChallenges>;
|
|
56
|
+
verify(): boolean;
|
|
54
57
|
getEthVersionedBlobHash(): Buffer;
|
|
55
|
-
static getEthVersionedBlobHash(commitment: Buffer): Buffer;
|
|
56
58
|
/**
|
|
57
59
|
* Returns a proof of opening of the blobs to verify on L1 using the point evaluation precompile:
|
|
58
60
|
*
|
|
@@ -65,30 +67,7 @@ export declare class BatchedBlob {
|
|
|
65
67
|
* See https://eips.ethereum.org/EIPS/eip-4844#point-evaluation-precompile
|
|
66
68
|
*/
|
|
67
69
|
getEthBlobEvaluationInputs(): `0x${string}`;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Final values z and gamma are injected into each block root circuit. We ensure they are correct by:
|
|
71
|
-
* - Checking equality in each block merge circuit and propagating up
|
|
72
|
-
* - Checking final z_acc == z in root circuit
|
|
73
|
-
* - Checking final gamma_acc == gamma in root circuit
|
|
74
|
-
*
|
|
75
|
-
* - z = H(...H(H(z_0, z_1) z_2)..z_n)
|
|
76
|
-
* - where z_i = H(H(fields of blob_i), C_i),
|
|
77
|
-
* - used such that p_i(z) = y_i = Blob.evaluationY for all n blob polynomials p_i().
|
|
78
|
-
* - gamma = H(H(...H(H(y_0, y_1) y_2)..y_n), z)
|
|
79
|
-
* - used such that y = sum_i { gamma^i * y_i }, and C = sum_i { gamma^i * C_i }
|
|
80
|
-
* for all blob evaluations y_i (see above) and commitments C_i.
|
|
81
|
-
*
|
|
82
|
-
* Iteratively calculated by BlobAccumulator.accumulate() in nr. See also precomputeBatchedBlobChallenges() above.
|
|
83
|
-
*/
|
|
84
|
-
export declare class FinalBlobBatchingChallenges {
|
|
85
|
-
readonly z: Fr;
|
|
86
|
-
readonly gamma: BLS12Fr;
|
|
87
|
-
constructor(z: Fr, gamma: BLS12Fr);
|
|
88
|
-
equals(other: FinalBlobBatchingChallenges): boolean;
|
|
89
|
-
static empty(): FinalBlobBatchingChallenges;
|
|
90
|
-
static fromBuffer(buffer: Buffer | BufferReader): FinalBlobBatchingChallenges;
|
|
91
|
-
toBuffer(): Buffer<ArrayBufferLike>;
|
|
70
|
+
toFinalBlobAccumulator(): FinalBlobAccumulator;
|
|
92
71
|
}
|
|
93
72
|
/**
|
|
94
73
|
* See noir-projects/noir-protocol-circuits/crates/blob/src/abis/blob_accumulator.nr
|
|
@@ -135,21 +114,6 @@ export declare class BatchedBlobAccumulator {
|
|
|
135
114
|
gammaPow: BLS12Fr,
|
|
136
115
|
/** Final challenge values used in evaluation. Optimistically input and checked in the final acc. */
|
|
137
116
|
finalBlobChallenges: FinalBlobBatchingChallenges);
|
|
138
|
-
/**
|
|
139
|
-
* Init the first accumulation state of the epoch.
|
|
140
|
-
* We assume the input blob has not been evaluated at z.
|
|
141
|
-
*
|
|
142
|
-
* First state of the accumulator:
|
|
143
|
-
* - v_acc := sha256(C_0)
|
|
144
|
-
* - z_acc := z_0
|
|
145
|
-
* - y_acc := gamma^0 * y_0 = y_0
|
|
146
|
-
* - c_acc := gamma^0 * c_0 = c_0
|
|
147
|
-
* - gamma_acc := poseidon2(y_0.limbs)
|
|
148
|
-
* - gamma^(i + 1) = gamma^1 = gamma // denoted gamma_pow_acc
|
|
149
|
-
*
|
|
150
|
-
* @returns An initial blob accumulator.
|
|
151
|
-
*/
|
|
152
|
-
static initialize(blob: Blob, finalBlobChallenges: FinalBlobBatchingChallenges): Promise<BatchedBlobAccumulator>;
|
|
153
117
|
/**
|
|
154
118
|
* Create the empty accumulation state of the epoch.
|
|
155
119
|
* @returns An empty blob accumulator with challenges.
|
|
@@ -160,10 +124,11 @@ export declare class BatchedBlobAccumulator {
|
|
|
160
124
|
* We assume the input blob has not been evaluated at z.
|
|
161
125
|
* @returns An updated blob accumulator.
|
|
162
126
|
*/
|
|
163
|
-
accumulate
|
|
127
|
+
private accumulate;
|
|
164
128
|
/**
|
|
165
129
|
* Given blobs, accumulate all state.
|
|
166
130
|
* We assume the input blobs have not been evaluated at z.
|
|
131
|
+
* @param blobs - The blobs to accumulate. They should be in the same L1 block.
|
|
167
132
|
* @returns An updated blob accumulator.
|
|
168
133
|
*/
|
|
169
134
|
accumulateBlobs(blobs: Blob[]): Promise<BatchedBlobAccumulator>;
|
|
@@ -178,10 +143,13 @@ export declare class BatchedBlobAccumulator {
|
|
|
178
143
|
* - c := c_acc (final commitment to be checked on L1)
|
|
179
144
|
* - gamma := poseidon2(gamma_acc, z) (challenge for linear combination of y and C, above)
|
|
180
145
|
*
|
|
146
|
+
* @param verifyProof - Whether to verify the KZG proof.
|
|
181
147
|
* @returns A batched blob.
|
|
182
148
|
*/
|
|
183
|
-
finalize(): Promise<BatchedBlob>;
|
|
149
|
+
finalize(verifyProof?: boolean): Promise<BatchedBlob>;
|
|
184
150
|
isEmptyState(): boolean;
|
|
185
151
|
clone(): BatchedBlobAccumulator;
|
|
152
|
+
toBlobAccumulator(): BlobAccumulator;
|
|
153
|
+
toFinalBlobAccumulator(): FinalBlobAccumulator;
|
|
186
154
|
}
|
|
187
155
|
//# sourceMappingURL=blob_batching.d.ts.map
|