Skip to content

Commit

Permalink
update js-sdk to 1.9.0 version & update tests with beta.1 circuits (#84)
Browse files Browse the repository at this point in the history
* update js-sdk to 1.9.* version & update tests with beta.1 circuits

* fix gateway URL

---------

Co-authored-by: vmidyllic <[email protected]>

---------

Co-authored-by: vmidyllic <[email protected]>
  • Loading branch information
volodymyr-basiuk and vmidyllic authored Mar 27, 2024
1 parent aa6f31b commit 94c93bb
Show file tree
Hide file tree
Showing 11 changed files with 868 additions and 1,490 deletions.
575 changes: 267 additions & 308 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions 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 Expand Up @@ -33,10 +33,10 @@
},
"dependencies": {
"@iden3/js-crypto": "1.0.3",
"@0xpolygonid/js-sdk": "1.7.4",
"@0xpolygonid/js-sdk": "1.9.4",
"@iden3/js-iden3-core": "1.2.1",
"@iden3/js-jsonld-merklization": "1.1.2",
"@iden3/js-jwz": "1.2.1",
"@iden3/js-jwz": "1.3.0",
"@iden3/js-merkletree": "1.1.2",
"did-resolver": "^4.1.0",
"ethers": "^5.4.0",
Expand Down
19 changes: 15 additions & 4 deletions src/circuits/atomicMtpV2.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { getDateFromUnixTimestamp } from '@iden3/js-iden3-core';
import { Resolvers } from '@lib/state/resolver';
import { checkQueryRequest, ClaimOutputs, Query } from '@lib/circuits/query';
import { checkQueryV2Circuits, ClaimOutputs, Query } from '@lib/circuits/query';
import { PubSignalsVerifier, VerifyOpts } from '@lib/circuits/registry';
import { IDOwnershipPubSignals } from '@lib/circuits/ownershipVerifier';
import { checkIssuerNonRevState, checkUserState, getResolverByID } from '@lib/circuits/common';
import { DocumentLoader } from '@iden3/js-jsonld-merklization';
import { AtomicQueryMTPV2PubSignals, BaseConfig, byteEncoder } from '@0xpolygonid/js-sdk';
import {
AtomicQueryMTPV2PubSignals,
BaseConfig,
byteEncoder,
CircuitId
} from '@0xpolygonid/js-sdk';

const valuesSize = 64;
const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour
Expand Down Expand Up @@ -52,7 +57,14 @@ export class AtomicQueryMTPV2PubSignalsVerifier
valueArraySize: valuesSize,
isRevocationChecked: this.pubSignals.isRevocationChecked
};
await checkQueryRequest(query, outs, schemaLoader, verifiablePresentation, false, opts);
await checkQueryV2Circuits(
CircuitId.AtomicQueryMTPV2,
query,
outs,
schemaLoader,
opts,
verifiablePresentation
);

return this.pubSignals;
}
Expand All @@ -79,7 +91,6 @@ export class AtomicQueryMTPV2PubSignalsVerifier
if (opts?.acceptedStateTransitionDelay) {
acceptedStateTransitionDelay = opts.acceptedStateTransitionDelay;
}

if (!issuerNonRevStateResolved.latest) {
const timeDiff =
Date.now() -
Expand Down
19 changes: 16 additions & 3 deletions src/circuits/atomicSigV2.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { PubSignalsVerifier, VerifyOpts } from '@lib/circuits/registry';
import { checkQueryRequest, ClaimOutputs, Query } from '@lib/circuits/query';
import { checkQueryV2Circuits, ClaimOutputs, Query } from '@lib/circuits/query';
import { Resolvers } from '@lib/state/resolver';
import { IDOwnershipPubSignals } from '@lib/circuits/ownershipVerifier';
import { checkIssuerNonRevState, checkUserState, getResolverByID } from '@lib/circuits/common';
import { getDateFromUnixTimestamp } from '@iden3/js-iden3-core';
import { DocumentLoader } from '@iden3/js-jsonld-merklization';
import { AtomicQuerySigV2PubSignals, BaseConfig, byteEncoder } from '@0xpolygonid/js-sdk';
import {
AtomicQuerySigV2PubSignals,
BaseConfig,
byteEncoder,
CircuitId
} from '@0xpolygonid/js-sdk';

const valuesSize = 64;
const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour
Expand Down Expand Up @@ -45,7 +50,15 @@ export class AtomicQuerySigV2PubSignalsVerifier
valueArraySize: valuesSize,
isRevocationChecked: this.pubSignals.isRevocationChecked
};
await checkQueryRequest(query, outs, schemaLoader, verifiablePresentation, false, opts);

await checkQueryV2Circuits(
CircuitId.AtomicQuerySigV2,
query,
outs,
schemaLoader,
opts,
verifiablePresentation
);

