Skip to content

Commit

Permalink
add unit test to V3 validator
Browse files Browse the repository at this point in the history
  • Loading branch information
volodymyr-basiuk committed Nov 22, 2023
1 parent 1ef8d40 commit 8058c12
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 3 deletions.
16 changes: 13 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"homepage": "https://github.com/iden3/contracts",
"devDependencies": {
"@iden3/js-iden3-core": "1.1.0",
"@iden3/js-crypto": "^1.0.1",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-etherscan": "^3.1.7",
Expand Down
45 changes: 45 additions & 0 deletions test/utils/query-hash-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { poseidon } from '@iden3/js-crypto';
import { SchemaHash } from '@iden3/js-iden3-core';

export function calculateQueryHash(
values: bigint[],
schema: string,
slotIndex: string | number,
operator: string | number,
claimPathKey: string | number,
claimPathNotExists: string | number
): bigint {
const expValue = prepareCircuitArrayValues(values, 64);
const valueHash = poseidon.spongeHashX(expValue, 6);
const schemaHash = coreSchemaFromStr(schema);
const quaryHash = poseidon.hash([
schemaHash.bigInt(),
BigInt(slotIndex),
BigInt(operator),
BigInt(claimPathKey),
BigInt(claimPathNotExists),
valueHash
]);
return quaryHash;
}

let prepareCircuitArrayValues = (arr: bigint[], size: number): bigint[] => {
if (!arr) {
arr = [];
}
if (arr.length > size) {
throw new Error(`array size ${arr.length} is bigger max expected size ${size}`);
}

// Add the empty values
for (let i = arr.length; i < size; i++) {
arr.push(BigInt(0));
}

return arr;
};

let coreSchemaFromStr = (schemaIntString: string) => {
const schemaInt = BigInt(schemaIntString);
return SchemaHash.newSchemaHashFromInt(schemaInt);
};
34 changes: 34 additions & 0 deletions test/utils/validator-pack-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,37 @@
}
);
}

export function packV3ValidatorParams(query: any, allowedIssuers: any[] = []) {
let web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");
return web3.eth.abi.encodeParameter(
{
"CredentialAtomicQueryV3": {
"schema": 'uint256',
"claimPathKey": 'uint256',
"operator": 'uint256',
"slotIndex": 'uint256',
"value": 'uint256[]',
"queryHash": 'uint256',
"allowedIssuers": 'uint256[]',
"circuitIds": 'string[]',
"skipClaimRevocationCheck": 'bool',
"claimPathNotExists": 'uint256',
'verifierID': 'uint256'
}
},
{
"schema": query.schema,
"claimPathKey": query.claimPathKey,
"operator": query.operator,
"slotIndex": query.slotIndex,
"value": query.value,
"queryHash": query.queryHash,
"allowedIssuers": allowedIssuers,
"circuitIds": query.circuitIds,
"skipClaimRevocationCheck": query.skipClaimRevocationCheck,
"claimPathNotExists": query.claimPathNotExists,
"verifierID": query.verifierID
}
);
}
47 changes: 47 additions & 0 deletions test/validators/v3/data/non-merk-sig-proof-no-auth.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"pub_signals": [
"0",
"21486081957406434312326137793636956944419786752362478156574432198905762306",
"3689469194074863493824697399240202920128454802627496308079287975484138729765",
"1840775094474209156340453684475119552573618786488967574225946775985623990900",
"0",
"0",
"0",
"1",
"84239",
"0",
"0",
"22382473121387415884005847265533170717221923702326943763943622761037238786",
"1",
"1840775094474209156340453684475119552573618786488967574225946775985623990900",
"1700589036",
"0",
"0",
"0"
],
"proof": {
"pi_a": [
"18123152198591907071015567960290089583824869172330900920534660478321480605012",
"6975196439864103932563633057846185170728351966659101647757897214178397982261",
"1"
],
"pi_b": [
[
"2926293499994855030390613276150476363219202368457158443310309958925312149081",
"20355627896817097998646584084462787631668640731225412067152314188369271781658"
],
[
"18303509250890911524261894086062671955667043287531044824849800873266121438534",
"15852363587833623080699417885794894558351717033185818265346790911805207983140"
],
["1", "0"]
],
"pi_c": [
"18980597255589432771620717291779914417743241623303506230202690577539016746478",
"9945950357908857726999076952448659611082658527183472199973861909495552701148",
"1"
],
"protocol": "groth16",
"curve": "bn128"
}
}
101 changes: 101 additions & 0 deletions test/validators/v3/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { expect } from "chai";
import { prepareInputs, publishState } from "../../utils/state-utils";
import { DeployHelper } from "../../../helpers/DeployHelper";
import { packV3ValidatorParams, packValidatorParams } from "../../utils/validator-pack-utils";
import { calculateQueryHash } from "../../utils/query-hash-utils";

