@aztec/stdlib 5.0.0-nightly.20260521 → 5.0.0-nightly.20260523

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 (49) hide show
  1. package/dest/avm/avm.d.ts +33 -26
  2. package/dest/avm/avm.d.ts.map +1 -1
  3. package/dest/avm/avm.js +6 -3
  4. package/dest/avm/avm_proving_request.d.ts +11 -9
  5. package/dest/avm/avm_proving_request.d.ts.map +1 -1
  6. package/dest/avm/message_pack.js +12 -3
  7. package/dest/contract/complete_address.d.ts +2 -1
  8. package/dest/contract/complete_address.d.ts.map +1 -1
  9. package/dest/contract/complete_address.js +6 -2
  10. package/dest/contract/contract_address.d.ts +5 -5
  11. package/dest/contract/contract_address.d.ts.map +1 -1
  12. package/dest/contract/contract_address.js +4 -3
  13. package/dest/contract/contract_instance.d.ts +4 -2
  14. package/dest/contract/contract_instance.d.ts.map +1 -1
  15. package/dest/contract/contract_instance.js +10 -3
  16. package/dest/contract/interfaces/contract_instance.d.ts +24 -20
  17. package/dest/contract/interfaces/contract_instance.d.ts.map +1 -1
  18. package/dest/contract/interfaces/contract_instance.js +4 -2
  19. package/dest/interfaces/proving-job.d.ts +11 -9
  20. package/dest/interfaces/proving-job.d.ts.map +1 -1
  21. package/dest/kernel/hints/key_validation_request.d.ts +12 -8
  22. package/dest/kernel/hints/key_validation_request.d.ts.map +1 -1
  23. package/dest/kernel/hints/key_validation_request.js +20 -18
  24. package/dest/keys/derivation.d.ts +6 -2
  25. package/dest/keys/derivation.d.ts.map +1 -1
  26. package/dest/keys/derivation.js +12 -5
  27. package/dest/keys/public_key.d.ts +22 -3
  28. package/dest/keys/public_key.d.ts.map +1 -1
  29. package/dest/keys/public_key.js +20 -1
  30. package/dest/keys/public_keys.d.ts +37 -69
  31. package/dest/keys/public_keys.d.ts.map +1 -1
  32. package/dest/keys/public_keys.js +77 -74
  33. package/dest/tests/factories.d.ts +2 -1
  34. package/dest/tests/factories.d.ts.map +1 -1
  35. package/dest/tests/factories.js +10 -6
  36. package/dest/tx/simulated_tx.d.ts +17 -13
  37. package/dest/tx/simulated_tx.d.ts.map +1 -1
  38. package/package.json +8 -8
  39. package/src/avm/avm.ts +5 -0
  40. package/src/avm/message_pack.ts +12 -3
  41. package/src/contract/complete_address.ts +7 -3
  42. package/src/contract/contract_address.ts +5 -5
  43. package/src/contract/contract_instance.ts +11 -2
  44. package/src/contract/interfaces/contract_instance.ts +6 -2
  45. package/src/kernel/hints/key_validation_request.ts +18 -16
  46. package/src/keys/derivation.ts +15 -8
  47. package/src/keys/public_key.ts +26 -2
  48. package/src/keys/public_keys.ts +80 -116
  49. package/src/tests/factories.ts +20 -10
@@ -1,17 +1,13 @@
1
1
  import {
2
2
  DEFAULT_IVPK_M_X,
3
3
  DEFAULT_IVPK_M_Y,
4
- DEFAULT_NPK_M_X,
5
- DEFAULT_NPK_M_Y,
6
- DEFAULT_OVPK_M_X,
7
- DEFAULT_OVPK_M_Y,
8
- DEFAULT_TPK_M_X,
9
- DEFAULT_TPK_M_Y,
4
+ DEFAULT_NPK_M_HASH,
5
+ DEFAULT_OVPK_M_HASH,
6
+ DEFAULT_TPK_M_HASH,
10
7
  DomainSeparator,
11
8
  } from '@aztec/constants';