return this.pubSignals;
}
Expand Down
86 changes: 80 additions & 6 deletions src/circuits/atomicV3.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import { PubSignalsVerifier, VerifyOpts } from '@lib/circuits/registry';
import { checkQueryRequest, ClaimOutputs, Query } from '@lib/circuits/query';
import { ClaimOutputs, Query } from '@lib/circuits/query';
import { Resolvers } from '@lib/state/resolver';
import { IDOwnershipPubSignals } from '@lib/circuits/ownershipVerifier';
import { checkIssuerNonRevState, checkUserState, getResolverByID } from '@lib/circuits/common';
import { DID, getDateFromUnixTimestamp } from '@iden3/js-iden3-core';
import { DocumentLoader } from '@iden3/js-jsonld-merklization';
import { DocumentLoader, getDocumentLoader } from '@iden3/js-jsonld-merklization';
import {
AtomicQueryV3PubSignals,
BaseConfig,
byteEncoder,
checkCircuitOperator,
checkQueryRequest,
CircuitId,
JSONObject,
ProofType
Operators,
parseQueriesMetadata,
ProofType,
validateDisclosureNativeSDSupport,
validateEmptyCredentialSubjectNoopNativeSupport,
validateOperators,
verifyFieldValueInclusionNativeExistsSupport
} from '@0xpolygonid/js-sdk';
import { JsonLd } from 'jsonld/jsonld-spec';

const valuesSize = 64;
const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour
Expand Down Expand Up @@ -52,12 +62,77 @@ export class AtomicQueryV3PubSignalsVerifier
timestamp: this.pubSignals.timestamp,
merklized: this.pubSignals.merklized,
claimPathKey: this.pubSignals.claimPathKey,
claimPathNotExists: this.pubSignals.claimPathNotExists,
valueArraySize: valuesSize,
isRevocationChecked: this.pubSignals.isRevocationChecked,
operatorOutput: this.pubSignals.operatorOutput
};
await checkQueryRequest(query, outs, schemaLoader, verifiablePresentation, true, opts);

if (!query.type) {
throw new Error(`proof query type is undefined`);
}

const loader = schemaLoader ?? getDocumentLoader();

// validate schema
let context: JsonLd;
try {
context = (await loader(query.context ?? '')).document;
} catch (e) {
throw new Error(`can't load schema for request query`);
}

const queriesMetadata = await parseQueriesMetadata(
query.type,
JSON.stringify(context),
query.credentialSubject as JSONObject,
{
documentLoader: loader
}
);

const circuitId = CircuitId.AtomicQueryV3;
await checkQueryRequest(
query,
queriesMetadata,
context,
outs,
CircuitId.AtomicQueryV3,
loader,
opts
);

const queryMetadata = queriesMetadata[0]; // only one query is supported

checkCircuitOperator(circuitId, outs.operator);
// validate selective disclosure
if (queryMetadata.operator === Operators.SD) {
try {
await validateDisclosureNativeSDSupport(
queryMetadata,
outs,
verifiablePresentation,
loader
);
} catch (e) {
throw new Error(`failed to validate selective disclosure: ${(e as Error).message}`);
}
} else if (!queryMetadata.fieldName && queryMetadata.operator == Operators.NOOP) {
try {
await validateEmptyCredentialSubjectNoopNativeSupport(outs);
} catch (e: unknown) {
throw new Error(`failed to validate operators: ${(e as Error).message}`);
}
} else {
try {
await validateOperators(queryMetadata, outs);
} catch (e) {
throw new Error(`failed to validate operators: ${(e as Error).message}`);
}
}

// verify field inclusion / non-inclusion

verifyFieldValueInclusionNativeExistsSupport(outs, queryMetadata);

const { proofType, verifierID, nullifier, nullifierSessionID, linkID } = this.pubSignals;

Expand All @@ -77,7 +152,6 @@ export class AtomicQueryV3PubSignalsVerifier
}

const nSessionId = BigInt((params?.nullifierSessionId as string) ?? 0);

if (nSessionId !== 0n) {
if (BigInt(nullifier ?? 0) === 0n) {
throw new Error('nullifier should be provided for nullification and should not be 0');
Expand Down
87 changes: 64 additions & 23 deletions src/circuits/linkedMultiQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ import {
LinkedMultiQueryPubSignals,
byteEncoder,
cacheLoader,
createSchemaHash,
parseQueriesMetadata
parseQueriesMetadata,
calculateQueryHashV3,
calculateCoreSchemaHash,
QueryMetadata,
LinkedMultiQueryInputs,
Operators,
fieldValueFromVerifiablePresentation
} from '@0xpolygonid/js-sdk';
import { poseidon } from '@iden3/js-crypto';

Expand All @@ -22,16 +27,19 @@ export class LinkedMultiQueryVerifier implements PubSignalsVerifier {

constructor(pubSignals: string[]) {
this.pubSignals = this.pubSignals.pubSignalsUnmarshal(
byteEncoder.encode(JSON.stringify(pubSignals)),
10
byteEncoder.encode(JSON.stringify(pubSignals))
);
}

verifyIdOwnership(): Promise<void> {
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 @@ -42,7 +50,7 @@ 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 = calculateCoreSchemaHash(byteEncoder.encode(schemaId));

const queriesMetadata = await parseQueriesMetadata(
query.type,
Expand All @@ -51,24 +59,57 @@ export class LinkedMultiQueryVerifier implements PubSignalsVerifier {
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,
schemaLoader
);
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
Loading

0 comments on commit 94c93bb

Please sign in to comment.