Skip to content

Commit

Permalink
Add VerifierData & return it alongside the proof (#310)
Browse files Browse the repository at this point in the history
  • Loading branch information
LogvinovLeon authored May 28, 2024
2 parents 84a7b89 + 95ae5bc commit 2ad4011
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import { filterPublic } from './abi.js';
import { publicInputs } from './abi.js';
import { Abi } from '@noir-lang/noirc_abi';

const type = { kind: 'field' } as const;
Expand All @@ -16,6 +16,6 @@ describe('abi', () => {
error_types: {}
};

expect(filterPublic(abi).parameters).toEqual([publicParam]);
expect(publicInputs(abi).parameters).toEqual([publicParam]);
});
});
19 changes: 19 additions & 0 deletions ethereum/oracles/src/noir/circuit/abi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Abi } from '@noir-lang/noirc_abi';

export function publicInputs(abi: Abi): Abi {
const parameters = abi.parameters.filter((param) => param.visibility === 'public');
return {
...abi,
parameters
};
}

export function returnValues(abi: Abi): Abi {
return {
parameters: [],
param_witnesses: {},
error_types: {},
return_type: abi.return_type,
return_witnesses: abi.return_witnesses
};
}
18 changes: 13 additions & 5 deletions ethereum/oracles/src/noir/circuit/baseProver.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import { randomUUID } from 'crypto';
import { MonorepoCircuit } from './circuit.js';
import { NargoProver } from './nargoProver.js';
import { encodeProofAsFields, encodePublicInputs } from './utils.js';
import { encodeProofAsFields } from './utils.js';
import { InputMap } from '@noir-lang/noirc_abi';
import { Hex } from 'viem';
import path from 'path';
import { VerifierData } from './verifierData.js';

export interface VerifiableComputation {
proofAsFields: Hex[];
verifierData: VerifierData;
}

