-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathindex.test.ts
110 lines (94 loc) · 3.45 KB
/
index.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import chai from 'chai';
const { expect } = chai;
import { Noir } from '@noir-lang/noir_js';
import { BarretenbergBackend } from '@noir-lang/backend_barretenberg';
import { BackendInstances, Circuits, Noirs } from '../types.js';
import hre from 'hardhat';
const { viem } = hre;
import { compile, createFileManager } from '@noir-lang/noir_wasm';
import { join, resolve } from 'path';
import { ProofData } from '@noir-lang/types';
import { bytesToHex } from 'viem';
async function getCircuit(name: string) {
const basePath = resolve(join('../noir', name));
const fm = createFileManager(basePath);
const compiled = await compile(fm, basePath);
if (!('program' in compiled)) {
throw new Error('Compilation failed');
}
return compiled.program;
}
describe('It compiles noir program code, receiving circuit bytes and abi object.', () => {
let circuits: Circuits;
let backends: BackendInstances;
let noirs: Noirs;
const mainInput = { x: 1, y: 2 };
before(async () => {
circuits = {
main: await getCircuit('main'),
recursive: await getCircuit('recursion'),
};
backends = {
main: new BarretenbergBackend(circuits.main, { threads: 8 }),
recursive: new BarretenbergBackend(circuits.recursive, { threads: 8 }),
};
noirs = {
main: new Noir(circuits.main, backends.main),
recursive: new Noir(circuits.recursive, backends.recursive),
};
});
after(async () => {
await backends.main.destroy();
await backends.recursive.destroy();
});
describe('Recursive flow', async () => {
let recursiveInputs: any;
let intermediateProof: ProofData;
let finalProof: ProofData;
describe.only('Proof generation', async () => {
it('Should generate an intermediate proof', async () => {
const { witness } = await noirs.main.execute(mainInput);
intermediateProof = await backends.main.generateProof(witness);
const { proof, publicInputs } = intermediateProof;
expect(proof instanceof Uint8Array).to.be.true;
const verified = await backends.main.verifyProof({ proof, publicInputs });
expect(verified).to.be.true;
const numPublicInputs = 1;
const { proofAsFields, vkAsFields, vkHash } =
await backends.main.generateRecursiveProofArtifacts(
{ publicInputs, proof },
numPublicInputs,
);
expect(vkAsFields).to.be.of.length(114);
expect(vkHash).to.be.a('string');
recursiveInputs = {
verification_key: vkAsFields,
proof: proofAsFields,
public_inputs: [mainInput.y],
key_hash: vkHash,
};
});
it('Should generate a final proof with a recursive input', async () => {
finalProof = await noirs.recursive.generateProof(recursiveInputs);
expect(finalProof.proof instanceof Uint8Array).to.be.true;
});
});
describe('Proof verification', async () => {
let verifierContract: any;
before(async () => {
verifierContract = await viem.deployContract('UltraVerifier');
});
it('Should verify off-chain', async () => {
const verified = await noirs.recursive.verifyProof(finalProof);
expect(verified).to.be.true;
});
it('Should verify on-chain', async () => {
const verified = await verifierContract.read.verify(
bytesToHex(finalProof.proof),
finalProof.publicInputs,
);
expect(verified).to.be.true;
});
});
});
});