@aztec/stdlib 5.0.0-nightly.20260629 → 5.0.0-nightly.20260701

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 (66) hide show
  1. package/dest/avm/avm.js +1 -1
  2. package/dest/aztec-address/index.d.ts +35 -5
  3. package/dest/aztec-address/index.d.ts.map +1 -1
  4. package/dest/aztec-address/index.js +32 -8
  5. package/dest/contract/interfaces/contract_data_source.d.ts +3 -5
  6. package/dest/contract/interfaces/contract_data_source.d.ts.map +1 -1
  7. package/dest/interfaces/archiver.js +1 -1
  8. package/dest/interfaces/aztec-node.d.ts +11 -3
  9. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  10. package/dest/interfaces/aztec-node.js +2 -1
  11. package/dest/kernel/hints/read_request.js +1 -1
  12. package/dest/kernel/log_hash.d.ts +1 -1
  13. package/dest/kernel/log_hash.d.ts.map +1 -1
  14. package/dest/kernel/log_hash.js +2 -2
  15. package/dest/kernel/note_hash.js +1 -1
  16. package/dest/kernel/nullifier.js +1 -1
  17. package/dest/kernel/private_log_data.d.ts +1 -1
  18. package/dest/kernel/private_log_data.d.ts.map +1 -1
  19. package/dest/kernel/private_log_data.js +1 -1
  20. package/dest/keys/derivation.d.ts +7 -1
  21. package/dest/keys/derivation.d.ts.map +1 -1
  22. package/dest/keys/derivation.js +24 -7
  23. package/dest/logs/app_tagging_secret.d.ts +21 -6
  24. package/dest/logs/app_tagging_secret.d.ts.map +1 -1
  25. package/dest/logs/app_tagging_secret.js +32 -22
  26. package/dest/logs/contract_class_log.d.ts +1 -2
  27. package/dest/logs/contract_class_log.d.ts.map +1 -1
  28. package/dest/logs/contract_class_log.js +0 -4
  29. package/dest/logs/message_context.d.ts +5 -15
  30. package/dest/logs/message_context.d.ts.map +1 -1
  31. package/dest/logs/message_context.js +1 -66
  32. package/dest/logs/pending_tagged_log.d.ts +6 -8
  33. package/dest/logs/pending_tagged_log.d.ts.map +1 -1
  34. package/dest/logs/pending_tagged_log.js +1 -31
  35. package/dest/tests/factories.js +2 -2
  36. package/dest/trees/nullifier_membership_witness.d.ts +5 -8
  37. package/dest/trees/nullifier_membership_witness.d.ts.map +1 -1
  38. package/dest/trees/nullifier_membership_witness.js +0 -9
  39. package/dest/trees/public_data_witness.d.ts +7 -17
  40. package/dest/trees/public_data_witness.d.ts.map +1 -1
  41. package/dest/trees/public_data_witness.js +0 -27
  42. package/dest/tx/execution_payload.d.ts +1 -1
  43. package/dest/tx/execution_payload.d.ts.map +1 -1
  44. package/dest/tx/execution_payload.js +1 -1
  45. package/dest/tx/global_variables.js +2 -2
  46. package/package.json +8 -8
  47. package/src/avm/avm.ts +1 -1
  48. package/src/aztec-address/index.ts +36 -6
  49. package/src/contract/interfaces/contract_data_source.ts +2 -4
  50. package/src/interfaces/archiver.ts +1 -1
  51. package/src/interfaces/aztec-node.ts +11 -3
  52. package/src/kernel/hints/read_request.ts +1 -1
  53. package/src/kernel/log_hash.ts +5 -2
  54. package/src/kernel/note_hash.ts +1 -1
  55. package/src/kernel/nullifier.ts +1 -1
  56. package/src/kernel/private_log_data.ts +4 -1
  57. package/src/keys/derivation.ts +21 -8
  58. package/src/logs/app_tagging_secret.ts +39 -23
  59. package/src/logs/contract_class_log.ts +0 -9
  60. package/src/logs/message_context.ts +7 -65
  61. package/src/logs/pending_tagged_log.ts +6 -33
  62. package/src/tests/factories.ts +2 -2
  63. package/src/trees/nullifier_membership_witness.ts +0 -11
  64. package/src/trees/public_data_witness.ts +0 -31
  65. package/src/tx/execution_payload.ts +2 -1
  66. package/src/tx/global_variables.ts +2 -2
