-
Notifications
You must be signed in to change notification settings - Fork 333
/
Copy pathunconstrained_function_membership_proof.test.ts
64 lines (54 loc) · 3.04 KB
/
unconstrained_function_membership_proof.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
import { type ContractArtifact, type FunctionArtifact, FunctionSelector, FunctionType } from '@aztec/foundation/abi';
import { Fr } from '@aztec/foundation/fields';
import { getTestContractArtifact } from '../tests/fixtures.js';
import { getContractClassFromArtifact } from './contract_class.js';
import { type ContractClassIdPreimage } from './contract_class_id.js';
import { type ContractClass } from './interfaces/contract_class.js';
import {
createUnconstrainedFunctionMembershipProof,
isValidUnconstrainedFunctionMembershipProof,
} from './unconstrained_function_membership_proof.js';
describe('unconstrained_function_membership_proof', () => {
let artifact: ContractArtifact;
let contractClass: ContractClass & ContractClassIdPreimage;
let unconstrainedFunction: FunctionArtifact;
let vkHash: Fr;
let selector: FunctionSelector;
beforeEach(() => {
artifact = getTestContractArtifact();
contractClass = getContractClassFromArtifact(artifact);
unconstrainedFunction = artifact.functions.findLast(fn => fn.functionType === FunctionType.UNCONSTRAINED)!;
selector = FunctionSelector.fromNameAndParameters(unconstrainedFunction);
});
const isUnconstrained = (fn: { functionType: FunctionType }) => fn.functionType === FunctionType.UNCONSTRAINED;
it('computes and verifies a proof', () => {
expect(unconstrainedFunction).toBeDefined();
const proof = createUnconstrainedFunctionMembershipProof(selector, artifact);
const fn = { ...unconstrainedFunction, ...proof, selector };
expect(isValidUnconstrainedFunctionMembershipProof(fn, contractClass)).toBeTruthy();
});
it('handles a contract with a single function', () => {
// Remove all unconstrained functions from the contract but one
const unconstrainedFns = artifact.functions.filter(isUnconstrained);
artifact.functions = artifact.functions.filter(fn => !isUnconstrained(fn) || fn === unconstrainedFns[0]);
expect(artifact.functions.filter(isUnconstrained).length).toBe(1);
const unconstrainedFunction = unconstrainedFns[0];
const selector = FunctionSelector.fromNameAndParameters(unconstrainedFunction);
const proof = createUnconstrainedFunctionMembershipProof(selector, artifact);
expect(proof.artifactTreeSiblingPath.length).toBe(0);
const fn = { ...unconstrainedFunction, ...proof, selector };
const contractClass = getContractClassFromArtifact(artifact);
expect(isValidUnconstrainedFunctionMembershipProof(fn, contractClass)).toBeTruthy();
});
test.each(['artifactTreeSiblingPath', 'artifactMetadataHash', 'functionMetadataHash'] as const)(
'fails proof if %s is mangled',
field => {
const proof = createUnconstrainedFunctionMembershipProof(selector, artifact);
const original = proof[field];
const mangled = Array.isArray(original) ? [Fr.random(), ...original.slice(1)] : Fr.random();
const wrong = { ...proof, [field]: mangled };
const fn = { ...unconstrainedFunction, ...wrong, selector, vkHash };
expect(isValidUnconstrainedFunctionMembershipProof(fn, contractClass)).toBeFalsy();
},
);
});