Skip to content

Commit

Permalink
test(avm): Add TS bb prover tests for hashing opcodes (#6970)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanmon authored Jun 7, 2024
1 parent 6a7be0c commit 312718a
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,12 @@ contract AvmTest {
context.da_gas_left()
}

#[aztec(public)]
fn assert_timestamp(expected_timestamp: u64) {
let timestamp = context.timestamp();
assert(timestamp == expected_timestamp, "timestamp did not match");
}

#[aztec(public)]
fn check_selector() {
assert(
Expand Down
103 changes: 78 additions & 25 deletions yarn-project/bb-prover/src/avm_proving.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import { type BBSuccess, BB_RESULT, generateAvmProof, verifyAvmProof } from './b
import { extractVkData } from './verification_key/verification_key_data.js';

const TIMEOUT = 30_000;
const TIMESTAMP = new Fr(99833);

describe('AVM WitGen, proof generation and verification', () => {
const avmFunctionsAndCalldata: [string, Fr[]][] = [
Expand Down Expand Up @@ -79,21 +80,66 @@ describe('AVM WitGen, proof generation and verification', () => {
TIMEOUT,
);

/************************************************************************
* Hashing functions
************************************************************************/
describe('AVM hash functions', () => {
const avmHashFunctions: [string, Fr[]][] = [
[
'keccak_hash',
[
new Fr(189),
new Fr(0),
new Fr(0),
new Fr(0),
new Fr(0),
new Fr(0),
new Fr(0),
new Fr(0),
new Fr(0),
new Fr(0),
],
],
[
'poseidon2_hash',
[new Fr(0), new Fr(1), new Fr(2), new Fr(3), new Fr(4), new Fr(5), new Fr(6), new Fr(7), new Fr(8), new Fr(9)],
],
[
'sha256_hash',
[new Fr(0), new Fr(1), new Fr(2), new Fr(3), new Fr(4), new Fr(5), new Fr(6), new Fr(7), new Fr(8), new Fr(9)],
],
[
'pedersen_hash',
[new Fr(0), new Fr(1), new Fr(2), new Fr(3), new Fr(4), new Fr(5), new Fr(6), new Fr(7), new Fr(8), new Fr(9)],
],
[
'pedersen_hash_with_index',
[new Fr(0), new Fr(1), new Fr(2), new Fr(3), new Fr(4), new Fr(5), new Fr(6), new Fr(7), new Fr(8), new Fr(9)],
],
];

it.each(avmHashFunctions)(
'Should prove %s',
async (name, calldata) => {
await proveAndVerifyAvmTestContract(name, calldata);
},
TIMEOUT,
);
});

it(
'Should prove that timestamp matches',
async () => {
await proveAndVerifyAvmTestContract('assert_timestamp', [TIMESTAMP]);
},
TIMEOUT,
);

// TODO: Investigate why does the prover throws an out-of-range exception
it.skip(
'Should prove a keccak hash evaluation',
'Should prove that mutated timestamp does not match',
async () => {
await proveAndVerifyAvmTestContract('keccak_hash', [
new Fr(0),
new Fr(1),
new Fr(2),
new Fr(3),
new Fr(4),
new Fr(5),
new Fr(6),
new Fr(7),
new Fr(8),
new Fr(9),
]);
await proveAndVerifyAvmTestContract('assert_timestamp', [TIMESTAMP], [new Fr(231)]);
},
TIMEOUT,
);
Expand Down Expand Up @@ -131,9 +177,11 @@ describe('AVM WitGen, proof generation and verification', () => {
* Helpers
************************************************************************/

const proveAndVerifyAvmTestContract = async (functionName: string, calldata: Fr[] = []) => {
const proveAndVerifyAvmTestContract = async (functionName: string, calldata: Fr[] = [], mutatedCalldata: Fr[] = []) => {
const startSideEffectCounter = 0;
const environment = initExecutionEnvironment({ calldata });
const globals = GlobalVariables.empty();
globals.timestamp = TIMESTAMP;
const environment = initExecutionEnvironment({ calldata, globals });

const contractsDb = mock<PublicContractsDB>();
const contractInstance = new SerializableContractInstance({
Expand Down Expand Up @@ -185,24 +233,29 @@ const proveAndVerifyAvmTestContract = async (functionName: string, calldata: Fr[
const publicInputs = getPublicInputs(pxResult);
const avmCircuitInputs = new AvmCircuitInputs(
uncompressedBytecode,
context.environment.calldata,
mutatedCalldata.length === 0 ? context.environment.calldata : mutatedCalldata,
publicInputs,
pxResult.avmHints,
);

// Then we prove.
const proofRes = await generateAvmProof(bbPath, bbWorkingDirectory, avmCircuitInputs, logger);
expect(proofRes.status).toEqual(BB_RESULT.SUCCESS);

// Then we test VK extraction.
const succeededRes = proofRes as BBSuccess;
const verificationKey = await extractVkData(succeededRes.vkPath!);
expect(verificationKey.keyAsBytes).toHaveLength(16);
if (mutatedCalldata.length !== 0) {
expect(proofRes.status).toEqual(BB_RESULT.FAILURE);
} else {
expect(proofRes.status).toEqual(BB_RESULT.SUCCESS);

// Then we test VK extraction.
const succeededRes = proofRes as BBSuccess;
const verificationKey = await extractVkData(succeededRes.vkPath!);
expect(verificationKey.keyAsBytes).toHaveLength(16);

// Then we verify.
const rawVkPath = path.join(succeededRes.vkPath!, 'vk');
const verificationRes = await verifyAvmProof(bbPath, succeededRes.proofPath!, rawVkPath, logger);
expect(verificationRes.status).toBe(BB_RESULT.SUCCESS);
// Then we verify.
const rawVkPath = path.join(succeededRes.vkPath!, 'vk');
const verificationRes = await verifyAvmProof(bbPath, succeededRes.proofPath!, rawVkPath, logger);
expect(verificationRes.status).toBe(BB_RESULT.SUCCESS);
}
};

// TODO: pub somewhere more usable - copied from abstract phase manager
Expand Down

0 comments on commit 312718a

Please sign in to comment.