@aztec/bb-prover 0.39.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 (49) hide show
  1. package/dest/bb/cli.d.ts +9 -0
  2. package/dest/bb/cli.d.ts.map +1 -0
  3. package/dest/bb/cli.js +64 -0
  4. package/dest/bb/execute.d.ts +88 -0
  5. package/dest/bb/execute.d.ts.map +1 -0
  6. package/dest/bb/execute.js +288 -0
  7. package/dest/bb/index.d.ts +3 -0
  8. package/dest/bb/index.d.ts.map +1 -0
  9. package/dest/bb/index.js +18 -0
  10. package/dest/index.d.ts +3 -0
  11. package/dest/index.d.ts.map +1 -0
  12. package/dest/index.js +3 -0
  13. package/dest/mappings/mappings.d.ts +12 -0
  14. package/dest/mappings/mappings.d.ts.map +1 -0
  15. package/dest/mappings/mappings.js +22 -0
  16. package/dest/prover/bb_native_proof_creator.d.ts +58 -0
  17. package/dest/prover/bb_native_proof_creator.d.ts.map +1 -0
  18. package/dest/prover/bb_native_proof_creator.js +238 -0
  19. package/dest/prover/bb_prover.d.ts +110 -0
  20. package/dest/prover/bb_prover.d.ts.map +1 -0
  21. package/dest/prover/bb_prover.js +321 -0
  22. package/dest/prover/index.d.ts +3 -0
  23. package/dest/prover/index.d.ts.map +1 -0
  24. package/dest/prover/index.js +3 -0
  25. package/dest/prover/verification_key_data.d.ts +16 -0
  26. package/dest/prover/verification_key_data.d.ts.map +1 -0
  27. package/dest/prover/verification_key_data.js +5 -0
  28. package/dest/stats.d.ts +9 -0
  29. package/dest/stats.d.ts.map +1 -0
  30. package/dest/stats.js +61 -0
  31. package/dest/test/index.d.ts +2 -0
  32. package/dest/test/index.d.ts.map +1 -0
  33. package/dest/test/index.js +2 -0
  34. package/dest/test/test_circuit_prover.d.ts +48 -0
  35. package/dest/test/test_circuit_prover.d.ts.map +1 -0
  36. package/dest/test/test_circuit_prover.js +128 -0
  37. package/package.json +85 -0
  38. package/src/bb/cli.ts +92 -0
  39. package/src/bb/execute.ts +359 -0
  40. package/src/bb/index.ts +23 -0
  41. package/src/index.ts +2 -0
  42. package/src/mappings/mappings.ts +41 -0
  43. package/src/prover/bb_native_proof_creator.ts +382 -0
  44. package/src/prover/bb_prover.ts +557 -0
  45. package/src/prover/index.ts +2 -0
  46. package/src/prover/verification_key_data.ts +16 -0
  47. package/src/stats.ts +82 -0
  48. package/src/test/index.ts +1 -0
  49. package/src/test/test_circuit_prover.ts +268 -0
