diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 4de55ad3f79..f854b388087 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -3,8 +3,7 @@ name: test-integration on: workflow_dispatch: pull_request: - paths: - - ./compiler/integration-tests/** + merge_group: schedule: - cron: "0 2 * * *" # Run nightly at 2 AM UTC @@ -222,6 +221,8 @@ jobs: run: | yarn workspace @noir-lang/source-resolver build yarn workspace @noir-lang/acvm_js build + yarn workspace @noir-lang/types build + yarn workspace @noir-lang/backend_barretenberg build yarn workspace @noir-lang/noir_js build - name: Run `integration-tests` diff --git a/compiler/integration-tests/package.json b/compiler/integration-tests/package.json index dbf372642b2..cc48ebd5449 100644 --- a/compiler/integration-tests/package.json +++ b/compiler/integration-tests/package.json @@ -13,7 +13,7 @@ "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "dependencies": { - "@aztec/bb.js": "^0.7.3", + "@noir-lang/backend_barretenberg": "workspace:*", "@noir-lang/noir_js": "workspace:*", "@noir-lang/noir_wasm": "workspace:*", "@noir-lang/source-resolver": "workspace:*", diff --git a/compiler/integration-tests/test/integration/browser/compile_prove_verify.test.ts b/compiler/integration-tests/test/integration/browser/compile_prove_verify.test.ts index 155fbbf02fa..44639a3657a 100644 --- a/compiler/integration-tests/test/integration/browser/compile_prove_verify.test.ts +++ b/compiler/integration-tests/test/integration/browser/compile_prove_verify.test.ts @@ -3,8 +3,8 @@ import { TEST_LOG_LEVEL } from '../../environment.js'; import { Logger } from 'tslog'; import { initializeResolver } from '@noir-lang/source-resolver'; import newCompiler, { compile, init_log_level as compilerLogLevel } from '@noir-lang/noir_wasm'; -import { acvm, abi, generateWitness, acirToUint8Array } from '@noir-lang/noir_js'; -import { Barretenberg, RawBuffer, Crs } from '@aztec/bb.js'; +import { acvm, abi, Noir } from '@noir-lang/noir_js'; +import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; import { ethers } from 'ethers'; import * as TOML from 'smol-toml'; @@ -29,39 +29,27 @@ async function getFile(file_path: string): Promise { return await response.text(); } -const CIRCUIT_SIZE = 2 ** 19; const FIELD_ELEMENT_BYTES = 32; const test_cases = [ { case: 'tooling/nargo_cli/tests/execution_success/1_mul', - compiled: 'foundry-project/out/1_mul.sol/UltraVerifier.json', - deployInformation: 'foundry-project/mul_output.json', + compiled: 'compiler/integration-tests/foundry-project/out/1_mul.sol/UltraVerifier.json', + deployInformation: 'compiler/integration-tests/foundry-project/mul_output.json', numPublicInputs: 0, }, { case: 'compiler/integration-tests/test/circuits/main', - compiled: 'foundry-project/out/main.sol/UltraVerifier.json', - deployInformation: 'foundry-project/main_output.json', + compiled: 'compiler/integration-tests/foundry-project/out/main.sol/UltraVerifier.json', + deployInformation: 'compiler/integration-tests/foundry-project/main_output.json', numPublicInputs: 1, }, ]; -const numberOfThreads = navigator.hardwareConcurrency || 1; - const suite = Mocha.Suite.create(mocha.suite, 'Noir end to end test'); suite.timeout(60 * 20e3); //20mins -const api = await Barretenberg.new(numberOfThreads); -await api.commonInitSlabAllocator(CIRCUIT_SIZE); - -// Plus 1 needed! -const crs = await Crs.new(CIRCUIT_SIZE + 1); -await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data())); - -const acirComposer = await api.acirNewAcirComposer(CIRCUIT_SIZE); - async function getCircuit(noirSource: string) { // eslint-disable-next-line @typescript-eslint/no-unused-vars initializeResolver((id: string) => { @@ -88,18 +76,6 @@ function separatePublicInputsFromProof( }; } -async function generateProof(base64Bytecode: string, witnessUint8Array: Uint8Array, optimizeForRecursion: boolean) { - const acirUint8Array = acirToUint8Array(base64Bytecode); - // This took ~6.5 minutes! - return api.acirCreateProof(acirComposer, acirUint8Array, witnessUint8Array, optimizeForRecursion); -} - -async function verifyProof(proof: Uint8Array, optimizeForRecursion: boolean) { - await api.acirInitVerificationKey(acirComposer); - const verified = await api.acirVerifyProof(acirComposer, proof, optimizeForRecursion); - return verified; -} - test_cases.forEach((testInfo) => { const test_name = testInfo.case.split('/').pop(); const mochaTest = new Mocha.Test(`${test_name} (Compile, Execute, Prove, Verify)`, async () => { @@ -118,25 +94,20 @@ test_cases.forEach((testInfo) => { throw e; } + const noir_program = { bytecode: compile_output.circuit, abi: compile_output.abi }; + const backend = new BarretenbergBackend(noir_program); + const program = new Noir(noir_program, backend); + const prover_toml = await getFile(`${base_relative_path}/${test_case}/Prover.toml`); const inputs = TOML.parse(prover_toml); - const witnessArray: Uint8Array = await generateWitness( - { - bytecode: compile_output.circuit, - abi: compile_output.abi, - }, - inputs, - ); - // JS Proving - const isRecursive = false; - const proofWithPublicInputs = await generateProof(compile_output.circuit, witnessArray, isRecursive); + const proofWithPublicInputs = await program.generateFinalProof(inputs); // JS verification - const verified = await verifyProof(proofWithPublicInputs, isRecursive); + const verified = await program.verifyFinalProof(proofWithPublicInputs); expect(verified, 'Proof fails verification in JS').to.be.true; // Smart contract verification diff --git a/compiler/integration-tests/test/integration/browser/recursion.test.ts b/compiler/integration-tests/test/integration/browser/recursion.test.ts index 88d9fe44099..7f2140a8e8e 100644 --- a/compiler/integration-tests/test/integration/browser/recursion.test.ts +++ b/compiler/integration-tests/test/integration/browser/recursion.test.ts @@ -4,13 +4,10 @@ import { TEST_LOG_LEVEL } from '../../environment.js'; import { Logger } from 'tslog'; import { initializeResolver } from '@noir-lang/source-resolver'; import newCompiler, { compile, init_log_level as compilerLogLevel } from '@noir-lang/noir_wasm'; -import { decompressSync as gunzip } from 'fflate'; import { acvm, abi, generateWitness } from '@noir-lang/noir_js'; -// @ts-ignore -import { Barretenberg, RawBuffer, Crs } from '@aztec/bb.js'; - import * as TOML from 'smol-toml'; +import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; const logger = new Logger({ name: 'test', minLevel: TEST_LOG_LEVEL }); @@ -23,8 +20,6 @@ await initACVM(); compilerLogLevel('INFO'); -const numberOfThreads = navigator.hardwareConcurrency || 1; - const base_relative_path = '../../../../..'; const circuit_main = 'compiler/integration-tests/test/circuits/main'; const circuit_recursion = 'compiler/integration-tests/test/circuits/recursion'; @@ -37,16 +32,6 @@ async function getFile(url: URL): Promise { return await response.text(); } -const CIRCUIT_SIZE = 2 ** 19; - -const api = await Barretenberg.new(numberOfThreads); -await api.commonInitSlabAllocator(CIRCUIT_SIZE); -// Plus 1 needed! -const crs = await Crs.new(CIRCUIT_SIZE + 1); -await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data())); - -const acirComposer = await api.acirNewAcirComposer(CIRCUIT_SIZE); - async function getCircuit(noirSource: string) { // eslint-disable-next-line @typescript-eslint/no-unused-vars initializeResolver((id: string) => { @@ -57,17 +42,6 @@ async function getCircuit(noirSource: string) { return compile({}); } -async function generateProof(acirUint8Array: Uint8Array, witnessUint8Array: Uint8Array, optimizeForRecursion: boolean) { - // This took ~6.5 minutes! - return api.acirCreateProof(acirComposer, acirUint8Array, witnessUint8Array, optimizeForRecursion); -} - -async function verifyProof(proof: Uint8Array, optimizeForRecursion: boolean) { - await api.acirInitVerificationKey(acirComposer); - const verified = await api.acirVerifyProof(acirComposer, proof, optimizeForRecursion); - return verified; -} - describe('It compiles noir program code, receiving circuit bytes and abi object.', () => { let circuit_main_source; let circuit_main_toml; @@ -92,36 +66,24 @@ describe('It compiles noir program code, receiving circuit bytes and abi object. const { circuit: main_circuit, abi: main_abi } = await getCircuit(circuit_main_source); const main_inputs = TOML.parse(circuit_main_toml); - const main_witnessUint8Array = await generateWitness( - { - bytecode: main_circuit, - abi: main_abi, - }, - main_inputs, - ); - const main_compressedByteCode = Uint8Array.from(atob(main_circuit), (c) => c.charCodeAt(0)); - const main_acirUint8Array = gunzip(main_compressedByteCode); + const main_program = { bytecode: main_circuit, abi: main_abi }; + const main_backend = new BarretenbergBackend(main_program); - const optimizeMainProofForRecursion = true; + const main_witnessUint8Array = await generateWitness(main_program, main_inputs); - const main_proof = await generateProof(main_acirUint8Array, main_witnessUint8Array, optimizeMainProofForRecursion); - - const main_verification = await verifyProof(main_proof, optimizeMainProofForRecursion); + const main_proof = await main_backend.generateIntermediateProof(main_witnessUint8Array); + const main_verification = await main_backend.verifyIntermediateProof(main_proof); logger.debug('main_verification', main_verification); expect(main_verification).to.be.true; const numPublicInputs = 1; - const proofAsFields = (await api.acirSerializeProofIntoFields(acirComposer, main_proof, numPublicInputs)).map((p) => - p.toString(), + const { proofAsFields, vkAsFields, vkHash } = await main_backend.generateIntermediateProofArtifacts( + main_proof, + numPublicInputs, ); - const vk = await api.acirSerializeVerificationKeyIntoFields(acirComposer); - - const vkAsFields = vk[0].map((vk) => vk.toString()); - const vkHash = vk[1].toString(); - const recursion_inputs = { verification_key: vkAsFields, proof: proofAsFields, @@ -133,36 +95,26 @@ describe('It compiles noir program code, receiving circuit bytes and abi object. logger.debug('recursion_inputs', recursion_inputs); const { circuit: recursion_circuit, abi: recursion_abi } = await getCircuit(circuit_recursion_source); + const recursion_program = { bytecode: recursion_circuit, abi: recursion_abi }; - const recursion_witnessUint8Array = await generateWitness( - { - bytecode: recursion_circuit, - abi: recursion_abi, - }, - recursion_inputs, - ); - - const recursion_compressedByteCode = Uint8Array.from(atob(recursion_circuit), (c) => c.charCodeAt(0)); - - const recursion_acirUint8Array = gunzip(recursion_compressedByteCode); - - const optimizeRecursionProofForRecursion = false; - - const recursion_proof = await generateProof( - recursion_acirUint8Array, - recursion_witnessUint8Array, - optimizeRecursionProofForRecursion, - ); + const recursion_backend = new BarretenbergBackend(recursion_program); - const recursion_numPublicInputs = 1; + const recursion_witnessUint8Array = await generateWitness(recursion_program, recursion_inputs); - const recursion_proofAsFields = ( - await api.acirSerializeProofIntoFields(acirComposer, recursion_proof, recursion_numPublicInputs) - ).map((p) => p.toString()); + const recursion_proof = await recursion_backend.generateFinalProof(recursion_witnessUint8Array); - logger.debug('recursion_proofAsFields', recursion_proofAsFields); + // Causes an "unreachable" error. + // Due to the fact that it's a non-recursive proof? + // + // const recursion_numPublicInputs = 1; + // const { proofAsFields: recursion_proofAsFields } = await recursion_backend.generateIntermediateProofArtifacts( + // recursion_proof, + // recursion_numPublicInputs, + // ); + // + // logger.debug('recursion_proofAsFields', recursion_proofAsFields); - const recursion_verification = await verifyProof(recursion_proof, false); + const recursion_verification = await recursion_backend.verifyFinalProof(recursion_proof); logger.debug('recursion_verification', recursion_verification); diff --git a/yarn.lock b/yarn.lock index ad6df96b4ab..32a87818163 100644 --- a/yarn.lock +++ b/yarn.lock @@ -57,20 +57,6 @@ __metadata: languageName: node linkType: hard -"@aztec/bb.js@npm:^0.7.3": - version: 0.7.3 - resolution: "@aztec/bb.js@npm:0.7.3" - dependencies: - comlink: ^4.4.1 - commander: ^10.0.1 - debug: ^4.3.4 - tslib: ^2.4.0 - bin: - bb.js: dest/node/main.js - checksum: 4da507d3de83b56c24f074cf61dfa6812b9c37f2047af25f79feac9973a900fd517bedb707ce00de9bf8acffec871f1894385e2bc3b74fd81f2c6b4c41a02293 - languageName: node - linkType: hard - "@babel/code-frame@npm:^7.12.11, @babel/code-frame@npm:^7.21.4": version: 7.22.13 resolution: "@babel/code-frame@npm:7.22.13" @@ -459,7 +445,7 @@ __metadata: languageName: unknown linkType: soft -"@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg": +"@noir-lang/backend_barretenberg@workspace:*, @noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg": version: 0.0.0-use.local resolution: "@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg" dependencies: @@ -4543,7 +4529,7 @@ __metadata: version: 0.0.0-use.local resolution: "integration-tests@workspace:compiler/integration-tests" dependencies: - "@aztec/bb.js": ^0.7.3 + "@noir-lang/backend_barretenberg": "workspace:*" "@noir-lang/noir_js": "workspace:*" "@noir-lang/noir_wasm": "workspace:*" "@noir-lang/source-resolver": "workspace:*"