Skip to content

Commit 94c93bb

Browse files
update js-sdk to 1.9.0 version & update tests with beta.1 circuits (#84)
* update js-sdk to 1.9.* version & update tests with beta.1 circuits * fix gateway URL --------- Co-authored-by: vmidyllic <74898029+vmidyllic@users.noreply.github.com> --------- Co-authored-by: vmidyllic <74898029+vmidyllic@users.noreply.github.com>
1 parent aa6f31b commit 94c93bb

File tree

11 files changed

+868
-1490
lines changed

11 files changed

+868
-1490
lines changed

package-lock.json

Lines changed: 267 additions & 308 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@iden3/js-iden3-auth",
3-
"version": "1.1.1",
3+
"version": "1.2.0",
44
"description": "iden3-auth implementation in JavaScript",
55
"main": "dist/cjs/index.js",
66
"source": "./src/index.ts",
@@ -33,10 +33,10 @@
3333
},
3434
"dependencies": {
3535
"@iden3/js-crypto": "1.0.3",
36-
"@0xpolygonid/js-sdk": "1.7.4",
36+
"@0xpolygonid/js-sdk": "1.9.4",
3737
"@iden3/js-iden3-core": "1.2.1",
3838
"@iden3/js-jsonld-merklization": "1.1.2",
39-
"@iden3/js-jwz": "1.2.1",
39+
"@iden3/js-jwz": "1.3.0",
4040
"@iden3/js-merkletree": "1.1.2",
4141
"did-resolver": "^4.1.0",
4242
"ethers": "^5.4.0",

src/circuits/atomicMtpV2.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import { getDateFromUnixTimestamp } from '@iden3/js-iden3-core';
22
import { Resolvers } from '@lib/state/resolver';
3-
import { checkQueryRequest, ClaimOutputs, Query } from '@lib/circuits/query';
3+
import { checkQueryV2Circuits, ClaimOutputs, Query } from '@lib/circuits/query';
44
import { PubSignalsVerifier, VerifyOpts } from '@lib/circuits/registry';
55
import { IDOwnershipPubSignals } from '@lib/circuits/ownershipVerifier';
66
import { checkIssuerNonRevState, checkUserState, getResolverByID } from '@lib/circuits/common';
77
import { DocumentLoader } from '@iden3/js-jsonld-merklization';
8-
import { AtomicQueryMTPV2PubSignals, BaseConfig, byteEncoder } from '@0xpolygonid/js-sdk';
8+
import {
9+
AtomicQueryMTPV2PubSignals,
10+
BaseConfig,
11+
byteEncoder,
12+
CircuitId
13+
} from '@0xpolygonid/js-sdk';
914

1015
const valuesSize = 64;
1116
const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour
@@ -52,7 +57,14 @@ export class AtomicQueryMTPV2PubSignalsVerifier
5257
valueArraySize: valuesSize,
5358
isRevocationChecked: this.pubSignals.isRevocationChecked
5459
};
55-
await checkQueryRequest(query, outs, schemaLoader, verifiablePresentation, false, opts);
60+
await checkQueryV2Circuits(
61+
CircuitId.AtomicQueryMTPV2,
62+
query,
63+
outs,
64+
schemaLoader,
65+
opts,
66+
verifiablePresentation
67+
);
5668

