Skip to content

Commit

Permalink
update linked checks
Browse files Browse the repository at this point in the history
  • Loading branch information
volodymyr-basiuk committed Mar 6, 2024
1 parent 471e3a1 commit 70c88c0
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 26 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@iden3/js-iden3-auth",
"version": "1.1.1",
"version": "1.2.0",
"description": "iden3-auth implementation in JavaScript",
"main": "dist/cjs/index.js",
"source": "./src/index.ts",
Expand Down
84 changes: 61 additions & 23 deletions src/circuits/linkedMultiQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ import {
LinkedMultiQueryPubSignals,
byteEncoder,
cacheLoader,
createSchemaHash,
parseQueriesMetadata
parseQueriesMetadata,
calculateQueryHashV3,
LinkedMultiQueryInputs,
QueryMetadata,
caclulateCoreSchemaHash,
Operators,
fieldValueFromVerifiablePresentation
} from '@0xpolygonid/js-sdk';
import { poseidon } from '@iden3/js-crypto';

/**
* Verifies the linked multi-query circuit.
Expand All @@ -30,7 +34,7 @@ export class LinkedMultiQueryVerifier implements PubSignalsVerifier {
return Promise.resolve();
}

async verifyQuery(query: Query, schemaLoader?: DocumentLoader): Promise<BaseConfig> {
async verifyQuery(query: Query, schemaLoader?: DocumentLoader, verifiablePresentation?: JSON): Promise<BaseConfig> {
let schema: JSONObject;
const ldOpts = { documentLoader: schemaLoader ?? cacheLoader() };
try {
Expand All @@ -41,34 +45,68 @@ export class LinkedMultiQueryVerifier implements PubSignalsVerifier {
const ldContextJSON = JSON.stringify(schema);
const credentialSubject = query.credentialSubject as JSONObject;
const schemaId: string = await Path.getTypeIDFromContext(ldContextJSON, query.type, ldOpts);
const schemaHash = createSchemaHash(byteEncoder.encode(schemaId));
// const schemaHash = createSchemaHash(byteEncoder.encode(schemaId));

const schemaHash = caclulateCoreSchemaHash(byteEncoder.encode(schemaId));
const queriesMetadata = await parseQueriesMetadata(
query.type,
ldContextJSON,
credentialSubject,
ldOpts
);

const queryHashes = queriesMetadata.map((queryMeta) => {
const valueHash = poseidon.spongeHashX(queryMeta.values, 6);
return poseidon.hash([
schemaHash.bigInt(),
BigInt(queryMeta.slotIndex),
BigInt(queryMeta.operator),
BigInt(queryMeta.claimPathKey),
queryMeta.merklizedSchema ? 0n : 1n,
valueHash
]);
});
const request: { queryHash: bigint; queryMeta: QueryMetadata }[] = [];
const merklized = queriesMetadata[0]?.merklizedSchema ? 1 : 0;
for (let i = 0; i < LinkedMultiQueryInputs.queryCount; i++) {
const queryMeta = queriesMetadata[i];
const values = queryMeta?.values ?? [];
const valArrSize = values.length;

const circuitQueryHashes = this.pubSignals.circuitQueryHash
.filter((i) => i !== 0n)
.sort(this.bigIntCompare);
queryHashes.sort(this.bigIntCompare);
// if (!queryHashes.every((queryHash, i) => queryHash === circuitQueryHashes[i])) {
// throw new Error('query hashes do not match');
// }
const queryHash = calculateQueryHashV3(
values,
schemaHash,
queryMeta?.slotIndex ?? 0,
queryMeta?.operator ?? 0,
queryMeta?.claimPathKey.toString() ?? 0,
valArrSize,
merklized,
0,
0,
0
);
request.push({ queryHash, queryMeta });
}

const queryHashCompare = (a: { queryHash: bigint }, b: { queryHash: bigint }): number => {
if (a.queryHash < b.queryHash) return -1;
if (a.queryHash > b.queryHash) return 1;
return 0;
};

const pubSignalsMeta = this.pubSignals.circuitQueryHash.map((queryHash, index) => ({
queryHash,
operatorOutput: this.pubSignals.operatorOutput[index]
}));

pubSignalsMeta.sort(queryHashCompare);
request.sort(queryHashCompare);

for (let i = 0; i < LinkedMultiQueryInputs.queryCount; i++) {
if (request[i].queryHash != pubSignalsMeta[i].queryHash) {
throw new Error('query hashes do not match');
}

if (request[i].queryMeta?.operator === Operators.SD) {
const disclosedValue = await fieldValueFromVerifiablePresentation(
request[i].queryMeta.fieldName,
verifiablePresentation,
ldOpts.documentLoader
);
if (disclosedValue != pubSignalsMeta[i].operatorOutput) {
throw new Error('disclosed value is not in the proof outputs');
}
}
}

return this.pubSignals as unknown as BaseConfig;
}
Expand Down

0 comments on commit 70c88c0

Please sign in to comment.