@aztec/pxe 0.35.1 → 0.37.0

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 (55) hide show
  1. package/dest/contract_data_oracle/index.d.ts +0 -10
  2. package/dest/contract_data_oracle/index.d.ts.map +1 -1
  3. package/dest/contract_data_oracle/index.js +1 -14
  4. package/dest/database/kv_pxe_database.js +2 -2
  5. package/dest/kernel_oracle/index.d.ts +0 -1
  6. package/dest/kernel_oracle/index.d.ts.map +1 -1
  7. package/dest/kernel_oracle/index.js +2 -2
  8. package/dest/kernel_prover/kernel_prover.d.ts +0 -1
  9. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  10. package/dest/kernel_prover/kernel_prover.js +13 -16
  11. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_inner_hints.d.ts +3 -0
  12. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_inner_hints.d.ts.map +1 -0
  13. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_inner_hints.js +6 -0
  14. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.d.ts +4 -0
  15. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.d.ts.map +1 -0
  16. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.js +85 -0
  17. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.d.ts +4 -0
  18. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.d.ts.map +1 -0
  19. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.js +10 -0
  20. package/dest/kernel_prover/private_inputs_builders/index.d.ts +4 -0
  21. package/dest/kernel_prover/private_inputs_builders/index.d.ts.map +1 -0
  22. package/dest/kernel_prover/private_inputs_builders/index.js +4 -0
  23. package/dest/note_processor/note_processor.d.ts +2 -2
  24. package/dest/note_processor/note_processor.d.ts.map +1 -1
  25. package/dest/note_processor/note_processor.js +12 -14
  26. package/dest/pxe_service/create_pxe_service.js +4 -3
  27. package/dest/pxe_service/pxe_service.d.ts +6 -4
  28. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  29. package/dest/pxe_service/pxe_service.js +89 -31
  30. package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
  31. package/dest/pxe_service/test/pxe_test_suite.js +11 -14
  32. package/dest/simulator_oracle/index.d.ts +5 -4
  33. package/dest/simulator_oracle/index.d.ts.map +1 -1
  34. package/dest/simulator_oracle/index.js +18 -9
  35. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  36. package/dest/synchronizer/synchronizer.js +9 -9
  37. package/package.json +20 -12
  38. package/src/contract_data_oracle/index.ts +0 -14
  39. package/src/database/kv_pxe_database.ts +1 -1
  40. package/src/kernel_oracle/index.ts +1 -1
  41. package/src/kernel_prover/kernel_prover.ts +26 -56
  42. package/src/kernel_prover/private_inputs_builders/build_private_kernel_inner_hints.ts +17 -0
  43. package/src/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.ts +194 -0
  44. package/src/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.ts +30 -0
  45. package/src/kernel_prover/private_inputs_builders/index.ts +3 -0
  46. package/src/note_processor/note_processor.ts +12 -12
  47. package/src/pxe_service/create_pxe_service.ts +2 -2
  48. package/src/pxe_service/pxe_service.ts +118 -31
  49. package/src/pxe_service/test/pxe_test_suite.ts +9 -14
  50. package/src/simulator_oracle/index.ts +22 -11
  51. package/src/synchronizer/synchronizer.ts +18 -13
  52. package/dest/kernel_prover/hints_builder.d.ts +0 -40
  53. package/dest/kernel_prover/hints_builder.d.ts.map +0 -1
  54. package/dest/kernel_prover/hints_builder.js +0 -103
  55. package/src/kernel_prover/hints_builder.ts +0 -155
@@ -10,14 +10,11 @@ import {
10
10
  CompleteAddress,
11
11
  Fr,
12
12
  FunctionData,
13
- GasSettings,
14
13
  INITIAL_L2_BLOCK_NUM,
15
14
  Point,
16
15
  TxContext,
17
16
  getContractClassFromArtifact,
18
17
  } from '@aztec/circuits.js';
19
- import { Grumpkin } from '@aztec/circuits.js/barretenberg';
20
- import { ConstantKeyPair } from '@aztec/key-store';
21
18
 