5769
return this.pubSignals;
5870
}
@@ -79,7 +91,6 @@ export class AtomicQueryMTPV2PubSignalsVerifier
7991
if (opts?.acceptedStateTransitionDelay) {
8092
acceptedStateTransitionDelay = opts.acceptedStateTransitionDelay;
8193
}
82-
8394
if (!issuerNonRevStateResolved.latest) {
8495
const timeDiff =
8596
Date.now() -

src/circuits/atomicSigV2.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import { PubSignalsVerifier, VerifyOpts } from '@lib/circuits/registry';
2-
import { checkQueryRequest, ClaimOutputs, Query } from '@lib/circuits/query';
2+
import { checkQueryV2Circuits, ClaimOutputs, Query } from '@lib/circuits/query';
33
import { Resolvers } from '@lib/state/resolver';
44
import { IDOwnershipPubSignals } from '@lib/circuits/ownershipVerifier';
55
import { checkIssuerNonRevState, checkUserState, getResolverByID } from '@lib/circuits/common';
66
import { getDateFromUnixTimestamp } from '@iden3/js-iden3-core';
77
import { DocumentLoader } from '@iden3/js-jsonld-merklization';
8-
import { AtomicQuerySigV2PubSignals, BaseConfig, byteEncoder } from '@0xpolygonid/js-sdk';
8+
import {
9+
AtomicQuerySigV2PubSignals,
10+
BaseConfig,
11+
byteEncoder,
12+
CircuitId
13+
} from '@0xpolygonid/js-sdk';
914

1015
const valuesSize = 64;
1116
const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour
@@ -45,7 +50,15 @@ export class AtomicQuerySigV2PubSignalsVerifier
4550
valueArraySize: valuesSize,
4651
isRevocationChecked: this.pubSignals.isRevocationChecked
4752
};
48-
await checkQueryRequest(query, outs, schemaLoader, verifiablePresentation, false, opts);
53+
54+
await checkQueryV2Circuits(
55+
CircuitId.AtomicQuerySigV2,
56+
query,
57+
outs,
58+
schemaLoader,
59+
opts,
60+
verifiablePresentation
61+
);
4962

5063
return this.pubSignals;
5164
}

src/circuits/atomicV3.ts

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import { PubSignalsVerifier, VerifyOpts } from '@lib/circuits/registry';
2-
import { checkQueryRequest, ClaimOutputs, Query } from '@lib/circuits/query';
2+
import { ClaimOutputs, Query } from '@lib/circuits/query';
33
import { Resolvers } from '@lib/state/resolver';
44
import { IDOwnershipPubSignals } from '@lib/circuits/ownershipVerifier';
55
import { checkIssuerNonRevState, checkUserState, getResolverByID } from '@lib/circuits/common';
66
import { DID, getDateFromUnixTimestamp } from '@iden3/js-iden3-core';
7-
import { DocumentLoader } from '@iden3/js-jsonld-merklization';
7+
import { DocumentLoader, getDocumentLoader } from '@iden3/js-jsonld-merklization';
88
import {
99
AtomicQueryV3PubSignals,
1010
BaseConfig,
1111
byteEncoder,
12+
checkCircuitOperator,
13+
checkQueryRequest,
14+
CircuitId,
1215
JSONObject,
13-
ProofType
16+
Operators,
17+
parseQueriesMetadata,
18+
ProofType,
19+
validateDisclosureNativeSDSupport,
20+
validateEmptyCredentialSubjectNoopNativeSupport,
21+
validateOperators,
22+
verifyFieldValueInclusionNativeExistsSupport
1423
} from '@0xpolygonid/js-sdk';
24+
import { JsonLd } from 'jsonld/jsonld-spec';
1525

