@aztec-labs/ivc-integration 6.0.0-nightly.20260829

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 (61) hide show
  1. package/README.md +3 -0
  2. package/artifacts/app_creator.d.json.ts +3 -0
  3. package/artifacts/app_creator.json +210 -0
  4. package/artifacts/app_reader.d.json.ts +3 -0
  5. package/artifacts/app_reader.json +210 -0
  6. package/artifacts/mock_hiding.d.json.ts +3 -0
  7. package/artifacts/mock_hiding.json +256 -0
  8. package/artifacts/mock_private_kernel_init.d.json.ts +3 -0
  9. package/artifacts/mock_private_kernel_init.json +783 -0
  10. package/artifacts/mock_private_kernel_inner.d.json.ts +3 -0
  11. package/artifacts/mock_private_kernel_inner.json +833 -0
  12. package/artifacts/mock_private_kernel_reset.d.json.ts +3 -0
  13. package/artifacts/mock_private_kernel_reset.json +342 -0
  14. package/artifacts/mock_private_kernel_tail.d.json.ts +3 -0
  15. package/artifacts/mock_private_kernel_tail.json +306 -0
  16. package/artifacts/mock_rollup_root.d.json.ts +3 -0
  17. package/artifacts/mock_rollup_root.json +331 -0
  18. package/artifacts/mock_rollup_tx_base_private.d.json.ts +3 -0
  19. package/artifacts/mock_rollup_tx_base_private.json +322 -0
  20. package/artifacts/mock_rollup_tx_base_public.d.json.ts +3 -0
  21. package/artifacts/mock_rollup_tx_base_public.json +1484 -0
  22. package/artifacts/mock_rollup_tx_merge.d.json.ts +3 -0
  23. package/artifacts/mock_rollup_tx_merge.json +387 -0
  24. package/dest/batch_verifier_test_helpers.d.ts +14 -0
  25. package/dest/batch_verifier_test_helpers.d.ts.map +1 -0
  26. package/dest/batch_verifier_test_helpers.js +19 -0
  27. package/dest/bb_working_directory.d.ts +2 -0
  28. package/dest/bb_working_directory.d.ts.map +1 -0
  29. package/dest/bb_working_directory.js +10 -0
  30. package/dest/index.d.ts +2 -0
  31. package/dest/index.d.ts.map +1 -0
  32. package/dest/index.js +1 -0
  33. package/dest/prove_native.d.ts +15 -0
  34. package/dest/prove_native.d.ts.map +1 -0
  35. package/dest/prove_native.js +188 -0
  36. package/dest/scripts/generate_declaration_files.d.ts +2 -0
  37. package/dest/scripts/generate_declaration_files.d.ts.map +1 -0
  38. package/dest/scripts/generate_declaration_files.js +21 -0
  39. package/dest/scripts/generate_ts_from_abi.d.ts +2 -0
  40. package/dest/scripts/generate_ts_from_abi.d.ts.map +1 -0
  41. package/dest/scripts/generate_ts_from_abi.js +49 -0
  42. package/dest/serve.d.ts +2 -0
  43. package/dest/serve.d.ts.map +1 -0
  44. package/dest/serve.js +79 -0
  45. package/dest/types/index.d.ts +227 -0
  46. package/dest/types/index.d.ts.map +1 -0
  47. package/dest/types/index.js +102 -0
  48. package/dest/witgen.d.ts +87 -0
  49. package/dest/witgen.d.ts.map +1 -0
  50. package/dest/witgen.js +328 -0
  51. package/package.json +112 -0
  52. package/src/batch_verifier_test_helpers.ts +32 -0
  53. package/src/bb_working_directory.ts +9 -0
  54. package/src/index.html +9 -0
  55. package/src/index.ts +1 -0
  56. package/src/prove_native.ts +171 -0
  57. package/src/scripts/generate_declaration_files.ts +24 -0
  58. package/src/scripts/generate_ts_from_abi.ts +57 -0
  59. package/src/serve.ts +128 -0
  60. package/src/types/index.ts +349 -0
  61. package/src/witgen.ts +444 -0