export class BaseProver {
constructor(public circuit: MonorepoCircuit) {}
public async proveBase(inputs: InputMap): Promise<Hex[]> {
public async proveBase(inputs: InputMap): Promise<VerifiableComputation> {
const proofId = randomUUID();
const prover = new NargoProver(this.circuit, proofId);

const { proof, verifierData } = await prover.prove(inputs);
const proof = await prover.prove(inputs);

const proofAsFieldsPath = path.join(this.circuit.root, 'proofs', `${this.circuit.name}.proof.json`);
return await encodeProofAsFields(
const verifierData = await VerifierData.create(prover.verifierTomlPath, this.circuit.artefact.abi);
const proofAsFields = await encodeProofAsFields(
proof,
encodePublicInputs(this.circuit.artefact.abi, verifierData),
verifierData.publicInputs(),
this.circuit.vkPath(),
proofAsFieldsPath
);
return { proofAsFields, verifierData };
}
}
17 changes: 3 additions & 14 deletions ethereum/oracles/src/noir/circuit/nargoProver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,16 @@ import { $ } from 'execa';
import toml from '@iarna/toml';
import { InputMap } from '@noir-lang/noirc_abi';
import { readFile, unlink, writeFile } from 'fs/promises';
import { readTomlObject } from '../../util/file.js';
import { addHexPrefix } from '../../util/hex.js';
import { type Hex } from 'viem';

export interface NargoProve {
proof: Hex;
verifierData: InputMap;
}

// IMPORTANT: The proof paths used here are not unique to the `proofId` - therefore they can be overridden in parallel proof generation.
// https://github.com/noir-lang/noir/issues/5037
export class NargoProver {
private proverName = `Prover_${this.proofId}`;
private proverTomlPath = path.join(this.circuit.packagePath(), `${this.proverName}.toml`);
private verifierName = `Verifier_${this.proofId}`;
private verifierTomlPath = path.join(this.circuit.packagePath(), `${this.verifierName}.toml`);
public verifierTomlPath = path.join(this.circuit.packagePath(), `${this.verifierName}.toml`);
private proofPath = path.join(this.circuit.root, 'proofs', `${this.circuit.name}.proof`);

constructor(
Expand All @@ -31,17 +25,12 @@ export class NargoProver {
await $`nargo prove --package ${this.circuit.name} --oracle-resolver http://localhost:5555 -p ${this.proverName} -v ${this.verifierName}`;
}

public async prove(inputs: InputMap): Promise<NargoProve> {
public async prove(inputs: InputMap): Promise<Hex> {
await writeFile(this.proverTomlPath, toml.stringify(inputs as toml.JsonMap));
await this.executeProveCommand();
const verifierData = await readTomlObject<InputMap>(this.verifierTomlPath);
await unlink(this.proverTomlPath);
await unlink(this.verifierTomlPath);

const proof = addHexPrefix(await readFile(this.proofPath, 'utf-8'));
return {
proof,
verifierData
};
return proof;
}
}
4 changes: 2 additions & 2 deletions ethereum/oracles/src/noir/circuit/provers/getStorage.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Address, Hex } from 'viem';
import { BaseProver } from '../baseProver.js';
import { BaseProver, VerifiableComputation } from '../baseProver.js';
import { encodeAddress, encodeField, encodeHex } from '../../oracles/common/encode.js';

export class GetStorageProver extends BaseProver {
public async prove(chainId: number, blockNumber: bigint, address: Address, key: Hex): Promise<Hex[]> {
public async prove(chainId: number, blockNumber: bigint, address: Address, key: Hex): Promise<VerifiableComputation> {
const inputs = {
chain_id: encodeField(chainId),
block_number: encodeField(blockNumber),
Expand Down
8 changes: 0 additions & 8 deletions ethereum/oracles/src/noir/circuit/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { Abi, InputMap, abiEncode } from '@noir-lang/noirc_abi';
import { filterPublic } from '../../util/abi.js';
import { writeFile } from 'fs/promises';
import { Hex, concatHex } from 'viem';
import { removeHexPrefix } from '../../util/hex.js';
Expand All @@ -25,9 +23,3 @@ export async function encodeProofAsFields(
const proofAsFields = proofAsFieldsWithInputs.slice(publicInputs.length);
return proofAsFields;
}

export function encodePublicInputs(abi: Abi, verifierData: InputMap): Hex[] {
const publicInputsAbi = filterPublic(abi);
const publicInputsEncodedMap = abiEncode(publicInputsAbi, verifierData, verifierData.return);
return Array.from(publicInputsEncodedMap.values()) as Hex[];
}
29 changes: 29 additions & 0 deletions ethereum/oracles/src/noir/circuit/verifierData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Abi, InputMap, abiEncode } from '@noir-lang/noirc_abi';
import { readTomlObject } from '../../util/file.js';
import { Hex } from 'viem';
import { publicInputs, returnValues } from './abi.js';

export class VerifierData {
public static async create(verifierTomlPath: string, abi: Abi) {
const verifierData = await readTomlObject<InputMap>(verifierTomlPath);
return new VerifierData(abi, verifierData);
}

public publicInputs(): Hex[] {
return this.encodeSubset(publicInputs(this.abi));
}

public returnValues(): Hex[] {
return this.encodeSubset(returnValues(this.abi));
}

public encodeSubset(subset: Abi): Hex[] {
const subsetEncodedMap = abiEncode(subset, this.verifierData, this.verifierData.return);
return Array.from(subsetEncodedMap.values()) as Hex[];
}

private constructor(
private abi: Abi,
private verifierData: InputMap
) {}
}
2 changes: 1 addition & 1 deletion ethereum/oracles/src/script/generateGetStorageProof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ const { blockNumber, address, storageKeys } = HISTORY_API_FIXTURES.mainnet.paris

const circuit = await MonorepoCircuit.create('../../', 'get_storage');
const getStorageProver = new GetStorageProver(circuit);
const proofAsFields = await getStorageProver.prove(mainnet.id, blockNumber, address!, storageKeys![0]);
const { proofAsFields } = await getStorageProver.prove(mainnet.id, blockNumber, address!, storageKeys![0]);
// eslint-disable-next-line no-console
console.log(proofAsFields);
9 changes: 0 additions & 9 deletions ethereum/oracles/src/util/abi.ts

This file was deleted.

0 comments on commit 2ad4011

Please sign in to comment.