@aztec/ivc-integration 3.0.0-nightly.20251115 → 3.0.0-nightly.20251118
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifacts/app_creator.json +1 -1
- package/artifacts/app_reader.json +1 -1
- package/artifacts/keys/mock_rollup_root_verifier.sol +26 -24
- package/artifacts/mock_hiding.json +1 -1
- package/artifacts/mock_private_kernel_init.json +1 -1
- package/artifacts/mock_private_kernel_inner.json +1 -1
- package/artifacts/mock_private_kernel_reset.json +1 -1
- package/artifacts/mock_private_kernel_tail.json +1 -1
- package/artifacts/mock_rollup_root.json +1 -1
- package/artifacts/mock_rollup_tx_base_private.json +91 -91
- package/artifacts/mock_rollup_tx_base_public.json +91 -91
- package/artifacts/mock_rollup_tx_merge.json +1 -1
- package/dest/prove_native.d.ts +4 -4
- package/dest/prove_native.d.ts.map +1 -1
- package/dest/prove_native.js +16 -37
- package/dest/serve.js +34 -17
- package/dest/witgen.d.ts +1 -1
- package/dest/witgen.d.ts.map +1 -1
- package/dest/witgen.js +18 -3
- package/package.json +19 -22
- package/src/prove_native.ts +19 -48
- package/src/serve.ts +43 -16
- package/src/witgen.ts +18 -2
- package/dest/prove_wasm.d.ts +0 -4
- package/dest/prove_wasm.d.ts.map +0 -1
- package/dest/prove_wasm.js +0 -38
- package/src/prove_wasm.ts +0 -57
package/src/prove_native.ts
CHANGED
|
@@ -4,8 +4,6 @@ import {
|
|
|
4
4
|
PUBLIC_INPUTS_FILENAME,
|
|
5
5
|
type UltraHonkFlavor,
|
|
6
6
|
VK_FILENAME,
|
|
7
|
-
executeBbChonkProof,
|
|
8
|
-
extractVkData,
|
|
9
7
|
generateAvmProof,
|
|
10
8
|
generateProof,
|
|
11
9
|
readProofsFromOutputDirectory,
|
|
@@ -16,6 +14,7 @@ import {
|
|
|
16
14
|
AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED,
|
|
17
15
|
AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED,
|
|
18
16
|
CHONK_PROOF_LENGTH,
|
|
17
|
+
HIDING_KERNEL_IO_PUBLIC_INPUTS_SIZE,
|
|
19
18
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
20
19
|
RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
21
20
|
} from '@aztec/constants';
|
|
@@ -23,61 +22,33 @@ import { Fr } from '@aztec/foundation/fields';
|
|
|
23
22
|
import type { Logger } from '@aztec/foundation/log';
|
|
24
23
|
import { BufferReader } from '@aztec/foundation/serialize';
|
|
25
24
|
import type { AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm';
|
|
26
|
-
import {
|
|
25
|
+
import { makeProofAndVerificationKey } from '@aztec/stdlib/interfaces/server';
|
|
27
26
|
import type { NoirCompiledCircuit } from '@aztec/stdlib/noir';
|
|
28
|
-
import
|
|
27
|
+
import { Proof, RecursiveProof } from '@aztec/stdlib/proofs';
|
|
29
28
|
import { enhanceProofWithPiValidationFlag } from '@aztec/stdlib/rollup';
|
|
30
29
|
import { VerificationKeyAsFields, VerificationKeyData } from '@aztec/stdlib/vks';
|
|
31
30
|
|
|
32
31
|
import * as fs from 'fs/promises';
|
|
33
|
-
import { Encoder } from 'msgpackr';
|
|
34
32
|
import * as path from 'path';
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// Convert
|
|
43
|
-
const
|
|
44
|
-
const reader = BufferReader.asReader(vkBytes);
|
|
45
|
-
const fields = reader.readArray(numFields, Fr);
|
|
34
|
+
export async function proofBytesToRecursiveProof(
|
|
35
|
+
proofAsFields: Uint8Array[],
|
|
36
|
+
vkBytes: Uint8Array,
|
|
37
|
+
): Promise<RecursiveProof<typeof CHONK_PROOF_LENGTH>> {
|
|
38
|
+
const vk = await VerificationKeyAsFields.fromFrBuffer(Buffer.from(vkBytes));
|
|
39
|
+
const numCustomPublicInputs = vk.numPublicInputs - HIDING_KERNEL_IO_PUBLIC_INPUTS_SIZE;
|
|
40
|
+
// Convert Uint8Array fields to Fr instances
|
|
41
|
+
const fields = proofAsFields.map(f => Fr.fromBuffer(Buffer.from(f)));
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export async function proveChonk(
|
|
52
|
-
bbBinaryPath: string,
|
|
53
|
-
bbWorkingDirectory: string,
|
|
54
|
-
witnessStack: Uint8Array[],
|
|
55
|
-
bytecodes: string[],
|
|
56
|
-
vks: string[],
|
|
57
|
-
logger: Logger,
|
|
58
|
-
): Promise<ProofAndVerificationKey<typeof CHONK_PROOF_LENGTH>> {
|
|
59
|
-
const stepToStruct = (bytecode: string, index: number) => {
|
|
60
|
-
return {
|
|
61
|
-
bytecode: Buffer.from(bytecode, 'base64'),
|
|
62
|
-
witness: witnessStack[index],
|
|
63
|
-
vk: Buffer.from(vks[index], 'hex'),
|
|
64
|
-
functionName: `unknown_${index}`,
|
|
65
|
-
};
|
|
66
|
-
};
|
|
67
|
-
const encoded = new Encoder({ useRecords: false }).pack(bytecodes.map(stepToStruct));
|
|
68
|
-
const ivcInputsPath = path.join(bbWorkingDirectory, 'ivc-inputs.msgpack');
|
|
69
|
-
await fs.writeFile(ivcInputsPath, encoded);
|
|
43
|
+
// Slice off custom public inputs from the beginning.
|
|
44
|
+
const fieldsWithoutPublicInputs = fields.slice(numCustomPublicInputs);
|
|
70
45
|
|
|
71
|
-
|
|
46
|
+
// Convert fields to binary buffer
|
|
47
|
+
const proofBuffer = Buffer.concat(proofAsFields.slice(numCustomPublicInputs));
|
|
72
48
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const vk = await extractVkData(provingResult.vkDirectoryPath!);
|
|
78
|
-
const proof = await readProofsFromOutputDirectory(provingResult.proofPath!, vk, CHONK_PROOF_LENGTH, logger);
|
|
79
|
-
|
|
80
|
-
return makeProofAndVerificationKey(proof, vk);
|
|
49
|
+
// Create Proof directly (not using fromBuffer which expects different format)
|
|
50
|
+
const proof = new Proof(proofBuffer, numCustomPublicInputs);
|
|
51
|
+
return new RecursiveProof(fieldsWithoutPublicInputs, proof, true, CHONK_PROOF_LENGTH);
|
|
81
52
|
}
|
|
82
53
|
|
|
83
54
|
async function verifyProofWithKey(
|
|
@@ -130,7 +101,7 @@ async function proveRollupCircuit<T extends UltraHonkFlavor, ProofLength extends
|
|
|
130
101
|
throw new Error(`Failed to generate proof for ${name} with flavor ${flavor}`);
|
|
131
102
|
}
|
|
132
103
|
|
|
133
|
-
const vk = await
|
|
104
|
+
const vk = await VerificationKeyData.fromFrBuffer(vkBuffer);
|
|
134
105
|
const proof = await readProofsFromOutputDirectory(proofResult.proofPath!, vk, proofLength, logger);
|
|
135
106
|
|
|
136
107
|
await verifyProofWithKey(pathToBB, workingDirectory, vk, proof.binaryProof, flavor, logger);
|
package/src/serve.ts
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
|
+
import { AztecClientBackend, Barretenberg } from '@aztec/bb.js';
|
|
1
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
4
|
+
import {
|
|
5
|
+
MockAppCreatorCircuit,
|
|
6
|
+
MockHidingCircuit,
|
|
7
|
+
MockPrivateKernelInitCircuit,
|
|
8
|
+
MockPrivateKernelTailCircuit,
|
|
9
|
+
generateTestingIVCStack,
|
|
10
|
+
} from './witgen.js';
|
|
5
11
|
|
|
6
12
|
const logger = createLogger('aztec:ivc-test');
|
|
7
13
|
|
|
8
14
|
/* eslint-disable no-console */
|
|
9
15
|
|
|
16
|
+
// Expose APIs on window for browser testing
|
|
17
|
+
(window as any).Barretenberg = Barretenberg;
|
|
18
|
+
(window as any).AztecClientBackend = AztecClientBackend;
|
|
19
|
+
(window as any).generateTestingIVCStack = generateTestingIVCStack;
|
|
20
|
+
(window as any).MockAppCreatorCircuit = MockAppCreatorCircuit;
|
|
21
|
+
(window as any).MockPrivateKernelInitCircuit = MockPrivateKernelInitCircuit;
|
|
22
|
+
(window as any).MockPrivateKernelTailCircuit = MockPrivateKernelTailCircuit;
|
|
23
|
+
(window as any).MockHidingCircuit = MockHidingCircuit;
|
|
24
|
+
|
|
10
25
|
// Function to set up the output element and redirect all console output
|
|
11
26
|
function setupConsoleOutput() {
|
|
12
27
|
const container = document.createElement('div');
|
|
@@ -78,20 +93,32 @@ function setupConsoleOutput() {
|
|
|
78
93
|
};
|
|
79
94
|
}
|
|
80
95
|
|
|
81
|
-
|
|
96
|
+
// Only set up the interactive UI if this is not being used for automated testing
|
|
97
|
+
if (!document.getElementById('status')) {
|
|
98
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
99
|
+
setupConsoleOutput(); // Initialize console output capture
|
|
100
|
+
|
|
101
|
+
const button = document.createElement('button');
|
|
102
|
+
button.innerText = 'Run Test';
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
104
|
+
button.addEventListener('click', async () => {
|
|
105
|
+
logger.info(`generating circuit and witness...`);
|
|
106
|
+
const [bytecodes, witnessStack, _publicInputs, precomputedVks] = await generateTestingIVCStack(1, 0);
|
|
107
|
+
logger.info(`done. proving and verifying...`);
|
|
108
|
+
|
|
109
|
+
const barretenberg = await Barretenberg.initSingleton({
|
|
110
|
+
threads: 16,
|
|
111
|
+
logger: (m: string) => logger.info(m),
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const backend = new AztecClientBackend(bytecodes, barretenberg);
|
|
115
|
+
const [, proof, vk] = await backend.prove(witnessStack, precomputedVks);
|
|
116
|
+
const verified = await backend.verify(proof, vk);
|
|
82
117
|
|
|
83
|
-
|
|
84
|
-
setupConsoleOutput(); // Initialize console output capture
|
|
118
|
+
logger.info(`verified? ${verified}`);
|
|
85
119
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
button.addEventListener('click', async () => {
|
|
90
|
-
logger.info(`generating circuit and witness...`);
|
|
91
|
-
const [bytecodes, witnessStack, _publicInputs, precomputedVks] = await generateTestingIVCStack(1, 0);
|
|
92
|
-
logger.info(`done. proving and verifying...`);
|
|
93
|
-
const verified = await proveThenVerifyAztecClient(bytecodes, witnessStack, precomputedVks);
|
|
94
|
-
logger.info(`verified? ${verified}`);
|
|
120
|
+
await Barretenberg.destroySingleton();
|
|
121
|
+
});
|
|
122
|
+
document.body.appendChild(button);
|
|
95
123
|
});
|
|
96
|
-
|
|
97
|
-
});
|
|
124
|
+
}
|
package/src/witgen.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type { RecursiveProof } from '@aztec/stdlib/proofs';
|
|
|
12
12
|
import { VerificationKeyAsFields } from '@aztec/stdlib/vks';
|
|
13
13
|
|
|
14
14
|
import { strict as assert } from 'assert';
|
|
15
|
+
import { ungzip } from 'pako';
|
|
15
16
|
|
|
16
17
|
import MockAppCreatorCircuit from '../artifacts/app_creator.json' with { type: 'json' };
|
|
17
18
|
import MockAppReaderCircuit from '../artifacts/app_reader.json' with { type: 'json' };
|
|
@@ -251,7 +252,7 @@ export async function generateTestingIVCStack(
|
|
|
251
252
|
// A call to the reader app creates 1 read request. A reset kernel will be run if there are 2 read requests in the
|
|
252
253
|
// public inputs. All read requests must be cleared before running the tail kernel.
|
|
253
254
|
numReaderAppCalls: number,
|
|
254
|
-
): Promise<[
|
|
255
|
+
): Promise<[Uint8Array[], Uint8Array[], KernelPublicInputs, Uint8Array[]]> {
|
|
255
256
|
if (numCreatorAppCalls > 2) {
|
|
256
257
|
throw new Error('The creator app can only be called at most twice.');
|
|
257
258
|
}
|
|
@@ -368,7 +369,22 @@ export async function generateTestingIVCStack(
|
|
|
368
369
|
bytecodes.push(MockHidingCircuit.bytecode);
|
|
369
370
|
vks.push(MockHidingVk.keyAsBytes);
|
|
370
371
|
|
|
371
|
-
|
|
372
|
+
function base64ToUint8Array(base64: string): Uint8Array {
|
|
373
|
+
return Uint8Array.from(atob(base64), c => c.charCodeAt(0));
|
|
374
|
+
}
|
|
375
|
+
function hexToUint8Array(hex: string): Uint8Array {
|
|
376
|
+
const cleaned = hex.replace(/^0x/i, '');
|
|
377
|
+
const bytes = new Uint8Array(cleaned.length / 2);
|
|
378
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
379
|
+
bytes[i] = parseInt(cleaned.slice(i * 2, i * 2 + 2), 16);
|
|
380
|
+
}
|
|
381
|
+
return bytes;
|
|
382
|
+
}
|
|
383
|
+
const rawBytecodes = bytecodes.map(base64ToUint8Array).map((arr: Uint8Array) => ungzip(arr));
|
|
384
|
+
const rawWitnessStack = witnessStack.map((arr: Uint8Array) => ungzip(arr));
|
|
385
|
+
const rawVks = vks.map(hexToUint8Array);
|
|
386
|
+
|
|
387
|
+
return [rawBytecodes, rawWitnessStack, hidingWitnessGenResult.publicInputs, rawVks];
|
|
372
388
|
}
|
|
373
389
|
|
|
374
390
|
export function mapRecursiveProofToNoir<N extends number>(proof: RecursiveProof<N>): FixedLengthArray<string, N> {
|
package/dest/prove_wasm.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { ChonkProofWithPublicInputs } from '@aztec/stdlib/proofs';
|
|
2
|
-
export declare function proveChonk(bytecodes: string[], witnessStack: Uint8Array[], vks: string[], threads?: number): Promise<ChonkProofWithPublicInputs>;
|
|
3
|
-
export declare function proveThenVerifyAztecClient(bytecodes: string[], witnessStack: Uint8Array[], vks: string[], threads?: number): Promise<boolean>;
|
|
4
|
-
//# sourceMappingURL=prove_wasm.d.ts.map
|
package/dest/prove_wasm.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prove_wasm.d.ts","sourceRoot":"","sources":["../src/prove_wasm.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAWlE,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EAAE,EACnB,YAAY,EAAE,UAAU,EAAE,EAC1B,GAAG,EAAE,MAAM,EAAE,EACb,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,0BAA0B,CAAC,CAerC;AAED,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,EAAE,EACnB,YAAY,EAAE,UAAU,EAAE,EAC1B,GAAG,EAAE,MAAM,EAAE,EACb,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAiBlB"}
|
package/dest/prove_wasm.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import { ChonkProofWithPublicInputs } from '@aztec/stdlib/proofs';
|
|
3
|
-
import os from 'os';
|
|
4
|
-
import { ungzip } from 'pako';
|
|
5
|
-
const logger = createLogger('ivc-integration:prove_wasm');
|
|
6
|
-
function base64ToUint8Array(base64) {
|
|
7
|
-
return Uint8Array.from(atob(base64), (c)=>c.charCodeAt(0));
|
|
8
|
-
}
|
|
9
|
-
export async function proveChonk(bytecodes, witnessStack, vks, threads) {
|
|
10
|
-
const { AztecClientBackend } = await import('@aztec/bb.js');
|
|
11
|
-
const backend = new AztecClientBackend(bytecodes.map(base64ToUint8Array).map((arr)=>ungzip(arr)), {
|
|
12
|
-
threads: threads || Math.min(os.cpus().length, 16),
|
|
13
|
-
logger: logger.info,
|
|
14
|
-
wasmPath: process.env.BB_WASM_PATH
|
|
15
|
-
});
|
|
16
|
-
try {
|
|
17
|
-
const [proof] = await backend.prove(witnessStack.map((arr)=>ungzip(arr)), vks.map((hex)=>new Uint8Array(Buffer.from(hex, 'hex'))));
|
|
18
|
-
return ChonkProofWithPublicInputs.fromBufferArray(proof);
|
|
19
|
-
} finally{
|
|
20
|
-
await backend.destroy();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export async function proveThenVerifyAztecClient(bytecodes, witnessStack, vks, threads) {
|
|
24
|
-
const { AztecClientBackend } = await import('@aztec/bb.js');
|
|
25
|
-
const backend = new AztecClientBackend(bytecodes.map(base64ToUint8Array).map((arr)=>ungzip(arr)), {
|
|
26
|
-
threads: threads || Math.min(os.cpus().length, 16),
|
|
27
|
-
logger: logger.info,
|
|
28
|
-
wasmPath: process.env.BB_WASM_PATH
|
|
29
|
-
});
|
|
30
|
-
try {
|
|
31
|
-
// These are optional - easier not to pass them.
|
|
32
|
-
const [_, msgpackProof, vk] = await backend.prove(witnessStack.map((arr)=>ungzip(arr)), vks.map((hex)=>new Uint8Array(Buffer.from(hex, 'hex'))));
|
|
33
|
-
const verified = await backend.verify(msgpackProof, vk);
|
|
34
|
-
return verified;
|
|
35
|
-
} finally{
|
|
36
|
-
await backend.destroy();
|
|
37
|
-
}
|
|
38
|
-
}
|
package/src/prove_wasm.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import { ChonkProofWithPublicInputs } from '@aztec/stdlib/proofs';
|
|
3
|
-
|
|
4
|
-
import os from 'os';
|
|
5
|
-
import { ungzip } from 'pako';
|
|
6
|
-
|
|
7
|
-
const logger = createLogger('ivc-integration:prove_wasm');
|
|
8
|
-
|
|
9
|
-
function base64ToUint8Array(base64: string): Uint8Array {
|
|
10
|
-
return Uint8Array.from(atob(base64), c => c.charCodeAt(0));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export async function proveChonk(
|
|
14
|
-
bytecodes: string[],
|
|
15
|
-
witnessStack: Uint8Array[],
|
|
16
|
-
vks: string[],
|
|
17
|
-
threads?: number,
|
|
18
|
-
): Promise<ChonkProofWithPublicInputs> {
|
|
19
|
-
const { AztecClientBackend } = await import('@aztec/bb.js');
|
|
20
|
-
const backend = new AztecClientBackend(
|
|
21
|
-
bytecodes.map(base64ToUint8Array).map((arr: Uint8Array) => ungzip(arr)),
|
|
22
|
-
{ threads: threads || Math.min(os.cpus().length, 16), logger: logger.info, wasmPath: process.env.BB_WASM_PATH },
|
|
23
|
-
);
|
|
24
|
-
try {
|
|
25
|
-
const [proof] = await backend.prove(
|
|
26
|
-
witnessStack.map((arr: Uint8Array) => ungzip(arr)),
|
|
27
|
-
vks.map(hex => new Uint8Array(Buffer.from(hex, 'hex'))),
|
|
28
|
-
);
|
|
29
|
-
return ChonkProofWithPublicInputs.fromBufferArray(proof);
|
|
30
|
-
} finally {
|
|
31
|
-
await backend.destroy();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function proveThenVerifyAztecClient(
|
|
36
|
-
bytecodes: string[],
|
|
37
|
-
witnessStack: Uint8Array[],
|
|
38
|
-
vks: string[],
|
|
39
|
-
threads?: number,
|
|
40
|
-
): Promise<boolean> {
|
|
41
|
-
const { AztecClientBackend } = await import('@aztec/bb.js');
|
|
42
|
-
const backend = new AztecClientBackend(
|
|
43
|
-
bytecodes.map(base64ToUint8Array).map((arr: Uint8Array) => ungzip(arr)),
|
|
44
|
-
{ threads: threads || Math.min(os.cpus().length, 16), logger: logger.info, wasmPath: process.env.BB_WASM_PATH },
|
|
45
|
-
);
|
|
46
|
-
try {
|
|
47
|
-
// These are optional - easier not to pass them.
|
|
48
|
-
const [_, msgpackProof, vk] = await backend.prove(
|
|
49
|
-
witnessStack.map((arr: Uint8Array) => ungzip(arr)),
|
|
50
|
-
vks.map(hex => new Uint8Array(Buffer.from(hex, 'hex'))),
|
|
51
|
-
);
|
|
52
|
-
const verified = await backend.verify(msgpackProof, vk);
|
|
53
|
-
return verified;
|
|
54
|
-
} finally {
|
|
55
|
-
await backend.destroy();
|
|
56
|
-
}
|
|
57
|
-
}
|