Skip to content

Commit

Permalink
chore(noir-js): Add program API (#2856)
Browse files Browse the repository at this point in the history
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
Co-authored-by: Tom French <tom@tomfren.ch>
  • Loading branch information
3 people authored Sep 29, 2023
1 parent 4deb07f commit 6a2cd78
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 20 deletions.
6 changes: 3 additions & 3 deletions tooling/noir_js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
"module": "lib/index.mjs",
"exports": {
"require": "./lib/index.cjs",
"default": "./lib/index.mjs",
"types": "./lib/index.d.ts"
"types": "./lib/index.d.ts",
"default": "./lib/index.mjs"
},
"types": "lib/index.d.ts",
"scripts": {
Expand Down Expand Up @@ -51,4 +51,4 @@
"tsc-multi": "^1.1.0",
"typescript": "^5.2.2"
}
}
}
20 changes: 20 additions & 0 deletions tooling/noir_js/src/program.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Backend } from './backend/backend_interface.js';
import { generateWitness } from './witness_generation.js';

export class Noir {
constructor(
private circuit: { bytecode: string; abi: any },
private backend: Backend,
) {}

// Initial inputs to your program
async generateFinalProof(inputs: any): Promise<Uint8Array> {
const serializedWitness = await generateWitness(this.circuit, inputs);
return this.backend.generateFinalProof(serializedWitness);
}

async verifyFinalProof(proof: Uint8Array): Promise<boolean> {
return this.backend.verifyFinalProof(proof);
}
}
19 changes: 13 additions & 6 deletions tooling/noir_js/test/backend/barretenberg.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
/* 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';
// TODO: This should be re-exported from @aztec/bb-js
import { Ptr } from '@aztec/bb.js/dest/browser/types';
import { acirToUint8Array } from '../../src/index.js';
import { Backend } from './backend_interface.js';
import { Backend } from '../../src/backend/backend_interface.js';

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 Ptr;
acirComposer = {} as any;
acirUncompressedBytecode: Uint8Array;

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

async init(): Promise<void> {
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);
Expand Down
35 changes: 25 additions & 10 deletions tooling/noir_js/test/node/e2e.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,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';

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

// Proof verification
const isValid = await prover.verifyFinalProof(proof);
expect(isValid).to.be.true;
});

it('end-to-end proof creation and verification (outer) -- Program API', async () => {
// Noir.Js part
const inputs = {
x: '2',
y: '3',
};

// Initialize backend
const backend = await Backend.initialize(assert_lt_json);
// Initialize program
const program = new Noir(assert_lt_json, backend);
// Generate proof
const proof = await program.generateFinalProof(inputs);

// Proof verification
const isValid = await program.verifyFinalProof(proof);
expect(isValid).to.be.true;
});

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

// Proof verification
Expand Down Expand Up @@ -64,14 +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 = new Backend(assert_lt_json.bytecode);
await prover.init();
const prover = await Backend.initialize(assert_lt_json);

const proof = await prover.generateFinalProof(serializedWitness);

try {
const verifier = new Backend(assert_lt_json.bytecode);
await verifier.init();
const verifier = await Backend.initialize(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 @@ -101,8 +117,7 @@ it('[BUG] -- bb.js null function or function signature mismatch (outer-inner) ',
//
// Proof creation
//
const prover = new Backend(assert_lt_json.bytecode);
await prover.init();
const prover = await Backend.initialize(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
2 changes: 1 addition & 1 deletion tooling/noir_js/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}
}

0 comments on commit 6a2cd78

Please sign in to comment.