1626
const valuesSize = 64;
1727
const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour
@@ -52,12 +62,77 @@ export class AtomicQueryV3PubSignalsVerifier
5262
timestamp: this.pubSignals.timestamp,
5363
merklized: this.pubSignals.merklized,
5464
claimPathKey: this.pubSignals.claimPathKey,
55-
claimPathNotExists: this.pubSignals.claimPathNotExists,
5665
valueArraySize: valuesSize,
5766
isRevocationChecked: this.pubSignals.isRevocationChecked,
5867
operatorOutput: this.pubSignals.operatorOutput
5968
};
60-
await checkQueryRequest(query, outs, schemaLoader, verifiablePresentation, true, opts);
69+
70+
if (!query.type) {
71+
throw new Error(`proof query type is undefined`);
72+
}
73+
74+
const loader = schemaLoader ?? getDocumentLoader();
75+
76+
// validate schema
77+
let context: JsonLd;
78+
try {
79+
context = (await loader(query.context ?? '')).document;
80+
} catch (e) {
81+
throw new Error(`can't load schema for request query`);
82+
}
83+
84+
const queriesMetadata = await parseQueriesMetadata(
85+
query.type,
86+
JSON.stringify(context),
87+
query.credentialSubject as JSONObject,
88+
{
89+
documentLoader: loader
90+
}
91+
);
92+
93+
const circuitId = CircuitId.AtomicQueryV3;
94+
await checkQueryRequest(
95+
query,
96+
queriesMetadata,
97+
context,
98+
outs,
99+
CircuitId.AtomicQueryV3,
100+
loader,
101+
opts
102+
);
103+
104+
const queryMetadata = queriesMetadata[0]; // only one query is supported
105+
106+
checkCircuitOperator(circuitId, outs.operator);
107+
// validate selective disclosure
108+
if (queryMetadata.operator === Operators.SD) {
109+
try {
110+
await validateDisclosureNativeSDSupport(
111+
queryMetadata,
112+
outs,
113+
verifiablePresentation,
114+
loader
115+
);
116+
} catch (e) {
117+
throw new Error(`failed to validate selective disclosure: ${(e as Error).message}`);
118+
}
119+
} else if (!queryMetadata.fieldName && queryMetadata.operator == Operators.NOOP) {
120+
try {
121+
await validateEmptyCredentialSubjectNoopNativeSupport(outs);
122+
} catch (e: unknown) {
123+
throw new Error(`failed to validate operators: ${(e as Error).message}`);
124+
}
125+
} else {
126+
try {
127+
await validateOperators(queryMetadata, outs);
128+
} catch (e) {
129+
throw new Error(`failed to validate operators: ${(e as Error).message}`);
130+
}
131+
}
132+
133+
// verify field inclusion / non-inclusion
134+
135+
verifyFieldValueInclusionNativeExistsSupport(outs, queryMetadata);
61136

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

@@ -77,7 +152,6 @@ export class AtomicQueryV3PubSignalsVerifier
77152
}
78153