@@ -0,0 +1,128 @@
1
+ import { PublicKernelType, makePublicInputsAndProof, } from '@aztec/circuit-types';
2
+ import { NESTED_RECURSIVE_PROOF_LENGTH, RECURSIVE_PROOF_LENGTH, RootParityInput, VerificationKeyAsFields, makeEmptyProof, makeRecursiveProof, } from '@aztec/circuits.js';
3
+ import { createDebugLogger } from '@aztec/foundation/log';
4
+ import { Timer } from '@aztec/foundation/timer';
5
+ import { BaseParityArtifact, MergeRollupArtifact, RootParityArtifact, RootRollupArtifact, ServerCircuitArtifacts, SimulatedBaseRollupArtifact, convertBaseParityInputsToWitnessMap, convertBaseParityOutputsFromWitnessMap, convertMergeRollupInputsToWitnessMap, convertMergeRollupOutputsFromWitnessMap, convertPublicTailInputsToWitnessMap, convertPublicTailOutputFromWitnessMap, convertRootParityInputsToWitnessMap, convertRootParityOutputsFromWitnessMap, convertRootRollupInputsToWitnessMap, convertRootRollupOutputsFromWitnessMap, convertSimulatedBaseRollupInputsToWitnessMap, convertSimulatedBaseRollupOutputsFromWitnessMap, } from '@aztec/noir-protocol-circuits-types';
6
+ import { WASMSimulator, emitCircuitSimulationStats } from '@aztec/simulator';
7
+ import { PublicKernelArtifactMapping } from '../mappings/mappings.js';
8
+ import { mapPublicKernelToCircuitName } from '../stats.js';
9
+ const VERIFICATION_KEYS = {
10
+ BaseParityArtifact: VerificationKeyAsFields.makeFake(),
11
+ RootParityArtifact: VerificationKeyAsFields.makeFake(),
12
+ PublicKernelAppLogicArtifact: VerificationKeyAsFields.makeFake(),
13
+ PublicKernelSetupArtifact: VerificationKeyAsFields.makeFake(),
14
+ PublicKernelTailArtifact: VerificationKeyAsFields.makeFake(),
15
+ PublicKernelTeardownArtifact: VerificationKeyAsFields.makeFake(),
16
+ BaseRollupArtifact: VerificationKeyAsFields.makeFake(),
17
+ MergeRollupArtifact: VerificationKeyAsFields.makeFake(),
18
+ RootRollupArtifact: VerificationKeyAsFields.makeFake(),
19
+ };
20
+ /**
21
+ * A class for use in testing situations (e2e, unit test etc)
22
+ * Simulates circuits using the most efficient method and performs no proving
23
+ */
24
+ export class TestCircuitProver {
25
+ constructor(simulationProvider, logger = createDebugLogger('aztec:test-prover')) {
26
+ this.simulationProvider = simulationProvider;
27
+ this.logger = logger;
28
+ this.wasmSimulator = new WASMSimulator();
29
+ }
30
+ /**
31
+ * Simulates the base parity circuit from its inputs.
32
+ * @param inputs - Inputs to the circuit.
33
+ * @returns The public inputs of the parity circuit.
34
+ */
35
+ async getBaseParityProof(inputs) {
36
+ const timer = new Timer();
37
+ const witnessMap = convertBaseParityInputsToWitnessMap(inputs);
38
+ // use WASM here as it is faster for small circuits
39
+ const witness = await this.wasmSimulator.simulateCircuit(witnessMap, BaseParityArtifact);
40
+ const result = convertBaseParityOutputsFromWitnessMap(witness);
41
+ const rootParityInput = new RootParityInput(makeRecursiveProof(RECURSIVE_PROOF_LENGTH), VERIFICATION_KEYS['BaseParityArtifact'], result);
42
+ emitCircuitSimulationStats('base-parity', timer.ms(), inputs.toBuffer().length, result.toBuffer().length, this.logger);
43
+ return Promise.resolve(rootParityInput);
44
+ }
45
+ /**
46
+ * Simulates the root parity circuit from its inputs.
47
+ * @param inputs - Inputs to the circuit.
48
+ * @returns The public inputs of the parity circuit.
49
+ */
50
+ async getRootParityProof(inputs) {
51
+ const timer = new Timer();
52
+ const witnessMap = convertRootParityInputsToWitnessMap(inputs);
53
+ // use WASM here as it is faster for small circuits
54
+ const witness = await this.wasmSimulator.simulateCircuit(witnessMap, RootParityArtifact);
55
+ const result = convertRootParityOutputsFromWitnessMap(witness);
56
+ const rootParityInput = new RootParityInput(makeRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH), VERIFICATION_KEYS['RootParityArtifact'], result);
57
+ emitCircuitSimulationStats('root-parity', timer.ms(), inputs.toBuffer().length, result.toBuffer().length, this.logger);
58
+ return Promise.resolve(rootParityInput);
59
+ }
60
+ /**
61
+ * Simulates the base rollup circuit from its inputs.
62
+ * @param input - Inputs to the circuit.
63
+ * @returns The public inputs as outputs of the simulation.
64
+ */
65
+ async getBaseRollupProof(input) {
66
+ const timer = new Timer();
67
+ const witnessMap = convertSimulatedBaseRollupInputsToWitnessMap(input);
68
+ const simulationProvider = this.simulationProvider ?? this.wasmSimulator;
69
+ const witness = await simulationProvider.simulateCircuit(witnessMap, SimulatedBaseRollupArtifact);
70
+ const result = convertSimulatedBaseRollupOutputsFromWitnessMap(witness);
71
+ emitCircuitSimulationStats('base-rollup', timer.ms(), input.toBuffer().length, result.toBuffer().length, this.logger);
72
+ return makePublicInputsAndProof(result, makeEmptyProof());
73
+ }
74
+ /**
75
+ * Simulates the merge rollup circuit from its inputs.
76
+ * @param input - Inputs to the circuit.
77
+ * @returns The public inputs as outputs of the simulation.
78
+ */
79
+ async getMergeRollupProof(input) {
80
+ const timer = new Timer();
81
+ const witnessMap = convertMergeRollupInputsToWitnessMap(input);
82
+ // use WASM here as it is faster for small circuits
83
+ const witness = await this.wasmSimulator.simulateCircuit(witnessMap, MergeRollupArtifact);
84
+ const result = convertMergeRollupOutputsFromWitnessMap(witness);
85
+ emitCircuitSimulationStats('merge-rollup', timer.ms(), input.toBuffer().length, result.toBuffer().length, this.logger);
86
+ return makePublicInputsAndProof(result, makeEmptyProof());
87
+ }
88
+ /**
89
+ * Simulates the root rollup circuit from its inputs.
90
+ * @param input - Inputs to the circuit.
91
+ * @returns The public inputs as outputs of the simulation.
92
+ */
93
+ async getRootRollupProof(input) {
94
+ const timer = new Timer();
95
+ const witnessMap = convertRootRollupInputsToWitnessMap(input);
96
+ // use WASM here as it is faster for small circuits
97
+ const witness = await this.wasmSimulator.simulateCircuit(witnessMap, RootRollupArtifact);
98
+ const result = convertRootRollupOutputsFromWitnessMap(witness);
99
+ emitCircuitSimulationStats('root-rollup', timer.ms(), input.toBuffer().length, result.toBuffer().length, this.logger);
100
+ return makePublicInputsAndProof(result, makeEmptyProof());
101
+ }
102
+ async getPublicKernelProof(kernelRequest) {
103
+ const timer = new Timer();
104
+ const kernelOps = PublicKernelArtifactMapping[kernelRequest.type];
105
+ if (kernelOps === undefined) {
106
+ throw new Error(`Unable to prove for kernel type ${PublicKernelType[kernelRequest.type]}`);
107
+ }
108
+ const witnessMap = kernelOps.convertInputs(kernelRequest.inputs);
109
+ const witness = await this.wasmSimulator.simulateCircuit(witnessMap, ServerCircuitArtifacts[kernelOps.artifact]);
110
+ const result = kernelOps.convertOutputs(witness);
111
+ emitCircuitSimulationStats(mapPublicKernelToCircuitName(kernelRequest.type), timer.ms(), kernelRequest.inputs.toBuffer().length, result.toBuffer().length, this.logger);
112
+ return makePublicInputsAndProof(result, makeEmptyProof());
113
+ }
114
+ async getPublicTailProof(kernelRequest) {
115
+ const timer = new Timer();
116
+ const witnessMap = convertPublicTailInputsToWitnessMap(kernelRequest.inputs);
117
+ // use WASM here as it is faster for small circuits
118
+ const witness = await this.wasmSimulator.simulateCircuit(witnessMap, ServerCircuitArtifacts['PublicKernelTailArtifact']);
119
+ const result = convertPublicTailOutputFromWitnessMap(witness);
120
+ emitCircuitSimulationStats('public-kernel-tail', timer.ms(), kernelRequest.inputs.toBuffer().length, result.toBuffer().length, this.logger);
121
+ return makePublicInputsAndProof(result, makeEmptyProof());
122
+ }
123
+ // Not implemented for test circuits
124
+ verifyProof(_1, _2) {
125
+ return Promise.reject(new Error('Method not implemented.'));
126
+ }
127
+ }
128
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdF9jaXJjdWl0X3Byb3Zlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L3Rlc3RfY2lyY3VpdF9wcm92ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUlMLGdCQUFnQixFQUVoQix3QkFBd0IsR0FDekIsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBTUwsNkJBQTZCLEVBRzdCLHNCQUFzQixFQUN0QixlQUFlLEVBSWYsdUJBQXVCLEVBQ3ZCLGNBQWMsRUFDZCxrQkFBa0IsR0FDbkIsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEQsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixtQkFBbUIsRUFDbkIsa0JBQWtCLEVBQ2xCLGtCQUFrQixFQUNsQixzQkFBc0IsRUFFdEIsMkJBQTJCLEVBQzNCLG1DQUFtQyxFQUNuQyxzQ0FBc0MsRUFDdEMsb0NBQW9DLEVBQ3BDLHVDQUF1QyxFQUN2QyxtQ0FBbUMsRUFDbkMscUNBQXFDLEVBQ3JDLG1DQUFtQyxFQUNuQyxzQ0FBc0MsRUFDdEMsbUNBQW1DLEVBQ25DLHNDQUFzQyxFQUN0Qyw0Q0FBNEMsRUFDNUMsK0NBQStDLEdBQ2hELE1BQU0scUNBQXFDLENBQUM7QUFDN0MsT0FBTyxFQUEyQixhQUFhLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUV0RyxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFM0QsTUFBTSxpQkFBaUIsR0FBNEQ7SUFDakYsa0JBQWtCLEVBQUUsdUJBQXVCLENBQUMsUUFBUSxFQUFFO0lBQ3RELGtCQUFrQixFQUFFLHVCQUF1QixDQUFDLFFBQVEsRUFB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
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@aztec/bb-prover",
3
+ "version": "0.39.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": "./dest/index.js"
7
+ },
8
+ "bin": {
9
+ "bb-cli": "./dest/bb/index.js"
10
+ },
11
+ "typedocOptions": {
12
+ "entryPoints": [
13
+ "./src/index.ts"
14
+ ],
15
+ "name": "BB Prover",
16
+ "tsconfig": "./tsconfig.json"
17
+ },
18
+ "inherits": [
19
+ "../package.common.json"
20
+ ],
21
+ "scripts": {
22
+ "build": "yarn clean && tsc -b",
23
+ "build:dev": "tsc -b --watch",
24
+ "clean": "rm -rf ./dest .tsbuildinfo",
25
+ "formatting": "run -T prettier --check ./src && run -T eslint ./src",
26
+ "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
27
+ "bb": "node --no-warnings ./dest/bb/index.js",
28
+ "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests"
29
+ },
30
+ "jest": {
31
+ "moduleNameMapper": {
32
+ "^(\\.{1,2}/.*)\\.[cm]?js$": "$1"
33
+ },
34
+ "testRegex": "./src/.*\\.test\\.(js|mjs|ts)$",
35
+ "rootDir": "./src",
36
+ "transform": {
37
+ "^.+\\.tsx?$": [
38
+ "@swc/jest"
39
+ ]
40
+ },
41
+ "extensionsToTreatAsEsm": [
42
+ ".ts"
43
+ ],
44
+ "reporters": [
45
+ [
46
+ "default",
47
+ {
48
+ "summaryThreshold": 9999
49
+ }
50
+ ]
51
+ ]
52
+ },
53
+ "dependencies": {
54
+ "@aztec/circuit-types": "0.39.0",
55
+ "@aztec/circuits.js": "0.39.0",
56
+ "@aztec/foundation": "0.39.0",
57
+ "@aztec/noir-protocol-circuits-types": "0.39.0",
58
+ "@aztec/simulator": "0.39.0",
59
+ "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi",
60
+ "@noir-lang/types": "portal:../../noir/packages/types",
61
+ "commander": "^9.0.0",
62
+ "source-map-support": "^0.5.21",
63
+ "tslib": "^2.4.0"
64
+ },
65
+ "devDependencies": {
66
+ "@jest/globals": "^29.5.0",
67
+ "@types/jest": "^29.5.0",
68
+ "@types/memdown": "^3.0.0",
69
+ "@types/node": "^18.7.23",
70
+ "@types/source-map-support": "^0.5.10",
71
+ "jest": "^29.5.0",
72
+ "jest-mock-extended": "^3.0.3",
73
+ "ts-node": "^10.9.1",
74
+ "typescript": "^5.0.4"
75
+ },
76
+ "files": [
77
+ "dest",
78
+ "src",
79
+ "!*.test.*"
80
+ ],
81
+ "types": "./dest/index.d.ts",
82
+ "engines": {
83
+ "node": ">=18"
84
+ }
85
+ }
package/src/bb/cli.ts ADDED
@@ -0,0 +1,92 @@
1
+ import { type LogFn } from '@aztec/foundation/log';
2
+ import { type ProtocolArtifact, ProtocolCircuitArtifacts } from '@aztec/noir-protocol-circuits-types';
3
+
4
+ import { Command } from 'commander';
5
+ import * as fs from 'fs/promises';
6
+
7
+ import { generateKeyForNoirCircuit } from './execute.js';
8
+
9
+ const { BB_WORKING_DIRECTORY, BB_BINARY_PATH } = process.env;
10
+
11
+ /**
12
+ * Returns commander program that defines the CLI.
13
+ * @param log - Console logger.
14
+ * @returns The CLI.
15
+ */
16
+ export function getProgram(log: LogFn): Command {
17
+ const program = new Command();
18
+
19
+ program.name('bb-cli').description('CLI for interacting with Barretenberg.');
20
+
21
+ program
22
+ .command('protocol-circuits')
23
+ .description('Lists the available protocol circuit artifacts')
24
+ .action(() => {
25
+ log(Object.keys(ProtocolCircuitArtifacts).reduce((prev: string, x: string) => prev.concat(`\n${x}`)));
26
+ });
27
+
28
+ program
29
+ .command('write-pk')
30
+ .description('Generates the proving key for the specified circuit')
31
+ .requiredOption(
32
+ '-w, --working-directory <string>',
33
+ 'A directory to use for storing input/output files',
34
+ BB_WORKING_DIRECTORY,
35
+ )
36
+ .requiredOption('-b, --bb-path <string>', 'The path to the BB binary', BB_BINARY_PATH)
37
+ .requiredOption('-c, --circuit <string>', 'The name of a protocol circuit')
38
+ .action(async options => {
39
+ const compiledCircuit = ProtocolCircuitArtifacts[options.circuit as ProtocolArtifact];
40
+ if (!compiledCircuit) {
41
+ log(`Failed to find circuit ${options.circuit}`);
42
+ return;
43
+ }
44
+ try {
45
+ await fs.access(options.workingDirectory, fs.constants.W_OK);
46
+ } catch (error) {
47
+ log(`Working directory does not exist`);
48
+ return;
49
+ }
50
+ await generateKeyForNoirCircuit(
51
+ options.bbPath,
52
+ options.workingDirectory,
53
+ options.circuit,
54
+ compiledCircuit,
55
+ 'pk',
56
+ log,
57
+ );
58
+ });
59
+
60
+ program
61
+ .command('write-vk')
62
+ .description('Generates the verification key for the specified circuit')
63
+ .requiredOption(
64
+ '-w, --working-directory <string>',
65
+ 'A directory to use for storing input/output files',
66
+ BB_WORKING_DIRECTORY,
67
+ )
68
+ .requiredOption('-b, --bb-path <string>', 'The path to the BB binary', BB_BINARY_PATH)
69
+ .requiredOption('-c, --circuit <string>', 'The name of a protocol circuit')
70
+ .action(async options => {
71
+ const compiledCircuit = ProtocolCircuitArtifacts[options.circuit as ProtocolArtifact];
72
+ if (!compiledCircuit) {
73
+ log(`Failed to find circuit ${options.circuit}`);
74
+ return;
75
+ }
76
+ try {
77
+ await fs.access(options.workingDirectory, fs.constants.W_OK);
78
+ } catch (error) {
79
+ log(`Working directory does not exist`);
80
+ return;
81
+ }
82
+ await generateKeyForNoirCircuit(
83
+ options.bbPath,
84
+ options.workingDirectory,
85
+ options.circuit,
86
+ compiledCircuit,
87
+ 'vk',
88
+ log,
89
+ );
90
+ });
91
+ return program;
92
+ }
@@ -0,0 +1,359 @@
1
+ import { sha256 } from '@aztec/foundation/crypto';
2
+ import { type LogFn } from '@aztec/foundation/log';
3
+ import { Timer } from '@aztec/foundation/timer';
4
+ import { type NoirCompiledCircuit } from '@aztec/types/noir';
5
+
6
+ import * as proc from 'child_process';
7
+ import * as fs from 'fs/promises';
8
+
9
+ export const VK_FILENAME = 'vk';
10
+ export const VK_FIELDS_FILENAME = 'vk_fields.json';
11
+ export const PROOF_FILENAME = 'proof';
12
+ export const PROOF_FIELDS_FILENAME = 'proof_fields.json';
13
+
14
+ export enum BB_RESULT {
15
+ SUCCESS,
16
+ FAILURE,
17
+ ALREADY_PRESENT,
18
+ }
19
+
20
+ export type BBSuccess = {
21
+ status: BB_RESULT.SUCCESS | BB_RESULT.ALREADY_PRESENT;
22
+ duration: number;
23
+ pkPath?: string;
24
+ vkPath?: string;
25
+ proofPath?: string;
26
+ };
27
+
28
+ export type BBFailure = {
29
+ status: BB_RESULT.FAILURE;
30
+ reason: string;
31
+ };
32
+
33
+ export type BBResult = BBSuccess | BBFailure;
34
+
35
+ /**
36
+ * Invokes the Barretenberg binary with the provided command and args
37
+ * @param pathToBB - The path to the BB binary
38
+ * @param command - The command to execute
39
+ * @param args - The arguments to pass
40
+ * @param logger - A log function
41
+ * @param resultParser - An optional handler for detecting success or failure
42
+ * @returns The completed partial witness outputted from the circuit
43
+ */
44
+ export function executeBB(
45
+ pathToBB: string,
46
+ command: string,
47
+ args: string[],
48
+ logger: LogFn,
49
+ resultParser = (code: number) => code === 0,
50
+ ) {
51
+ return new Promise<BB_RESULT.SUCCESS | BB_RESULT.FAILURE>((resolve, reject) => {
52
+ // spawn the bb process
53
+ const bb = proc.spawn(pathToBB, [command, ...args]);
54
+ bb.stdout.on('data', data => {
55
+ const message = data.toString('utf-8').replace(/\n$/, '');
56
+ logger(message);
57
+ });
58
+ bb.stderr.on('data', data => {
59
+ const message = data.toString('utf-8').replace(/\n$/, '');
60
+ logger(message);
61
+ });
62
+ bb.on('close', (code: number) => {
63
+ if (resultParser(code)) {
64
+ resolve(BB_RESULT.SUCCESS);
65
+ } else {
66
+ reject();
67
+ }
68
+ });
69
+ }).catch(_ => BB_RESULT.FAILURE);
70
+ }
71
+
72
+ const bytecodeHashFilename = 'bytecode_hash';
73
+ const bytecodeFilename = 'bytecode';
74
+
75
+ /**
76
+ * Used for generating either a proving or verification key, will exit early if the key already exists
77
+ * It assumes the provided working directory is one where the caller wishes to maintain a permanent set of keys
78
+ * It is not considered a temporary directory
79
+ * @param pathToBB - The full path to the bb binary
80
+ * @param workingDirectory - The directory into which the key should be created
81
+ * @param circuitName - An identifier for the circuit
82
+ * @param compiledCircuit - The compiled circuit
83
+ * @param key - The type of key, either 'pk' or 'vk'
84
+ * @param log - A logging function
85
+ * @param force - Force the key to be regenerated even if it already exists
86
+ * @returns An instance of BBResult
87
+ */
88
+ export async function generateKeyForNoirCircuit(
89
+ pathToBB: string,
90
+ workingDirectory: string,
91
+ circuitName: string,
92
+ compiledCircuit: NoirCompiledCircuit,
93
+ key: 'vk' | 'pk',
94
+ log: LogFn,
95
+ force = false,
96
+ ): Promise<BBSuccess | BBFailure> {
97
+ const bytecode = Buffer.from(compiledCircuit.bytecode, 'base64');
98
+
99
+ // The key generation is written to e.g. /workingDirectory/pk/BaseParityArtifact/pk
100
+ // The bytecode hash file is also written here as /workingDirectory/pk/BaseParityArtifact/bytecode-hash
101
+ // The bytecode is written to e.g. /workingDirectory/pk/BaseParityArtifact/bytecode
102
+ // The bytecode is removed after the key is generated, leaving just the hash file
103
+ const circuitOutputDirectory = `${workingDirectory}/${key}/${circuitName}`;
104
+ const bytecodeHashPath = `${circuitOutputDirectory}/${bytecodeHashFilename}`;
105
+ const bytecodePath = `${circuitOutputDirectory}/${bytecodeFilename}`;
106
+ const bytecodeHash = sha256(bytecode);
107
+
108
+ const outputPath = `${circuitOutputDirectory}`;
109
+
110
+ // ensure the directory exists
111
+ await fs.mkdir(circuitOutputDirectory, { recursive: true });
112
+
113
+ // Generate the key if we have been told to, or there is no bytecode hash
114
+ let mustRegenerate =
115
+ force ||
116
+ (await fs
117
+ .access(bytecodeHashPath, fs.constants.R_OK)
118
+ .then(_ => false)
119
+ .catch(_ => true));
120
+
121
+ if (!mustRegenerate) {
122
+ // Check to see if the bytecode hash has changed from the stored value
123
+ const data: Buffer = await fs.readFile(bytecodeHashPath).catch(_ => Buffer.alloc(0));
124
+ mustRegenerate = data.length == 0 || !data.equals(bytecodeHash);
125
+ }
126
+
127
+ if (!mustRegenerate) {
128
+ // No need to generate, early out
129
+ return {
130
+ status: BB_RESULT.ALREADY_PRESENT,
131
+ duration: 0,
132
+ pkPath: key === 'pk' ? outputPath : undefined,
133
+ vkPath: key === 'vk' ? outputPath : undefined,
134
+ proofPath: undefined,
135
+ };
136
+ }
137
+
138
+ // Check we have access to bb
139
+ const binaryPresent = await fs
140
+ .access(pathToBB, fs.constants.R_OK)
141
+ .then(_ => true)
142
+ .catch(_ => false);
143
+ if (!binaryPresent) {
144
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
145
+ }
146
+
147
+ // We are now going to generate the key
148
+ try {
149
+ // Write the bytecode to the working directory
150
+ await fs.writeFile(bytecodePath, bytecode);
151
+
152
+ // args are the output path and the input bytecode path
153
+ const args = ['-o', outputPath, '-b', bytecodePath];
154
+ const timer = new Timer();
155
+ let result = await executeBB(pathToBB, `write_${key}`, args, log);
156
+ // If we succeeded and the type of key if verification, have bb write the 'fields' version too
157
+ if (result == BB_RESULT.SUCCESS && key === 'vk') {
158
+ const asFieldsArgs = ['-k', `${outputPath}/${VK_FILENAME}`, '-o', `${outputPath}/${VK_FIELDS_FILENAME}`, '-v'];
159
+ result = await executeBB(pathToBB, `vk_as_fields`, asFieldsArgs, log);
160
+ }
161
+ const duration = timer.ms();
162
+ // Cleanup the bytecode file
163
+ await fs.rm(bytecodePath, { force: true });
164
+ if (result == BB_RESULT.SUCCESS) {
165
+ // Store the bytecode hash so we don't need to regenerate at a later time
166
+ await fs.writeFile(bytecodeHashPath, bytecodeHash);
167
+ return {
168
+ status: BB_RESULT.SUCCESS,
169
+ duration,
170
+ pkPath: key === 'pk' ? outputPath : undefined,
171
+ vkPath: key === 'vk' ? outputPath : undefined,
172
+ proofPath: undefined,
173
+ };
174
+ }
175
+ // Not a great error message here but it is difficult to decipher what comes from bb
176
+ return { status: BB_RESULT.FAILURE, reason: `Failed to generate key` };
177
+ } catch (error) {
178
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Used for generating proofs of noir circuits.
184
+ * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
185
+ * @param pathToBB - The full path to the bb binary
186
+ * @param workingDirectory - A working directory for use by bb
187
+ * @param circuitName - An identifier for the circuit
188
+ * @param bytecode - The compiled circuit bytecode
189
+ * @param inputWitnessFile - The circuit input witness
190
+ * @param log - A logging function
191
+ * @returns An object containing a result indication, the location of the proof and the duration taken
192
+ */
193
+ export async function generateProof(
194
+ pathToBB: string,
195
+ workingDirectory: string,
196
+ circuitName: string,
197
+ bytecode: Buffer,
198
+ inputWitnessFile: string,
199
+ log: LogFn,
200
+ ): Promise<BBFailure | BBSuccess> {
201
+ // Check that the working directory exists
202
+ try {
203
+ await fs.access(workingDirectory);
204
+ } catch (error) {
205
+ return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
206
+ }
207
+
208
+ // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
209
+ const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
210
+
211
+ // The proof is written to e.g. /workingDirectory/proof
212
+ const outputPath = `${workingDirectory}`;
213
+
214
+ const binaryPresent = await fs
215
+ .access(pathToBB, fs.constants.R_OK)
216
+ .then(_ => true)
217
+ .catch(_ => false);
218
+ if (!binaryPresent) {
219
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
220
+ }
221
+
222
+ try {
223
+ // Write the bytecode to the working directory
224
+ await fs.writeFile(bytecodePath, bytecode);
225
+ const args = ['-o', outputPath, '-b', bytecodePath, '-w', inputWitnessFile, '-v'];
226
+ const timer = new Timer();
227
+ const logFunction = (message: string) => {
228
+ log(`${circuitName} BB out - ${message}`);
229
+ };
230
+ const result = await executeBB(pathToBB, 'prove_output_all', args, logFunction);
231
+ const duration = timer.ms();
232
+ // cleanup the bytecode
233
+ await fs.rm(bytecodePath, { force: true });
234
+ if (result == BB_RESULT.SUCCESS) {
235
+ return {
236
+ status: BB_RESULT.SUCCESS,
237
+ duration,
238
+ proofPath: `${outputPath}`,
239
+ pkPath: undefined,
240
+ vkPath: `${outputPath}`,
241
+ };
242
+ }
243
+ // Not a great error message here but it is difficult to decipher what comes from bb
244
+ return { status: BB_RESULT.FAILURE, reason: `Failed to generate proof` };
245
+ } catch (error) {
246
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Used for verifying proofs of noir circuits
252
+ * @param pathToBB - The full path to the bb binary
253
+ * @param proofFullPath - The full path to the proof to be verified
254
+ * @param verificationKeyPath - The full path to the circuit verification key
255
+ * @param log - A logging function
256
+ * @returns An object containing a result indication and duration taken
257
+ */
258
+ export async function verifyProof(
259
+ pathToBB: string,
260
+ proofFullPath: string,
261
+ verificationKeyPath: string,
262
+ log: LogFn,
263
+ ): Promise<BBFailure | BBSuccess> {
264
+ const binaryPresent = await fs
265
+ .access(pathToBB, fs.constants.R_OK)
266
+ .then(_ => true)
267
+ .catch(_ => false);
268
+ if (!binaryPresent) {
269
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
270
+ }
271
+
272
+ try {
273
+ const args = ['-p', proofFullPath, '-k', verificationKeyPath];
274
+ const timer = new Timer();
275
+ const result = await executeBB(pathToBB, 'verify', args, log);
276
+ const duration = timer.ms();
277
+ if (result == BB_RESULT.SUCCESS) {
278
+ return { status: BB_RESULT.SUCCESS, duration };
279
+ }
280
+ // Not a great error message here but it is difficult to decipher what comes from bb
281
+ return { status: BB_RESULT.FAILURE, reason: `Failed to verify proof` };
282
+ } catch (error) {
283
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
284
+ }
285
+ }
286
+
287
+ /**
288
+ * Used for verifying proofs of noir circuits
289
+ * @param pathToBB - The full path to the bb binary
290
+ * @param verificationKeyPath - The directory containing the binary verification key
291
+ * @param verificationKeyFilename - The filename of the verification key
292
+ * @param log - A logging function
293
+ * @returns An object containing a result indication and duration taken
294
+ */
295
+ export async function writeVkAsFields(
296
+ pathToBB: string,
297
+ verificationKeyPath: string,
298
+ verificationKeyFilename: string,
299
+ log: LogFn,
300
+ ): Promise<BBFailure | BBSuccess> {
301
+ const binaryPresent = await fs
302
+ .access(pathToBB, fs.constants.R_OK)
303
+ .then(_ => true)
304
+ .catch(_ => false);
305
+ if (!binaryPresent) {
306
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
307
+ }
308
+
309
+ try {
310
+ const args = ['-k', `${verificationKeyPath}/${verificationKeyFilename}`, '-v'];
311
+ const timer = new Timer();
312
+ const result = await executeBB(pathToBB, 'vk_as_fields', args, log);
313
+ const duration = timer.ms();
314
+ if (result == BB_RESULT.SUCCESS) {
315
+ return { status: BB_RESULT.SUCCESS, duration, vkPath: verificationKeyPath };
316
+ }
317
+ // Not a great error message here but it is difficult to decipher what comes from bb
318
+ return { status: BB_RESULT.FAILURE, reason: `Failed to create vk as fields` };
319
+ } catch (error) {
320
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Used for verifying proofs of noir circuits
326
+ * @param pathToBB - The full path to the bb binary
327
+ * @param proofPath - The directory containing the binary proof
328
+ * @param proofFileName - The filename of the proof
329
+ * @param log - A logging function
330
+ * @returns An object containing a result indication and duration taken
331
+ */
332
+ export async function writeProofAsFields(
333
+ pathToBB: string,
334
+ proofPath: string,
335
+ proofFileName: string,
336
+ log: LogFn,
337
+ ): Promise<BBFailure | BBSuccess> {
338
+ const binaryPresent = await fs
339
+ .access(pathToBB, fs.constants.R_OK)
340
+ .then(_ => true)
341
+ .catch(_ => false);
342
+ if (!binaryPresent) {
343
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
344
+ }
345
+
346
+ try {
347
+ const args = ['-p', `${proofPath}/${proofFileName}`, '-v'];
348
+ const timer = new Timer();
349
+ const result = await executeBB(pathToBB, 'proof_as_fields', args, log);
350
+ const duration = timer.ms();
351
+ if (result == BB_RESULT.SUCCESS) {
352
+ return { status: BB_RESULT.SUCCESS, duration, proofPath: proofPath };
353
+ }
354
+ // Not a great error message here but it is difficult to decipher what comes from bb
355
+ return { status: BB_RESULT.FAILURE, reason: `Failed to create proof as fields` };
356
+ } catch (error) {
357
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
358
+ }
359
+ }