@0xpolygonid/js-sdk 1.8.3 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/esm/index.js +420 -189
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/browser/umd/index.js +425 -189
- package/dist/browser/umd/index.js.map +1 -1
- package/dist/node/cjs/circuits/atomic-query-v3-on-chain.js +8 -25
- package/dist/node/cjs/circuits/atomic-query-v3.js +6 -5
- package/dist/node/cjs/circuits/common.js +1 -1
- package/dist/node/cjs/circuits/comparer.js +24 -3
- package/dist/node/cjs/circuits/linked-multi-query.js +6 -17
- package/dist/node/cjs/circuits/models.js +47 -3
- package/dist/node/cjs/iden3comm/handlers/auth.js +14 -55
- package/dist/node/cjs/iden3comm/handlers/common.js +85 -0
- package/dist/node/cjs/iden3comm/handlers/contract-request.js +6 -25
- package/dist/node/cjs/iden3comm/handlers/index.js +2 -0
- package/dist/node/cjs/iden3comm/handlers/revocation-status.js +119 -0
- package/dist/node/cjs/identity/identity-wallet.js +4 -0
- package/dist/node/cjs/proof/common.js +11 -5
- package/dist/node/cjs/proof/provers/inputs-generator.js +6 -10
- package/dist/node/cjs/proof/verifiers/index.js +1 -0
- package/dist/node/cjs/proof/verifiers/pub-signals-verifier.js +37 -22
- package/dist/node/cjs/proof/verifiers/query-hash.js +40 -0
- package/dist/node/cjs/proof/verifiers/query.js +24 -16
- package/dist/node/cjs/schema-processor/utils.js +2 -2
- package/dist/node/cjs/storage/filters/jsonQuery.js +28 -2
- package/dist/node/cjs/verifiable/core-utils.js +3 -3
- package/dist/node/cjs/verifiable/credential.js +1 -1
- package/dist/node/esm/circuits/atomic-query-v3-on-chain.js +9 -26
- package/dist/node/esm/circuits/atomic-query-v3.js +7 -6
- package/dist/node/esm/circuits/common.js +1 -1
- package/dist/node/esm/circuits/comparer.js +24 -3
- package/dist/node/esm/circuits/linked-multi-query.js +7 -18
- package/dist/node/esm/circuits/models.js +48 -4
- package/dist/node/esm/iden3comm/handlers/auth.js +15 -56
- package/dist/node/esm/iden3comm/handlers/common.js +81 -0
- package/dist/node/esm/iden3comm/handlers/contract-request.js +7 -26
- package/dist/node/esm/iden3comm/handlers/index.js +2 -0
- package/dist/node/esm/iden3comm/handlers/revocation-status.js +92 -0
- package/dist/node/esm/identity/identity-wallet.js +4 -0
- package/dist/node/esm/proof/common.js +12 -6
- package/dist/node/esm/proof/provers/inputs-generator.js +7 -11
- package/dist/node/esm/proof/verifiers/index.js +1 -0
- package/dist/node/esm/proof/verifiers/pub-signals-verifier.js +41 -26
- package/dist/node/esm/proof/verifiers/query-hash.js +35 -0
- package/dist/node/esm/proof/verifiers/query.js +23 -16
- package/dist/node/esm/schema-processor/utils.js +3 -3
- package/dist/node/esm/storage/filters/jsonQuery.js +28 -2
- package/dist/node/esm/verifiable/core-utils.js +1 -1
- package/dist/node/esm/verifiable/credential.js +2 -2
- package/dist/types/circuits/atomic-query-v3-on-chain.d.ts +4 -8
- package/dist/types/circuits/atomic-query-v3.d.ts +2 -2
- package/dist/types/circuits/common.d.ts +1 -1
- package/dist/types/circuits/comparer.d.ts +4 -0
- package/dist/types/circuits/linked-multi-query.d.ts +0 -1
- package/dist/types/circuits/models.d.ts +7 -4
- package/dist/types/iden3comm/handlers/auth.d.ts +1 -0
- package/dist/types/iden3comm/handlers/common.d.ts +23 -0
- package/dist/types/iden3comm/handlers/contract-request.d.ts +1 -1
- package/dist/types/iden3comm/handlers/index.d.ts +2 -0
- package/dist/types/iden3comm/handlers/revocation-status.d.ts +59 -0
- package/dist/types/iden3comm/types/protocol/contract-request.d.ts +1 -0
- package/dist/types/identity/identity-wallet.d.ts +13 -1
- package/dist/types/proof/verifiers/index.d.ts +1 -0
- package/dist/types/proof/verifiers/query-hash.d.ts +3 -0
- package/dist/types/proof/verifiers/query.d.ts +1 -0
- package/dist/types/schema-processor/utils.d.ts +1 -1
- package/dist/types/storage/filters/jsonQuery.d.ts +1 -1
- package/dist/types/verifiable/core-utils.d.ts +1 -1
- package/dist/types/verifiable/credential.d.ts +1 -1
- package/dist/types/verifiable/proof.d.ts +5 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Claim, Id } from '@iden3/js-iden3-core';
|
|
2
|
-
import { BaseConfig, bigIntArrayToStringArray, prepareSiblingsStr,
|
|
2
|
+
import { BaseConfig, bigIntArrayToStringArray, prepareSiblingsStr, getNodeAuxValue, prepareCircuitArrayValues } from './common';
|
|
3
3
|
import { CircuitError, ValueProof } from './models';
|
|
4
4
|
import { Hash, Proof, ZERO_HASH } from '@iden3/js-merkletree';
|
|
5
5
|
import { byteDecoder, byteEncoder } from '../utils';
|
|
@@ -23,13 +23,14 @@ export class AtomicQueryV3OnChainInputs extends BaseConfig {
|
|
|
23
23
|
if (!this.query.values) {
|
|
24
24
|
throw new Error(CircuitError.EmptyQueryValue);
|
|
25
25
|
}
|
|
26
|
+
this.query.validateValueArraySize(this.getValueArrSize());
|
|
26
27
|
if (!this.proofType) {
|
|
27
28
|
throw new Error(CircuitError.InvalidProofType);
|
|
28
29
|
}
|
|
29
30
|
if (!this.challenge) {
|
|
30
31
|
throw new Error(CircuitError.EmptyChallenge);
|
|
31
32
|
}
|
|
32
|
-
if (this.
|
|
33
|
+
if (this.isBJJAuthEnabled === 1) {
|
|
33
34
|
if (!this.authClaimIncMtp) {
|
|
34
35
|
throw new Error(CircuitError.EmptyAuthClaimProof);
|
|
35
36
|
}
|
|
@@ -145,7 +146,7 @@ export class AtomicQueryV3OnChainInputs extends BaseConfig {
|
|
|
145
146
|
isRevocationChecked: 1
|
|
146
147
|
};
|
|
147
148
|
s.challenge = this.challenge?.toString();
|
|
148
|
-
if (this.
|
|
149
|
+
if (this.isBJJAuthEnabled === 1) {
|
|
149
150
|
s.authClaim = this.authClaim?.marshalJson();
|
|
150
151
|
s.userClaimsTreeRoot = this.treeState.claimsRoot?.bigInt().toString();
|
|
151
152
|
s.userRevTreeRoot = this.treeState.revocationRoot?.bigInt().toString();
|
|
@@ -220,18 +221,18 @@ export class AtomicQueryV3OnChainInputs extends BaseConfig {
|
|
|
220
221
|
s.issuerClaimNonRevMtpAuxHi = nodeAuxNonRev.key.bigInt().toString();
|
|
221
222
|
s.issuerClaimNonRevMtpAuxHv = nodeAuxNonRev.value.bigInt().toString();
|
|
222
223
|
s.issuerClaimNonRevMtpNoAux = nodeAuxNonRev.noAux;
|
|
223
|
-
s.claimPathNotExists = existenceToInt(valueProof.mtp.existence);
|
|
224
224
|
const nodAuxJSONLD = getNodeAuxValue(valueProof.mtp);
|
|
225
225
|
s.claimPathMtpNoAux = nodAuxJSONLD.noAux;
|
|
226
226
|
s.claimPathMtpAuxHi = nodAuxJSONLD.key.bigInt().toString();
|
|
227
227
|
s.claimPathMtpAuxHv = nodAuxJSONLD.value.bigInt().toString();
|
|
228
228
|
s.claimPathKey = valueProof.path.toString();
|
|
229
|
+
s.valueArraySize = this.query.values.length;
|
|
229
230
|
const values = prepareCircuitArrayValues(this.query.values, this.getValueArrSize());
|
|
230
231
|
s.value = bigIntArrayToStringArray(values);
|
|
231
232
|
s.linkNonce = this.linkNonce.toString();
|
|
232
233
|
s.verifierID = this.verifierID?.bigInt().toString() ?? '0';
|
|
233
234
|
s.nullifierSessionID = this.nullifierSessionID.toString();
|
|
234
|
-
s.
|
|
235
|
+
s.isBJJAuthEnabled = this.isBJJAuthEnabled.toString();
|
|
235
236
|
return byteEncoder.encode(JSON.stringify(s));
|
|
236
237
|
}
|
|
237
238
|
}
|
|
@@ -243,7 +244,6 @@ export class AtomicQueryV3OnChainPubSignals extends BaseConfig {
|
|
|
243
244
|
// PubSignalsUnmarshal unmarshal credentialAtomicQueryV3.circom public signals
|
|
244
245
|
pubSignalsUnmarshal(data) {
|
|
245
246
|
// expected order:
|
|
246
|
-
// merklized
|
|
247
247
|
// userID
|
|
248
248
|
// circuitQueryHash
|
|
249
249
|
// issuerState
|
|
@@ -255,17 +255,11 @@ export class AtomicQueryV3OnChainPubSignals extends BaseConfig {
|
|
|
255
255
|
// challenge
|
|
256
256
|
// gistRoot
|
|
257
257
|
// issuerID
|
|
258
|
-
// isRevocationChecked
|
|
259
258
|
// issuerClaimNonRevState
|
|
260
259
|
// timestamp
|
|
261
|
-
//
|
|
262
|
-
// nullifierSessionID
|
|
263
|
-
// authEnabled
|
|
260
|
+
// isBJJAuthEnabled
|
|
264
261
|
const sVals = JSON.parse(byteDecoder.decode(data));
|
|
265
262
|
let fieldIdx = 0;
|
|
266
|
-
// -- merklized
|
|
267
|
-
this.merklized = parseInt(sVals[fieldIdx]);
|
|
268
|
-
fieldIdx++;
|
|
269
263
|
// - userID
|
|
270
264
|
this.userID = Id.fromBigInt(BigInt(sVals[fieldIdx]));
|
|
271
265
|
fieldIdx++;
|
|
@@ -299,25 +293,14 @@ export class AtomicQueryV3OnChainPubSignals extends BaseConfig {
|
|
|
299
293
|
// - issuerID
|
|
300
294
|
this.issuerID = Id.fromBigInt(BigInt(sVals[fieldIdx]));
|
|
301
295
|
fieldIdx++;
|
|
302
|
-
// - isRevocationChecked
|
|
303
|
-
this.isRevocationChecked = parseInt(sVals[fieldIdx]);
|
|
304
|
-
fieldIdx++;
|
|
305
296
|
// - issuerClaimNonRevState
|
|
306
297
|
this.issuerClaimNonRevState = Hash.fromString(sVals[fieldIdx]);
|
|
307
298
|
fieldIdx++;
|
|
308
299
|
// - timestamp
|
|
309
300
|
this.timestamp = parseInt(sVals[fieldIdx]);
|
|
310
301
|
fieldIdx++;
|
|
311
|
-
// -
|
|
312
|
-
|
|
313
|
-
this.verifierID = Id.fromBigInt(BigInt(sVals[fieldIdx]));
|
|
314
|
-
}
|
|
315
|
-
fieldIdx++;
|
|
316
|
-
// - nullifierSessionID
|
|
317
|
-
this.nullifierSessionID = BigInt(sVals[fieldIdx]);
|
|
318
|
-
fieldIdx++;
|
|
319
|
-
// - authEnabled
|
|
320
|
-
this.authEnabled = parseInt(sVals[fieldIdx]);
|
|
302
|
+
// - isBJJAuthEnabled
|
|
303
|
+
this.isBJJAuthEnabled = parseInt(sVals[fieldIdx]);
|
|
321
304
|
return this;
|
|
322
305
|
}
|
|
323
306
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Claim, Id, SchemaHash } from '@iden3/js-iden3-core';
|
|
2
|
-
import { BaseConfig, bigIntArrayToStringArray, prepareSiblingsStr,
|
|
2
|
+
import { BaseConfig, bigIntArrayToStringArray, prepareSiblingsStr, getNodeAuxValue, prepareCircuitArrayValues } from './common';
|
|
3
3
|
import { CircuitError, ValueProof } from './models';
|
|
4
4
|
import { Hash, Proof, ZERO_HASH } from '@iden3/js-merkletree';
|
|
5
5
|
import { byteDecoder, byteEncoder } from '../utils';
|
|
@@ -23,6 +23,7 @@ export class AtomicQueryV3Inputs extends BaseConfig {
|
|
|
23
23
|
if (!this.query.values) {
|
|
24
24
|
throw new Error(CircuitError.EmptyQueryValue);
|
|
25
25
|
}
|
|
26
|
+
this.query.validateValueArraySize(this.getValueArrSize());
|
|
26
27
|
if (!this.proofType) {
|
|
27
28
|
throw new Error(CircuitError.InvalidProofType);
|
|
28
29
|
}
|
|
@@ -152,12 +153,12 @@ export class AtomicQueryV3Inputs extends BaseConfig {
|
|
|
152
153
|
s.issuerClaimNonRevMtpAuxHi = nodeAuxNonRev.key.bigInt().toString();
|
|
153
154
|
s.issuerClaimNonRevMtpAuxHv = nodeAuxNonRev.value.bigInt().toString();
|
|
154
155
|
s.issuerClaimNonRevMtpNoAux = nodeAuxNonRev.noAux;
|
|
155
|
-
s.claimPathNotExists = existenceToInt(valueProof.mtp.existence);
|
|
156
156
|
const nodAuxJSONLD = getNodeAuxValue(valueProof.mtp);
|
|
157
157
|
s.claimPathMtpNoAux = nodAuxJSONLD.noAux;
|
|
158
158
|
s.claimPathMtpAuxHi = nodAuxJSONLD.key.bigInt().toString();
|
|
159
159
|
s.claimPathMtpAuxHv = nodAuxJSONLD.value.bigInt().toString();
|
|
160
160
|
s.claimPathKey = valueProof.path.toString();
|
|
161
|
+
s.valueArraySize = this.query.values.length;
|
|
161
162
|
const values = prepareCircuitArrayValues(this.query.values, this.getValueArrSize());
|
|
162
163
|
s.value = bigIntArrayToStringArray(values);
|
|
163
164
|
s.linkNonce = this.linkNonce.toString();
|
|
@@ -191,11 +192,11 @@ export class AtomicQueryV3PubSignals extends BaseConfig {
|
|
|
191
192
|
// issuerClaimNonRevState
|
|
192
193
|
// timestamp
|
|
193
194
|
// claimSchema
|
|
194
|
-
// claimPathNotExists
|
|
195
195
|
// claimPathKey
|
|
196
196
|
// slotIndex
|
|
197
197
|
// operator
|
|
198
198
|
// value
|
|
199
|
+
// valueArraySize
|
|
199
200
|
// verifierID
|
|
200
201
|
// nullifierSessionID
|
|
201
202
|
// 19 is a number of fields in AtomicQueryV3PubSignals before values, values is last element in the proof and
|
|
@@ -246,9 +247,6 @@ export class AtomicQueryV3PubSignals extends BaseConfig {
|
|
|
246
247
|
// - claimSchema
|
|
247
248
|
this.claimSchema = SchemaHash.newSchemaHashFromInt(BigInt(sVals[fieldIdx]));
|
|
248
249
|
fieldIdx++;
|
|
249
|
-
// - ClaimPathNotExists
|
|
250
|
-
this.claimPathNotExists = parseInt(sVals[fieldIdx]);
|
|
251
|
-
fieldIdx++;
|
|
252
250
|
// - ClaimPathKey
|
|
253
251
|
this.claimPathKey = BigInt(sVals[fieldIdx]);
|
|
254
252
|
fieldIdx++;
|
|
@@ -263,6 +261,9 @@ export class AtomicQueryV3PubSignals extends BaseConfig {
|
|
|
263
261
|
this.value.push(BigInt(sVals[fieldIdx]));
|
|
264
262
|
fieldIdx++;
|
|
265
263
|
}
|
|
264
|
+
// - valueArraySize
|
|
265
|
+
this.valueArraySize = parseInt(sVals[fieldIdx]);
|
|
266
|
+
fieldIdx++;
|
|
266
267
|
// - verifierID
|
|
267
268
|
if (sVals[fieldIdx] !== '0') {
|
|
268
269
|
this.verifierID = Id.fromBigInt(BigInt(sVals[fieldIdx]));
|
|
@@ -42,7 +42,7 @@ export class BaseConfig {
|
|
|
42
42
|
* @returns number
|
|
43
43
|
*/
|
|
44
44
|
getValueArrSize() {
|
|
45
|
-
return this.
|
|
45
|
+
return this.maxValueArraySize ? this.maxValueArraySize : defaultValueArraySize;
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
48
|
* getMTLevelOnChain return level on chain for given circuit
|
|
@@ -30,6 +30,8 @@ export var Operators;
|
|
|
30
30
|
Operators[Operators["LTE"] = 7] = "LTE";
|
|
31
31
|
Operators[Operators["GTE"] = 8] = "GTE";
|
|
32
32
|
Operators[Operators["BETWEEN"] = 9] = "BETWEEN";
|
|
33
|
+
Operators[Operators["NONBETWEEN"] = 10] = "NONBETWEEN";
|
|
34
|
+
Operators[Operators["EXISTS"] = 11] = "EXISTS";
|
|
33
35
|
Operators[Operators["SD"] = 16] = "SD";
|
|
34
36
|
Operators[Operators["NULLIFY"] = 17] = "NULLIFY";
|
|
35
37
|
})(Operators || (Operators = {}));
|
|
@@ -45,12 +47,17 @@ export const QueryOperators = {
|
|
|
45
47
|
$lte: Operators.LTE,
|
|
46
48
|
$gte: Operators.GTE,
|
|
47
49
|
$between: Operators.BETWEEN,
|
|
50
|
+
$nonbetween: Operators.NONBETWEEN,
|
|
51
|
+
$exists: Operators.EXISTS,
|
|
48
52
|
$sd: Operators.SD,
|
|
49
53
|
$nullify: Operators.NULLIFY
|
|
50
54
|
};
|
|
51
55
|
const allOperations = Object.values(QueryOperators);
|
|
52
56
|
export const availableTypesOperators = new Map([
|
|
53
|
-
[
|
|
57
|
+
[
|
|
58
|
+
XSDNS.Boolean,
|
|
59
|
+
[QueryOperators.$eq, QueryOperators.$ne, QueryOperators.$sd, QueryOperators.$exists]
|
|
60
|
+
],
|
|
54
61
|
[XSDNS.Integer, allOperations],
|
|
55
62
|
[XSDNS.NonNegativeInteger, allOperations],
|
|
56
63
|
[XSDNS.PositiveInteger, allOperations],
|
|
@@ -61,7 +68,8 @@ export const availableTypesOperators = new Map([
|
|
|
61
68
|
QueryOperators.$ne,
|
|
62
69
|
QueryOperators.$in,
|
|
63
70
|
QueryOperators.$nin,
|
|
64
|
-
QueryOperators.$sd
|
|
71
|
+
QueryOperators.$sd,
|
|
72
|
+
QueryOperators.$exists
|
|
65
73
|
]
|
|
66
74
|
],
|
|
67
75
|
[
|
|
@@ -71,7 +79,8 @@ export const availableTypesOperators = new Map([
|
|
|
71
79
|
QueryOperators.$ne,
|
|
72
80
|
QueryOperators.$in,
|
|
73
81
|
QueryOperators.$nin,
|
|
74
|
-
QueryOperators.$sd
|
|
82
|
+
QueryOperators.$sd,
|
|
83
|
+
QueryOperators.$exists
|
|
75
84
|
]
|
|
76
85
|
],
|
|
77
86
|
[XSDNS.DateTime, allOperations]
|
|
@@ -162,6 +171,16 @@ export class Vector {
|
|
|
162
171
|
return this.y.includes(this.x);
|
|
163
172
|
case Operators.NIN:
|
|
164
173
|
return !this.y.includes(this.x);
|
|
174
|
+
case Operators.BETWEEN:
|
|
175
|
+
if (this.y.length !== 2) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
return this.x >= this.y[0] && this.x <= this.y[1];
|
|
179
|
+
case Operators.NONBETWEEN:
|
|
180
|
+
if (this.y.length !== 2) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return this.x < this.y[0] || this.x > this.y[1];
|
|
165
184
|
default:
|
|
166
185
|
throw new Error('unknown compare type for vector');
|
|
167
186
|
}
|
|
@@ -187,6 +206,8 @@ export const factoryComparer = (x, y, operator) => {
|
|
|
187
206
|
return new Scalar(x, y[0]);
|
|
188
207
|
case Operators.IN:
|
|
189
208
|
case Operators.NIN:
|
|
209
|
+
case Operators.BETWEEN:
|
|
210
|
+
case Operators.NONBETWEEN:
|
|
190
211
|
return new Vector(x, y);
|
|
191
212
|
default:
|
|
192
213
|
throw new Error('unknown compare type');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Proof } from '@iden3/js-merkletree';
|
|
2
2
|
import { byteDecoder, byteEncoder } from '../utils';
|
|
3
|
-
import { BaseConfig, bigIntArrayToStringArray,
|
|
3
|
+
import { BaseConfig, bigIntArrayToStringArray, getNodeAuxValue, prepareCircuitArrayValues, prepareSiblingsStr } from './common';
|
|
4
4
|
import { ValueProof } from './models';
|
|
5
5
|
/**
|
|
6
6
|
* LinkedMultiQuery circuit representation
|
|
@@ -12,8 +12,6 @@ import { ValueProof } from './models';
|
|
|
12
12
|
export class LinkedMultiQueryInputs extends BaseConfig {
|
|
13
13
|
// InputsMarshal returns Circom private inputs for linkedMultiQueryInputs.circom
|
|
14
14
|
inputsMarshal() {
|
|
15
|
-
const enabled = [];
|
|
16
|
-
const claimPathNotExists = [];
|
|
17
15
|
const claimPathMtp = [];
|
|
18
16
|
const claimPathMtpNoAux = [];
|
|
19
17
|
const claimPathMtpAuxHi = [];
|
|
@@ -23,10 +21,9 @@ export class LinkedMultiQueryInputs extends BaseConfig {
|
|
|
23
21
|
const slotIndex = [];
|
|
24
22
|
const operator = [];
|
|
25
23
|
const value = [];
|
|
24
|
+
const valueArraySize = [];
|
|
26
25
|
for (let i = 0; i < LinkedMultiQueryInputs.queryCount; i++) {
|
|
27
26
|
if (!this.query[i]) {
|
|
28
|
-
enabled.push(0);
|
|
29
|
-
claimPathNotExists.push(0);
|
|
30
27
|
claimPathMtp.push(new Array(this.getMTLevelsClaim()).fill('0'));
|
|
31
28
|
claimPathMtpNoAux.push('0');
|
|
32
29
|
claimPathMtpAuxHi.push('0');
|
|
@@ -37,9 +34,9 @@ export class LinkedMultiQueryInputs extends BaseConfig {
|
|
|
37
34
|
operator.push(0);
|
|
38
35
|
const valuesArr = prepareCircuitArrayValues([], this.getValueArrSize());
|
|
39
36
|
value.push(bigIntArrayToStringArray(valuesArr));
|
|
37
|
+
valueArraySize.push(0);
|
|
40
38
|
continue;
|
|
41
39
|
}
|
|
42
|
-
enabled.push(1);
|
|
43
40
|
let valueProof = this.query[i].valueProof;
|
|
44
41
|
if (!valueProof) {
|
|
45
42
|
valueProof = new ValueProof();
|
|
@@ -47,7 +44,6 @@ export class LinkedMultiQueryInputs extends BaseConfig {
|
|
|
47
44
|
valueProof.value = 0n;
|
|
48
45
|
valueProof.mtp = new Proof();
|
|
49
46
|
}
|
|
50
|
-
claimPathNotExists.push(existenceToInt(valueProof.mtp.existence));
|
|
51
47
|
claimPathMtp.push(prepareSiblingsStr(valueProof.mtp, this.getMTLevelsClaim()));
|
|
52
48
|
const nodAuxJSONLD = getNodeAuxValue(valueProof.mtp);
|
|
53
49
|
claimPathMtpNoAux.push(nodAuxJSONLD.noAux);
|
|
@@ -57,15 +53,14 @@ export class LinkedMultiQueryInputs extends BaseConfig {
|
|
|
57
53
|
claimPathValue.push(valueProof.value.toString());
|
|
58
54
|
slotIndex.push(this.query[i].slotIndex);
|
|
59
55
|
operator.push(this.query[i].operator);
|
|
56
|
+
valueArraySize.push(this.query[i].values.length);
|
|
60
57
|
const valuesArr = prepareCircuitArrayValues(this.query[i].values, this.getValueArrSize());
|
|
61
58
|
value.push(bigIntArrayToStringArray(valuesArr));
|
|
62
59
|
}
|
|
63
60
|
const s = {
|
|
64
61
|
linkNonce: this.linkNonce.toString(),
|
|
65
62
|
issuerClaim: this.claim.marshalJson(),
|
|
66
|
-
enabled,
|
|
67
63
|
claimSchema: this.claim.getSchemaHash().bigInt().toString(),
|
|
68
|
-
claimPathNotExists,
|
|
69
64
|
claimPathMtp,
|
|
70
65
|
claimPathMtpNoAux,
|
|
71
66
|
claimPathMtpAuxHi,
|
|
@@ -74,7 +69,8 @@ export class LinkedMultiQueryInputs extends BaseConfig {
|
|
|
74
69
|
claimPathValue,
|
|
75
70
|
slotIndex,
|
|
76
71
|
operator,
|
|
77
|
-
value
|
|
72
|
+
value,
|
|
73
|
+
valueArraySize
|
|
78
74
|
};
|
|
79
75
|
return byteEncoder.encode(JSON.stringify(s));
|
|
80
76
|
}
|
|
@@ -96,7 +92,7 @@ export class LinkedMultiQueryPubSignals {
|
|
|
96
92
|
* @returns LinkedMultiQueryPubSignals
|
|
97
93
|
*/
|
|
98
94
|
pubSignalsUnmarshal(data) {
|
|
99
|
-
const len =
|
|
95
|
+
const len = 22;
|
|
100
96
|
const queryLength = LinkedMultiQueryInputs.queryCount;
|
|
101
97
|
const sVals = JSON.parse(byteDecoder.decode(data));
|
|
102
98
|
if (sVals.length !== len) {
|
|
@@ -121,13 +117,6 @@ export class LinkedMultiQueryPubSignals {
|
|
|
121
117
|
this.circuitQueryHash.push(BigInt(sVals[fieldIdx]));
|
|
122
118
|
fieldIdx++;
|
|
123
119
|
}
|
|
124
|
-
// - enabled
|
|
125
|
-
this.enabled = [];
|
|
126
|
-
for (let i = 0; i < queryLength; i++) {
|
|
127
|
-
const enabledNum = parseInt(sVals[fieldIdx]);
|
|
128
|
-
this.enabled.push(enabledNum === 1);
|
|
129
|
-
fieldIdx++;
|
|
130
|
-
}
|
|
131
120
|
return this;
|
|
132
121
|
}
|
|
133
122
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Proof } from '@iden3/js-merkletree';
|
|
2
|
-
import { QueryOperators } from './comparer';
|
|
2
|
+
import { Operators, QueryOperators } from './comparer';
|
|
3
3
|
/**
|
|
4
4
|
* Query represents basic request to claim slot verification
|
|
5
5
|
*
|
|
@@ -17,6 +17,48 @@ export class Query {
|
|
|
17
17
|
this.values?.some((v) => typeof v !== 'bigint'))
|
|
18
18
|
throw new Error(CircuitError.EmptyQueryValue);
|
|
19
19
|
}
|
|
20
|
+
validateValueArraySize(maxArrSize) {
|
|
21
|
+
switch (this.values.length) {
|
|
22
|
+
case 0: {
|
|
23
|
+
const zeroArrSizeOps = [Operators.NOOP, Operators.SD, Operators.NULLIFY];
|
|
24
|
+
if (!zeroArrSizeOps.includes(this.operator)) {
|
|
25
|
+
throw new Error(CircuitError.InvalidValuesArrSize);
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
case 1: {
|
|
30
|
+
const oneArrSizeOps = [
|
|
31
|
+
Operators.EQ,
|
|
32
|
+
Operators.LT,
|
|
33
|
+
Operators.GT,
|
|
34
|
+
Operators.NE,
|
|
35
|
+
Operators.LTE,
|
|
36
|
+
Operators.GTE,
|
|
37
|
+
Operators.EXISTS
|
|
38
|
+
];
|
|
39
|
+
if (!oneArrSizeOps.includes(this.operator)) {
|
|
40
|
+
throw new Error(CircuitError.InvalidValuesArrSize);
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
case 2: {
|
|
45
|
+
const twoArrSizeOps = [Operators.BETWEEN, Operators.NONBETWEEN];
|
|
46
|
+
if (!twoArrSizeOps.includes(this.operator)) {
|
|
47
|
+
throw new Error(CircuitError.InvalidValuesArrSize);
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
default: {
|
|
52
|
+
const maxArrSizeOps = [Operators.IN, Operators.NIN];
|
|
53
|
+
if (!maxArrSizeOps.includes(this.operator)) {
|
|
54
|
+
throw new Error(CircuitError.InvalidOperationType);
|
|
55
|
+
}
|
|
56
|
+
if (!this.values.length || this.values.length > maxArrSize) {
|
|
57
|
+
throw new Error(CircuitError.InvalidValuesArrSize);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
20
62
|
}
|
|
21
63
|
/**
|
|
22
64
|
* CircuitID is alias for circuit identifier
|
|
@@ -41,17 +83,17 @@ export var CircuitId;
|
|
|
41
83
|
* @beta
|
|
42
84
|
*/
|
|
43
85
|
// AtomicQueryV3CircuitID is a type for credentialAtomicQueryV3.circom
|
|
44
|
-
CircuitId["AtomicQueryV3"] = "credentialAtomicQueryV3-beta.
|
|
86
|
+
CircuitId["AtomicQueryV3"] = "credentialAtomicQueryV3-beta.1";
|
|
45
87
|
/**
|
|
46
88
|
* @beta
|
|
47
89
|
*/
|
|
48
90
|
// AtomicQueryV3OnChainCircuitID is a type for credentialAtomicQueryV3OnChain.circom
|
|
49
|
-
CircuitId["AtomicQueryV3OnChain"] = "credentialAtomicQueryV3OnChain-beta.
|
|
91
|
+
CircuitId["AtomicQueryV3OnChain"] = "credentialAtomicQueryV3OnChain-beta.1";
|
|
50
92
|
/**
|
|
51
93
|
* @beta
|
|
52
94
|
*/
|
|
53
95
|
// LinkedMultiQuery is a type for linkedMultiQuery.circom
|
|
54
|
-
CircuitId["LinkedMultiQuery10"] = "linkedMultiQuery10-beta.
|
|
96
|
+
CircuitId["LinkedMultiQuery10"] = "linkedMultiQuery10-beta.1";
|
|
55
97
|
})(CircuitId || (CircuitId = {}));
|
|
56
98
|
/**
|
|
57
99
|
* Claim structure for circuit inputs
|
|
@@ -88,6 +130,8 @@ export var CircuitError;
|
|
|
88
130
|
CircuitError["EmptyTreeState"] = "empty tree state";
|
|
89
131
|
CircuitError["EmptyRequestID"] = "empty request ID";
|
|
90
132
|
CircuitError["InvalidProofType"] = "invalid proof type";
|
|
133
|
+
CircuitError["InvalidValuesArrSize"] = "invalid query Values array size";
|
|
134
|
+
CircuitError["InvalidOperationType"] = "invalid operation type";
|
|
91
135
|
})(CircuitError || (CircuitError = {}));
|
|
92
136
|
/**
|
|
93
137
|
* ValueProof represents a Merkle Proof for a value stored as MT
|
|
@@ -3,8 +3,9 @@ import { PROTOCOL_MESSAGE_TYPE } from '../constants';
|
|
|
3
3
|
import { DID } from '@iden3/js-iden3-core';
|
|
4
4
|
import { proving } from '@iden3/js-jwz';
|
|
5
5
|
import * as uuid from 'uuid';
|
|
6
|
-
import { byteDecoder, byteEncoder
|
|
7
|
-
import {
|
|
6
|
+
import { byteDecoder, byteEncoder } from '../../utils';
|
|
7
|
+
import { processZeroKnowledgeProofRequests } from './common';
|
|
8
|
+
import { CircuitId } from '../../circuits';
|
|
8
9
|
/**
|
|
9
10
|
* createAuthorizationRequest is a function to create protocol authorization request
|
|
10
11
|
* @param {string} reason - reason to request proof
|
|
@@ -59,6 +60,12 @@ export class AuthHandler {
|
|
|
59
60
|
constructor(_packerMgr, _proofService) {
|
|
60
61
|
this._packerMgr = _packerMgr;
|
|
61
62
|
this._proofService = _proofService;
|
|
63
|
+
this._supportedCircuits = [
|
|
64
|
+
CircuitId.AtomicQueryV3,
|
|
65
|
+
CircuitId.AtomicQuerySigV2,
|
|
66
|
+
CircuitId.AtomicQueryMTPV2,
|
|
67
|
+
CircuitId.LinkedMultiQuery10
|
|
68
|
+
];
|
|
62
69
|
}
|
|
63
70
|
/**
|
|
64
71
|
* @inheritdoc IAuthHandler#parseAuthorizationRequest
|
|
@@ -93,6 +100,11 @@ export class AuthHandler {
|
|
|
93
100
|
did = DID.parse(authRequest.to);
|
|
94
101
|
}
|
|
95
102
|
const guid = uuid.v4();
|
|
103
|
+
if (!authRequest.from) {
|
|
104
|
+
throw new Error('auth request should contain from field');
|
|
105
|
+
}
|
|
106
|
+
const from = DID.parse(authRequest.from);
|
|
107
|
+
const responseScope = await processZeroKnowledgeProofRequests(did, authRequest?.body.scope, from, this._proofService, { ...opts, supportedCircuits: this._supportedCircuits });
|
|
96
108
|
const authResponse = {
|
|
97
109
|
id: guid,
|
|
98
110
|
typ: opts.mediaType,
|
|
@@ -100,64 +112,11 @@ export class AuthHandler {
|
|
|
100
112
|
thid: authRequest.thid ?? guid,
|
|
101
113
|
body: {
|
|
102
114
|
message: authRequest?.body?.message,
|
|
103
|
-
scope:
|
|
115
|
+
scope: responseScope
|
|
104
116
|
},
|
|
105
117
|
from: did.string(),
|
|
106
118
|
to: authRequest.from
|
|
107
119
|
};
|
|
108
|
-
const requestScope = authRequest.body.scope;
|
|
109
|
-
const combinedQueries = requestScope.reduce((acc, proofReq) => {
|
|
110
|
-
const groupId = proofReq.query.groupId;
|
|
111
|
-
if (!groupId) {
|
|
112
|
-
return acc;
|
|
113
|
-
}
|
|
114
|
-
const existedData = acc.get(groupId);
|
|
115
|
-
if (!existedData) {
|
|
116
|
-
const seed = getRandomBytes(12);
|
|
117
|
-
const dataView = new DataView(seed.buffer);
|
|
118
|
-
const linkNonce = dataView.getUint32(0);
|
|
119
|
-
acc.set(groupId, { query: proofReq.query, linkNonce });
|
|
120
|
-
return acc;
|
|
121
|
-
}
|
|
122
|
-
const credentialSubject = mergeObjects(existedData.query.credentialSubject, proofReq.query.credentialSubject);
|
|
123
|
-
acc.set(groupId, {
|
|
124
|
-
...existedData,
|
|
125
|
-
query: {
|
|
126
|
-
skipClaimRevocationCheck: existedData.query.skipClaimRevocationCheck || proofReq.query.skipClaimRevocationCheck,
|
|
127
|
-
...existedData.query,
|
|
128
|
-
credentialSubject
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
return acc;
|
|
132
|
-
}, new Map());
|
|
133
|
-
const groupedCredentialsCache = new Map();
|
|
134
|
-
for (const proofReq of requestScope) {
|
|
135
|
-
const query = proofReq.query;
|
|
136
|
-
const groupId = query.groupId;
|
|
137
|
-
const combinedQueryData = combinedQueries.get(groupId);
|
|
138
|
-
if (groupId) {
|
|
139
|
-
if (!combinedQueryData) {
|
|
140
|
-
throw new Error(`Invalid group id ${query.groupId}`);
|
|
141
|
-
}
|
|
142
|
-
const combinedQuery = combinedQueryData.query;
|
|
143
|
-
if (!groupedCredentialsCache.has(groupId)) {
|
|
144
|
-
const credWithRevStatus = await this._proofService.findCredentialByProofQuery(did, combinedQueryData.query);
|
|
145
|
-
if (!credWithRevStatus.cred) {
|
|
146
|
-
throw new Error(`Credential not found for query ${JSON.stringify(combinedQuery)}`);
|
|
147
|
-
}
|
|
148
|
-
groupedCredentialsCache.set(groupId, credWithRevStatus);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
const credWithRevStatus = groupedCredentialsCache.get(groupId);
|
|
152
|
-
const zkpRes = await this._proofService.generateProof(proofReq, did, {
|
|
153
|
-
verifierDid: DID.parse(authRequest.from),
|
|
154
|
-
skipRevocation: Boolean(query.skipClaimRevocationCheck),
|
|
155
|
-
credential: credWithRevStatus?.cred,
|
|
156
|
-
credentialRevocationStatus: credWithRevStatus?.revStatus,
|
|
157
|
-
linkNonce: combinedQueryData?.linkNonce ? BigInt(combinedQueryData.linkNonce) : undefined
|
|
158
|
-
});
|
|
159
|
-
authResponse.body.scope.push(zkpRes);
|
|
160
|
-
}
|
|
161
120
|
const msgBytes = byteEncoder.encode(JSON.stringify(authResponse));
|
|
162
121
|
const packerOpts = opts.mediaType === MediaType.SignedMessage
|
|
163
122
|
? opts.packerOptions
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { getRandomBytes } from '@iden3/js-crypto';
|
|
2
|
+
import { mergeObjects } from '../../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Groups the ZeroKnowledgeProofRequest objects based on their groupId.
|
|
5
|
+
* Returns a Map where the key is the groupId and the value is an object containing the query and linkNonce.
|
|
6
|
+
*
|
|
7
|
+
* @param requestScope - An array of ZeroKnowledgeProofRequest objects.
|
|
8
|
+
* @returns A Map<number, { query: JSONObject; linkNonce: number }> representing the grouped queries.
|
|
9
|
+
*/
|
|
10
|
+
const getGroupedQueries = (requestScope) => requestScope.reduce((acc, proofReq) => {
|
|
11
|
+
const groupId = proofReq.query.groupId;
|
|
12
|
+
if (!groupId) {
|
|
13
|
+
return acc;
|
|
14
|
+
}
|
|
15
|
+
const existedData = acc.get(groupId);
|
|
16
|
+
if (!existedData) {
|
|
17
|
+
const seed = getRandomBytes(12);
|
|
18
|
+
const dataView = new DataView(seed.buffer);
|
|
19
|
+
const linkNonce = dataView.getUint32(0);
|
|
20
|
+
acc.set(groupId, { query: proofReq.query, linkNonce });
|
|
21
|
+
return acc;
|
|
22
|
+
}
|
|
23
|
+
const credentialSubject = mergeObjects(existedData.query.credentialSubject, proofReq.query.credentialSubject);
|
|
24
|
+
acc.set(groupId, {
|
|
25
|
+
...existedData,
|
|
26
|
+
query: {
|
|
27
|
+
skipClaimRevocationCheck: existedData.query.skipClaimRevocationCheck || proofReq.query.skipClaimRevocationCheck,
|
|
28
|
+
...existedData.query,
|
|
29
|
+
credentialSubject
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return acc;
|
|
33
|
+
}, new Map());
|
|
34
|
+
/**
|
|
35
|
+
* Processes zero knowledge proof requests.
|
|
36
|
+
*
|
|
37
|
+
* @param senderIdentifier - The identifier of the sender.
|
|
38
|
+
* @param requests - An array of zero knowledge proof requests.
|
|
39
|
+
* @param from - The identifier of the sender.
|
|
40
|
+
* @param proofService - The proof service.
|
|
41
|
+
* @param opts - Additional options for processing the requests.
|
|
42
|
+
* @returns A promise that resolves to an array of zero knowledge proof responses.
|
|
43
|
+
*/
|
|
44
|
+
export const processZeroKnowledgeProofRequests = async (senderIdentifier, requests, from, proofService, opts) => {
|
|
45
|
+
const requestScope = requests ?? [];
|
|
46
|
+
const combinedQueries = getGroupedQueries(requestScope);
|
|
47
|
+
const groupedCredentialsCache = new Map();
|
|
48
|
+
const zkpResponses = [];
|
|
49
|
+
for (const proofReq of requestScope) {
|
|
50
|
+
if (!opts.supportedCircuits.includes(proofReq.circuitId)) {
|
|
51
|
+
throw new Error(`Circuit ${proofReq.circuitId} is not allowed`);
|
|
52
|
+
}
|
|
53
|
+
const query = proofReq.query;
|
|
54
|
+
const groupId = query.groupId;
|
|
55
|
+
const combinedQueryData = combinedQueries.get(groupId);
|
|
56
|
+
if (groupId) {
|
|
57
|
+
if (!combinedQueryData) {
|
|
58
|
+
throw new Error(`Invalid group id ${query.groupId}`);
|
|
59
|
+
}
|
|
60
|
+
const combinedQuery = combinedQueryData.query;
|
|
61
|
+
if (!groupedCredentialsCache.has(groupId)) {
|
|
62
|
+
const credWithRevStatus = await proofService.findCredentialByProofQuery(senderIdentifier, combinedQueryData.query);
|
|
63
|
+
if (!credWithRevStatus.cred) {
|
|
64
|
+
throw new Error(`Credential not found for query ${JSON.stringify(combinedQuery)}`);
|
|
65
|
+
}
|
|
66
|
+
groupedCredentialsCache.set(groupId, credWithRevStatus);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const credWithRevStatus = groupedCredentialsCache.get(groupId);
|
|
70
|
+
const zkpRes = await proofService.generateProof(proofReq, senderIdentifier, {
|
|
71
|
+
verifierDid: from,
|
|
72
|
+
challenge: opts.challenge,
|
|
73
|
+
skipRevocation: Boolean(query.skipClaimRevocationCheck),
|
|
74
|
+
credential: credWithRevStatus?.cred,
|
|
75
|
+
credentialRevocationStatus: credWithRevStatus?.revStatus,
|
|
76
|
+
linkNonce: combinedQueryData?.linkNonce ? BigInt(combinedQueryData.linkNonce) : undefined
|
|
77
|
+
});
|
|
78
|
+
zkpResponses.push(zkpRes);
|
|
79
|
+
}
|
|
80
|
+
return zkpResponses;
|
|
81
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CircuitId } from '../../circuits/models';
|
|
2
2
|
import { PROTOCOL_MESSAGE_TYPE } from '../constants';
|
|
3
|
-
import { DID, ChainIds
|
|
4
|
-
import {
|
|
3
|
+
import { DID, ChainIds } from '@iden3/js-iden3-core';
|
|
4
|
+
import { processZeroKnowledgeProofRequests } from './common';
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
7
7
|
* Allows to process ContractInvokeRequest protocol message
|
|
@@ -23,7 +23,7 @@ export class ContractRequestHandler {
|
|
|
23
23
|
this._packerMgr = _packerMgr;
|
|
24
24
|
this._proofService = _proofService;
|
|
25
25
|
this._zkpVerifier = _zkpVerifier;
|
|
26
|
-
this.
|
|
26
|
+
this._supportedCircuits = [
|
|
27
27
|
CircuitId.AtomicQueryMTPV2OnChain,
|
|
28
28
|
CircuitId.AtomicQuerySigV2OnChain,
|
|
29
29
|
CircuitId.AtomicQueryV3OnChain
|
|
@@ -60,32 +60,13 @@ export class ContractRequestHandler {
|
|
|
60
60
|
if (!opts.ethSigner) {
|
|
61
61
|
throw new Error("Can't sign transaction. Provide Signer in options.");
|
|
62
62
|
}
|
|
63
|
-
const
|
|
64
|
-
const { contract_address, chain_id } = ciRequest.body.transaction_data;
|
|
63
|
+
const { chain_id } = ciRequest.body.transaction_data;
|
|
65
64
|
const networkFlag = Object.keys(ChainIds).find((key) => ChainIds[key] === chain_id);
|
|
66
65
|
if (!networkFlag) {
|
|
67
66
|
throw new Error(`Invalid chain id ${chain_id}`);
|
|
68
67
|
}
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
networkId,
|
|
73
|
-
// DidMethod.Iden3 is used based on discussions: all onchain issuers have iden3 did method by default. This can be changed in the release of v3 circuit.
|
|
74
|
-
method: DidMethod.Iden3
|
|
75
|
-
});
|
|
76
|
-
const verifierDid = DID.parseFromId(verifierId);
|
|
77
|
-
for (const proofReq of ciRequest.body.scope) {
|
|
78
|
-
if (!this._allowedCircuits.includes(proofReq.circuitId)) {
|
|
79
|
-
throw new Error(`Can't handle circuit ${proofReq.circuitId}. Only onchain circuits are allowed.`);
|
|
80
|
-
}
|
|
81
|
-
const query = proofReq.query;
|
|
82
|
-
const zkpRes = await this._proofService.generateProof(proofReq, did, {
|
|
83
|
-
skipRevocation: query.skipClaimRevocationCheck ?? false,
|
|
84
|
-
challenge: opts.challenge,
|
|
85
|
-
verifierDid
|
|
86
|
-
});
|
|
87
|
-
zkRequests.push(zkpRes);
|
|
88
|
-
}
|
|
89
|
-
return this._zkpVerifier.submitZKPResponse(opts.ethSigner, ciRequest.body.transaction_data, zkRequests);
|
|
68
|
+
const verifierDid = ciRequest.from ? DID.parse(ciRequest.from) : undefined;
|
|
69
|
+
const zkpResponses = await processZeroKnowledgeProofRequests(did, ciRequest?.body?.scope, verifierDid, this._proofService, { ...opts, supportedCircuits: this._supportedCircuits });
|
|
70
|
+
return this._zkpVerifier.submitZKPResponse(opts.ethSigner, ciRequest.body.transaction_data, zkpResponses);
|
|
90
71
|
}
|
|
91
72
|
}
|