79154
const nSessionId = BigInt((params?.nullifierSessionId as string) ?? 0);
80-
81155
if (nSessionId !== 0n) {
82156
if (BigInt(nullifier ?? 0) === 0n) {
83157
throw new Error('nullifier should be provided for nullification and should not be 0');

src/circuits/linkedMultiQuery.ts

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,13 @@ import {
88
LinkedMultiQueryPubSignals,
99
byteEncoder,
1010
cacheLoader,
11-
createSchemaHash,
12-
parseQueriesMetadata
11+
parseQueriesMetadata,
12+
calculateQueryHashV3,
13+
calculateCoreSchemaHash,
14+
QueryMetadata,
15+
LinkedMultiQueryInputs,
16+
Operators,
17+
fieldValueFromVerifiablePresentation
1318
} from '@0xpolygonid/js-sdk';
1419
import { poseidon } from '@iden3/js-crypto';
1520

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

2328
constructor(pubSignals: string[]) {
2429
this.pubSignals = this.pubSignals.pubSignalsUnmarshal(
25-
byteEncoder.encode(JSON.stringify(pubSignals)),
26-
10
30+
byteEncoder.encode(JSON.stringify(pubSignals))
2731
);
2832
}
2933

3034
verifyIdOwnership(): Promise<void> {
3135
return Promise.resolve();
3236
}
3337

34-
async verifyQuery(query: Query, schemaLoader?: DocumentLoader): Promise<BaseConfig> {
38+
async verifyQuery(
39+
query: Query,
40+
schemaLoader?: DocumentLoader,
41+
verifiablePresentation?: JSON
42+
): Promise<BaseConfig> {
3543
let schema: JSONObject;
3644
const ldOpts = { documentLoader: schemaLoader ?? cacheLoader() };
3745
try {
@@ -42,7 +50,7 @@ export class LinkedMultiQueryVerifier implements PubSignalsVerifier {
4250
const ldContextJSON = JSON.stringify(schema);
4351
const credentialSubject = query.credentialSubject as JSONObject;
4452
const schemaId: string = await Path.getTypeIDFromContext(ldContextJSON, query.type, ldOpts);
45-
const schemaHash = createSchemaHash(byteEncoder.encode(schemaId));
53+
const schemaHash = calculateCoreSchemaHash(byteEncoder.encode(schemaId));
4654

4755
const queriesMetadata = await parseQueriesMetadata(
4856
query.type,
@@ -51,24 +59,57 @@ export class LinkedMultiQueryVerifier implements PubSignalsVerifier {
5159
ldOpts
5260
);
5361

54-
const queryHashes = queriesMetadata.map((queryMeta) => {
55-
const valueHash = poseidon.spongeHashX(queryMeta.values, 6);
56-
return poseidon.hash([
57-
schemaHash.bigInt(),
58-
BigInt(queryMeta.slotIndex),
59-
BigInt(queryMeta.operator),
60-
BigInt(queryMeta.claimPathKey),
61-
queryMeta.merklizedSchema ? 0n : 1n,
62-
valueHash
63-
]);
64-
});
62+
const request: { queryHash: bigint; queryMeta: QueryMetadata }[] = [];
63+
const merklized = queriesMetadata[0]?.merklizedSchema ? 1 : 0;
64+
for (let i = 0; i < LinkedMultiQueryInputs.queryCount; i++) {
65+
const queryMeta = queriesMetadata[i];
66+
const values = queryMeta?.values ?? [];
67+
const valArrSize = values.length;
6568

66-
const circuitQueryHashes = this.pubSignals.circuitQueryHash
67-
.filter((i) => i !== 0n)
68-
.sort(this.bigIntCompare);
69-
queryHashes.sort(this.bigIntCompare);
70-
if (!queryHashes.every((queryHash, i) => queryHash === circuitQueryHashes[i])) {
71-
throw new Error('query hashes do not match');
69+
const queryHash = calculateQueryHashV3(
70+
values,
71+
schemaHash,
72+
queryMeta?.slotIndex ?? 0,
73+
queryMeta?.operator ?? 0,
74+
queryMeta?.claimPathKey.toString() ?? 0,
75+
valArrSize,
76+
merklized,
77+
0,
78+
0,
79+
0
80+
);
81+
request.push({ queryHash, queryMeta });
82+
}
83+
84+
const queryHashCompare = (a: { queryHash: bigint }, b: { queryHash: bigint }): number => {
85+
if (a.queryHash < b.queryHash) return -1;
86+
if (a.queryHash > b.queryHash) return 1;
87+
return 0;
88+
};
89+
90+
const pubSignalsMeta = this.pubSignals.circuitQueryHash.map((queryHash, index) => ({
91+
queryHash,
92+
operatorOutput: this.pubSignals.operatorOutput[index]
93+
}));
94+
95+
pubSignalsMeta.sort(queryHashCompare);
96+
request.sort(queryHashCompare);
97+
98+
for (let i = 0; i < LinkedMultiQueryInputs.queryCount; i++) {
99+
if (request[i].queryHash != pubSignalsMeta[i].queryHash) {
100+
throw new Error('query hashes do not match');
101+
}
102+
103+
if (request[i].queryMeta?.operator === Operators.SD) {
104+
const disclosedValue = await fieldValueFromVerifiablePresentation(
105+
request[i].queryMeta.fieldName,
106+
verifiablePresentation,
107+
schemaLoader
108+
);
109+
if (disclosedValue != pubSignalsMeta[i].operatorOutput) {
110+
throw new Error('disclosed value is not in the proof outputs');
111+
}
112+
}
72113
}
73114

74115
return this.pubSignals as unknown as BaseConfig;

0 commit comments

Comments
 (0)