const tenYears = 315360000;
const testCases: any[] = [
{
name: "Non merklized SigProof (AuthEnabled=0)",
stateTransitions: [require("../common-data/issuer_genesis_state.json")],
proofJson: require("./data/non-merk-sig-proof-no-auth.json"),
setProofExpiration: tenYears,
}
];

function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

describe.only("Atomic V3 Validator", function () {
let state: any, sig: any;

beforeEach(async () => {
const deployHelper = await DeployHelper.initialize(null, true);

const contracts = await deployHelper.deployValidatorContracts(
"VerifierV3Wrapper",
"CredentialAtomicQueryV3Validator"
);
state = contracts.state;
sig = contracts.validator;
});

for (const test of testCases) {
it(test.name, async function () {
this.timeout(50000);
for (let i = 0; i < test.stateTransitions.length; i++) {
if (test.stateTransitionDelayMs) {
await Promise.all([publishState(state, test.stateTransitions[i]), delay(test.stateTransitionDelayMs)]);
} else {
await publishState(state, test.stateTransitions[i]);
}
}

const value = [
'99',
...new Array(63).fill("0"),
];

const schema = '198285726510688200335207273836123338699';
const slotIndex = 3;
const operator = 1;
const claimPathKey = '0';
const claimPathNotExists = 1;

const query = {
schema,
claimPathKey,
operator,
slotIndex,
value,
circuitIds: ["credentialAtomicQueryV3OnChain"],
skipClaimRevocationCheck: false,
claimPathNotExists,
queryHash: calculateQueryHash(value,
schema,
slotIndex,
operator,
claimPathKey,
claimPathNotExists).toString(),
verifierID: 0
};

const { inputs, pi_a, pi_b, pi_c } = prepareInputs(test.proofJson);
if (test.setProofExpiration) {
await sig.setProofExpirationTimeout(test.setProofExpiration);
}
if (test.setRevStateExpiration) {
await sig.setRevocationStateExpirationTimeout(test.setRevStateExpiration);
}
if (test.setGISTRootExpiration) {
await sig.setGISTRootExpirationTimeout(test.setGISTRootExpiration);
}
if (test.errorMessage) {
await expect(sig.verify(inputs, pi_a, pi_b, pi_c, packV3ValidatorParams(query, test.allowedIssuers))).to.be.revertedWith(
test.errorMessage
);
} else if (test.errorMessage === "") {
await expect(sig.verify(inputs, pi_a, pi_b, pi_c, packV3ValidatorParams(query, test.allowedIssuers))).to.be.reverted;
} else {
await sig.verify(inputs, pi_a, pi_b, pi_c, packV3ValidatorParams(query, test.allowedIssuers));
}
});
}

it ('check inputIndexOf', async () => {
const challengeIndx = await sig.inputIndexOf('challenge');
expect(challengeIndx).to.be.equal(9);
});
});

0 comments on commit 8058c12

Please sign in to comment.