Skip to content

Commit

Permalink
Merge branch 'master' into arv/oracle_mocker
Browse files Browse the repository at this point in the history
  • Loading branch information
sirasistant committed Oct 2, 2023
2 parents 066de05 + 1f04037 commit e463f6c
Show file tree
Hide file tree
Showing 17 changed files with 200 additions and 68 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/test-noir-js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ jobs:

- name: Build noirc_abi
run: yarn workspace @noir-lang/noirc_abi build

- name: Build barretenberg wrapper
run: yarn workspace @noir-lang/backend_barretenberg build

- name: Run noir_js tests
run: |
Expand Down
32 changes: 10 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion acvm-repo/barretenberg_blackbox_solver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ wasmer = "3.3"
pkg-config = "0.3"
tar = "~0.4.15"
flate2 = "~1.0.1"
reqwest = { version = "0.11.16", default-features = false, features = [
reqwest = { version = "0.11.20", default-features = false, features = [
"rustls-tls",
"blocking",
] }
Expand Down
6 changes: 3 additions & 3 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ allow = [
"LicenseRef-webpki",
# https://github.com/rustls/webpki/blob/main/LICENSE ISC Style
"LicenseRef-rustls-webpki",
# bitmaps 2.1.0, generational-arena 0.2.9,im 15.1.0
"MPL-2.0",
]

# Allow 1 or more licenses on a per-crate basis, so that particular licenses
Expand Down Expand Up @@ -95,6 +97,4 @@ unknown-registry = "warn"
# Lint level for what to happen when a crate from a git repository that is not
# in the allow list is encountered
unknown-git = "deny"
allow-git = [
"https://github.com/jfecher/chumsky"
]
allow-git = ["https://github.com/jfecher/chumsky"]
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"tooling/noir_js_types",
"tooling/noirc_abi_wasm",
"tooling/noir_js",
"tooling/noir_js_backend_barretenberg",
"acvm-repo/acvm_js",
"release-tests"
],
Expand Down
2 changes: 1 addition & 1 deletion tooling/backend_interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ tempfile = "3.6.0"
## bb binary downloading
tar = "~0.4.15"
flate2 = "~1.0.1"
reqwest = { version = "0.11.16", default-features = false, features = [
reqwest = { version = "0.11.20", default-features = false, features = [
"rustls-tls",
"blocking",
] }
Expand Down
14 changes: 7 additions & 7 deletions tooling/noir_js/test/node/e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect } from 'chai';
import assert_lt_json from '../noir_compiled_examples/assert_lt/target/assert_lt.json' assert { type: 'json' };
import { generateWitness } from '../../src/index.js';
import { Noir } from '../../src/program.js';
import { BarretenbergBackend as Backend } from '../backend/barretenberg.js';
import { BarretenbergBackend as Backend } from '@noir-lang/backend_barretenberg';

it('end-to-end proof creation and verification (outer)', async () => {
// Noir.Js part
Expand All @@ -15,7 +15,7 @@ it('end-to-end proof creation and verification (outer)', async () => {
// bb.js part
//
// Proof creation
const prover = await Backend.initialize(assert_lt_json);
const prover = new Backend(assert_lt_json);
const proof = await prover.generateFinalProof(serializedWitness);

// Proof verification
Expand All @@ -31,7 +31,7 @@ it('end-to-end proof creation and verification (outer) -- Program API', async ()
};

// Initialize backend
const backend = await Backend.initialize(assert_lt_json);
const backend = new Backend(assert_lt_json);
// Initialize program
const program = new Noir(assert_lt_json, backend);
// Generate proof
Expand All @@ -53,7 +53,7 @@ it('end-to-end proof creation and verification (inner)', async () => {
// bb.js part
//
// Proof creation
const prover = await Backend.initialize(assert_lt_json);
const prover = new Backend(assert_lt_json);
const proof = await prover.generateIntermediateProof(serializedWitness);

// Proof verification
Expand Down Expand Up @@ -82,12 +82,12 @@ it('[BUG] -- bb.js null function or function signature mismatch (different insta
const serializedWitness = await generateWitness(assert_lt_json, inputs);

// bb.js part
const prover = await Backend.initialize(assert_lt_json);
const prover = new Backend(assert_lt_json);

const proof = await prover.generateFinalProof(serializedWitness);

try {
const verifier = await Backend.initialize(assert_lt_json);
const verifier = new Backend(assert_lt_json);
await verifier.verifyFinalProof(proof);
expect.fail(
'bb.js currently returns a bug when we try to verify a proof with a different Barretenberg instance that created it.',
Expand Down Expand Up @@ -117,7 +117,7 @@ it('[BUG] -- bb.js null function or function signature mismatch (outer-inner) ',
//
// Proof creation
//
const prover = await Backend.initialize(assert_lt_json);
const prover = new Backend(assert_lt_json);
// Create a proof using both proving systems, the majority of the time
// one would only use outer proofs.
const proofOuter = await prover.generateFinalProof(serializedWitness);
Expand Down
1 change: 1 addition & 0 deletions tooling/noir_js_backend_barretenberg/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
3 changes: 3 additions & 0 deletions tooling/noir_js_backend_barretenberg/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ["../../.eslintrc.js"],
};
2 changes: 2 additions & 0 deletions tooling/noir_js_backend_barretenberg/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
crs
lib
43 changes: 43 additions & 0 deletions tooling/noir_js_backend_barretenberg/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "@noir-lang/backend_barretenberg",
"collaborators": [
"The Noir Team <team@noir-lang.org>"
],
"version": "0.7.10",
"packageManager": "yarn@3.5.1",
"license": "(MIT OR Apache-2.0)",
"type": "module",
"source": "src/index.ts",
"main": "lib/cjs/index.cjs",
"module": "lib/esm/index.js",
"exports": {
"require": "./lib/cjs/index.cjs",
"default": "./lib/esm/index.js",
"types": "./lib/esm/index.d.ts"
},
"types": "lib/esm/index.d.ts",
"scripts": {
"dev": "tsc --watch",
"build": "yarn clean && tsc && tsc -p ./tsconfig.cjs.json && mv ./lib/cjs/index.js ./lib/cjs/index.cjs && mv ./lib/cjs/serialize.js ./lib/cjs/serialize.cjs && mv ./lib/cjs/base64_decode.js ./lib/cjs/base64_decode.cjs",
"clean": "rm -rf ./lib",
"prettier": "prettier 'src/**/*.ts'",
"prettier:fix": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
"lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0"
},
"dependencies": {
"@aztec/bb.js": "0.7.10",
"@noir-lang/types": "workspace:*",
"fflate": "^0.8.0"
},
"peerDependencies": {
"@noir-lang/backend_barretenberg": "workspace:*"
},
"devDependencies": {
"@types/node": "^20.6.2",
"@types/prettier": "^3",
"eslint": "^8.40.0",
"eslint-plugin-prettier": "^5.0.0",
"prettier": "3.0.3",
"typescript": "5.1.5"
}
}
13 changes: 13 additions & 0 deletions tooling/noir_js_backend_barretenberg/src/base64_decode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Since this is a simple function, we can use feature detection to
// see if we are in the nodeJs environment or the browser environment.
export function base64Decode(input: string): Uint8Array {
if (typeof Buffer !== 'undefined') {
// Node.js environment
return Buffer.from(input, 'base64');
} else if (typeof atob === 'function') {
// Browser environment
return Uint8Array.from(atob(input), (c) => c.charCodeAt(0));
} else {
throw new Error('No implementation found for base64 decoding.');
}
}
Original file line number Diff line number Diff line change
@@ -1,49 +1,38 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { Barretenberg, Crs, RawBuffer } from '@aztec/bb.js';
import { acirToUint8Array } from '../../src/index.js';
import { Backend } from '@noir-lang/types';
import { acirToUint8Array } from './serialize.js';
import { Backend, CompiledCircuit } from '@noir-lang/types';

export class BarretenbergBackend implements Backend {
// These type assertions are used so that we don't
// have to initialize `api` and `acirComposer` in the constructor.
// These are initialized asynchronously in the `init` function,
// constructors cannot be asynchronous which is why we do this.
api = {} as Barretenberg;
acirComposer = {} as any;
acirUncompressedBytecode: Uint8Array;
private api: any;
private acirComposer: any;
private acirUncompressedBytecode: Uint8Array;
private numberOfThreads = 1;

private constructor(acirCircuit: { bytecode: string }) {
constructor(acirCircuit: CompiledCircuit, numberOfThreads = 1) {
const acirBytecodeBase64 = acirCircuit.bytecode;
this.numberOfThreads = numberOfThreads;
this.acirUncompressedBytecode = acirToUint8Array(acirBytecodeBase64);
}

static async initialize(acirCircuit: { bytecode: string }): Promise<BarretenbergBackend> {
const backend = new BarretenbergBackend(acirCircuit);
await backend.init();
return backend;
}

private async init(): Promise<void> {
const numThreads = 4;

const { api, composer } = await this.initBarretenberg(numThreads, this.acirUncompressedBytecode);

this.api = api;
this.acirComposer = composer;
}

private async initBarretenberg(numThreads: number, acirUncompressedBytecode: Uint8Array) {
const api = await Barretenberg.new(numThreads);

const [_exact, _total, subgroupSize] = await api.acirGetCircuitSizes(acirUncompressedBytecode);
const crs = await Crs.new(subgroupSize + 1);
await api.commonInitSlabAllocator(subgroupSize);
await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data()));

const acirComposer = await api.acirNewAcirComposer(subgroupSize);
return { api: api, composer: acirComposer };
private async instantiate(): Promise<void> {
if (!this.api) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
const { Barretenberg, RawBuffer, Crs } = await import('@aztec/bb.js');
const api = await Barretenberg.new(this.numberOfThreads);

const [_exact, _total, subgroupSize] = await api.acirGetCircuitSizes(this.acirUncompressedBytecode);
const crs = await Crs.new(subgroupSize + 1);
await api.commonInitSlabAllocator(subgroupSize);
await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data()));

this.acirComposer = await api.acirNewAcirComposer(subgroupSize);
this.api = api;
}
}

// Generate an outer proof. This is the proof for the circuit which will verify
Expand Down Expand Up @@ -73,6 +62,7 @@ export class BarretenbergBackend implements Backend {
}

async generateProof(decompressedWitness: Uint8Array, makeEasyToVerifyInCircuit: boolean): Promise<Uint8Array> {
await this.instantiate();
const proof = await this.api.acirCreateProof(
this.acirComposer,
this.acirUncompressedBytecode,
Expand Down Expand Up @@ -100,6 +90,7 @@ export class BarretenbergBackend implements Backend {
vkAsFields: string[];
vkHash: string;
}> {
await this.instantiate();
const proofAsFields = await this.api.acirSerializeProofIntoFields(this.acirComposer, proof, numOfPublicInputs);

// TODO: perhaps we should put this in the init function. Need to benchmark
Expand Down Expand Up @@ -128,11 +119,15 @@ export class BarretenbergBackend implements Backend {
}

async verifyProof(proof: Uint8Array, makeEasyToVerifyInCircuit: boolean): Promise<boolean> {
await this.instantiate();
await this.api.acirInitVerificationKey(this.acirComposer);
return await this.api.acirVerifyProof(this.acirComposer, proof, makeEasyToVerifyInCircuit);
}

async destroy(): Promise<void> {
if (!this.api) {
return;
}
await this.api.destroy();
}
}
8 changes: 8 additions & 0 deletions tooling/noir_js_backend_barretenberg/src/serialize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { decompressSync as gunzip } from 'fflate';
import { base64Decode } from './base64_decode.js';

// Converts bytecode from a base64 string to a Uint8Array
export function acirToUint8Array(base64EncodedBytecode): Uint8Array {
const compressedByteCode = base64Decode(base64EncodedBytecode);
return gunzip(compressedByteCode);
}
7 changes: 7 additions & 0 deletions tooling/noir_js_backend_barretenberg/tsconfig.cjs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "CommonJS",
"outDir": "./lib/cjs"
},
}
16 changes: 16 additions & 0 deletions tooling/noir_js_backend_barretenberg/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "esnext",
"declaration": true,
"emitDeclarationOnly": false,
"module": "ESNext",
"moduleResolution": "NodeNext",
"outDir": "./lib/esm",
"esModuleInterop": true,
"resolveJsonModule": true,
"strict": true,
"noImplicitAny": false,
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}
Loading

0 comments on commit e463f6c

Please sign in to comment.