12
9
  import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
13
10
  import { Fr } from '@aztec/foundation/curves/bn254';
14
- import { Point } from '@aztec/foundation/curves/grumpkin';
15
11
  import { schemas } from '@aztec/foundation/schemas';
16
12
  import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
17
13
  import { bufferToHex, withoutHexPrefix } from '@aztec/foundation/string';
@@ -19,108 +15,107 @@ import type { FieldsOf } from '@aztec/foundation/types';
19
15
 
20
16
  import { z } from 'zod';
21
17
 
22
- import type { PublicKey } from './public_key.js';
18
+ import { PublicKey, hashPublicKey } from './public_key.js';
23
19
 
20
+ /**
21
+ * A non-owner's view of an account's master public keys.
22
+ *
23
+ * Only `ivpkM` is exposed as a point (since address derivation needs the curve
24
+ * point in-circuit); the other three keys are exposed as their `hashPublicKey` digests.
25
+ */
24
26
  export class PublicKeys {
25
27
  public constructor(
26
- /** Master nullifier public key */
27
- public masterNullifierPublicKey: PublicKey,
28
+ /** Hash of the master nullifier public key */
29
+ public npkMHash: Fr,
28
30
  /** Master incoming viewing public key */
29
- public masterIncomingViewingPublicKey: PublicKey,
30
- /** Master outgoing viewing public key */
31
- public masterOutgoingViewingPublicKey: PublicKey,
32
- /** Master tagging viewing public key */
33
- public masterTaggingPublicKey: PublicKey,
31
+ public ivpkM: PublicKey,
32
+ /** Hash of the master outgoing viewing public key */
33
+ public ovpkMHash: Fr,
34
+ /** Hash of the master tagging public key */
35
+ public tpkMHash: Fr,
34
36
  ) {}
35
37
 
36
38
  static get schema() {
37
39
  return z
38
40
  .object({
39
- masterNullifierPublicKey: schemas.Point,
40
- masterIncomingViewingPublicKey: schemas.Point,
41
- masterOutgoingViewingPublicKey: schemas.Point,
42
- masterTaggingPublicKey: schemas.Point,
41
+ npkMHash: schemas.Fr,
42
+ ivpkM: schemas.Point,
43
+ ovpkMHash: schemas.Fr,
44
+ tpkMHash: schemas.Fr,
43
45
  })
44
46
  .transform(PublicKeys.from);
45
47
  }
46
48
 
47
49
  static from(fields: FieldsOf<PublicKeys>) {
48
- return new PublicKeys(
49
- fields.masterNullifierPublicKey,
50
- fields.masterIncomingViewingPublicKey,
51
- fields.masterOutgoingViewingPublicKey,
52
- fields.masterTaggingPublicKey,
53
- );
50
+ return new PublicKeys(fields.npkMHash, fields.ivpkM, fields.ovpkMHash, fields.tpkMHash);
54
51
  }
55
52
 
56
53
  /**
57
54
  * Creates a PublicKeys from a plain object without Zod validation.
58
- * This method is optimized for performance and skips validation, making it suitable
59
- * for deserializing trusted data (e.g., from C++ via MessagePack).
60
- * @param obj - Plain object containing PublicKeys fields
61
- * @returns A PublicKeys instance
55
+ * Suitable for deserializing trusted data (e.g., from C++ via MessagePack).
62
56
  */
63
57
  static fromPlainObject(obj: any): PublicKeys {
64
58
  if (obj instanceof PublicKeys) {
65
59
  return obj;
66
60
  }
67
61
  return new PublicKeys(
68
- Point.fromPlainObject(obj.masterNullifierPublicKey),
69
- Point.fromPlainObject(obj.masterIncomingViewingPublicKey),
70
- Point.fromPlainObject(obj.masterOutgoingViewingPublicKey),
71
- Point.fromPlainObject(obj.masterTaggingPublicKey),
62
+ Fr.fromPlainObject(obj.npkMHash),
63
+ PublicKey.fromPlainObject(obj.ivpkM),
64
+ Fr.fromPlainObject(obj.ovpkMHash),
65
+ Fr.fromPlainObject(obj.tpkMHash),
72
66
  );
73
67
  }
74
68
 
75
- hash() {
76
- return this.isEmpty()
77
- ? Fr.ZERO
78
- : poseidon2HashWithSeparator(
79
- [
80
- this.masterNullifierPublicKey,
81
- this.masterIncomingViewingPublicKey,
82
- this.masterOutgoingViewingPublicKey,
83
- this.masterTaggingPublicKey,
84
- ],
85
- DomainSeparator.PUBLIC_KEYS_HASH,
86
- );
69
+ async hash() {
70
+ if (this.isEmpty()) {
71
+ return Fr.ZERO;
72
+ }
73
+ // Mirror Noir's `PublicKeys::hash`: hash the four single-key digests under
74
+ // DOM_SEP__PUBLIC_KEYS_HASH. `ivpk_m` must be reduced to its single-key digest first
75
+ // (Poseidon2 over [x, y]); passing the Point directly would omit the DOM_SEP__SINGLE_PUBLIC_KEY_HASH
76
+ const ivpkMHash = await hashPublicKey(this.ivpkM);
77
+ return poseidon2HashWithSeparator(
78
+ [this.npkMHash, ivpkMHash, this.ovpkMHash, this.tpkMHash],
79
+ DomainSeparator.PUBLIC_KEYS_HASH,
80
+ );
87
81
  }
88
82
 
89
83
  isEmpty() {
90
- return (
91
- this.masterNullifierPublicKey.isZero() &&
92
- this.masterIncomingViewingPublicKey.isZero() &&
93
- this.masterOutgoingViewingPublicKey.isZero() &&
94
- this.masterTaggingPublicKey.isZero()
95
- );
84
+ return this.npkMHash.isZero() && this.ivpkM.isZero() && this.ovpkMHash.isZero() && this.tpkMHash.isZero();
96
85
  }
97
86
 
98
87
  static default(): PublicKeys {
88
+ // Precomputed `hash_public_key(Point { DEFAULT_*_X, DEFAULT_*_Y })` for npk/ovpk/tpk.
89
+ // Sourced from constants.gen.ts (originally defined in
90
+ // noir-protocol-circuits/crates/types/src/constants.nr); a self-test in public_keys.nr
91
+ // (`default_hashes_match_default_points`) catches drift between the *_HASH constants and
92
+ // the underlying X/Y points.
99
93
  return new PublicKeys(
100
- new Point(new Fr(DEFAULT_NPK_M_X), new Fr(DEFAULT_NPK_M_Y), false),
101
- new Point(new Fr(DEFAULT_IVPK_M_X), new Fr(DEFAULT_IVPK_M_Y), false),
102
- new Point(new Fr(DEFAULT_OVPK_M_X), new Fr(DEFAULT_OVPK_M_Y), false),
103
- new Point(new Fr(DEFAULT_TPK_M_X), new Fr(DEFAULT_TPK_M_Y), false),
94
+ new Fr(DEFAULT_NPK_M_HASH),
95
+ new PublicKey(new Fr(DEFAULT_IVPK_M_X), new Fr(DEFAULT_IVPK_M_Y)),
96
+ new Fr(DEFAULT_OVPK_M_HASH),
97
+ new Fr(DEFAULT_TPK_M_HASH),
104
98
  );
105
99
  }
106
100
 
107
101
  static async random(): Promise<PublicKeys> {
108
- return new PublicKeys(await Point.random(), await Point.random(), await Point.random(), await Point.random());
102
+ const npkM = await PublicKey.random();
103
+ const ovpkM = await PublicKey.random();
104
+ const tpkM = await PublicKey.random();
105
+ return new PublicKeys(
106
+ await hashPublicKey(npkM),
107
+ await PublicKey.random(),
108
+ await hashPublicKey(ovpkM),
109
+ await hashPublicKey(tpkM),
110
+ );
109
111
  }
110
112
 
111
- /**
112
- * Determines if this PublicKeys instance is equal to the given PublicKeys instance.
113
- * Equality is based on the content of their respective buffers.
114
- *
115
- * @param other - The PublicKeys instance to compare against.
116
- * @returns True if the buffers of both instances are equal, false otherwise.
117
- */
118
113
  equals(other: PublicKeys): boolean {
119
114
  return (
120
- this.masterNullifierPublicKey.equals(other.masterNullifierPublicKey) &&
121
- this.masterIncomingViewingPublicKey.equals(other.masterIncomingViewingPublicKey) &&
122
- this.masterOutgoingViewingPublicKey.equals(other.masterOutgoingViewingPublicKey) &&
123
- this.masterTaggingPublicKey.equals(other.masterTaggingPublicKey)
115
+ this.npkMHash.equals(other.npkMHash) &&
116
+ this.ivpkM.equals(other.ivpkM) &&
117
+ this.ovpkMHash.equals(other.ovpkMHash) &&
118
+ this.tpkMHash.equals(other.tpkMHash)
124
119
  );
125
120
  }
126
121
 
@@ -131,77 +126,46 @@ export class PublicKeys {
131
126
  * @returns A Buffer representation of the PublicKeys instance.
132
127
  */
133
128
  toBuffer(): Buffer {
134
- return serializeToBuffer([
135
- this.masterNullifierPublicKey,
136
- this.masterIncomingViewingPublicKey,
137
- this.masterOutgoingViewingPublicKey,
138
- this.masterTaggingPublicKey,
139
- ]);
129
+ return serializeToBuffer([this.npkMHash, this.ivpkM, this.ovpkMHash, this.tpkMHash]);
140
130
  }
141
131
 
142
- /**
143
- * Creates an PublicKeys instance from a given buffer or BufferReader.
144
- * If the input is a Buffer, it wraps it in a BufferReader before processing.
145
- * Throws an error if the input length is not equal to the expected size.
146
- *
147
- * @param buffer - The input buffer or BufferReader containing the address data.
148
- * @returns - A new PublicKeys instance with the extracted address data.
149
- */
150
132
  static fromBuffer(buffer: Buffer | BufferReader): PublicKeys {
151
133
  const reader = BufferReader.asReader(buffer);
152
- const masterNullifierPublicKey = reader.readObject(Point);
153
- const masterIncomingViewingPublicKey = reader.readObject(Point);
154
- const masterOutgoingViewingPublicKey = reader.readObject(Point);
155
- const masterTaggingPublicKey = reader.readObject(Point);
156
- return new PublicKeys(
157
- masterNullifierPublicKey,
158
- masterIncomingViewingPublicKey,
159
- masterOutgoingViewingPublicKey,
160
- masterTaggingPublicKey,
161
- );
134
+ const npkMHash = Fr.fromBuffer(reader);
135
+ const ivpkM = reader.readObject(PublicKey);
136
+ const ovpkMHash = Fr.fromBuffer(reader);
137
+ const tpkMHash = Fr.fromBuffer(reader);
138
+ return new PublicKeys(npkMHash, ivpkM, ovpkMHash, tpkMHash);
162
139
  }
163
140
 
164
141
  toNoirStruct() {
165
- // We need to use lowercase identifiers as those are what the noir interface expects
166
-
142
+ // We need to use lowercase identifiers as those are what the noir interface expects.
143
+ /* eslint-disable camelcase */
167
144
  return {
168
- // TODO(#6337): Directly dump account.publicKeys here
169
- /* eslint-disable camelcase */
170
- npk_m: this.masterNullifierPublicKey.toWrappedNoirStruct(),
171
- ivpk_m: this.masterIncomingViewingPublicKey.toWrappedNoirStruct(),
172
- ovpk_m: this.masterOutgoingViewingPublicKey.toWrappedNoirStruct(),
173
- tpk_m: this.masterTaggingPublicKey.toWrappedNoirStruct(),
174
- /* eslint-enable camelcase */
145
+ npk_m_hash: this.npkMHash,
146
+ ivpk_m: this.ivpkM.toWrappedNoirStruct(),
147
+ ovpk_m_hash: this.ovpkMHash,
148
+ tpk_m_hash: this.tpkMHash,
175
149
  };
150
+ /* eslint-enable camelcase */
176
151
  }
177
152
 
178
153
  /**
179
- * Serializes the payload to an array of fields
180
- * @returns The fields of the payload
154
+ * Wire-format fields matching Noir's struct flattening of `PublicKeys`:
155
+ * `[npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash]` (5 fields).
181
156
  */
182
157
  toFields(): Fr[] {
183
- return [
184
- ...this.masterNullifierPublicKey.toFields(),
185
- ...this.masterIncomingViewingPublicKey.toFields(),
186
- ...this.masterOutgoingViewingPublicKey.toFields(),
187
- ...this.masterTaggingPublicKey.toFields(),
188
- ];
158
+ return [this.npkMHash, this.ivpkM.x, this.ivpkM.y, this.ovpkMHash, this.tpkMHash];
189
159
  }
190
160
 
191
- // TOOD: This is used in foundation/src/abi/encoder. This is probably non-optimal but I did not want
192
- // to spend too much time on the encoder now. It probably needs a refactor.
161
+ // Used in foundation/src/abi/encoder. Probably non-optimal but the encoder needs a refactor.
193
162
  encodeToNoir(): Fr[] {
194
163
  return this.toFields();
195
164
  }
196
165
 
197
166
  static fromFields(fields: Fr[] | FieldReader): PublicKeys {
198
167
  const reader = FieldReader.asReader(fields);
199
- return new PublicKeys(
200
- reader.readObject(Point),
201
- reader.readObject(Point),
202
- reader.readObject(Point),
203
- reader.readObject(Point),
204
- );
168
+ return new PublicKeys(reader.readField(), reader.readObject(PublicKey), reader.readField(), reader.readField());
205
169
  }
206
170
 
207
171
  toString() {
@@ -123,7 +123,7 @@ import {
123
123
  PublicCallRequest,
124
124
  PublicCallRequestArrayLengths,
125
125
  } from '../kernel/public_call_request.js';
126
- import { PublicKeys, computeAddress } from '../keys/index.js';
126
+ import { PublicKey, PublicKeys, computeAddress, hashPublicKey } from '../keys/index.js';
127
127
  import { ExtendedDirectionalAppTaggingSecret } from '../logs/extended_directional_app_tagging_secret.js';
128
128
  import { ContractClassLog, ContractClassLogFields } from '../logs/index.js';
129
129
  import { PrivateLog } from '../logs/private_log.js';
@@ -252,7 +252,7 @@ function makeScopedReadRequest(n: number): ScopedReadRequest {
252
252
  * @returns A KeyValidationRequest.
253
253
  */
254
254
  function makeKeyValidationRequests(seed: number): KeyValidationRequest {
255
- return new KeyValidationRequest(makePoint(seed), fr(seed + 2));
255
+ return new KeyValidationRequest(fr(seed), fr(seed + 2));
256
256
  }
257
257
 
258
258
  /**
@@ -577,7 +577,7 @@ export function makeVerificationKeyAsFields(size: number): VerificationKeyAsFiel
577
577
  * @returns A point.
578
578
  */
579
579
  export function makePoint(seed = 1): Point {
580
- return new Point(fr(seed), fr(seed + 1), false);
580
+ return new Point(fr(seed), fr(seed + 1));
581
581
  }
582
582
 
583
583
  /**
@@ -1220,8 +1220,13 @@ export async function makeMapAsync<T>(size: number, fn: (i: number) => Promise<[
1220
1220
 
1221
1221
  export async function makePublicKeys(seed = 0): Promise<PublicKeys> {
1222
1222
  const f = (offset: number) => Grumpkin.mul(Grumpkin.generator, new Fq(seed + offset));
1223
-
1224
- return new PublicKeys(await f(0), await f(1), await f(2), await f(3));
1223
+ const ivpkM = await f(1);
1224
+ return new PublicKeys(
1225
+ await hashPublicKey(await f(0)),
1226
+ ivpkM,
1227
+ await hashPublicKey(await f(2)),
1228
+ await hashPublicKey(await f(3)),
1229
+ );
1225
1230
  }
1226
1231
 
1227
1232
  export async function makeContractInstanceFromClassId(
@@ -1230,6 +1235,7 @@ export async function makeContractInstanceFromClassId(
1230
1235
  overrides?: {
1231
1236
  deployer?: AztecAddress;
1232
1237
  initializationHash?: Fr;
1238
+ immutablesHash?: Fr;
1233
1239
  publicKeys?: PublicKeys;
1234
1240
  currentClassId?: Fr;
1235
1241
  },
@@ -1238,21 +1244,24 @@ export async function makeContractInstanceFromClassId(
1238
1244
  const initializationHash = overrides?.initializationHash ?? new Fr(seed + 1);
1239
1245
  const deployer = overrides?.deployer ?? new AztecAddress(new Fr(seed + 2));
1240
1246
  const publicKeys = overrides?.publicKeys ?? (await makePublicKeys(seed + 3));
1247
+ const immutablesHash = overrides?.immutablesHash ?? new Fr(seed + 4);
1241
1248
 
1242
1249
  const partialAddress = await computePartialAddress({
1243
1250
  originalContractClassId: classId,
1244
1251
  salt,
1245
1252
  initializationHash,
1253
+ immutablesHash,
1246
1254
  deployer,
1247
1255
  });
1248
1256
  const address = await computeAddress(publicKeys, partialAddress);
1249
1257
  return new SerializableContractInstance({
1250
- version: 1,
1258
+ version: 2,
1251
1259
  salt,
1252
1260
  deployer,
1253
1261
  currentContractClassId: overrides?.currentClassId ?? classId,
1254
1262
  originalContractClassId: classId,
1255
1263
  initializationHash,
1264
+ immutablesHash,
1256
1265
  publicKeys,
1257
1266
  }).withAddress(address);
1258
1267
  }
@@ -1430,11 +1439,12 @@ export function makeAvmContractInstanceHint(seed = 0): AvmContractInstanceHint {
1430
1439
  new Fr(seed + 0x4),
1431
1440
  new Fr(seed + 0x5),
1432
1441
  new Fr(seed + 0x6),
1442
+ new Fr(seed + 0x7),
1433
1443
  new PublicKeys(
1434
- new Point(new Fr(seed + 0x7), new Fr(seed + 0x8), false),
1435
- new Point(new Fr(seed + 0x9), new Fr(seed + 0x10), false),
1436
- new Point(new Fr(seed + 0x11), new Fr(seed + 0x12), false),
1437
- new Point(new Fr(seed + 0x13), new Fr(seed + 0x14), false),
1444
+ new Fr(seed + 0x7),
1445
+ new PublicKey(new Fr(seed + 0x9), new Fr(seed + 0x10)),
1446
+ new Fr(seed + 0x11),
1447
+ new Fr(seed + 0x13),
1438
1448
  ),
1439
1449
  );
1440
1450
  }