@aztec/blob-lib 0.76.4 → 0.77.0-testnet-ignition.21

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/encoding.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Fr } from '@aztec/foundation/fields';
2
2
  import { BufferReader, FieldReader } from '@aztec/foundation/serialize';
3
- // Note duplicated from circuit-types !
3
+ // Note duplicated from stdlib !
4
4
  // This will appear as 0x74785f7374617274 in logs
5
5
  export const TX_START_PREFIX = 8392562855083340404n;
6
6
  // These are helper constants to decode tx effects from blob encoded fields
@@ -39,14 +39,13 @@ export const REVERT_CODE_PREFIX = 1;
39
39
  *
40
40
  * @param blob - The blob buffer to deserialize.
41
41
  * @returns An array of field elements.
42
- */
43
- export function deserializeEncodedBlobToFields(blob) {
42
+ */ export function deserializeEncodedBlobToFields(blob) {
44
43
  // Convert blob buffer to array of field elements
45
44
  const reader = BufferReader.asReader(blob);
46
45
  const array = reader.readArray(blob.length >> 5, Fr); // >> 5 = / 32 (bytes per field)
47
46
  const fieldReader = FieldReader.asReader(array);
48
47
  // Read fields until we hit zeros at the end
49
- while (!fieldReader.isFinished()) {
48
+ while(!fieldReader.isFinished()){
50
49
  const currentField = fieldReader.peekField();
51
50
  // Stop when we hit a zero field
52
51
  if (!currentField || currentField.isZero()) {
@@ -66,8 +65,7 @@ export function deserializeEncodedBlobToFields(blob) {
66
65
  * @returns The length of the transaction.
67
66
  *
68
67
  * @throws If the first field does not include the correct prefix - encoding invalid.
69
- */
70
- export function getLengthFromFirstField(firstField) {
68
+ */ export function getLengthFromFirstField(firstField) {
71
69
  // Check that the first field includes the correct prefix
72
70
  if (!isValidFirstField(firstField)) {
73
71
  throw new Error('Invalid prefix');
@@ -75,25 +73,18 @@ export function getLengthFromFirstField(firstField) {
75
73
  const buf = firstField.toBuffer().subarray(-TX_EFFECT_PREFIX_BYTE_LENGTH);
76
74
  return new Fr(buf.subarray(TX_START_PREFIX_BYTES_LENGTH + 1, TX_START_PREFIX_BYTES_LENGTH + 3)).toNumber();
77
75
  }
78
- // NOTE: duplicated from circuit-types tx effect!
79
76
  /**
80
77
  * Determines whether a field is the first field of a tx effect
81
- */
82
- export function isValidFirstField(field) {
78
+ */ export function isValidFirstField(field) {
83
79
  const buf = field.toBuffer();
84
- if (!buf
85
- .subarray(0, field.size - TX_EFFECT_PREFIX_BYTE_LENGTH)
86
- .equals(Buffer.alloc(field.size - TX_EFFECT_PREFIX_BYTE_LENGTH))) {
80
+ if (!buf.subarray(0, field.size - TX_EFFECT_PREFIX_BYTE_LENGTH).equals(Buffer.alloc(field.size - TX_EFFECT_PREFIX_BYTE_LENGTH))) {
87
81
  return false;
88
82
  }
89
83
  const sliced = buf.subarray(-TX_EFFECT_PREFIX_BYTE_LENGTH);
90
- if (
91
- // Checking we start with the correct prefix...
92
- !new Fr(sliced.subarray(0, TX_START_PREFIX_BYTES_LENGTH)).equals(new Fr(TX_START_PREFIX)) ||
93
- // ...and include the revert code prefix..
94
- sliced[sliced.length - 3] !== REVERT_CODE_PREFIX ||
95
- // ...and the following revert code is valid.
96
- sliced[sliced.length - 1] > 4) {
84
+ if (// Checking we start with the correct prefix...
85
+ !new Fr(sliced.subarray(0, TX_START_PREFIX_BYTES_LENGTH)).equals(new Fr(TX_START_PREFIX)) || // ...and include the revert code prefix..
86
+ sliced[sliced.length - 3] !== REVERT_CODE_PREFIX || // ...and the following revert code is valid.
87
+ sliced[sliced.length - 1] > 4) {
97
88
  return false;
98
89
  }
99
90
  return true;
@@ -109,16 +100,14 @@ export function isValidFirstField(field) {
109
100
  * ^
110
101
  * |
111
102
  * Function reads until here ----------------------
112
- */
113
- export function extractBlobFieldsFromBuffer(blob) {
103
+ */ export function extractBlobFieldsFromBuffer(blob) {
114
104
  const reader = BufferReader.asReader(blob);
115
105
  const array = reader.readArray(blob.length >> 5, Fr);
116
106
  // Find the index of the last non-zero field
117
107
  let lastNonZeroIndex = array.length - 1;
118
- while (lastNonZeroIndex >= 0 && array[lastNonZeroIndex].isZero()) {
108
+ while(lastNonZeroIndex >= 0 && array[lastNonZeroIndex].isZero()){
119
109
  lastNonZeroIndex--;
120
110
  }
121
111
  // Return the trimmed array
122
112
  return array.slice(0, lastNonZeroIndex + 1);
123
113
  }
124
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZW5jb2RpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFJeEUsdUNBQXVDO0FBQ3ZDLGlEQUFpRDtBQUNqRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsb0JBQW9CLENBQUM7QUFDcEQsMkVBQTJFO0FBQzNFLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUFHLGVBQWUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUNwRixxRkFBcUY7QUFDckYsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQUcsNEJBQTRCLEdBQUcsQ0FBQyxDQUFDO0FBQzdFLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsQ0FBQztBQUVwQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUNILE1BQU0sVUFBVSw4QkFBOEIsQ0FBQyxJQUFnQjtJQUM3RCxpREFBaUQ7SUFDakQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsZ0NBQWdDO0lBQ3RGLE1BQU0sV0FBVyxHQUFHLFdBQVcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFaEQsNENBQTRDO0lBQzVDLE9BQU8sQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztRQUNqQyxNQUFNLFlBQVksR0FBRyxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFN0MsZ0NBQWdDO1FB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
package/dest/errors.js CHANGED
@@ -1,7 +1,6 @@
1
1
  export class BlobDeserializationError extends Error {
2
- constructor(message) {
2
+ constructor(message){
3
3
  super(message);
4
4
  this.name = 'BlobDeserializationError';
5
5
  }
6
6
  }
7
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLE9BQU8sd0JBQXlCLFNBQVEsS0FBSztJQUNqRCxZQUFZLE9BQWU7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksR0FBRywwQkFBMEIsQ0FBQztJQUN6QyxDQUFDO0NBQ0YifQ==
package/dest/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './blob.js';
2
- export * from './mocks.js';
3
2
  export * from './encoding.js';
4
3
  export * from './interface.js';
5
4
  export * from './errors.js';
5
+ export * from './blob_public_inputs.js';
6
+ export * from './sponge_blob.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC"}
package/dest/index.js CHANGED
@@ -1,22 +1,19 @@
1
1
  import cKzg from 'c-kzg';
2
- /* eslint-disable import/no-named-as-default-member */
3
- const { loadTrustedSetup } = cKzg;
2
+ /* eslint-disable import/no-named-as-default-member */ const { loadTrustedSetup } = cKzg;
4
3
  export * from './blob.js';
5
- export * from './mocks.js';
6
4
  export * from './encoding.js';
7
5
  export * from './interface.js';
8
6
  export * from './errors.js';
7
+ export * from './blob_public_inputs.js';
8
+ export * from './sponge_blob.js';
9
9
  try {
10
10
  loadTrustedSetup();
11
- }
12
- catch (error) {
11
+ } catch (error) {
13
12
  if (error.message.includes('trusted setup is already loaded')) {
14
- // NB: The c-kzg lib has no way of checking whether the setup is loaded or not,
15
- // and it throws an error if it's already loaded, even though nothing is wrong.
16
- // This is a rudimentary way of ensuring we load the trusted setup if we need it.
17
- }
18
- else {
13
+ // NB: The c-kzg lib has no way of checking whether the setup is loaded or not,
14
+ // and it throws an error if it's already loaded, even though nothing is wrong.
15
+ // This is a rudimentary way of ensuring we load the trusted setup if we need it.
16
+ } else {
19
17
  throw new Error(error);
20
18
  }
21
19
  }
22
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxJQUFJLE1BQU0sT0FBTyxDQUFDO0FBRXpCLHNEQUFzRDtBQUN0RCxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFbEMsY0FBYyxXQUFXLENBQUM7QUFDMUIsY0FBYyxZQUFZLENBQUM7QUFDM0IsY0FBYyxlQUFlLENBQUM7QUFDOUIsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLGFBQWEsQ0FBQztBQUU1QixJQUFJLENBQUM7SUFDSCxnQkFBZ0IsRUFBRSxDQUFDO0FBQ3JCLENBQUM7QUFBQyxPQUFPLEtBQVUsRUFBRSxDQUFDO0lBQ3BCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsaUNBQWlDLENBQUMsRUFBRSxDQUFDO1FBQzlELCtFQUErRTtRQUMvRSwrRUFBK0U7UUFDL0UsaUZBQWlGO0lBQ25GLENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QixDQUFDO0FBQ0gsQ0FBQyJ9
package/dest/interface.js CHANGED
@@ -1,2 +1,3 @@
1
- export {};
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ludGVyZmFjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
1
+ /**
2
+ * The relevant parts of a response from https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getBlobSidecars
3
+ */ export { };
@@ -0,0 +1,52 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ import { type FieldsOf } from '@aztec/foundation/array';
4
+ import { Fr } from '@aztec/foundation/fields';
5
+ import { BufferReader, FieldReader, type Tuple } from '@aztec/foundation/serialize';
6
+ /**
7
+ * A Poseidon2 sponge used to accumulate data that will be added to a blob.
8
+ * See noir-projects/noir-protocol-circuits/crates/types/src/abis/sponge_blob.nr.
9
+ */
10
+ export declare class SpongeBlob {
11
+ /** Sponge with absorbed tx effects that will go into a blob. */
12
+ readonly sponge: Poseidon2Sponge;
13
+ /** Number of effects absorbed so far. */
14
+ fields: number;
15
+ /** Number of effects that will be absorbed. */
16
+ readonly expectedFields: number;
17
+ constructor(
18
+ /** Sponge with absorbed tx effects that will go into a blob. */
19
+ sponge: Poseidon2Sponge,
20
+ /** Number of effects absorbed so far. */
21
+ fields: number,
22
+ /** Number of effects that will be absorbed. */
23
+ expectedFields: number);
24
+ static fromBuffer(buffer: Buffer | BufferReader): SpongeBlob;
25
+ toBuffer(): Buffer;
26
+ static getFields(fields: FieldsOf<SpongeBlob>): (number | Poseidon2Sponge)[];
27
+ toFields(): Fr[];
28
+ static fromFields(fields: Fr[] | FieldReader): SpongeBlob;
29
+ clone(): SpongeBlob;
30
+ absorb(fields: Fr[]): Promise<void>;
31
+ squeeze(): Promise<Fr>;
32
+ static empty(): SpongeBlob;
33
+ static init(expectedFields: number): SpongeBlob;
34
+ }
35
+ export declare class Poseidon2Sponge {
36
+ cache: Tuple<Fr, 3>;
37
+ state: Tuple<Fr, 4>;
38
+ cacheSize: number;
39
+ squeezeMode: boolean;
40
+ constructor(cache: Tuple<Fr, 3>, state: Tuple<Fr, 4>, cacheSize: number, squeezeMode: boolean);
41
+ static fromBuffer(buffer: Buffer | BufferReader): Poseidon2Sponge;
42
+ toBuffer(): Buffer;
43
+ static getFields(fields: FieldsOf<Poseidon2Sponge>): (number | boolean | [Fr, Fr, Fr] | [Fr, Fr, Fr, Fr])[];
44
+ toFields(): Fr[];
45
+ static fromFields(fields: Fr[] | FieldReader): Poseidon2Sponge;
46
+ static empty(): Poseidon2Sponge;
47
+ static init(expectedFields: number): Poseidon2Sponge;
48
+ performDuplex(): Promise<void>;
49
+ absorb(fields: Fr[]): Promise<void>;
50
+ squeeze(): Promise<Fr>;
51
+ }
52
+ //# sourceMappingURL=sponge_blob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sponge_blob.d.ts","sourceRoot":"","sources":["../src/sponge_blob.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,KAAK,QAAQ,EAAa,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,WAAW,EACX,KAAK,KAAK,EAGX,MAAM,6BAA6B,CAAC;AAErC;;;GAGG;AACH,qBAAa,UAAU;IAEnB,gEAAgE;aAChD,MAAM,EAAE,eAAe;IACvC,yCAAyC;IAClC,MAAM,EAAE,MAAM;IACrB,+CAA+C;aAC/B,cAAc,EAAE,MAAM;;IALtC,gEAAgE;IAChD,MAAM,EAAE,eAAe;IACvC,yCAAyC;IAClC,MAAM,EAAE,MAAM;IACrB,+CAA+C;IAC/B,cAAc,EAAE,MAAM;IAGxC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU;IAK5D,QAAQ;IAIR,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC;IAI7C,QAAQ,IAAI,EAAE,EAAE;IAIhB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,WAAW,GAAG,UAAU;IASzD,KAAK;IAIC,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE;IAUnB,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC;IAS5B,MAAM,CAAC,KAAK,IAAI,UAAU;IAI1B,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,UAAU;CAGhD;AAGD,qBAAa,eAAe;IAEjB,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IACnB,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,OAAO;gBAHpB,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EACnB,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,OAAO;IAG7B,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe;IAUjE,QAAQ;IAIR,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC;IAIlD,QAAQ,IAAI,EAAE,EAAE;IAIhB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,WAAW,GAAG,eAAe;IAU9D,MAAM,CAAC,KAAK,IAAI,eAAe;IAS/B,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,eAAe;IAU9C,aAAa;IAWb,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE;IAenB,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC;CAQ7B"}
@@ -0,0 +1,148 @@
1
+ import { makeTuple } from '@aztec/foundation/array';
2
+ import { poseidon2Permutation } from '@aztec/foundation/crypto';
3
+ import { Fr } from '@aztec/foundation/fields';
4
+ import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize';
5
+ /**
6
+ * A Poseidon2 sponge used to accumulate data that will be added to a blob.
7
+ * See noir-projects/noir-protocol-circuits/crates/types/src/abis/sponge_blob.nr.
8
+ */ export class SpongeBlob {
9
+ sponge;
10
+ fields;
11
+ expectedFields;
12
+ constructor(/** Sponge with absorbed tx effects that will go into a blob. */ sponge, /** Number of effects absorbed so far. */ fields, /** Number of effects that will be absorbed. */ expectedFields){
13
+ this.sponge = sponge;
14
+ this.fields = fields;
15
+ this.expectedFields = expectedFields;
16
+ }
17
+ static fromBuffer(buffer) {
18
+ const reader = BufferReader.asReader(buffer);
19
+ return new SpongeBlob(reader.readObject(Poseidon2Sponge), reader.readNumber(), reader.readNumber());
20
+ }
21
+ toBuffer() {
22
+ return serializeToBuffer(this.sponge, this.fields, this.expectedFields);
23
+ }
24
+ static getFields(fields) {
25
+ return [
26
+ fields.sponge,
27
+ fields.fields,
28
+ fields.expectedFields
29
+ ];
30
+ }
31
+ toFields() {
32
+ return serializeToFields(...SpongeBlob.getFields(this));
33
+ }
34
+ static fromFields(fields) {
35
+ const reader = FieldReader.asReader(fields);
36
+ return new SpongeBlob(reader.readObject(Poseidon2Sponge), reader.readField().toNumber(), reader.readField().toNumber());
37
+ }
38
+ clone() {
39
+ return SpongeBlob.fromBuffer(this.toBuffer());
40
+ }
41
+ async absorb(fields) {
42
+ if (this.fields + fields.length > this.expectedFields) {
43
+ throw new Error(`Attempted to fill spongeblob with ${this.fields + fields.length}, but it has a max of ${this.expectedFields}`);
44
+ }
45
+ await this.sponge.absorb(fields);
46
+ this.fields += fields.length;
47
+ }
48
+ async squeeze() {
49
+ // If the blob sponge is not 'full', we append 1 to match Poseidon2::hash_internal()
50
+ // NB: There is currently no use case in which we don't 'fill' a blob sponge, but adding for completeness
51
+ if (this.fields != this.expectedFields) {
52
+ await this.sponge.absorb([
53
+ Fr.ONE
54
+ ]);
55
+ }
56
+ return this.sponge.squeeze();
57
+ }
58
+ static empty() {
59
+ return new SpongeBlob(Poseidon2Sponge.empty(), 0, 0);
60
+ }
61
+ static init(expectedFields) {
62
+ return new SpongeBlob(Poseidon2Sponge.init(expectedFields), 0, expectedFields);
63
+ }
64
+ }
65
+ // This is just noir's stdlib version of the poseidon2 sponge. We use it for a blob-specific implmentation of the hasher.
66
+ export class Poseidon2Sponge {
67
+ cache;
68
+ state;
69
+ cacheSize;
70
+ squeezeMode;
71
+ constructor(cache, state, cacheSize, squeezeMode){
72
+ this.cache = cache;
73
+ this.state = state;
74
+ this.cacheSize = cacheSize;
75
+ this.squeezeMode = squeezeMode;
76
+ }
77
+ static fromBuffer(buffer) {
78
+ const reader = BufferReader.asReader(buffer);
79
+ return new Poseidon2Sponge(reader.readArray(3, Fr), reader.readArray(4, Fr), reader.readNumber(), reader.readBoolean());
80
+ }
81
+ toBuffer() {
82
+ return serializeToBuffer(this.cache, this.state, this.cacheSize, this.squeezeMode);
83
+ }
84
+ static getFields(fields) {
85
+ return [
86
+ fields.cache,
87
+ fields.state,
88
+ fields.cacheSize,
89
+ fields.squeezeMode
90
+ ];
91
+ }
92
+ toFields() {
93
+ return serializeToFields(...Poseidon2Sponge.getFields(this));
94
+ }
95
+ static fromFields(fields) {
96
+ const reader = FieldReader.asReader(fields);
97
+ return new Poseidon2Sponge(reader.readFieldArray(3), reader.readFieldArray(4), reader.readField().toNumber(), reader.readBoolean());
98
+ }
99
+ static empty() {
100
+ return new Poseidon2Sponge(makeTuple(3, ()=>Fr.ZERO), makeTuple(4, ()=>Fr.ZERO), 0, false);
101
+ }
102
+ static init(expectedFields) {
103
+ const iv = new Fr(expectedFields).mul(new Fr(BigInt('18446744073709551616')));
104
+ const sponge = Poseidon2Sponge.empty();
105
+ sponge.state[3] = iv;
106
+ return sponge;
107
+ }
108
+ // Note: there isn't currently an impl in ts that allows for a custom aborption via an
109
+ // existing sponge.
110
+ // A custom blob-based impl of noir/noir-repo/noir_stdlib/src/hash/poseidon2.nr
111
+ async performDuplex() {
112
+ for(let i = 0; i < this.cache.length; i++){
113
+ if (i < this.cacheSize) {
114
+ this.state[i] = this.state[i].add(this.cache[i]);
115
+ }
116
+ }
117
+ const perm = await poseidon2Permutation(this.state);
118
+ // ts doesn't understand that the above always gives 4
119
+ this.state = [
120
+ perm[0],
121
+ perm[1],
122
+ perm[2],
123
+ perm[3]
124
+ ];
125
+ }
126
+ async absorb(fields) {
127
+ if (this.squeezeMode) {
128
+ throw new Error(`Poseidon sponge is not able to absorb more inputs.`);
129
+ }
130
+ for (const field of fields){
131
+ if (this.cacheSize == this.cache.length) {
132
+ await this.performDuplex();
133
+ this.cache[0] = field;
134
+ this.cacheSize = 1;
135
+ } else {
136
+ this.cache[this.cacheSize++] = field;
137
+ }
138
+ }
139
+ }
140
+ async squeeze() {
141
+ if (this.squeezeMode) {
142
+ throw new Error(`Poseidon sponge has already been squeezed.`);
143
+ }
144
+ await this.performDuplex();
145
+ this.squeezeMode = true;
146
+ return this.state[0];
147
+ }
148
+ }
@@ -0,0 +1,43 @@
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import { Blob } from './blob.js';
3
+ import { BlobPublicInputs, BlockBlobPublicInputs } from './blob_public_inputs.js';
4
+ import { SpongeBlob } from './sponge_blob.js';
5
+ /**
6
+ * Makes arbitrary poseidon sponge for blob inputs.
7
+ * Note: will not verify inside the circuit.
8
+ * @param seed - The seed to use for generating the sponge.
9
+ * @returns A sponge blob instance.
10
+ */
11
+ export declare function makeSpongeBlob(seed?: number): SpongeBlob;
12
+ /**
13
+ * Makes arbitrary blob public inputs.
14
+ * Note: will not verify inside the circuit.
15
+ * @param seed - The seed to use for generating the blob inputs.
16
+ * @returns A blob public inputs instance.
17
+ */
18
+ export declare function makeBlobPublicInputs(seed?: number): BlobPublicInputs;
19
+ /**
20
+ * Makes arbitrary block blob public inputs.
21
+ * Note: will not verify inside the circuit.
22
+ * @param seed - The seed to use for generating the blob inputs.
23
+ * @returns A block blob public inputs instance.
24
+ */
25
+ export declare function makeBlockBlobPublicInputs(seed?: number): BlockBlobPublicInputs;
26
+ /**
27
+ * Make an encoded blob with the given length
28
+ *
29
+ * This will deserialise correctly in the archiver
30
+ * @param length
31
+ * @returns
32
+ */
33
+ export declare function makeEncodedBlob(length: number): Promise<Blob>;
34
+ /**
35
+ * Make an unencoded blob with the given length
36
+ *
37
+ * This will fail deserialisation in the archiver
38
+ * @param length
39
+ * @returns
40
+ */
41
+ export declare function makeUnencodedBlob(length: number): Promise<Blob>;
42
+ export declare function makeEncodedBlobFields(fields: Fr[]): Promise<Blob>;
43
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAElF,OAAO,EAAmB,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE/D;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,SAAI,GAAG,UAAU,CAWnD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,SAAI,GAAG,gBAAgB,CAM/D;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,SAAI,GAAG,qBAAqB,CAEzE;AAmBD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/D;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE"}
@@ -0,0 +1,81 @@
1
+ import { BLOBS_PER_BLOCK } from '@aztec/constants';
2
+ import { makeTuple } from '@aztec/foundation/array';
3
+ import { toBufferBE } from '@aztec/foundation/bigint-buffer';
4
+ import { Fr } from '@aztec/foundation/fields';
5
+ import { Blob } from './blob.js';
6
+ import { BlobPublicInputs, BlockBlobPublicInputs } from './blob_public_inputs.js';
7
+ import { TX_START_PREFIX, TX_START_PREFIX_BYTES_LENGTH } from './encoding.js';
8
+ import { Poseidon2Sponge, SpongeBlob } from './sponge_blob.js';
9
+ /**
10
+ * Makes arbitrary poseidon sponge for blob inputs.
11
+ * Note: will not verify inside the circuit.
12
+ * @param seed - The seed to use for generating the sponge.
13
+ * @returns A sponge blob instance.
14
+ */ export function makeSpongeBlob(seed = 1) {
15
+ return new SpongeBlob(new Poseidon2Sponge(makeTuple(3, (i)=>new Fr(i)), makeTuple(4, (i)=>new Fr(i)), 1, false), seed, seed + 1);
16
+ }
17
+ /**
18
+ * Makes arbitrary blob public inputs.
19
+ * Note: will not verify inside the circuit.
20
+ * @param seed - The seed to use for generating the blob inputs.
21
+ * @returns A blob public inputs instance.
22
+ */ export function makeBlobPublicInputs(seed = 1) {
23
+ return new BlobPublicInputs(new Fr(seed), BigInt(seed + 1), makeTuple(2, (i)=>new Fr(i)));
24
+ }
25
+ /**
26
+ * Makes arbitrary block blob public inputs.
27
+ * Note: will not verify inside the circuit.
28
+ * @param seed - The seed to use for generating the blob inputs.
29
+ * @returns A block blob public inputs instance.
30
+ */ export function makeBlockBlobPublicInputs(seed = 1) {
31
+ return new BlockBlobPublicInputs(makeTuple(BLOBS_PER_BLOCK, ()=>makeBlobPublicInputs(seed)));
32
+ }
33
+ // TODO: copied form stdlib tx effect
34
+ function encodeFirstField(length) {
35
+ const lengthBuf = Buffer.alloc(2);
36
+ lengthBuf.writeUInt16BE(length, 0);
37
+ return new Fr(Buffer.concat([
38
+ toBufferBE(TX_START_PREFIX, TX_START_PREFIX_BYTES_LENGTH),
39
+ Buffer.alloc(1),
40
+ lengthBuf,
41
+ Buffer.alloc(1),
42
+ Buffer.from([
43
+ 1
44
+ ]),
45
+ Buffer.alloc(1),
46
+ Buffer.alloc(1)
47
+ ]));
48
+ }
49
+ /**
50
+ * Make an encoded blob with the given length
51
+ *
52
+ * This will deserialise correctly in the archiver
53
+ * @param length
54
+ * @returns
55
+ */ export function makeEncodedBlob(length) {
56
+ return Blob.fromFields([
57
+ encodeFirstField(length + 1),
58
+ ...Array.from({
59
+ length: length
60
+ }, ()=>Fr.random())
61
+ ]);
62
+ }
63
+ /**
64
+ * Make an unencoded blob with the given length
65
+ *
66
+ * This will fail deserialisation in the archiver
67
+ * @param length
68
+ * @returns
69
+ */ export function makeUnencodedBlob(length) {
70
+ return Blob.fromFields([
71
+ ...Array.from({
72
+ length: length
73
+ }, ()=>Fr.random())
74
+ ]);
75
+ }
76
+ export function makeEncodedBlobFields(fields) {
77
+ return Blob.fromFields([
78
+ encodeFirstField(fields.length + 1),
79
+ ...fields
80
+ ]);
81
+ }
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@aztec/blob-lib",
3
- "version": "0.76.4",
3
+ "version": "0.77.0-testnet-ignition.21",
4
4
  "type": "module",
5
5
  "exports": {
6
- ".": "./dest/index.js"
6
+ ".": "./dest/index.js",
7
+ "./testing": "./dest/testing.js"
7
8
  },
8
9
  "typedocOptions": {
9
10
  "entryPoints": [
@@ -20,13 +21,14 @@
20
21
  "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
21
22
  "start:dev": "tsc-watch -p tsconfig.json --onSuccess 'yarn start'",
22
23
  "start": "node ./dest/index.js",
23
- "test": "HARDWARE_CONCURRENCY=${HARDWARE_CONCURRENCY:-16} RAYON_NUM_THREADS=${RAYON_NUM_THREADS:-4} NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
24
+ "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
24
25
  },
25
26
  "inherits": [
26
27
  "../package.common.json"
27
28
  ],
28
29
  "dependencies": {
29
- "@aztec/foundation": "0.76.4",
30
+ "@aztec/constants": "0.77.0-testnet-ignition.21",
31
+ "@aztec/foundation": "0.77.0-testnet-ignition.21",
30
32
  "c-kzg": "4.0.0-alpha.1",
31
33
  "tslib": "^2.4.0"
32
34
  },
@@ -73,7 +75,7 @@
73
75
  "reporters": [
74
76
  "default"
75
77
  ],
76
- "testTimeout": 30000,
78
+ "testTimeout": 120000,
77
79
  "setupFiles": [
78
80
  "../../foundation/src/jest/setup.mjs"
79
81
  ]
package/src/blob.ts CHANGED
@@ -8,7 +8,7 @@ import type { Blob as BlobBuffer } from 'c-kzg';
8
8
 
9
9
  import { deserializeEncodedBlobToFields, extractBlobFieldsFromBuffer } from './encoding.js';
10
10
  import { BlobDeserializationError } from './errors.js';
11
- import { type BlobJson } from './interface.js';
11
+ import type { BlobJson } from './interface.js';
12
12
 
13
13
  /* eslint-disable import/no-named-as-default-member */
14
14
  const { BYTES_PER_BLOB, FIELD_ELEMENTS_PER_BLOB, blobToKzgCommitment, computeKzgProof, verifyKzgProof } = cKzg;