@@ -0,0 +1,32 @@
1
+ import { BatchChonkVerifier } from '@aztec-labs/bb-prover';
2
+ import type { IVCProofVerificationResult } from '@aztec-labs/stdlib/interfaces/server';
3
+
4
+ /** Corrupt flat proof fields by flipping bytes in an early field element. */
5
+ export function corruptProofFields(fields: Uint8Array[]): Uint8Array[] {
6
+ const corrupted = fields.map(f => Uint8Array.from(f));
7
+ corrupted[2] = Uint8Array.from(corrupted[2]);
8
+ corrupted[2][30] ^= 0xff;
9
+ corrupted[2][31] ^= 0xff;
10
+ return corrupted;
11
+ }
12
+
13
+ /** Create a BatchChonkVerifier, enqueue proofs, collect results, and stop. */
14
+ export async function runBatchVerifier(opts: {
15
+ vks: Uint8Array[];
16
+ numCores: number;
17
+ batchSize: number;
18
+ proofs: { vkIndex: number; proofFields: Uint8Array[] }[];
19
+ }): Promise<IVCProofVerificationResult[]> {
20
+ const verifier = await BatchChonkVerifier.newForTesting(
21
+ { bbChonkVerifyConcurrency: opts.numCores },
22
+ opts.vks,
23
+ opts.batchSize,
24
+ );
25
+
26
+ try {
27
+ const promises = opts.proofs.map(p => verifier.enqueueProof(p.vkIndex, p.proofFields));
28
+ return await Promise.all(promises);
29
+ } finally {
30
+ await verifier.stop();
31
+ }
32
+ }
@@ -0,0 +1,9 @@
1
+ import fs from 'fs/promises';
2
+ import os from 'os';
3
+ import path from 'path';
4
+
5
+ export async function getWorkingDirectory(prefix: string): Promise<string> {
6
+ const baseFolder = process.env.BB_WORKING_DIRECTORY || os.tmpdir();
7
+ await fs.mkdir(baseFolder, { recursive: true });
8
+ return await fs.mkdtemp(path.join(baseFolder, prefix));
9
+ }
package/src/index.html ADDED
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>My Test bb.js App</title>
5
+ </head>
6
+ <body>
7
+ <script src="index.js"></script>
8
+ </body>
9
+ </html>
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './witgen.js';
@@ -0,0 +1,171 @@
1
+ import { BBJsFactory, type UltraHonkFlavor, constructRecursiveProofFromBuffers } from '@aztec-labs/bb-prover';
2
+ import {
3
+ AVM_V2_PROOF_LENGTH_IN_FIELDS,
4
+ CHONK_PROOF_LENGTH,
5
+ HIDING_KERNEL_IO_PUBLIC_INPUTS_SIZE,
6
+ NESTED_RECURSIVE_PROOF_LENGTH,
7
+ RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
8
+ } from '@aztec-labs/constants';
9
+ import { Fr } from '@aztec-labs/foundation/curves/bn254';
10
+ import type { Logger } from '@aztec-labs/foundation/log';
11
+ import type { AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec-labs/stdlib/avm';
12
+ import { makeProofAndVerificationKey } from '@aztec-labs/stdlib/interfaces/server';
13
+ import type { NoirCompiledCircuit } from '@aztec-labs/stdlib/noir';
14
+ import { Proof, RecursiveProof } from '@aztec-labs/stdlib/proofs';
15
+ import { VerificationKeyAsFields, VerificationKeyData } from '@aztec-labs/stdlib/vks';
16
+ import { ungzip } from 'pako';
17
+ import * as path from 'path';
18
+
19
+ export async function proofBytesToRecursiveProof(
20
+ proofAsFields: Uint8Array[],
21
+ vkBytes: Uint8Array,
22
+ ): Promise<RecursiveProof<typeof CHONK_PROOF_LENGTH>> {
23
+ const vk = await VerificationKeyAsFields.fromFrBuffer(Buffer.from(vkBytes));
24
+ const numCustomPublicInputs = vk.numPublicInputs - HIDING_KERNEL_IO_PUBLIC_INPUTS_SIZE;
25
+ // Convert Uint8Array fields to Fr instances
26
+ const fields = proofAsFields.map(f => Fr.fromBuffer(Buffer.from(f)));
27
+
28
+ // Slice off custom public inputs from the beginning.
29
+ const fieldsWithoutPublicInputs = fields.slice(numCustomPublicInputs);
30
+
31
+ // Convert fields to binary buffer
32
+ const proofBuffer = Buffer.concat(proofAsFields.slice(numCustomPublicInputs));
33
+
34
+ // Create Proof directly (not using fromBuffer which expects different format)
35
+ const proof = new Proof(proofBuffer, numCustomPublicInputs);
36
+ return new RecursiveProof(fieldsWithoutPublicInputs, proof, true, CHONK_PROOF_LENGTH);
37
+ }
38
+
39
+ async function proveRollupCircuit<T extends UltraHonkFlavor, ProofLength extends number>(
40
+ name: string,
41
+ pathToBB: string,
42
+ _workingDirectory: string,
43
+ circuit: NoirCompiledCircuit,
44
+ witness: Uint8Array,
45
+ logger: Logger,
46
+ flavor: T,
47
+ proofLength: ProofLength,
48
+ ) {
49
+ const factory = new BBJsFactory(pathToBB, { logger });
50
+ try {
51
+ // Decompress witness and bytecode for bb.js
52
+ const decompressedWitness = ungzip(witness);
53
+ const bytecode = ungzip(Buffer.from(circuit.bytecode, 'base64'));
54
+ const vkBuffer = Buffer.from(circuit.verificationKey.bytes, 'hex');
55
+
56
+ // Generate proof via bb.js
57
+ await using proveInstance = await factory.getInstance();
58
+ const proofResult = await proveInstance.generateProof(name, bytecode, vkBuffer, decompressedWitness, flavor);
59
+
60
+ const vk = await VerificationKeyData.fromFrBuffer(vkBuffer);
61
+
62
+ // Construct proof from in-memory buffers
63
+ const proof = constructRecursiveProofFromBuffers(
64
+ proofResult.proofFields,
65
+ proofResult.publicInputFields,
66
+ vk,
67
+ proofLength,
68
+ );
69
+
70
+ // Verify the proof via bb.js
71
+ await using verifyInstance = await factory.getInstance();
72
+ const { verified } = await verifyInstance.verifyProof(
73
+ proofResult.proofFields,
74
+ vk.keyAsBytes,
75
+ proofResult.publicInputFields,
76
+ flavor,
77
+ );
78
+
79
+ if (!verified) {
80
+ throw new Error(`Failed to verify proof from key!`);
81
+ }
82
+ logger.info(`Successfully verified proof from key`);
83
+
84
+ return makeProofAndVerificationKey(proof, vk);
85
+ } finally {
86
+ await factory.destroy();
87
+ }
88
+ }
89
+
90
+ export function proveRollupHonk(
91
+ name: string,
92
+ pathToBB: string,
93
+ workingDirectory: string,
94
+ circuit: NoirCompiledCircuit,
95
+ witness: Uint8Array,
96
+ logger: Logger,
97
+ ) {
98
+ return proveRollupCircuit(
99
+ name,
100
+ pathToBB,
101
+ workingDirectory,
102
+ circuit,
103
+ witness,
104
+ logger,
105
+ 'ultra_rollup_honk',
106
+ RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
107
+ );
108
+ }
109
+
110
+ export function proveKeccakHonk(
111
+ name: string,
112
+ pathToBB: string,
113
+ workingDirectory: string,
114
+ circuit: NoirCompiledCircuit,
115
+ witness: Uint8Array,
116
+ logger: Logger,
117
+ ) {
118
+ return proveRollupCircuit(
119
+ name,
120
+ pathToBB,
121
+ workingDirectory,
122
+ circuit,
123
+ witness,
124
+ logger,
125
+ 'ultra_keccak_honk',
126
+ NESTED_RECURSIVE_PROOF_LENGTH,
127
+ );
128
+ }
129
+
130
+ /** Generate and verify an AVM proof via bb.js. */
131
+ export async function proveAvm(
132
+ avmCircuitInputs: AvmCircuitInputs,
133
+ _workingDirectory: string,
134
+ logger: Logger,
135
+ ): Promise<{
136
+ proof: Fr[];
137
+ publicInputs: AvmCircuitPublicInputs;
138
+ }> {
139
+ const bbPath = path.resolve('../../labs-aztec-toolchain/bin/bb-avm');
140
+ const factory = new BBJsFactory(bbPath, { logger });
141
+ try {
142
+ const inputsBuffer = avmCircuitInputs.serializeWithMessagePack();
143
+ let proofFields: Uint8Array[];
144
+ {
145
+ await using instance = await factory.getInstance();
146
+ ({ proof: proofFields } = await instance.generateAvmProof(inputsBuffer));
147
+ }
148
+
149
+ // Convert Uint8Array field elements → Fr[]
150
+ const proof: Fr[] = proofFields.map(f => Fr.fromBuffer(Buffer.from(f)));
151
+
152
+ if (proof.length !== AVM_V2_PROOF_LENGTH_IN_FIELDS) {
153
+ throw new Error(`AVM V2 proof has ${proof.length} fields, expected exactly ${AVM_V2_PROOF_LENGTH_IN_FIELDS}.`);
154
+ }
155
+
156
+ // Explicit verify pass against the serialized public inputs (matches the legacy binary flow).
157
+ const piBuffer = avmCircuitInputs.publicInputs.serializeWithMessagePack();
158
+ await using verifyInstance = await factory.getInstance();
159
+ const { verified: reVerified } = await verifyInstance.verifyAvmProof(proofFields, piBuffer);
160
+ if (!reVerified) {
161
+ throw new Error('AVM V2 proof verification failed');
162
+ }
163
+
164
+ return {
165
+ proof,
166
+ publicInputs: avmCircuitInputs.publicInputs,
167
+ };
168
+ } finally {
169
+ await factory.destroy();
170
+ }
171
+ }
@@ -0,0 +1,24 @@
1
+ import { fileURLToPath } from '@aztec-labs/foundation/url';
2
+ import { readdir, writeFile } from 'fs/promises';
3
+ import { join } from 'path';
4
+
5
+ const contract = `\
6
+ import { type NoirCompiledCircuit } from '@aztec-labs/stdlib/noir';
7
+ const circuit: NoirCompiledCircuit;
8
+ export = circuit;
9
+ `;
10
+
11
+ async function generateDeclarationFor(target: string, content: string) {
12
+ const files = await readdir(target);
13
+ for (const file of files) {
14
+ // guard against running this script twice without cleaning the artifacts/ dir first
15
+ if (!file.endsWith('.json')) {
16
+ continue;
17
+ }
18
+ const name = file.replace('.json', '');
19
+ await writeFile(join(target, `${name}.d.json.ts`), content);
20
+ }
21
+ }
22
+
23
+ // Generate declaration files for contracts
24
+ await generateDeclarationFor(fileURLToPath(new URL('../../artifacts', import.meta.url).href), contract);
@@ -0,0 +1,57 @@
1
+ import { codegen } from '@aztec/noir-noir_codegen';
2
+ import { type CompiledCircuit } from '@aztec/noir-types';
3
+
4
+ import { createConsoleLogger } from '@aztec-labs/foundation/log';
5
+ import { pascalCase } from 'change-case';
6
+ import { promises as fs } from 'fs';
7
+
8
+ const log = createConsoleLogger('mock-circuits');
9
+
10
+ const circuits = [
11
+ 'app_creator',
12
+ 'app_reader',
13
+ 'mock_hiding',
14
+ 'mock_private_kernel_init',
15
+ 'mock_private_kernel_inner',
16
+ 'mock_private_kernel_reset',
17
+ 'mock_private_kernel_tail',
18
+ 'mock_rollup_tx_base_public',
19
+ 'mock_rollup_tx_base_private',
20
+ 'mock_rollup_tx_merge',
21
+ 'mock_rollup_root',
22
+ ];
23
+
24
+ const main = async () => {
25
+ try {
26
+ await fs.access('./src/types/');
27
+ } catch (error) {
28
+ await fs.mkdir('./src/types', { recursive: true });
29
+ }
30
+ const programs: [string, CompiledCircuit][] = [];
31
+ // Collect all circuits
32
+ for (const circuit of circuits) {
33
+ const rawData = await fs.readFile(`./artifacts/${circuit}.json`, 'utf-8');
34
+ const abiObj: CompiledCircuit = JSON.parse(rawData);
35
+ programs.push([pascalCase(circuit), abiObj]);
36
+ }
37
+ let code = codegen(
38
+ programs,
39
+ false, // Don't embed artifacts
40
+ true, // Use fixed length arrays
41
+ );
42
+ // noir_codegen emits `InputMap` as a value import, but it is type-only: under
43
+ // verbatimModuleSyntax that trips TS1484. Rewrite until the generator qualifies it upstream.
44
+ // TODO(A-1611): Remove once fixed upstream in Noir.
45
+ code = code.replace(
46
+ 'import { Noir, InputMap, type CompiledCircuit, type ForeignCallHandler }',
47
+ 'import { Noir, type InputMap, type CompiledCircuit, type ForeignCallHandler }',
48
+ );
49
+ await fs.writeFile('./src/types/index.ts', code);
50
+ };
51
+
52
+ try {
53
+ await main();
54
+ } catch (err: unknown) {
55
+ log(`Error generating types ${err}`);
56
+ process.exit(1);
57
+ }
package/src/serve.ts ADDED
@@ -0,0 +1,128 @@
1
+ import { AztecClientBackend, Barretenberg } from '@aztec/bb.js';
2
+
3
+ import { createLogger } from '@aztec-labs/foundation/log';
4
+
5
+ import {
6
+ MockAppCreatorCircuit,
7
+ MockHidingCircuit,
8
+ MockPrivateKernelInitCircuit,
9
+ MockPrivateKernelTailCircuit,
10
+ generateTestingIVCStack,
11
+ } from './witgen.js';
12
+
13
+ const logger = createLogger('aztec:ivc-test');
14
+
15
+ /* eslint-disable no-console */
16
+
17
+ // Expose APIs on window for browser testing
18
+ (window as any).Barretenberg = Barretenberg;
19
+ (window as any).AztecClientBackend = AztecClientBackend;
20
+ (window as any).generateTestingIVCStack = generateTestingIVCStack;
21
+ (window as any).MockAppCreatorCircuit = MockAppCreatorCircuit;
22
+ (window as any).MockPrivateKernelInitCircuit = MockPrivateKernelInitCircuit;
23
+ (window as any).MockPrivateKernelTailCircuit = MockPrivateKernelTailCircuit;
24
+ (window as any).MockHidingCircuit = MockHidingCircuit;
25
+
26
+ // Function to set up the output element and redirect all console output
27
+ function setupConsoleOutput() {
28
+ const container = document.createElement('div');
29
+ container.style.marginBottom = '10px';
30
+ document.body.appendChild(container);
31
+
32
+ const copyButton = document.createElement('button');
33
+ copyButton.innerText = 'Copy Logs to Clipboard';
34
+ copyButton.style.marginBottom = '10px';
35
+ copyButton.addEventListener('click', () => {
36
+ const logContent = logContainer.textContent || ''; // Get text content of log container
37
+ navigator.clipboard
38
+ .writeText(logContent)
39
+ .then(() => {
40
+ alert('Logs copied to clipboard!');
41
+ })
42
+ .catch(err => {
43
+ console.error('Failed to copy logs:', err);
44
+ });
45
+ });
46
+ container.appendChild(copyButton);
47
+
48
+ const logContainer = document.createElement('pre');
49
+ logContainer.id = 'logOutput';
50
+ logContainer.style.border = '1px solid #ccc';
51
+ logContainer.style.padding = '10px';
52
+ logContainer.style.maxHeight = '400px';
53
+ logContainer.style.overflowY = 'auto';
54
+ container.appendChild(logContainer);
55
+
56
+ // Helper to append messages to logContainer
57
+ function addLogMessage(message: string) {
58
+ logContainer.textContent += message + '\n';
59
+ logContainer.scrollTop = logContainer.scrollHeight; // Auto-scroll to the bottom
60
+ }
61
+
62
+ // Override console methods to output clean logs
63
+ const originalLog = console.log;
64
+ const originalDebug = console.debug;
65
+
66
+ console.log = (...args: any[]) => {
67
+ const message = args
68
+ .map(arg =>
69
+ typeof arg === 'string'
70
+ ? arg
71
+ .replace(/%c/g, '')
72
+ .replace(/color:.*?(;|$)/g, '')
73
+ .trim()
74
+ : arg,
75
+ )
76
+ .join(' ');
77
+ originalLog.apply(console, args); // Keep original behavior
78
+ addLogMessage(message);
79
+ };
80
+
81
+ console.debug = (...args: any[]) => {
82
+ const message = args
83
+ .map(arg =>
84
+ typeof arg === 'string'
85
+ ? arg
86
+ .replace(/%c/g, '')
87
+ .replace(/color:.*?(;|$)/g, '')
88
+ .trim()
89
+ : arg,
90
+ )
91
+ .join(' ');
92
+ originalDebug.apply(console, args); // Keep original behavior
93
+ addLogMessage(message);
94
+ };
95
+ }
96
+
97
+ // Only set up the interactive UI if this is not being used for automated testing
98
+ if (!document.getElementById('status')) {
99
+ document.addEventListener('DOMContentLoaded', function () {
100
+ setupConsoleOutput(); // Initialize console output capture
101
+
102
+ const button = document.createElement('button');
103
+ button.innerText = 'Run Test';
104
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
105
+ button.addEventListener('click', async () => {
106
+ logger.info(`generating circuit and witness...`);
107
+ const [bytecodes, witnessStack, _publicInputs, precomputedVks, circuitKinds] = await generateTestingIVCStack(
108
+ 1,
109
+ 0,
110
+ );
111
+ logger.info(`done. proving and verifying...`);
112
+
113
+ const barretenberg = await Barretenberg.initSingleton({
114
+ threads: 16,
115
+ logger: (m: string) => logger.info(m),
116
+ });
117
+
118
+ const backend = new AztecClientBackend(bytecodes, barretenberg, [], circuitKinds);
119
+ const { proof, vk } = await backend.prove(witnessStack, precomputedVks);
120
+ const verified = await backend.verify(proof, vk);
121
+
122
+ logger.info(`verified? ${verified}`);
123
+
124
+ await Barretenberg.destroySingleton();
125
+ });
126
+ document.body.appendChild(button);
127
+ });
128
+ }