@aztec/blob-lib 0.0.0-test.1 → 0.0.1-fake-c83136db25
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 +58 -99
- package/dest/blob.d.ts.map +1 -1
- package/dest/blob.js +83 -183
- package/dest/blob_batching.d.ts +155 -0
- package/dest/blob_batching.d.ts.map +1 -0
- package/dest/blob_batching.js +260 -0
- 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 +14 -0
- package/dest/deserialize.d.ts.map +1 -0
- package/dest/deserialize.js +33 -0
- package/dest/encoding.d.ts +22 -62
- package/dest/encoding.d.ts.map +1 -1
- package/dest/encoding.js +114 -104
- 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 +6 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +6 -15
- package/dest/interface.d.ts +1 -2
- package/dest/interface.d.ts.map +1 -1
- package/dest/kzg_context.d.ts +4 -0
- package/dest/kzg_context.d.ts.map +1 -0
- package/dest/kzg_context.js +5 -0
- package/dest/sponge_blob.d.ts +15 -13
- package/dest/sponge_blob.d.ts.map +1 -1
- package/dest/sponge_blob.js +28 -17
- package/dest/testing.d.ts +12 -16
- package/dest/testing.d.ts.map +1 -1
- package/dest/testing.js +60 -46
- package/dest/types.d.ts +16 -0
- package/dest/types.d.ts.map +1 -0
- package/dest/types.js +3 -0
- package/package.json +16 -12
- package/src/blob.ts +82 -221
- package/src/blob_batching.ts +335 -0
- 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 +38 -0
- package/src/encoding.ts +136 -120
- package/src/hash.ts +77 -0
- package/src/index.ts +6 -19
- package/src/interface.ts +1 -4
- package/src/kzg_context.ts +5 -0
- package/src/sponge_blob.ts +24 -14
- package/src/testing.ts +68 -43
- package/src/trusted_setup_bit_reversed.json +4100 -0
- package/src/types.ts +16 -0
- package/dest/blob_public_inputs.d.ts +0 -50
- package/dest/blob_public_inputs.d.ts.map +0 -1
- package/dest/blob_public_inputs.js +0 -146
- package/src/blob_public_inputs.ts +0 -157
package/dest/blob.d.ts
CHANGED
|
@@ -1,62 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
1
|
+
import { FIELDS_PER_BLOB } from '@aztec/constants';
|
|
2
|
+
import { BLS12Fr, Fr } from '@aztec/foundation/fields';
|
|
4
3
|
import { BufferReader } from '@aztec/foundation/serialize';
|
|
5
|
-
import cKzg from 'c-kzg';
|
|
6
|
-
import type { Blob as BlobBuffer } from 'c-kzg';
|
|
7
4
|
import type { BlobJson } from './interface.js';
|
|
8
|
-
export
|
|
5
|
+
export { FIELDS_PER_BLOB };
|
|
9
6
|
/**
|
|
10
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.
|
|
11
12
|
*/
|
|
12
13
|
export declare class Blob {
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
readonly
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
readonly evaluationY: Buffer;
|
|
21
|
-
/** Commitment to the blob C. Used in compressed BLS12 point format (48 bytes). */
|
|
14
|
+
/**
|
|
15
|
+
* The data to be broadcast on L1 in bytes form.
|
|
16
|
+
*/
|
|
17
|
+
readonly data: Uint8Array;
|
|
18
|
+
/**
|
|
19
|
+
* Commitment to the blob data. Used in compressed BLS12 point format (48 bytes).
|
|
20
|
+
*/
|
|
22
21
|
readonly commitment: Buffer;
|
|
23
|
-
/** KZG opening proof for y = p(z). The commitment to quotient polynomial Q, used in compressed BLS12 point format (48 bytes). */
|
|
24
|
-
readonly proof: Buffer;
|
|
25
22
|
constructor(
|
|
26
|
-
/** The blob to be broadcast on L1 in bytes form. */
|
|
27
|
-
data: BlobBuffer,
|
|
28
|
-
/** The hash of all tx effects inside the blob. Used in generating the challenge z and proving that we have included all required effects. */
|
|
29
|
-
fieldsHash: Fr,
|
|
30
|
-
/** Challenge point z (= H(H(tx_effects), kzgCommmitment). Used such that p(z) = y. */
|
|
31
|
-
challengeZ: Fr,
|
|
32
|
-
/** Evaluation y = p(z), where p() is the blob polynomial. BLS12 field element, rep. as BigNum in nr, bigint in ts. */
|
|
33
|
-
evaluationY: Buffer,
|
|
34
|
-
/** Commitment to the blob C. Used in compressed BLS12 point format (48 bytes). */
|
|
35
|
-
commitment: Buffer,
|
|
36
|
-
/** KZG opening proof for y = p(z). The commitment to quotient polynomial Q, used in compressed BLS12 point format (48 bytes). */
|
|
37
|
-
proof: Buffer);
|
|
38
23
|
/**
|
|
39
|
-
* The
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
24
|
+
* The data to be broadcast on L1 in bytes form.
|
|
25
|
+
*/
|
|
26
|
+
data: Uint8Array,
|
|
27
|
+
/**
|
|
28
|
+
* Commitment to the blob data. Used in compressed BLS12 point format (48 bytes).
|
|
29
|
+
*/
|
|
30
|
+
commitment: Buffer);
|
|
31
|
+
/**
|
|
32
|
+
* Create a Blob from a buffer.
|
|
33
|
+
* @param data - The buffer of the Blob.
|
|
47
34
|
* @returns A Blob created from the buffer.
|
|
48
35
|
*
|
|
49
|
-
* @throws If
|
|
36
|
+
* @throws If data does not match the expected length (BYTES_PER_BLOB).
|
|
50
37
|
*/
|
|
51
|
-
static
|
|
38
|
+
static fromBlobBuffer(data: Uint8Array): Blob;
|
|
52
39
|
/**
|
|
53
40
|
* Create a Blob from an array of fields.
|
|
54
41
|
*
|
|
42
|
+
* @dev This method pads 0s to the data, extending it to the size of a full blob.
|
|
43
|
+
*
|
|
55
44
|
* @param fields - The array of fields to create the Blob from.
|
|
56
|
-
* @param multiBlobFieldsHash - The fields hash to use for the Blob.
|
|
57
45
|
* @returns A Blob created from the array of fields.
|
|
58
46
|
*/
|
|
59
|
-
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[];
|
|
60
56
|
/**
|
|
61
57
|
* Create a Blob from a JSON object.
|
|
62
58
|
*
|
|
@@ -64,65 +60,41 @@ export declare class Blob {
|
|
|
64
60
|
* the beacon chain via `getBlobSidecars`
|
|
65
61
|
* https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getBlobSidecars
|
|
66
62
|
*
|
|
67
|
-
* @dev WARNING: by default json deals with encoded buffers
|
|
68
|
-
*
|
|
69
63
|
* @param json - The JSON object to create the Blob from.
|
|
70
64
|
* @returns A Blob created from the JSON object.
|
|
71
65
|
*/
|
|
72
|
-
static fromJson(json: BlobJson):
|
|
66
|
+
static fromJson(json: BlobJson): Blob;
|
|
73
67
|
/**
|
|
74
68
|
* Get the JSON representation of the blob.
|
|
75
69
|
*
|
|
76
|
-
* @dev WARNING: by default json deals with encoded buffers
|
|
77
70
|
* @param index - optional - The index of the blob in the block.
|
|
78
71
|
* @returns The JSON representation of the blob.
|
|
79
72
|
*/
|
|
80
|
-
toJson(index
|
|
81
|
-
|
|
82
|
-
* Get the fields from the blob.
|
|
83
|
-
*
|
|
84
|
-
* @dev WARNING: this method does not take into account trailing zeros
|
|
85
|
-
*
|
|
86
|
-
* @returns The fields from the blob.
|
|
87
|
-
*/
|
|
88
|
-
toFields(): Fr[];
|
|
73
|
+
toJson(index: number): BlobJson;
|
|
74
|
+
getEthVersionedBlobHash(): Buffer;
|
|
89
75
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* @dev This method takes into account trailing zeros
|
|
93
|
-
*
|
|
94
|
-
* @returns The encoded fields from the blob.
|
|
95
|
-
*
|
|
96
|
-
* @throws If unable to deserialize 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).
|
|
97
78
|
*/
|
|
98
|
-
|
|
79
|
+
computeChallengeZ(blobFieldsHash: Fr): Promise<Fr>;
|
|
99
80
|
/**
|
|
100
|
-
*
|
|
81
|
+
* Evaluate the blob at a given challenge and return the evaluation and KZG proof.
|
|
101
82
|
*
|
|
102
|
-
* @
|
|
83
|
+
* @param challengeZ - The challenge z at which to evaluate the blob.
|
|
84
|
+
* @param verifyProof - Whether to verify the KZG proof.
|
|
103
85
|
*
|
|
104
|
-
* @returns
|
|
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.
|
|
88
|
+
* proof: Buffer - KZG opening proof for y = p(z). The commitment to quotient polynomial Q, used in compressed BLS12 point format (48 bytes).
|
|
105
89
|
*/
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
* The 48-byte commitment is encoded into two field elements:
|
|
111
|
-
* +------------------+------------------+
|
|
112
|
-
* | Field Element 1 | Field Element 2 |
|
|
113
|
-
* | [bytes 0-31] | [bytes 32-47] |
|
|
114
|
-
* +------------------+------------------+
|
|
115
|
-
* | 32 bytes | 16 bytes |
|
|
116
|
-
* +------------------+------------------+
|
|
117
|
-
* @returns The commitment fields from the blob.
|
|
118
|
-
*/
|
|
119
|
-
commitmentToFields(): [Fr, Fr];
|
|
120
|
-
getEthVersionedBlobHash(): Buffer;
|
|
121
|
-
static getEthVersionedBlobHash(commitment: Buffer): Buffer;
|
|
90
|
+
evaluate(challengeZ: Fr, verifyProof?: boolean): {
|
|
91
|
+
y: BLS12Fr;
|
|
92
|
+
proof: Buffer<ArrayBuffer>;
|
|
93
|
+
};
|
|
122
94
|
/**
|
|
123
95
|
* Get the buffer representation of the ENTIRE blob.
|
|
124
96
|
*
|
|
125
|
-
* @dev WARNING: this buffer contains all metadata
|
|
97
|
+
* @dev WARNING: this buffer contains all metadata as well as the data itself.
|
|
126
98
|
*
|
|
127
99
|
* @returns The buffer representation of the blob.
|
|
128
100
|
*/
|
|
@@ -130,7 +102,7 @@ export declare class Blob {
|
|
|
130
102
|
/**
|
|
131
103
|
* Create a Blob from a buffer.
|
|
132
104
|
*
|
|
133
|
-
* @dev WARNING: this method contains all metadata
|
|
105
|
+
* @dev WARNING: this method contains all metadata as well as the data itself.
|
|
134
106
|
*
|
|
135
107
|
* @param buf - The buffer to create the Blob from.
|
|
136
108
|
* @returns A Blob created from the buffer.
|
|
@@ -140,23 +112,10 @@ export declare class Blob {
|
|
|
140
112
|
* Get the size of the blob in bytes
|
|
141
113
|
*/
|
|
142
114
|
getSize(): number;
|
|
143
|
-
/**
|
|
144
|
-
* Returns a proof of opening of the blob to verify on L1 using the point evaluation precompile:
|
|
145
|
-
*
|
|
146
|
-
* input[:32] - versioned_hash
|
|
147
|
-
* input[32:64] - z
|
|
148
|
-
* input[64:96] - y
|
|
149
|
-
* input[96:144] - commitment C
|
|
150
|
-
* input[144:192] - proof (a commitment to the quotient polynomial q(X))
|
|
151
|
-
*
|
|
152
|
-
* See https://eips.ethereum.org/EIPS/eip-4844#point-evaluation-precompile
|
|
153
|
-
*/
|
|
154
|
-
getEthBlobEvaluationInputs(): `0x${string}`;
|
|
155
|
-
static getEthBlobEvaluationInputs(blobs: Blob[]): `0x${string}`;
|
|
156
115
|
static getViemKzgInstance(): {
|
|
157
|
-
blobToKzgCommitment:
|
|
158
|
-
computeBlobKzgProof:
|
|
116
|
+
blobToKzgCommitment: (blob: Uint8Array) => Uint8Array;
|
|
117
|
+
computeBlobKzgProof: (blob: Uint8Array, commitment: Uint8Array) => Uint8Array;
|
|
118
|
+
computeCellsAndKzgProofs: (b: Uint8Array) => [Uint8Array[], Uint8Array[]];
|
|
159
119
|
};
|
|
160
|
-
static getBlobs(fields: Fr[]): Promise<Blob[]>;
|
|
161
120
|
}
|
|
162
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,77 +1,69 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
1
|
+
import { FIELDS_PER_BLOB } from '@aztec/constants';
|
|
2
|
+
import { BLS12Fr, Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import { BlobDeserializationError } from './errors.js';
|
|
8
|
-
/* eslint-disable import/no-named-as-default-member */ const { BYTES_PER_BLOB, FIELD_ELEMENTS_PER_BLOB, blobToKzgCommitment, computeKzgProof, verifyKzgProof } = cKzg;
|
|
9
|
-
// The prefix to the EVM blobHash, defined here: https://eips.ethereum.org/EIPS/eip-4844#specification
|
|
10
|
-
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 };
|
|
11
7
|
/**
|
|
12
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.
|
|
13
13
|
*/ export class Blob {
|
|
14
14
|
data;
|
|
15
|
-
fieldsHash;
|
|
16
|
-
challengeZ;
|
|
17
|
-
evaluationY;
|
|
18
15
|
commitment;
|
|
19
|
-
|
|
20
|
-
|
|
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){
|
|
21
21
|
this.data = data;
|
|
22
|
-
this.fieldsHash = fieldsHash;
|
|
23
|
-
this.challengeZ = challengeZ;
|
|
24
|
-
this.evaluationY = evaluationY;
|
|
25
22
|
this.commitment = commitment;
|
|
26
|
-
|
|
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
|
+
}
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* See `./encoding.ts` for more details.
|
|
33
|
-
*
|
|
34
|
-
* This method is used to create a Blob from a buffer.
|
|
35
|
-
* @param blob - The buffer to create the Blob from.
|
|
36
|
-
* @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.
|
|
37
33
|
* @returns A Blob created from the buffer.
|
|
38
34
|
*
|
|
39
|
-
* @throws If
|
|
40
|
-
*/ static
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return Blob.fromFields(fields, multiBlobFieldsHash);
|
|
44
|
-
} catch (err) {
|
|
45
|
-
throw new BlobDeserializationError(`Failed to create Blob from encoded blob buffer, this blob was likely not created by us`);
|
|
46
|
-
}
|
|
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);
|
|
47
39
|
}
|
|
48
40
|
/**
|
|
49
41
|
* Create a Blob from an array of fields.
|
|
50
42
|
*
|
|
43
|
+
* @dev This method pads 0s to the data, extending it to the size of a full blob.
|
|
44
|
+
*
|
|
51
45
|
* @param fields - The array of fields to create the Blob from.
|
|
52
|
-
* @param multiBlobFieldsHash - The fields hash to use for the Blob.
|
|
53
46
|
* @returns A Blob created from the array of fields.
|
|
54
|
-
*/ static
|
|
55
|
-
if (fields.length >
|
|
56
|
-
throw new Error(`Attempted to overfill blob with ${fields.length}
|
|
47
|
+
*/ static fromFields(fields) {
|
|
48
|
+
if (fields.length > FIELDS_PER_BLOB) {
|
|
49
|
+
throw new Error(`Attempted to overfill blob with ${fields.length} fields. The maximum is ${FIELDS_PER_BLOB}.`);
|
|
57
50
|
}
|
|
58
51
|
const data = Buffer.concat([
|
|
59
52
|
serializeToBuffer(fields)
|
|
60
53
|
], BYTES_PER_BLOB);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
return new Blob(data, fieldsHash, challengeZ, evaluationY, commitment, proof);
|
|
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);
|
|
75
67
|
}
|
|
76
68
|
/**
|
|
77
69
|
* Create a Blob from a JSON object.
|
|
@@ -80,187 +72,95 @@ export const VERSIONED_HASH_VERSION_KZG = 0x01;
|
|
|
80
72
|
* the beacon chain via `getBlobSidecars`
|
|
81
73
|
* https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getBlobSidecars
|
|
82
74
|
*
|
|
83
|
-
* @dev WARNING: by default json deals with encoded buffers
|
|
84
|
-
*
|
|
85
75
|
* @param json - The JSON object to create the Blob from.
|
|
86
76
|
* @returns A Blob created from the JSON object.
|
|
87
|
-
*/ static
|
|
77
|
+
*/ static fromJson(json) {
|
|
88
78
|
const blobBuffer = Buffer.from(json.blob.slice(2), 'hex');
|
|
89
|
-
const blob =
|
|
79
|
+
const blob = Blob.fromBlobBuffer(blobBuffer);
|
|
90
80
|
if (blob.commitment.toString('hex') !== json.kzg_commitment.slice(2)) {
|
|
91
81
|
throw new Error('KZG commitment does not match');
|
|
92
82
|
}
|
|
93
|
-
// We do not check the proof, as it will be different if the challenge is shared
|
|
94
|
-
// across multiple blobs
|
|
95
83
|
return blob;
|
|
96
84
|
}
|
|
97
85
|
/**
|
|
98
86
|
* Get the JSON representation of the blob.
|
|
99
87
|
*
|
|
100
|
-
* @dev WARNING: by default json deals with encoded buffers
|
|
101
88
|
* @param index - optional - The index of the blob in the block.
|
|
102
89
|
* @returns The JSON representation of the blob.
|
|
103
90
|
*/ toJson(index) {
|
|
104
91
|
return {
|
|
105
92
|
blob: `0x${Buffer.from(this.data).toString('hex')}`,
|
|
106
|
-
index,
|
|
107
|
-
// eslint-disable-next-line camelcase
|
|
108
|
-
kzg_commitment: `0x${this.commitment.toString('hex')}`,
|
|
93
|
+
index: index.toString(),
|
|
109
94
|
// eslint-disable-next-line camelcase
|
|
110
|
-
|
|
95
|
+
kzg_commitment: `0x${this.commitment.toString('hex')}`
|
|
111
96
|
};
|
|
112
97
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
*
|
|
116
|
-
* @dev WARNING: this method does not take into account trailing zeros
|
|
117
|
-
*
|
|
118
|
-
* @returns The fields from the blob.
|
|
119
|
-
*/ toFields() {
|
|
120
|
-
return extractBlobFieldsFromBuffer(this.data);
|
|
98
|
+
getEthVersionedBlobHash() {
|
|
99
|
+
return computeEthVersionedBlobHash(this.commitment);
|
|
121
100
|
}
|
|
122
101
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
* @returns The encoded fields from the blob.
|
|
128
|
-
*
|
|
129
|
-
* @throws If unable to deserialize the blob.
|
|
130
|
-
*/ toEncodedFields() {
|
|
131
|
-
try {
|
|
132
|
-
return deserializeEncodedBlobToFields(this.data);
|
|
133
|
-
} catch (err) {
|
|
134
|
-
throw new BlobDeserializationError(`Failed to deserialize encoded blob fields, this blob was likely not created by us`);
|
|
135
|
-
}
|
|
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);
|
|
136
106
|
}
|
|
137
107
|
/**
|
|
138
|
-
*
|
|
108
|
+
* Evaluate the blob at a given challenge and return the evaluation and KZG proof.
|
|
139
109
|
*
|
|
140
|
-
* @
|
|
110
|
+
* @param challengeZ - The challenge z at which to evaluate the blob.
|
|
111
|
+
* @param verifyProof - Whether to verify the KZG proof.
|
|
141
112
|
*
|
|
142
|
-
* @returns
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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.
|
|
115
|
+
* proof: Buffer - KZG opening proof for y = p(z). The commitment to quotient polynomial Q, used in compressed BLS12 point format (48 bytes).
|
|
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])) {
|
|
119
|
+
throw new Error(`KZG proof did not verify.`);
|
|
148
120
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
* | Field Element 1 | Field Element 2 |
|
|
156
|
-
* | [bytes 0-31] | [bytes 32-47] |
|
|
157
|
-
* +------------------+------------------+
|
|
158
|
-
* | 32 bytes | 16 bytes |
|
|
159
|
-
* +------------------+------------------+
|
|
160
|
-
* @returns The commitment fields from the blob.
|
|
161
|
-
*/ commitmentToFields() {
|
|
162
|
-
return commitmentToFields(this.commitment);
|
|
163
|
-
}
|
|
164
|
-
// Returns ethereum's versioned blob hash, following kzg_to_versioned_hash: https://eips.ethereum.org/EIPS/eip-4844#helpers
|
|
165
|
-
getEthVersionedBlobHash() {
|
|
166
|
-
const hash = sha256(this.commitment);
|
|
167
|
-
hash[0] = VERSIONED_HASH_VERSION_KZG;
|
|
168
|
-
return hash;
|
|
169
|
-
}
|
|
170
|
-
static getEthVersionedBlobHash(commitment) {
|
|
171
|
-
const hash = sha256(commitment);
|
|
172
|
-
hash[0] = VERSIONED_HASH_VERSION_KZG;
|
|
173
|
-
return hash;
|
|
121
|
+
const proof = Buffer.from(res[0]);
|
|
122
|
+
const y = BLS12Fr.fromBuffer(Buffer.from(res[1]));
|
|
123
|
+
return {
|
|
124
|
+
y,
|
|
125
|
+
proof
|
|
126
|
+
};
|
|
174
127
|
}
|
|
175
128
|
/**
|
|
176
129
|
* Get the buffer representation of the ENTIRE blob.
|
|
177
130
|
*
|
|
178
|
-
* @dev WARNING: this buffer contains all metadata
|
|
131
|
+
* @dev WARNING: this buffer contains all metadata as well as the data itself.
|
|
179
132
|
*
|
|
180
133
|
* @returns The buffer representation of the blob.
|
|
181
134
|
*/ toBuffer() {
|
|
182
|
-
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));
|
|
183
136
|
}
|
|
184
137
|
/**
|
|
185
138
|
* Create a Blob from a buffer.
|
|
186
139
|
*
|
|
187
|
-
* @dev WARNING: this method contains all metadata
|
|
140
|
+
* @dev WARNING: this method contains all metadata as well as the data itself.
|
|
188
141
|
*
|
|
189
142
|
* @param buf - The buffer to create the Blob from.
|
|
190
143
|
* @returns A Blob created from the buffer.
|
|
191
144
|
*/ static fromBuffer(buf) {
|
|
192
145
|
const reader = BufferReader.asReader(buf);
|
|
193
|
-
return new Blob(reader.readUint8Array(), reader.
|
|
146
|
+
return new Blob(reader.readUint8Array(), reader.readBuffer());
|
|
194
147
|
}
|
|
195
148
|
/**
|
|
196
149
|
* Get the size of the blob in bytes
|
|
197
150
|
*/ getSize() {
|
|
198
151
|
return this.data.length;
|
|
199
152
|
}
|
|
200
|
-
/**
|
|
201
|
-
* Returns a proof of opening of the blob to verify on L1 using the point evaluation precompile:
|
|
202
|
-
*
|
|
203
|
-
* input[:32] - versioned_hash
|
|
204
|
-
* input[32:64] - z
|
|
205
|
-
* input[64:96] - y
|
|
206
|
-
* input[96:144] - commitment C
|
|
207
|
-
* input[144:192] - proof (a commitment to the quotient polynomial q(X))
|
|
208
|
-
*
|
|
209
|
-
* See https://eips.ethereum.org/EIPS/eip-4844#point-evaluation-precompile
|
|
210
|
-
*/ getEthBlobEvaluationInputs() {
|
|
211
|
-
const buf = Buffer.concat([
|
|
212
|
-
this.getEthVersionedBlobHash(),
|
|
213
|
-
this.challengeZ.toBuffer(),
|
|
214
|
-
this.evaluationY,
|
|
215
|
-
this.commitment,
|
|
216
|
-
this.proof
|
|
217
|
-
]);
|
|
218
|
-
return `0x${buf.toString('hex')}`;
|
|
219
|
-
}
|
|
220
|
-
static getEthBlobEvaluationInputs(blobs) {
|
|
221
|
-
let buf = Buffer.alloc(0);
|
|
222
|
-
blobs.forEach((blob)=>{
|
|
223
|
-
buf = Buffer.concat([
|
|
224
|
-
buf,
|
|
225
|
-
blob.getEthVersionedBlobHash(),
|
|
226
|
-
blob.challengeZ.toBuffer(),
|
|
227
|
-
blob.evaluationY,
|
|
228
|
-
blob.commitment,
|
|
229
|
-
blob.proof
|
|
230
|
-
]);
|
|
231
|
-
});
|
|
232
|
-
// For multiple blobs, we prefix the number of blobs:
|
|
233
|
-
const lenBuf = Buffer.alloc(1);
|
|
234
|
-
lenBuf.writeUint8(blobs.length);
|
|
235
|
-
buf = Buffer.concat([
|
|
236
|
-
lenBuf,
|
|
237
|
-
buf
|
|
238
|
-
]);
|
|
239
|
-
return `0x${buf.toString('hex')}`;
|
|
240
|
-
}
|
|
241
153
|
static getViemKzgInstance() {
|
|
242
154
|
return {
|
|
243
|
-
blobToKzgCommitment:
|
|
244
|
-
computeBlobKzgProof:
|
|
155
|
+
blobToKzgCommitment: kzg.blobToKzgCommitment.bind(kzg),
|
|
156
|
+
computeBlobKzgProof: kzg.computeBlobKzgProof.bind(kzg),
|
|
157
|
+
computeCellsAndKzgProofs: (b)=>{
|
|
158
|
+
const result = kzg.computeCellsAndKzgProofs(b);
|
|
159
|
+
return [
|
|
160
|
+
result.cells,
|
|
161
|
+
result.proofs
|
|
162
|
+
];
|
|
163
|
+
}
|
|
245
164
|
};
|
|
246
165
|
}
|
|
247
|
-
// Returns as many blobs as we require to broadcast the given fields
|
|
248
|
-
// Assumes we share the fields hash between all blobs
|
|
249
|
-
static async getBlobs(fields) {
|
|
250
|
-
const numBlobs = Math.max(Math.ceil(fields.length / FIELD_ELEMENTS_PER_BLOB), 1);
|
|
251
|
-
const multiBlobFieldsHash = await poseidon2Hash(fields);
|
|
252
|
-
const res = [];
|
|
253
|
-
for(let i = 0; i < numBlobs; i++){
|
|
254
|
-
const end = fields.length < (i + 1) * FIELD_ELEMENTS_PER_BLOB ? fields.length : (i + 1) * FIELD_ELEMENTS_PER_BLOB;
|
|
255
|
-
res.push(await Blob.fromFields(fields.slice(i * FIELD_ELEMENTS_PER_BLOB, end), multiBlobFieldsHash));
|
|
256
|
-
}
|
|
257
|
-
return res;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
// 48 bytes encoded in fields as [Fr, Fr] = [0->31, 31->48]
|
|
261
|
-
function commitmentToFields(commitment) {
|
|
262
|
-
return [
|
|
263
|
-
new Fr(commitment.subarray(0, 31)),
|
|
264
|
-
new Fr(commitment.subarray(31, 48))
|
|
265
|
-
];
|
|
266
166
|
}
|