@@ -43,34 +43,64 @@ export class AztecAddress {
43
43
  static ZERO = new AztecAddress(Buffer.alloc(32, 0));
44
44
 
45
45
  /** Null msg sender address. Not part of the protocol contracts tree. */
46
- static NULL_MSG_SENDER = AztecAddress.fromBigInt(NULL_MSG_SENDER_CONTRACT_ADDRESS);
46
+ static NULL_MSG_SENDER = AztecAddress.fromBigIntUnsafe(NULL_MSG_SENDER_CONTRACT_ADDRESS);
47
47
 
48
48
  static zero(): AztecAddress {
49
49
  return AztecAddress.ZERO;
50
50
  }
51
51
 
52
- static fromField(fr: Fr) {
52
+ /**
53
+ * Builds an `AztecAddress` from a field **without checking it is a valid address** (the x-coordinate of a point on
54
+ * the Grumpkin curve, which is what lets it be encrypted to). Use {@link AztecAddress.isValid} to validate an
55
+ * untrusted one, or {@link AztecAddress.random} for valid test addresses.
56
+ */
57
+ static fromFieldUnsafe(fr: Fr) {
53
58
  return new AztecAddress(fr);
54
59
  }
55
60
 
61
+ /**
62
+ * Deserializes an `AztecAddress` from a buffer. It does **not** check the value is a valid Grumpkin-curve address
63
+ * (see {@link AztecAddress.isValid}); it is meant for reading addresses from already-validated serialized data. Use
64
+ * {@link AztecAddress.random} for valid test addresses.
65
+ */
56
66
  static fromBuffer(buffer: Buffer | BufferReader) {
57
67
  return new AztecAddress(fromBuffer(buffer, Fr));
58
68
  }
59
69
 
70
+ /**
71
+ * Deserializes an `AztecAddress` from a field reader. It does **not** check the value is a valid Grumpkin-curve
72
+ * address (see {@link AztecAddress.isValid}); it is meant for reading addresses from already-validated serialized
73
+ * data. Use {@link AztecAddress.random} for valid test addresses.
74
+ */
60
75
  static fromFields(fields: Fr[] | FieldReader) {
61
76
  const reader = FieldReader.asReader(fields);
62
77
  return new AztecAddress(reader.readField());
63
78
  }
64
79
 
65
- static fromBigInt(value: bigint) {
80
+ /**
81
+ * Builds an `AztecAddress` from a bigint **without checking it is a valid address** (the x-coordinate of a point on
82
+ * the Grumpkin curve, which is what lets it be encrypted to). Use {@link AztecAddress.isValid} to validate an
83
+ * untrusted one, or {@link AztecAddress.random} for valid test addresses.
84
+ */
85
+ static fromBigIntUnsafe(value: bigint) {
66
86
  return new AztecAddress(new Fr(value));
67
87
  }
68
88
 
69
- static fromNumber(value: number) {
89
+ /**
90
+ * Builds an `AztecAddress` from a number **without checking it is a valid address** (the x-coordinate of a point on
91
+ * the Grumpkin curve, which is what lets it be encrypted to). Use {@link AztecAddress.isValid} to validate an
92
+ * untrusted one, or {@link AztecAddress.random} for valid test addresses.
93
+ */
94
+ static fromNumberUnsafe(value: number) {
70
95
  return new AztecAddress(new Fr(value));
71
96
  }
72
97
 
73
- static fromString(buf: string) {
98
+ /**
99
+ * Builds an `AztecAddress` from a hex string **without checking it is a valid address** (the x-coordinate of a
100
+ * point on the Grumpkin curve, which is what lets it be encrypted to). Use {@link AztecAddress.isValid} to
101
+ * validate an untrusted one, or {@link AztecAddress.random} for valid test addresses.
102
+ */
103
+ static fromStringUnsafe(buf: string) {
74
104
  return new AztecAddress(hexToBuffer(buf));
75
105
  }
76
106
 
@@ -89,7 +119,7 @@ export class AztecAddress {
89
119
  if (obj instanceof Buffer || Buffer.isBuffer(obj)) {
90
120
  return new AztecAddress(obj);
91
121
  }
92
- return AztecAddress.fromString(obj);
122
+ return AztecAddress.fromStringUnsafe(obj);
93
123
  }
94
124
 
95
125
  /**
@@ -25,11 +25,9 @@ export interface ContractDataSource {
25
25
  /**
26
26
  * Returns a publicly deployed contract instance given its address.
27
27
  * @param address - Address of the deployed contract.
28
- * @param timestamp - Timestamp at which to retrieve the contract instance. If not provided, the latest block should
29
- * be used.
30
- * TODO(#15170): Fix the implementations ignoring the timestamp param and make timestamp required.
28
+ * @param timestamp - Timestamp at which to resolve the contract instance's current class id.
31
29
  */
32
- getContract(address: AztecAddress, timestamp?: UInt64): Promise<ContractInstanceWithAddress | undefined>;
30
+ getContract(address: AztecAddress, timestamp: UInt64): Promise<ContractInstanceWithAddress | undefined>;
33
31
 
34
32
  /**
35
33
  * Returns the list of all class ids known.
@@ -122,7 +122,7 @@ export const ArchiverApiSchema: ApiSchemaFor<ArchiverApi> = {
122
122
  getContractClass: z.function({ input: z.tuple([schemas.Fr]), output: ContractClassPublicSchema.optional() }),
123
123
  getBytecodeCommitment: z.function({ input: z.tuple([schemas.Fr]), output: schemas.Fr }),
124
124
  getContract: z.function({
125
- input: z.tuple([schemas.AztecAddress, optional(schemas.BigInt)]),
125
+ input: z.tuple([schemas.AztecAddress, schemas.BigInt]),
126
126
  output: ContractInstanceWithAddressSchema.optional(),
127
127
  }),
128
128
  getContractClassIds: z.function({ input: z.tuple([]), output: z.array(schemas.Fr) }),
@@ -522,10 +522,18 @@ export interface AztecNode {
522
522
  getContractClass(id: Fr): Promise<ContractClassPublic | undefined>;
523
523
 
524
524
  /**
525
- * Returns a publicly deployed contract instance given its address.
525
+ * Returns a publicly deployed contract instance given its address. Its current class id is resolved as of the given
526
+ * reference block.
527
+ *
528
+ * Returns `undefined` if the instance has not been published (i.e. `publish_for_public_execution` was never called
529
+ * on the `ContractInstanceRegistry`). A contract whose class has been updated will never return `undefined`:
530
+ * scheduling an update requires the contract's deployment nullifier, which is only emitted by publishing, so any
531
+ * updatable contract has necessarily been published.
526
532
  * @param address - Address of the deployed contract.
533
+ * @param referenceBlock - The block parameter (block number, block hash, or 'latest') at which to get the data.
534
+ * Defaults to 'latest'.
527
535
  */
528
- getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined>;
536
+ getContract(address: AztecAddress, referenceBlock?: BlockParameter): Promise<ContractInstanceWithAddress | undefined>;
529
537
 
530
538
  /**
531
539
  * Returns the ENR of this node for peer discovery, if available.
@@ -758,7 +766,7 @@ export const AztecNodeApiSchema: ApiSchemaFor<AztecNode> = {
758
766
  getContractClass: z.function({ input: z.tuple([schemas.Fr]), output: ContractClassPublicSchema.optional() }),
759
767
 
760
768
  getContract: z.function({
761
- input: z.tuple([schemas.AztecAddress]),
769
+ input: z.tuple([schemas.AztecAddress, optional(BlockParameterSchema)]),
762
770
  output: ContractInstanceWithAddressSchema.optional(),
763
771
  }),
764
772
 
@@ -112,7 +112,7 @@ export class ScopedReadRequest {
112
112
 
113
113
  static fromFields(fields: Fr[] | FieldReader) {
114
114
  const reader = FieldReader.asReader(fields);
115
- return new ScopedReadRequest(reader.readObject(ReadRequest), AztecAddress.fromField(reader.readField()));
115
+ return new ScopedReadRequest(reader.readObject(ReadRequest), AztecAddress.fromFieldUnsafe(reader.readField()));
116
116
  }
117
117
 
118
118
  /**
@@ -114,7 +114,7 @@ export class ScopedLogHash {
114
114
 
115
115
  static fromFields(fields: Fr[] | FieldReader) {
116
116
  const reader = FieldReader.asReader(fields);
117
- return new ScopedLogHash(reader.readObject(LogHash), AztecAddress.fromField(reader.readField()));
117
+ return new ScopedLogHash(reader.readObject(LogHash), AztecAddress.fromFieldUnsafe(reader.readField()));
118
118
  }
119
119
 
120
120
  isEmpty() {
@@ -156,7 +156,10 @@ export class ScopedCountedLogHash {
156
156
 
157
157
  static fromFields(fields: Fr[] | FieldReader) {
158
158
  const reader = FieldReader.asReader(fields);
159
- return new ScopedCountedLogHash(reader.readObject(CountedLogHash), AztecAddress.fromField(reader.readField()));
159
+ return new ScopedCountedLogHash(
160
+ reader.readObject(CountedLogHash),
161
+ AztecAddress.fromFieldUnsafe(reader.readField()),
162
+ );
160
163
  }
161
164
 
162
165
  toBuffer(): Buffer;
@@ -65,7 +65,7 @@ export class ScopedNoteHash implements Ordered {
65
65
 
66
66
  static fromFields(fields: Fr[] | FieldReader) {
67
67
  const reader = FieldReader.asReader(fields);
68
- return new ScopedNoteHash(reader.readObject(NoteHash), AztecAddress.fromField(reader.readField()));
68
+ return new ScopedNoteHash(reader.readObject(NoteHash), AztecAddress.fromFieldUnsafe(reader.readField()));
69
69
  }
70
70
 
71
71
  isEmpty() {
@@ -70,7 +70,7 @@ export class ScopedNullifier implements Ordered {
70
70
 
71
71
  static fromFields(fields: Fr[] | FieldReader) {
72
72
  const reader = FieldReader.asReader(fields);
73
- return new ScopedNullifier(reader.readObject(Nullifier), AztecAddress.fromField(reader.readField()));
73
+ return new ScopedNullifier(reader.readObject(Nullifier), AztecAddress.fromFieldUnsafe(reader.readField()));
74
74
  }
75
75
 
76
76
  isEmpty() {
@@ -85,7 +85,10 @@ export class ScopedPrivateLogData {
85
85
 
86
86
  static fromFields(fields: Fr[] | FieldReader) {
87
87
  const reader = FieldReader.asReader(fields);
88
- return new ScopedPrivateLogData(reader.readObject(PrivateLogData), AztecAddress.fromField(reader.readField()));
88
+ return new ScopedPrivateLogData(
89
+ reader.readObject(PrivateLogData),
90
+ AztecAddress.fromFieldUnsafe(reader.readField()),
91
+ );
89
92
  }
90
93
 
91
94
  isEmpty() {
@@ -1,4 +1,4 @@
1
- import { DEFAULT_FBPK_M_HASH, DEFAULT_MSPK_M_HASH, DomainSeparator } from '@aztec/constants';
1
+ import { DomainSeparator } from '@aztec/constants';
2
2
  import { Grumpkin } from '@aztec/foundation/crypto/grumpkin';
3
3
  import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
4
4
  import { sha512ToGrumpkinScalar } from '@aztec/foundation/crypto/sha512';
@@ -39,6 +39,14 @@ export function deriveMasterOutgoingViewingSecretKey(secretKey: Fr): GrumpkinSca
39
39
  return sha512ToGrumpkinScalar([secretKey, DomainSeparator.OVSK_M]);
40
40
  }
41
41
 
42
+ export function deriveMasterMessageSigningSecretKey(secretKey: Fr): GrumpkinScalar {
43
+ return sha512ToGrumpkinScalar([secretKey, DomainSeparator.MSSK_M]);
44
+ }
45
+
46
+ export function deriveMasterFallbackSecretKey(secretKey: Fr): GrumpkinScalar {
47
+ return sha512ToGrumpkinScalar([secretKey, DomainSeparator.FBSK_M]);
48
+ }
49
+
42
50
  export function deriveSigningKey(secretKey: Fr): GrumpkinScalar {
43
51
  // TODO(#5837): come up with a standard signing key derivation scheme instead of using ivsk_m as signing keys here
44
52
  return sha512ToGrumpkinScalar([secretKey, DomainSeparator.IVSK_M]);
@@ -100,27 +108,28 @@ export async function deriveKeys(secretKey: Fr) {
100
108
  const masterIncomingViewingSecretKey = deriveMasterIncomingViewingSecretKey(secretKey);
101
109
  const masterOutgoingViewingSecretKey = deriveMasterOutgoingViewingSecretKey(secretKey);
102
110
  const masterTaggingSecretKey = sha512ToGrumpkinScalar([secretKey, DomainSeparator.TSK_M]);
111
+ const masterMessageSigningSecretKey = deriveMasterMessageSigningSecretKey(secretKey);
112
+ const masterFallbackSecretKey = deriveMasterFallbackSecretKey(secretKey);
103
113
 
104
114
  // Then we derive master public keys
105
115
  const masterNullifierPublicKey = await derivePublicKeyFromSecretKey(masterNullifierHidingKey);
106
116
  const masterIncomingViewingPublicKey = await derivePublicKeyFromSecretKey(masterIncomingViewingSecretKey);
107
117
  const masterOutgoingViewingPublicKey = await derivePublicKeyFromSecretKey(masterOutgoingViewingSecretKey);
108
118
  const masterTaggingPublicKey = await derivePublicKeyFromSecretKey(masterTaggingSecretKey);
119
+ const masterMessageSigningPublicKey = await derivePublicKeyFromSecretKey(masterMessageSigningSecretKey);
120
+ const masterFallbackPublicKey = await derivePublicKeyFromSecretKey(masterFallbackSecretKey);
109
121
 
110
122
  // The non-owner-visible PublicKeys carries hashes for npk/ovpk/tpk/mspk/fbpk and the raw
111
- // point only for ivpk_m. The npk/ovpk/tpk raw points are also returned alongside so the key
112
- // store can persist them under `${account}-{n|ov|t}pk_m` (only their hashes live in publicKeys).
123
+ // point only for ivpk_m. The npk/ovpk/tpk/mspk/fbpk raw points are also returned alongside so the key
124
+ // store can persist them under `${account}-{n|ov|t|ms|fb}pk_m` (only their hashes live in publicKeys).
113
125
  // The ivpk_m point isn't returned separately because it already lives in publicKeys.ivpkM.
114
- //
115
- // TODO: There isn't a derivation path for the message signing(msk) and fallback(fbk) keys yet. So we just use the the
116
- // default values for now.
117
126
  const publicKeys = new PublicKeys(
118
127
  await hashPublicKey(masterNullifierPublicKey),
119
128
  masterIncomingViewingPublicKey,
120
129
  await hashPublicKey(masterOutgoingViewingPublicKey),
121
130
  await hashPublicKey(masterTaggingPublicKey),
122
- new Fr(DEFAULT_MSPK_M_HASH),
123
- new Fr(DEFAULT_FBPK_M_HASH),
131
+ await hashPublicKey(masterMessageSigningPublicKey),
132
+ await hashPublicKey(masterFallbackPublicKey),
124
133
  );
125
134
 
126
135
  return {
@@ -128,9 +137,13 @@ export async function deriveKeys(secretKey: Fr) {
128
137
  masterIncomingViewingSecretKey,
129
138
  masterOutgoingViewingSecretKey,
130
139
  masterTaggingSecretKey,
140
+ masterMessageSigningSecretKey,
141
+ masterFallbackSecretKey,
131
142
  masterNullifierPublicKey,
132
143
  masterOutgoingViewingPublicKey,
133
144
  masterTaggingPublicKey,
145
+ masterMessageSigningPublicKey,
146
+ masterFallbackPublicKey,
134
147
  publicKeys,
135
148
  };
136
149
  }
@@ -30,16 +30,33 @@ export class AppTaggingSecret {
30
30
  ) {}
31
31
 
32
32
  /**
33
- * Derives shared tagging secret and from that, the app address and recipient derives the directional app tagging
34
- * secret. Returns undefined if `externalAddress` is an invalid address.
33
+ * Derives an app-siloed, recipient-directional tagging secret from a shared tagging secret point.
35
34
  *
36
- * @param localAddress - The complete address of entity A in the shared tagging secret derivation scheme
37
- * @param localIvsk - The incoming viewing secret key of entity A
38
- * @param externalAddress - The address of entity B in the shared tagging secret derivation scheme
35
+ * The point is obtained either via {@link computeSharedTaggingSecret} (an ECDH key exchange against a sender) or
36
+ * registered directly as a pre-shared secret. Each secret point yields a distinct tagging secret per (app, recipient)
37
+ * pair.
38
+ *
39
+ * @param taggingSecretPoint - The shared tagging secret point (ECDH output, or a directly registered pre-shared secret)
39
40
  * @param app - Contract address to silo the secret to
40
41
  * @param recipient - Recipient of the log. Defines the "direction of the secret".
41
42
  * @returns The secret that can be used along with an index to compute a tag to be included in a log.
42
43
  */
44
+ static async compute(
45
+ taggingSecretPoint: Point,
46
+ app: AztecAddress,
47
+ recipient: AztecAddress,
48
+ ): Promise<AppTaggingSecret> {
49
+ const appTaggingSecret = await poseidon2Hash([taggingSecretPoint.x, taggingSecretPoint.y, app]);
50
+ const directionalAppTaggingSecret = await poseidon2Hash([appTaggingSecret, recipient]);
51
+
52
+ return new AppTaggingSecret(directionalAppTaggingSecret, app);
53
+ }
54
+
55
+ /**
56
+ * Derives the unconstrained tagging secret for `(externalAddress, recipient, app)` by performing the ECDH key
57
+ * exchange against `externalAddress` and then siloing and directing the result. Returns undefined if
58
+ * `externalAddress` is not a valid address.
59
+ */
43
60
  static async computeUnconstrained(
44
61
  localAddress: CompleteAddress,
45
62
  localIvsk: Fq,
@@ -52,10 +69,7 @@ export class AppTaggingSecret {
52
69
  return undefined;
53
70
  }
54
71
 
55
- const appTaggingSecret = await poseidon2Hash([taggingSecretPoint.x, taggingSecretPoint.y, app]);
56
- const directionalAppTaggingSecret = await poseidon2Hash([appTaggingSecret, recipient]);
57
-
58
- return new AppTaggingSecret(directionalAppTaggingSecret, app);
72
+ return AppTaggingSecret.compute(taggingSecretPoint, app, recipient);
59
73
  }
60
74
 
61
75
  toString(): string {
@@ -71,13 +85,13 @@ export class AppTaggingSecret {
71
85
  if (parts.length === 2) {
72
86
  // TODO(F-680): Remove legacy two-part parsing after stored tagging keys are migrated.
73
87
  const [secretStr, appStr] = parts;
74
- return new AppTaggingSecret(Fr.fromString(secretStr), AztecAddress.fromString(appStr));
88
+ return new AppTaggingSecret(Fr.fromString(secretStr), AztecAddress.fromStringUnsafe(appStr));
75
89
  }
76
90
  if (parts.length === 3) {
77
91
  const [kindStr, secretStr, appStr] = parts;
78
92
  return new AppTaggingSecret(
79
93
  Fr.fromString(secretStr),
80
- AztecAddress.fromString(appStr),
94
+ AztecAddress.fromStringUnsafe(appStr),
81
95
  appTaggingSecretKindFromString(kindStr),
82
96
  );
83
97
  }
@@ -111,18 +125,17 @@ function appTaggingSecretKindFromString(kind: string): AppTaggingSecretKind {
111
125
  }
112
126
  }
113
127
 
114
- // Returns shared tagging secret computed with Diffie-Hellman key exchange, or undefined if `externalAddress` is an
115
- // invalid address.
116
- async function computeSharedTaggingSecret(
128
+ /**
129
+ * Computes the shared tagging secret point between a local address (i.e. one for which the privacy keys are known) and
130
+ * an external one via a Diffie-Hellman key exchange.
131
+ *
132
+ * Returns undefined if `externalAddress` is an invalid address.
133
+ */
134
+ export async function computeSharedTaggingSecret(
117
135
  localAddress: CompleteAddress,
118
136
  localIvsk: Fq,
119
137
  externalAddress: AztecAddress,
120
138
  ): Promise<Point | undefined> {
121
- // Given A (local complete address) -> B (external address) and h == preaddress
122
- // Compute shared secret as S = (h_A + local_ivsk_A) * Addr_Point_B
123
-
124
- const knownPreaddress = await computePreaddress(await localAddress.publicKeys.hash(), localAddress.partialAddress);
125
-
126
139
  // An invalid address has no corresponding address point
127
140
  if (!(await externalAddress.isValid())) {
128
141
  return undefined;
@@ -130,8 +143,11 @@ async function computeSharedTaggingSecret(
130
143
 
131
144
  const externalAddressPoint = await externalAddress.toAddressPoint();
132
145
 
133
- // Beware! h_a + local_ivsk_a (also known as the address secret) can lead to an address point with a negative
134
- // y-coordinate, since there's two possible candidates computeAddressSecret takes care of selecting the one that
135
- // leads to a positive y-coordinate, which is the only valid address point
136
- return Grumpkin.mul(externalAddressPoint, await computeAddressSecret(knownPreaddress, localIvsk));
146
+ const localPreaddress = await computePreaddress(await localAddress.publicKeys.hash(), localAddress.partialAddress);
147
+ const localAddressSecret = await computeAddressSecret(localPreaddress, localIvsk);
148
+
149
+ // For a given local address A and external address B, the shared tagging secret S is (h_A + ivsk_A) * Addr_Point_B
150
+ // (conceptually, in reality we don't use h_A + ivsk_A directly but rather the actual address secret, which is the
151
+ // same but with an optional sign adjustment to prevent A's address point from having a negative y-coordinate).
152
+ return Grumpkin.mul(externalAddressPoint, localAddressSecret);
137
153
  }
@@ -138,15 +138,6 @@ export class ContractClassLog {
138
138
  );
139
139
  }
140
140
 
141
- static fromFields(fields: Fr[] | FieldReader) {
142
- const reader = FieldReader.asReader(fields);
143
- return new ContractClassLog(
144
- reader.readObject(AztecAddress),
145
- reader.readObject(ContractClassLogFields),
146
- reader.readU32(),
147
- );
148
- }
149
-
150
141
  getEmittedFields() {
151
142
  return this.fields.getEmittedFields(this.emittedLength);
152
143
  }
@@ -1,8 +1,6 @@
1
- import { MAX_NOTE_HASHES_PER_TX } from '@aztec/constants';
2
- import { range } from '@aztec/foundation/array';
3
- import { Fr } from '@aztec/foundation/curves/bn254';
1
+ import type { Fr } from '@aztec/foundation/curves/bn254';
4
2
 
5
- import { TxHash } from '../tx/tx_hash.js';
3
+ import type { TxHash } from '../tx/tx_hash.js';
6
4
 
7
5
  /**
8
6
  * Additional information needed to process a message.
@@ -13,64 +11,8 @@ import { TxHash } from '../tx/tx_hash.js';
13
11
  *
14
12
  * A TS version of `message_context.nr`.
15
13
  */
16
- export class MessageContext {
17
- constructor(
18
- public txHash: TxHash,
19
- public uniqueNoteHashesInTx: Fr[],
20
- public firstNullifierInTx: Fr,
21
- ) {}
22
-
23
- toFields(): Fr[] {
24
- return [
25
- this.txHash.hash,
26
- ...serializeBoundedVec(this.uniqueNoteHashesInTx, MAX_NOTE_HASHES_PER_TX),
27
- this.firstNullifierInTx,
28
- ];
29
- }
30
-
31
- toNoirStruct() {
32
- /* eslint-disable camelcase */
33
- return {
34
- tx_hash: this.txHash.hash,
35
- unique_note_hashes_in_tx: this.uniqueNoteHashesInTx,
36
- first_nullifier_in_tx: this.firstNullifierInTx,
37
- };
38
- /* eslint-enable camelcase */
39
- }
40
-
41
- static empty(): MessageContext {
42
- return new MessageContext(TxHash.zero(), [], Fr.ZERO);
43
- }
44
-
45
- static toEmptyFields(): Fr[] {
46
- const serializationLen =
47
- 1 /* txHash */ + MAX_NOTE_HASHES_PER_TX + 1 /* uniqueNoteHashesInTx BVec */ + 1; /* firstNullifierInTx */
48
- return range(serializationLen).map(_ => Fr.zero());
49
- }
50
-
51
- static toSerializedOption(response: MessageContext | null): Fr[] {
52
- if (response) {
53
- return [new Fr(1), ...response.toFields()];
54
- } else {
55
- return [new Fr(0), ...MessageContext.toEmptyFields()];
56
- }
57
- }
58
- }
59
-
60
- /**
61
- * Helper function to serialize a bounded vector according to Noir's BoundedVec format
62
- * @param values - The values to serialize
63
- * @param maxLength - The maximum length of the bounded vector
64
- * @returns The serialized bounded vector as Fr[]
65
- * @dev Copied over from pending_tagged_log.ts.
66
- */
67
- function serializeBoundedVec(values: Fr[], maxLength: number): Fr[] {
68
- if (values.length > maxLength) {
69
- throw new Error(`Attempted to serialize ${values} values into a BoundedVec with max length ${maxLength}`);
70
- }
71
-
72
- const lengthDiff = maxLength - values.length;
73
- const zeroPaddingArray = Array(lengthDiff).fill(Fr.ZERO);
74
- const storage = values.concat(zeroPaddingArray);
75
- return [...storage, new Fr(values.length)];
76
- }
14
+ export type MessageContext = {
15
+ txHash: TxHash;
16
+ uniqueNoteHashesInTx: Fr[];
17
+ firstNullifierInTx: Fr;
18
+ };
@@ -1,39 +1,12 @@
1
- import { PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
2
- import { Fr } from '@aztec/foundation/curves/bn254';
1
+ import type { Fr } from '@aztec/foundation/curves/bn254';
3
2
 
4
- import type { TxHash } from '../tx/tx_hash.js';
5
- import { MessageContext } from './message_context.js';
3
+ import type { MessageContext } from './message_context.js';
6
4
 
7
5
  /**
8
6
  * Represents a pending tagged log as it is stored in the pending tagged log array to which the fetchTaggedLogs oracle
9
7
  * inserts found private logs. A TS version of `pending_tagged_log.nr`.
10
8
  */
11
- export class PendingTaggedLog {
12
- private context: MessageContext;
13
-
14
- constructor(
15
- public log: Fr[],
16
- txHash: TxHash,
17
- uniqueNoteHashesInTx: Fr[],
18
- firstNullifierInTx: Fr,
19
- ) {
20
- this.context = new MessageContext(txHash, uniqueNoteHashesInTx, firstNullifierInTx);
21
- }
22
-
23
- toFields(): Fr[] {
24
- return [...serializeBoundedVec(this.log, PRIVATE_LOG_SIZE_IN_FIELDS), ...this.context.toFields()];
25
- }
26
- }
27
-
28
- /**
29
- * Helper function to serialize a bounded vector according to Noir's BoundedVec format
30
- * @param values - The values to serialize
31
- * @param maxLength - The maximum length of the bounded vector
32
- * @returns The serialized bounded vector as Fr[]
33
- */
34
- function serializeBoundedVec(values: Fr[], maxLength: number): Fr[] {
35
- const lengthDiff = maxLength - values.length;
36
- const zeroPaddingArray = Array(lengthDiff).fill(Fr.ZERO);
37
- const storage = values.concat(zeroPaddingArray);
38
- return [...storage, new Fr(values.length)];
39
- }
9
+ export type PendingTaggedLog = {
10
+ log: Fr[];
11
+ context: MessageContext;
12
+ };
@@ -703,7 +703,7 @@ export function makeGlobalVariables(seed = 1, overrides: Partial<FieldsOf<Global
703
703
  slotNumber: SlotNumber(seed + 3),
704
704
  timestamp: BigInt(seed + 4),
705
705
  coinbase: EthAddress.fromField(new Fr(seed + 5)),
706
- feeRecipient: AztecAddress.fromField(new Fr(seed + 6)),
706
+ feeRecipient: AztecAddress.fromFieldUnsafe(new Fr(seed + 6)),
707
707
  gasFees: new GasFees(seed + 7, seed + 8),
708
708
  ...compact(overrides),
709
709
  });
@@ -753,7 +753,7 @@ export function makeBytes(size = 32, fill = 1): Buffer {
753
753
  * @returns An aztec address.
754
754
  */
755
755
  export function makeAztecAddress(seed = 1): AztecAddress {
756
- return AztecAddress.fromField(fr(seed));
756
+ return AztecAddress.fromFieldUnsafe(fr(seed));
757
757
  }
758
758
 
759
759
  function makeBlockConstantData(seed = 1, globalVariables?: GlobalVariables) {
@@ -1,5 +1,4 @@
1
1
  import { NULLIFIER_TREE_HEIGHT } from '@aztec/constants';
2
- import { Fr } from '@aztec/foundation/curves/bn254';
3
2
  import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees';
4
3
 
5
4
  import { z } from 'zod';
@@ -52,14 +51,4 @@ export class NullifierMembershipWitness {
52
51
  public withoutPreimage(): MembershipWitness<typeof NULLIFIER_TREE_HEIGHT> {
53
52
  return new MembershipWitness(NULLIFIER_TREE_HEIGHT, this.index, this.siblingPath.toTuple());
54
53
  }
55
-
56
- /** Serializes as `(NullifierLeafPreimage, MembershipWitness)` to match the Noir oracle return type. */
57
- public toNoirRepresentation(): (string | string[])[] {
58
- // TODO(#12874): remove the stupid as string conversion by modifying ForeignCallOutput type in acvm.js
59
- return [
60
- ...(this.leafPreimage.toFields().map(fr => fr.toString()) as string[]),
61
- new Fr(this.index).toString() as string,
62
- this.siblingPath.toFields().map(fr => fr.toString()) as string[],
63
- ];
64
- }
65
54
  }
@@ -1,6 +1,5 @@
1
1
  import { PUBLIC_DATA_TREE_HEIGHT } from '@aztec/constants';
2
2
  import { toBigIntBE } from '@aztec/foundation/bigint-buffer';
3
- import { Fr } from '@aztec/foundation/curves/bn254';
4
3
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
5
4
  import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
6
5
  import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees';
@@ -43,36 +42,6 @@ export class PublicDataWitness {
43
42
  .transform(({ index, leafPreimage, siblingPath }) => new PublicDataWitness(index, leafPreimage, siblingPath));
44
43
  }
45
44
 
46
- /**
47
- * Returns a field array representation of a public data witness.
48
- * @returns A field array representation of a public data witness.
49
- */
50
- public toFields(): Fr[] {
51
- return [
52
- new Fr(this.index),
53
- new Fr(this.leafPreimage.leaf.slot),
54
- new Fr(this.leafPreimage.leaf.value),
55
- new Fr(this.leafPreimage.nextIndex),
56
- new Fr(this.leafPreimage.nextKey),
57
- ...this.siblingPath.toFields(),
58
- ];
59
- }
60
-
61
- /**
62
- * Returns a representation of the public data witness as expected by intrinsic Noir deserialization.
63
- */
64
- public toNoirRepresentation(): (string | string[])[] {
65
- // TODO(#12874): remove the stupid as string conversion by modifying ForeignCallOutput type in acvm.js
66
- return [
67
- new Fr(this.index).toString() as string,
68
- new Fr(this.leafPreimage.leaf.slot).toString() as string,
69
- new Fr(this.leafPreimage.leaf.value).toString() as string,
70
- new Fr(this.leafPreimage.nextKey).toString() as string,
71
- new Fr(this.leafPreimage.nextIndex).toString() as string,
72
- this.siblingPath.toFields().map(fr => fr.toString()) as string[],
73
- ];
74
- }
75
-
76
45
  toBuffer(): Buffer {
77
46
  return serializeToBuffer([this.index, this.leafPreimage, this.siblingPath]);
78
47
  }
@@ -54,7 +54,8 @@ export function mergeExecutionPayloads(requests: ExecutionPayload[]): ExecutionP
54
54
  );
55
55
  }
56
56
 
57
- const feePayer = uniqueFeePayers.size === 1 ? AztecAddress.fromString(Array.from(uniqueFeePayers)[0]) : undefined;
57
+ const feePayer =
58
+ uniqueFeePayers.size === 1 ? AztecAddress.fromStringUnsafe(Array.from(uniqueFeePayers)[0]) : undefined;
58
59
 
59
60
  return new ExecutionPayload(calls, combinedAuthWitnesses, combinedCapsules, combinedExtraHashedArgs, feePayer);
60
61
  }
@@ -125,7 +125,7 @@ export class GlobalVariables {
125
125
  SlotNumber(reader.readU32()),
126
126
  reader.readField().toBigInt(),
127
127
  EthAddress.fromField(reader.readField()),
128
- AztecAddress.fromField(reader.readField()),
128
+ AztecAddress.fromFieldUnsafe(reader.readField()),
129
129
  GasFees.fromFields(reader),
130
130
  );
131
131
  }
@@ -220,7 +220,7 @@ export class GlobalVariables {
220
220
  blockNumber: BlockNumber(randomInt(100_000)),
221
221
  slotNumber: SlotNumber(randomInt(100_000)),
222
222
  coinbase: EthAddress.random(),
223
- feeRecipient: AztecAddress.fromField(Fr.random()),
223
+ feeRecipient: AztecAddress.fromFieldUnsafe(Fr.random()),
224
224
  gasFees: GasFees.random(),
225
225
  timestamp: BigInt(randomInt(100_000_000)),
226
226
  ...overrides,