22
19
  export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) => {
23
20
  describe(testName, () => {
@@ -28,10 +25,9 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
28
25
  }, 120_000);
29
26
 
30
27
  it('registers an account and returns it as an account only and not as a recipient', async () => {
31
- const keyPair = ConstantKeyPair.random(new Grumpkin());
32
- const completeAddress = CompleteAddress.fromPrivateKeyAndPartialAddress(keyPair.getPrivateKey(), Fr.random());
33
-
34
- await pxe.registerAccount(keyPair.getPrivateKey(), completeAddress.partialAddress);
28
+ const randomSecretKey = Fr.random();
29
+ const randomPartialAddress = Fr.random();
30
+ const completeAddress = await pxe.registerAccount(randomSecretKey, randomPartialAddress);
35
31
 
36
32
  // Check that the account is correctly registered using the getAccounts and getRecipients methods
37
33
  const accounts = await pxe.getRegisteredAccounts();
@@ -65,11 +61,11 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
65
61
  });
66
62
 
67
63
  it('does not throw when registering the same account twice (just ignores the second attempt)', async () => {
68
- const keyPair = ConstantKeyPair.random(new Grumpkin());
69
- const completeAddress = CompleteAddress.fromPrivateKeyAndPartialAddress(keyPair.getPrivateKey(), Fr.random());
64
+ const randomSecretKey = Fr.random();
65
+ const randomPartialAddress = Fr.random();
70
66
 
71
- await pxe.registerAccount(keyPair.getPrivateKey(), completeAddress.partialAddress);
72
- await pxe.registerAccount(keyPair.getPrivateKey(), completeAddress.partialAddress);
67
+ await pxe.registerAccount(randomSecretKey, randomPartialAddress);
68
+ await pxe.registerAccount(randomSecretKey, randomPartialAddress);
73
69
  });
74
70
 
75
71
  it('cannot register a recipient with the same aztec address but different pub key or partial address', async () => {
@@ -129,12 +125,11 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
129
125
  functionData.isPrivate = false;
130
126
  const txExecutionRequest = TxExecutionRequest.from({
131
127
  origin: AztecAddress.random(),
132
- argsHash: new Fr(0),
128
+ firstCallArgsHash: new Fr(0),
133
129
  functionData,
134
130
  txContext: TxContext.empty(),
135
- packedArguments: [],
131
+ argsOfCalls: [],
136
132
  authWitnesses: [],
137
- gasSettings: GasSettings.default(),
138
133
  });
139
134
 
140
135
  await expect(async () => await pxe.proveTx(txExecutionRequest, false)).rejects.toThrow(
@@ -11,16 +11,16 @@ import {
11
11
  import {
12
12
  type AztecAddress,
13
13
  type CompleteAddress,
14
- type EthAddress,
15
14
  type Fr,
16
15
  type FunctionSelector,
17
16
  type Header,
18
17
  type L1_TO_L2_MSG_TREE_HEIGHT,
18
+ type Point,
19
19
  } from '@aztec/circuits.js';
20
20
  import { computeL1ToL2MessageNullifier } from '@aztec/circuits.js/hash';
21
21
  import { type FunctionArtifactWithDebugMetadata, getFunctionArtifactWithDebugMetadata } from '@aztec/foundation/abi';
22
22
  import { createDebugLogger } from '@aztec/foundation/log';
23
- import { type DBOracle, type KeyPair, MessageLoadOracleInputs } from '@aztec/simulator';
23
+ import { type DBOracle, MessageLoadOracleInputs, type NullifierKeys } from '@aztec/simulator';
24
24
  import { type ContractInstance } from '@aztec/types/contracts';
25
25
 
26
26
  import { type ContractDataOracle } from '../contract_data_oracle/index.js';
@@ -38,13 +38,13 @@ export class SimulatorOracle implements DBOracle {
38
38
  private log = createDebugLogger('aztec:pxe:simulator_oracle'),
39
39
  ) {}
40
40
 
41
- async getNullifierKeyPair(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise<KeyPair> {
42
- const accountPublicKey = (await this.db.getCompleteAddress(accountAddress))!.publicKey;
43
- const publicKey = await this.keyStore.getNullifierPublicKey(accountPublicKey);
44
- const secretKey = await this.keyStore.getSiloedNullifierSecretKey(accountPublicKey, contractAddress);
45
- return { publicKey, secretKey };
41
+ async getNullifierKeys(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise<NullifierKeys> {
42
+ const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(accountAddress);
43
+ const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(accountAddress, contractAddress);
44
+ return { masterNullifierPublicKey, appNullifierSecretKey };
46
45
  }
47
46
 
47
+ // TODO: #5834
48
48
  async getCompleteAddress(address: AztecAddress): Promise<CompleteAddress> {
49
49
  const completeAddress = await this.db.getCompleteAddress(address);
50
50
  if (!completeAddress) {
@@ -79,6 +79,16 @@ export class SimulatorOracle implements DBOracle {
79
79
  return capsule;
80
80
  }
81
81
 
82
+ // TODO: #5834
83
+ async getPublicKeysForAddress(address: AztecAddress): Promise<Point[]> {
84
+ const nullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(address);
85
+ const incomingViewingPublicKey = await this.keyStore.getMasterIncomingViewingPublicKey(address);
86
+ const outgoingViewingPublicKey = await this.keyStore.getMasterOutgoingViewingPublicKey(address);
87
+ const taggingPublicKey = await this.keyStore.getMasterTaggingPublicKey(address);
88
+
89
+ return [nullifierPublicKey, incomingViewingPublicKey, outgoingViewingPublicKey, taggingPublicKey];
90
+ }
91
+
82
92
  async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus) {
83
93
  const noteDaos = await this.db.getNotes({
84
94
  contractAddress,
@@ -118,10 +128,6 @@ export class SimulatorOracle implements DBOracle {
118
128
  return artifact && getFunctionArtifactWithDebugMetadata(artifact, functionName);
119
129
  }
120
130
 
121
- async getPortalContractAddress(contractAddress: AztecAddress): Promise<EthAddress> {
122
- return await this.contractDataOracle.getPortalContractAddress(contractAddress);
123
- }
124
-
125
131
  /**
126
132
  * Fetches a message from the db, given its key.
127
133
  * @param contractAddress - Address of a contract by which the message was emitted.
@@ -159,6 +165,11 @@ export class SimulatorOracle implements DBOracle {
159
165
  return new MessageLoadOracleInputs(messageIndex, siblingPath);
160
166
  }
161
167
 
168
+ // Only used in public.
169
+ public getL1ToL2LeafValue(_leafIndex: bigint): Promise<Fr | undefined> {
170
+ throw new Error('Unimplemented in private!');
171
+ }
172
+
162
173
  /**
163
174
  * Gets the index of a commitment in the note hash tree.
164
175
  * @param commitment - The commitment.
@@ -198,7 +198,7 @@ export class Synchronizer {
198
198
  }
199
199
 
200
200
  this.log.debug(
201
- `Catching up note processor ${noteProcessor.publicKey.toString()} by processing ${
201
+ `Catching up note processor ${noteProcessor.masterIncomingViewingPublicKey.toString()} by processing ${
202
202
  blocks.length - index
203
203
  } blocks`,
204
204
  );
@@ -206,16 +206,19 @@ export class Synchronizer {
206
206
 
207
207
  if (noteProcessor.status.syncedToBlock === toBlockNumber) {
208
208
  // Note processor caught up, move it to `noteProcessors` from `noteProcessorsToCatchUp`.
209
- this.log.debug(`Note processor for ${noteProcessor.publicKey.toString()} has caught up`, {
210
- eventName: 'note-processor-caught-up',
211
- publicKey: noteProcessor.publicKey.toString(),
212
- duration: noteProcessor.timer.ms(),
213
- dbSize: this.db.estimateSize(),
214
- ...noteProcessor.stats,
215
- } satisfies NoteProcessorCaughtUpStats);
209
+ this.log.debug(
210
+ `Note processor for ${noteProcessor.masterIncomingViewingPublicKey.toString()} has caught up`,
211
+ {
212
+ eventName: 'note-processor-caught-up',
213
+ publicKey: noteProcessor.masterIncomingViewingPublicKey.toString(),
214
+ duration: noteProcessor.timer.ms(),
215
+ dbSize: this.db.estimateSize(),
216
+ ...noteProcessor.stats,
217
+ } satisfies NoteProcessorCaughtUpStats,
218
+ );
216
219
 
217
220
  this.noteProcessorsToCatchUp = this.noteProcessorsToCatchUp.filter(
218
- np => !np.publicKey.equals(noteProcessor.publicKey),
221
+ np => !np.masterIncomingViewingPublicKey.equals(noteProcessor.masterIncomingViewingPublicKey),
219
222
  );
220
223
  this.noteProcessors.push(noteProcessor);
221
224
  }
@@ -260,7 +263,7 @@ export class Synchronizer {
260
263
  * @returns A promise that resolves once the account is added to the Synchronizer.
261
264
  */
262
265
  public addAccount(publicKey: PublicKey, keyStore: KeyStore, startingBlock: number) {
263
- const predicate = (x: NoteProcessor) => x.publicKey.equals(publicKey);
266
+ const predicate = (x: NoteProcessor) => x.masterIncomingViewingPublicKey.equals(publicKey);
264
267
  const processor = this.noteProcessors.find(predicate) ?? this.noteProcessorsToCatchUp.find(predicate);
265
268
  if (processor) {
266
269
  return;
@@ -282,7 +285,7 @@ export class Synchronizer {
282
285
  if (!completeAddress) {
283
286
  throw new Error(`Checking if account is synched is not possible for ${account} because it is not registered.`);
284
287
  }
285
- const findByPublicKey = (x: NoteProcessor) => x.publicKey.equals(completeAddress.publicKey);
288
+ const findByPublicKey = (x: NoteProcessor) => x.masterIncomingViewingPublicKey.equals(completeAddress.publicKey);
286
289
  const processor = this.noteProcessors.find(findByPublicKey) ?? this.noteProcessorsToCatchUp.find(findByPublicKey);
287
290
  if (!processor) {
288
291
  throw new Error(
@@ -315,7 +318,9 @@ export class Synchronizer {
315
318
  const lastBlockNumber = this.getSynchedBlockNumber();
316
319
  return {
317
320
  blocks: lastBlockNumber,
318
- notes: Object.fromEntries(this.noteProcessors.map(n => [n.publicKey.toString(), n.status.syncedToBlock])),
321
+ notes: Object.fromEntries(
322
+ this.noteProcessors.map(n => [n.masterIncomingViewingPublicKey.toString(), n.status.syncedToBlock]),
323
+ ),
319
324
  };
320
325
  }
321
326
 
@@ -345,7 +350,7 @@ export class Synchronizer {
345
350
  // to be safe, try each note processor in case the deferred notes are for different accounts.
346
351
  for (const processor of this.noteProcessors) {
347
352
  const decodedNotes = await processor.decodeDeferredNotes(
348
- deferredNotes.filter(n => n.publicKey.equals(processor.publicKey)),
353
+ deferredNotes.filter(n => n.publicKey.equals(processor.masterIncomingViewingPublicKey)),
349
354
  );
350
355
  newNotes.push(...decodedNotes);
351
356
  }
@@ -1,40 +0,0 @@
1
- import { Fr, type MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, type MAX_NULLIFIER_READ_REQUESTS_PER_TX, MembershipWitness, type NullifierKeyValidationRequestContext, type ReadRequestContext, type SideEffect, type SideEffectLinkedToNoteHash, type SideEffectType } from '@aztec/circuits.js';
2
- import { type Tuple } from '@aztec/foundation/serialize';
3
- import { type ProvingDataOracle } from './proving_data_oracle.js';
4
- export declare class HintsBuilder {
5
- private oracle;
6
- constructor(oracle: ProvingDataOracle);
7
- sortSideEffects<T extends SideEffectType, K extends number>(sideEffects: Tuple<T, K>): [Tuple<T, K>, Tuple<number, K>];
8
- /**
9
- * Performs the matching between an array of read request and an array of note hashes. This produces
10
- * hints for the private kernel tail circuit to efficiently match a read request with the corresponding
11
- * note hash. Several read requests might be pointing to the same note hash. It is therefore valid
12
- * to return more than one hint with the same index (contrary to getNullifierHints).
13
- *
14
- * @param noteHashReadRequests - The array of read requests.
15
- * @param noteHashes - The array of note hashes.
16
- * @returns An array of hints where each element is the index of the note hash in note hashes array
17
- * corresponding to the read request. In other words we have readRequests[i] == noteHashes[hints[i]].
18
- */
19
- getNoteHashReadRequestHints(noteHashReadRequests: Tuple<SideEffect, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>, noteHashes: Tuple<SideEffect, typeof MAX_NEW_NOTE_HASHES_PER_TX>): Tuple<Fr, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>;
20
- getNullifierReadRequestHints(nullifierReadRequests: Tuple<ReadRequestContext, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>, nullifiers: Tuple<SideEffectLinkedToNoteHash, typeof MAX_NEW_NULLIFIERS_PER_TX>): Promise<import("@aztec/circuits.js").NullifierReadRequestHints>;
21
- getNullifierMembershipWitness(nullifier: Fr): Promise<{
22
- membershipWitness: MembershipWitness<20>;
23
- leafPreimage: import("@aztec/circuits.js").NullifierLeafPreimage;
24
- } | undefined>;
25
- /**
26
- * Performs the matching between an array of nullified note hashes and an array of note hashes. This produces
27
- * hints for the private kernel tail circuit to efficiently match a nullifier with the corresponding
28
- * note hash. Note that the same note hash value might appear more than once in the note hashes
29
- * (resp. nullified note hashes) array. It is crucial in this case that each hint points to a different index
30
- * of the nullified note hashes array. Otherwise, the private kernel will fail to validate.
31
- *
32
- * @param nullifiedNoteHashes - The array of nullified note hashes.
33
- * @param noteHashes - The array of note hashes.
34
- * @returns An array of hints where each element is the index of the note hash in note hashes array
35
- * corresponding to the nullified note hash. In other words we have nullifiedNoteHashes[i] == noteHashes[hints[i]].
36
- */
37
- getNullifierHints(nullifiedNoteHashes: Tuple<Fr, typeof MAX_NEW_NULLIFIERS_PER_TX>, noteHashes: Tuple<SideEffect, typeof MAX_NEW_NOTE_HASHES_PER_TX>): Tuple<Fr, typeof MAX_NEW_NULLIFIERS_PER_TX>;
38
- getMasterNullifierSecretKeys(nullifierKeyValidationRequests: Tuple<NullifierKeyValidationRequestContext, typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX>): Promise<[import("@aztec/circuits.js").Fq, import("@aztec/circuits.js").Fq, import("@aztec/circuits.js").Fq, import("@aztec/circuits.js").Fq]>;
39
- }
40
- //# sourceMappingURL=hints_builder.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hints_builder.d.ts","sourceRoot":"","sources":["../../src/kernel_prover/hints_builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,EAAE,EAEF,KAAK,0BAA0B,EAC/B,yBAAyB,EACzB,kCAAkC,EAClC,4CAA4C,EAC5C,KAAK,kCAAkC,EACvC,iBAAiB,EAEjB,KAAK,oCAAoC,EACzC,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,0BAA0B,EAC/B,KAAK,cAAc,EAEpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEzD,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,qBAAa,YAAY;IACX,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,iBAAiB;IAE7C,eAAe,CAAC,CAAC,SAAS,cAAc,EAAE,CAAC,SAAS,MAAM,EACxD,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GACvB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAmBlC;;;;;;;;;;OAUG;IACH,2BAA2B,CACzB,oBAAoB,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,kCAAkC,CAAC,EAClF,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,0BAA0B,CAAC,GAC/D,KAAK,CAAC,EAAE,EAAE,OAAO,kCAAkC,CAAC;IAgBvD,4BAA4B,CAC1B,qBAAqB,EAAE,KAAK,CAAC,kBAAkB,EAAE,OAAO,kCAAkC,CAAC,EAC3F,UAAU,EAAE,KAAK,CAAC,0BAA0B,EAAE,OAAO,yBAAyB,CAAC;IAK3E,6BAA6B,CAAC,SAAS,EAAE,EAAE;;;;IAiBjD;;;;;;;;;;;OAWG;IACH,iBAAiB,CACf,mBAAmB,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,yBAAyB,CAAC,EAChE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,0BAA0B,CAAC,GAC/D,KAAK,CAAC,EAAE,EAAE,OAAO,yBAAyB,CAAC;IAuBxC,4BAA4B,CAChC,8BAA8B,EAAE,KAAK,CACnC,oCAAoC,EACpC,OAAO,4CAA4C,CACpD;CAYJ"}
@@ -1,103 +0,0 @@
1
- import { Fr, GrumpkinScalar, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MembershipWitness, NULLIFIER_TREE_HEIGHT, buildNullifierReadRequestHints, } from '@aztec/circuits.js';
2
- import { makeTuple } from '@aztec/foundation/array';
3
- export class HintsBuilder {
4
- constructor(oracle) {
5
- this.oracle = oracle;
6
- }
7
- sortSideEffects(sideEffects) {
8
- const sorted = sideEffects
9
- .map((sideEffect, index) => ({ sideEffect, index }))
10
- .sort((a, b) => {
11
- // Empty ones go to the right
12
- if (a.sideEffect.isEmpty()) {
13
- return 1;
14
- }
15
- return Number(a.sideEffect.counter.toBigInt() - b.sideEffect.counter.toBigInt());
16
- });
17
- const originalToSorted = sorted.map(() => 0);
18
- sorted.forEach(({ index }, i) => {
19
- originalToSorted[index] = i;
20
- });
21
- return [sorted.map(({ sideEffect }) => sideEffect), originalToSorted];
22
- }
23
- /**
24
- * Performs the matching between an array of read request and an array of note hashes. This produces
25
- * hints for the private kernel tail circuit to efficiently match a read request with the corresponding
26
- * note hash. Several read requests might be pointing to the same note hash. It is therefore valid
27
- * to return more than one hint with the same index (contrary to getNullifierHints).
28
- *
29
- * @param noteHashReadRequests - The array of read requests.
30
- * @param noteHashes - The array of note hashes.
31
- * @returns An array of hints where each element is the index of the note hash in note hashes array
32
- * corresponding to the read request. In other words we have readRequests[i] == noteHashes[hints[i]].
33
- */
34
- getNoteHashReadRequestHints(noteHashReadRequests, noteHashes) {
35
- const hints = makeTuple(MAX_NOTE_HASH_READ_REQUESTS_PER_TX, Fr.zero);
36
- for (let i = 0; i < MAX_NOTE_HASH_READ_REQUESTS_PER_TX && !noteHashReadRequests[i].isEmpty(); i++) {
37
- const equalToRR = (cmt) => cmt.value.equals(noteHashReadRequests[i].value);
38
- const result = noteHashes.findIndex(equalToRR);
39
- if (result == -1) {
40
- throw new Error(`The read request at index ${i} ${noteHashReadRequests[i].toString()} does not match to any note hash.`);
41
- }
42
- else {
43
- hints[i] = new Fr(result);
44
- }
45
- }
46
- return hints;
47
- }
48
- getNullifierReadRequestHints(nullifierReadRequests, nullifiers) {
49
- return buildNullifierReadRequestHints(this, nullifierReadRequests, nullifiers);
50
- }
51
- async getNullifierMembershipWitness(nullifier) {
52
- const res = await this.oracle.getNullifierMembershipWitness(nullifier);
53
- if (!res) {
54
- return;
55
- }
56
- const { index, siblingPath, leafPreimage } = res;
57
- return {
58
- membershipWitness: new MembershipWitness(NULLIFIER_TREE_HEIGHT, index, siblingPath.toTuple()),
59
- leafPreimage,
60
- };
61
- }
62
- /**
63
- * Performs the matching between an array of nullified note hashes and an array of note hashes. This produces
64
- * hints for the private kernel tail circuit to efficiently match a nullifier with the corresponding
65
- * note hash. Note that the same note hash value might appear more than once in the note hashes
66
- * (resp. nullified note hashes) array. It is crucial in this case that each hint points to a different index
67
- * of the nullified note hashes array. Otherwise, the private kernel will fail to validate.
68
- *
69
- * @param nullifiedNoteHashes - The array of nullified note hashes.
70
- * @param noteHashes - The array of note hashes.
71
- * @returns An array of hints where each element is the index of the note hash in note hashes array
72
- * corresponding to the nullified note hash. In other words we have nullifiedNoteHashes[i] == noteHashes[hints[i]].
73
- */
74
- getNullifierHints(nullifiedNoteHashes, noteHashes) {
75
- const hints = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.zero);
76
- const alreadyUsed = new Set();
77
- for (let i = 0; i < MAX_NEW_NULLIFIERS_PER_TX; i++) {
78
- if (!nullifiedNoteHashes[i].isZero()) {
79
- const result = noteHashes.findIndex((cmt, index) => cmt.value.equals(nullifiedNoteHashes[i]) && !alreadyUsed.has(index));
80
- alreadyUsed.add(result);
81
- if (result == -1) {
82
- throw new Error(`The nullified note hash at index ${i} with value ${nullifiedNoteHashes[i].toString()} does not match to any note hash.`);
83
- }
84
- else {
85
- hints[i] = new Fr(result);
86
- }
87
- }
88
- }
89
- return hints;
90
- }
91
- async getMasterNullifierSecretKeys(nullifierKeyValidationRequests) {
92
- const keys = makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, GrumpkinScalar.zero);
93
- for (let i = 0; i < nullifierKeyValidationRequests.length; ++i) {
94
- const request = nullifierKeyValidationRequests[i];
95
- if (request.isEmpty()) {
96
- break;
97
- }
98
- keys[i] = await this.oracle.getMasterNullifierSecretKey(request.publicKey);
99
- }
100
- return keys;
101
- }
102
- }
103
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGludHNfYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9rZXJuZWxfcHJvdmVyL2hpbnRzX2J1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLEVBQUUsRUFDRixjQUFjLEVBRWQseUJBQXlCLEVBQ3pCLGtDQUFrQyxFQUNsQyw0Q0FBNEMsRUFFNUMsaUJBQWlCLEVBQ2pCLHFCQUFxQixFQU1yQiw4QkFBOEIsR0FDL0IsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFLcEQsTUFBTSxPQUFPLFlBQVk7SUFDdkIsWUFBb0IsTUFBeUI7UUFBekIsV0FBTSxHQUFOLE1BQU0sQ0FBbUI7SUFBRyxDQUFDO0lBRWpELGVBQWUsQ0FDYixXQUF3QjtRQUV4QixNQUFNLE1BQU0sR0FBRyxXQUFXO2FBQ3ZCLEdBQUcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQzthQUNuRCxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDYiw2QkFBNkI7WUFDN0IsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7Z0JBQzNCLE9BQU8sQ0FBQyxDQUFDO1lBQ1gsQ0FBQztZQUNELE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDbkYsQ0FBQyxDQUFDLENBQUM7UUFFTCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFD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
@@ -1,155 +0,0 @@
1
- import {
2
- Fr,
3
- GrumpkinScalar,
4
- type MAX_NEW_NOTE_HASHES_PER_TX,
5
- MAX_NEW_NULLIFIERS_PER_TX,
6
- MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
7
- MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX,
8
- type MAX_NULLIFIER_READ_REQUESTS_PER_TX,
9
- MembershipWitness,
10
- NULLIFIER_TREE_HEIGHT,
11
- type NullifierKeyValidationRequestContext,
12
- type ReadRequestContext,
13
- type SideEffect,
14
- type SideEffectLinkedToNoteHash,
15
- type SideEffectType,
16
- buildNullifierReadRequestHints,
17
- } from '@aztec/circuits.js';
18
- import { makeTuple } from '@aztec/foundation/array';
19
- import { type Tuple } from '@aztec/foundation/serialize';
20
-
21
- import { type ProvingDataOracle } from './proving_data_oracle.js';
22
-
23
- export class HintsBuilder {
24
- constructor(private oracle: ProvingDataOracle) {}
25
-
26
- sortSideEffects<T extends SideEffectType, K extends number>(
27
- sideEffects: Tuple<T, K>,
28
- ): [Tuple<T, K>, Tuple<number, K>] {
29
- const sorted = sideEffects
30
- .map((sideEffect, index) => ({ sideEffect, index }))
31
- .sort((a, b) => {
32
- // Empty ones go to the right
33
- if (a.sideEffect.isEmpty()) {
34
- return 1;
35
- }
36
- return Number(a.sideEffect.counter.toBigInt() - b.sideEffect.counter.toBigInt());
37
- });
38
-
39
- const originalToSorted = sorted.map(() => 0);
40
- sorted.forEach(({ index }, i) => {
41
- originalToSorted[index] = i;
42
- });
43
-
44
- return [sorted.map(({ sideEffect }) => sideEffect) as Tuple<T, K>, originalToSorted as Tuple<number, K>];
45
- }
46
-
47
- /**
48
- * Performs the matching between an array of read request and an array of note hashes. This produces
49
- * hints for the private kernel tail circuit to efficiently match a read request with the corresponding
50
- * note hash. Several read requests might be pointing to the same note hash. It is therefore valid
51
- * to return more than one hint with the same index (contrary to getNullifierHints).
52
- *
53
- * @param noteHashReadRequests - The array of read requests.
54
- * @param noteHashes - The array of note hashes.
55
- * @returns An array of hints where each element is the index of the note hash in note hashes array
56
- * corresponding to the read request. In other words we have readRequests[i] == noteHashes[hints[i]].
57
- */
58
- getNoteHashReadRequestHints(
59
- noteHashReadRequests: Tuple<SideEffect, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>,
60
- noteHashes: Tuple<SideEffect, typeof MAX_NEW_NOTE_HASHES_PER_TX>,
61
- ): Tuple<Fr, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX> {
62
- const hints = makeTuple(MAX_NOTE_HASH_READ_REQUESTS_PER_TX, Fr.zero);
63
- for (let i = 0; i < MAX_NOTE_HASH_READ_REQUESTS_PER_TX && !noteHashReadRequests[i].isEmpty(); i++) {
64
- const equalToRR = (cmt: SideEffect) => cmt.value.equals(noteHashReadRequests[i].value);
65
- const result = noteHashes.findIndex(equalToRR);
66
- if (result == -1) {
67
- throw new Error(
68
- `The read request at index ${i} ${noteHashReadRequests[i].toString()} does not match to any note hash.`,
69
- );
70
- } else {
71
- hints[i] = new Fr(result);
72
- }
73
- }
74
- return hints;
75
- }
76
-
77
- getNullifierReadRequestHints(
78
- nullifierReadRequests: Tuple<ReadRequestContext, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
79
- nullifiers: Tuple<SideEffectLinkedToNoteHash, typeof MAX_NEW_NULLIFIERS_PER_TX>,
80
- ) {
81
- return buildNullifierReadRequestHints(this, nullifierReadRequests, nullifiers);
82
- }
83
-
84
- async getNullifierMembershipWitness(nullifier: Fr) {
85
- const res = await this.oracle.getNullifierMembershipWitness(nullifier);
86
- if (!res) {
87
- return;
88
- }
89
-
90
- const { index, siblingPath, leafPreimage } = res;
91
- return {
92
- membershipWitness: new MembershipWitness(
93
- NULLIFIER_TREE_HEIGHT,
94
- index,
95
- siblingPath.toTuple<typeof NULLIFIER_TREE_HEIGHT>(),
96
- ),
97
- leafPreimage,
98
- };
99
- }
100
-
101
- /**
102
- * Performs the matching between an array of nullified note hashes and an array of note hashes. This produces
103
- * hints for the private kernel tail circuit to efficiently match a nullifier with the corresponding
104
- * note hash. Note that the same note hash value might appear more than once in the note hashes
105
- * (resp. nullified note hashes) array. It is crucial in this case that each hint points to a different index
106
- * of the nullified note hashes array. Otherwise, the private kernel will fail to validate.
107
- *
108
- * @param nullifiedNoteHashes - The array of nullified note hashes.
109
- * @param noteHashes - The array of note hashes.
110
- * @returns An array of hints where each element is the index of the note hash in note hashes array
111
- * corresponding to the nullified note hash. In other words we have nullifiedNoteHashes[i] == noteHashes[hints[i]].
112
- */
113
- getNullifierHints(
114
- nullifiedNoteHashes: Tuple<Fr, typeof MAX_NEW_NULLIFIERS_PER_TX>,
115
- noteHashes: Tuple<SideEffect, typeof MAX_NEW_NOTE_HASHES_PER_TX>,
116
- ): Tuple<Fr, typeof MAX_NEW_NULLIFIERS_PER_TX> {
117
- const hints = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.zero);
118
- const alreadyUsed = new Set<number>();
119
- for (let i = 0; i < MAX_NEW_NULLIFIERS_PER_TX; i++) {
120
- if (!nullifiedNoteHashes[i].isZero()) {
121
- const result = noteHashes.findIndex(
122
- (cmt: SideEffect, index: number) => cmt.value.equals(nullifiedNoteHashes[i]) && !alreadyUsed.has(index),
123
- );
124
- alreadyUsed.add(result);
125
- if (result == -1) {
126
- throw new Error(
127
- `The nullified note hash at index ${i} with value ${nullifiedNoteHashes[
128
- i
129
- ].toString()} does not match to any note hash.`,
130
- );
131
- } else {
132
- hints[i] = new Fr(result);
133
- }
134
- }
135
- }
136
- return hints;
137
- }
138
-
139
- async getMasterNullifierSecretKeys(
140
- nullifierKeyValidationRequests: Tuple<
141
- NullifierKeyValidationRequestContext,
142
- typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX
143
- >,
144
- ) {
145
- const keys = makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, GrumpkinScalar.zero);
146
- for (let i = 0; i < nullifierKeyValidationRequests.length; ++i) {
147
- const request = nullifierKeyValidationRequests[i];
148
- if (request.isEmpty()) {
149
- break;
150
- }
151
- keys[i] = await this.oracle.getMasterNullifierSecretKey(request.publicKey);
152
- }
153
- return keys;
154
- }
155
- }