@0xpolygonid/js-sdk 1.7.4 → 1.8.0

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.
Files changed (108) hide show
  1. package/dist/browser/esm/index.js +13086 -11852
  2. package/dist/browser/esm/index.js.map +1 -1
  3. package/dist/browser/umd/index.js +13115 -11861
  4. package/dist/browser/umd/index.js.map +1 -1
  5. package/dist/node/cjs/circuits/atomic-query-mtp-v2.js +3 -3
  6. package/dist/node/cjs/circuits/atomic-query-sig-v2.js +3 -3
  7. package/dist/node/cjs/circuits/atomic-query-v3.js +18 -13
  8. package/dist/node/cjs/circuits/auth-v2.js +1 -1
  9. package/dist/node/cjs/circuits/index.js +0 -1
  10. package/dist/node/cjs/circuits/linked-multi-query.js +16 -6
  11. package/dist/node/cjs/circuits/models.js +0 -5
  12. package/dist/node/cjs/credentials/credential-wallet.js +1 -3
  13. package/dist/node/cjs/credentials/index.js +1 -0
  14. package/dist/node/cjs/credentials/models.js +2 -0
  15. package/dist/node/cjs/credentials/status/credential-status-publisher.js +23 -4
  16. package/dist/node/cjs/iden3comm/constants.js +3 -1
  17. package/dist/node/cjs/iden3comm/handlers/auth.js +119 -14
  18. package/dist/node/cjs/kms/key-providers/sec256k1-provider.js +5 -2
  19. package/dist/node/cjs/proof/common.js +3 -4
  20. package/dist/node/cjs/proof/index.js +2 -1
  21. package/dist/node/cjs/proof/proof-service.js +22 -2
  22. package/dist/node/cjs/proof/provers/index.js +19 -0
  23. package/dist/node/cjs/proof/{inputs-generator.js → provers/inputs-generator.js} +43 -40
  24. package/dist/node/cjs/proof/{prover.js → provers/prover.js} +1 -1
  25. package/dist/node/cjs/proof/verifiers/index.js +18 -0
  26. package/dist/node/cjs/proof/verifiers/pub-signals-verifier.js +344 -0
  27. package/dist/node/cjs/proof/verifiers/query.js +190 -0
  28. package/dist/node/cjs/schema-processor/json/parser.js +39 -198
  29. package/dist/node/cjs/schema-processor/utils.js +13 -26
  30. package/dist/node/cjs/storage/blockchain/state.js +53 -8
  31. package/dist/node/cjs/storage/filters/jsonQuery.js +2 -2
  32. package/dist/node/cjs/utils/compare-func.js +11 -0
  33. package/dist/node/cjs/utils/index.js +2 -0
  34. package/dist/node/cjs/utils/message-bus.js +73 -0
  35. package/dist/node/cjs/verifiable/core-utils.js +234 -0
  36. package/dist/node/cjs/verifiable/credential.js +139 -1
  37. package/dist/node/cjs/verifiable/index.js +1 -0
  38. package/dist/node/esm/circuits/atomic-query-mtp-v2.js +3 -3
  39. package/dist/node/esm/circuits/atomic-query-sig-v2.js +3 -3
  40. package/dist/node/esm/circuits/atomic-query-v3.js +18 -13
  41. package/dist/node/esm/circuits/auth-v2.js +2 -2
  42. package/dist/node/esm/circuits/index.js +0 -1
  43. package/dist/node/esm/circuits/linked-multi-query.js +16 -6
  44. package/dist/node/esm/circuits/models.js +0 -5
  45. package/dist/node/esm/credentials/credential-wallet.js +1 -3
  46. package/dist/node/esm/credentials/index.js +1 -0
  47. package/dist/node/esm/credentials/models.js +1 -0
  48. package/dist/node/esm/credentials/status/credential-status-publisher.js +23 -4
  49. package/dist/node/esm/iden3comm/constants.js +3 -1
  50. package/dist/node/esm/iden3comm/handlers/auth.js +116 -13
  51. package/dist/node/esm/kms/key-providers/sec256k1-provider.js +5 -2
  52. package/dist/node/esm/proof/common.js +4 -5
  53. package/dist/node/esm/proof/index.js +2 -1
  54. package/dist/node/esm/proof/proof-service.js +22 -2
  55. package/dist/node/esm/proof/provers/index.js +3 -0
  56. package/dist/node/esm/proof/{inputs-generator.js → provers/inputs-generator.js} +40 -37
  57. package/dist/node/esm/proof/{prover.js → provers/prover.js} +1 -1
  58. package/dist/node/esm/proof/verifiers/index.js +2 -0
  59. package/dist/node/esm/proof/verifiers/pub-signals-verifier.js +340 -0
  60. package/dist/node/esm/proof/verifiers/query.js +186 -0
  61. package/dist/node/esm/schema-processor/json/parser.js +40 -199
  62. package/dist/node/esm/schema-processor/utils.js +13 -26
  63. package/dist/node/esm/storage/blockchain/state.js +53 -8
  64. package/dist/node/esm/storage/filters/jsonQuery.js +2 -2
  65. package/dist/node/esm/utils/compare-func.js +7 -0
  66. package/dist/node/esm/utils/index.js +2 -0
  67. package/dist/node/esm/utils/message-bus.js +66 -0
  68. package/dist/node/esm/verifiable/core-utils.js +200 -0
  69. package/dist/node/esm/verifiable/credential.js +118 -3
  70. package/dist/node/esm/verifiable/index.js +1 -0
  71. package/dist/types/circuits/index.d.ts +0 -1
  72. package/dist/types/circuits/linked-multi-query.d.ts +3 -3
  73. package/dist/types/circuits/models.d.ts +0 -4
  74. package/dist/types/credentials/credential-wallet.d.ts +2 -60
  75. package/dist/types/credentials/index.d.ts +1 -0
  76. package/dist/types/credentials/models.d.ts +68 -0
  77. package/dist/types/credentials/status/credential-status-publisher.d.ts +2 -0
  78. package/dist/types/iden3comm/constants.d.ts +1 -0
  79. package/dist/types/iden3comm/handlers/auth.d.ts +53 -13
  80. package/dist/types/iden3comm/types/protocol/credentials.d.ts +16 -0
  81. package/dist/types/identity/identity-wallet.d.ts +3 -1
  82. package/dist/types/kms/key-providers/sec256k1-provider.d.ts +1 -1
  83. package/dist/types/proof/index.d.ts +2 -1
  84. package/dist/types/proof/proof-service.d.ts +28 -3
  85. package/dist/types/proof/provers/index.d.ts +3 -0
  86. package/dist/types/proof/{inputs-generator.d.ts → provers/inputs-generator.d.ts} +15 -9
  87. package/dist/types/proof/{prover.d.ts → provers/prover.d.ts} +2 -2
  88. package/dist/types/proof/verifiers/index.d.ts +2 -0
  89. package/dist/types/proof/verifiers/pub-signals-verifier.d.ts +58 -0
  90. package/dist/types/proof/verifiers/query.d.ts +25 -0
  91. package/dist/types/schema-processor/json/parser.d.ts +47 -28
  92. package/dist/types/schema-processor/utils.d.ts +9 -4
  93. package/dist/types/storage/blockchain/state.d.ts +5 -1
  94. package/dist/types/storage/interfaces/state.d.ts +8 -0
  95. package/dist/types/utils/compare-func.d.ts +1 -0
  96. package/dist/types/utils/index.d.ts +2 -0
  97. package/dist/types/utils/message-bus.d.ts +62 -0
  98. package/dist/types/verifiable/core-utils.d.ts +84 -0
  99. package/dist/types/verifiable/credential.d.ts +11 -1
  100. package/dist/types/verifiable/index.d.ts +1 -0
  101. package/dist/types/verifiable/proof.d.ts +4 -0
  102. package/package.json +10 -10
  103. package/dist/node/cjs/circuits/linked-nullifier.js +0 -57
  104. package/dist/node/esm/circuits/linked-nullifier.js +0 -52
  105. package/dist/types/circuits/linked-nullifier.d.ts +0 -37
  106. /package/dist/node/cjs/proof/{witness_calculator.js → provers/witness_calculator.js} +0 -0
  107. /package/dist/node/esm/proof/{witness_calculator.js → provers/witness_calculator.js} +0 -0
  108. /package/dist/types/proof/{witness_calculator.d.ts → provers/witness_calculator.d.ts} +0 -0
@@ -1,5 +1,7 @@
1
+ import { Proof } from '@iden3/js-merkletree';
1
2
  import { byteDecoder, byteEncoder } from '../utils';
2
3
  import { BaseConfig, bigIntArrayToStringArray, existenceToInt, getNodeAuxValue, prepareCircuitArrayValues, prepareSiblingsStr } from './common';
4
+ import { ValueProof } from './models';
3
5
  /**
4
6
  * LinkedMultiQuery circuit representation
5
7
  * Inputs and public signals declaration, marshalling and parsing
@@ -21,7 +23,7 @@ export class LinkedMultiQueryInputs extends BaseConfig {
21
23
  const slotIndex = [];
22
24
  const operator = [];
23
25
  const value = [];
24
- for (let i = 0; i < this.queryLength; i++) {
26
+ for (let i = 0; i < LinkedMultiQueryInputs.queryCount; i++) {
25
27
  if (!this.query[i]) {
26
28
  enabled.push(0);
27
29
  claimPathNotExists.push(0);
@@ -38,7 +40,13 @@ export class LinkedMultiQueryInputs extends BaseConfig {
38
40
  continue;
39
41
  }
40
42
  enabled.push(1);
41
- const valueProof = this.query[i].valueProof;
43
+ let valueProof = this.query[i].valueProof;
44
+ if (!valueProof) {
45
+ valueProof = new ValueProof();
46
+ valueProof.path = 0n;
47
+ valueProof.value = 0n;
48
+ valueProof.mtp = new Proof();
49
+ }
42
50
  claimPathNotExists.push(existenceToInt(valueProof.mtp.existence));
43
51
  claimPathMtp.push(prepareSiblingsStr(valueProof.mtp, this.getMTLevelsClaim()));
44
52
  const nodAuxJSONLD = getNodeAuxValue(valueProof.mtp);
@@ -71,7 +79,8 @@ export class LinkedMultiQueryInputs extends BaseConfig {
71
79
  return byteEncoder.encode(JSON.stringify(s));
72
80
  }
73
81
  }
74
- // LinkedMultiQueryPubSignals linkedMultiQuery.circom public signals
82
+ LinkedMultiQueryInputs.queryCount = 10;
83
+ // LinkedMultiQueryPubSignals linkedMultiQuery10.circom public signals
75
84
  /**
76
85
  * public signals
77
86
  *
@@ -80,14 +89,15 @@ export class LinkedMultiQueryInputs extends BaseConfig {
80
89
  */
81
90
  export class LinkedMultiQueryPubSignals {
82
91
  /**
83
- * PubSignalsUnmarshal unmarshal linkedMultiQuery.circom public inputs to LinkedMultiQueryPubSignals
92
+ * PubSignalsUnmarshal unmarshal linkedMultiQuery10.circom public inputs to LinkedMultiQueryPubSignals
84
93
  *
85
94
  * @beta
86
95
  * @param {Uint8Array} data
87
96
  * @returns LinkedMultiQueryPubSignals
88
97
  */
89
- pubSignalsUnmarshal(data, queryLength) {
90
- const len = queryLength * 3 + 2;
98
+ pubSignalsUnmarshal(data) {
99
+ const len = 32;
100
+ const queryLength = LinkedMultiQueryInputs.queryCount;
91
101
  const sVals = JSON.parse(byteDecoder.decode(data));
92
102
  if (sVals.length !== len) {
93
103
  throw new Error(`invalid number of Output values expected ${len} got ${sVals.length}`);
@@ -47,11 +47,6 @@ export var CircuitId;
47
47
  */
48
48
  // AtomicQueryV3OnChainCircuitID is a type for credentialAtomicQueryV3OnChain.circom
49
49
  CircuitId["AtomicQueryV3OnChain"] = "credentialAtomicQueryV3OnChain-beta.0";
50
- /**
51
- * @beta
52
- */
53
- // LinkedNullifier is a type for linkedNullifier.circom
54
- CircuitId["LinkedNullifier"] = "linkedNullifier-beta.0";
55
50
  /**
56
51
  * @beta
57
52
  */
@@ -5,8 +5,6 @@ import { CredentialStatusResolverRegistry } from './status/resolver';
5
5
  import { IssuerResolver } from './status/sparse-merkle-tree';
6
6
  import { AgentResolver } from './status/agent-revocation';
7
7
  import { getUserDIDFromCredential } from './utils';
8
- // ErrAllClaimsRevoked all claims are revoked.
9
- const ErrAllClaimsRevoked = 'all claims are revoked';
10
8
  /**
11
9
  *
12
10
  * Wallet instance is a wrapper of CRUD logic for W3C credentials,
@@ -222,6 +220,6 @@ export class CredentialWallet {
222
220
  }
223
221
  return { cred, revStatus };
224
222
  }
225
- throw new Error(ErrAllClaimsRevoked);
223
+ throw new Error('all claims are revoked');
226
224
  }
227
225
  }
@@ -7,3 +7,4 @@ export * from './status/credential-status-publisher';
7
7
  export * from './credential-wallet';
8
8
  export * from './rhs';
9
9
  export * from './utils';
10
+ export * from './models';
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,5 @@
1
1
  import { CredentialStatusType } from '../../verifiable';
2
+ import { MessageBus, SDK_EVENTS } from '../../utils';
2
3
  /**
3
4
  * Registry for managing credential status publishers.
4
5
  */
@@ -42,12 +43,30 @@ export class Iden3OnchainSmtCredentialStatusPublisher {
42
43
  }
43
44
  const nodesBigInts = params.nodes.map((n) => n.children.map((c) => c.bigInt()));
44
45
  const txPromise = this._storage.saveNodes(nodesBigInts);
46
+ let publishMode = params.onChain?.publishMode ?? 'sync';
45
47
  if (params.onChain?.txCallback) {
46
- const cb = params.onChain?.txCallback;
47
- txPromise.then((receipt) => cb(receipt));
48
- return;
48
+ publishMode = 'callback';
49
+ }
50
+ switch (publishMode) {
51
+ case 'sync':
52
+ await txPromise;
53
+ break;
54
+ case 'callback': {
55
+ if (!params.onChain?.txCallback) {
56
+ throw new Error('txCallback is required for publishMode "callback"');
57
+ }
58
+ const cb = params.onChain?.txCallback;
59
+ txPromise.then((receipt) => cb(receipt));
60
+ break;
61
+ }
62
+ case 'async': {
63
+ const mb = MessageBus.getInstance();
64
+ txPromise.then((receipt) => mb.publish(SDK_EVENTS.TX_RECEIPT_ACCEPTED, receipt));
65
+ break;
66
+ }
67
+ default:
68
+ throw new Error(`Invalid publishMode: ${publishMode}`);
49
69
  }
50
- await txPromise;
51
70
  }
52
71
  }
53
72
  /**
@@ -30,7 +30,9 @@ export const PROTOCOL_MESSAGE_TYPE = Object.freeze({
30
30
  // RevocationStatusResponseMessageType is type for response with a revocation status
31
31
  REVOCATION_STATUS_RESPONSE_MESSAGE_TYPE: IDEN3_PROTOCOL + 'revocation/1.0/status',
32
32
  // ContractInvokeRequestMessageType is type for request of contract invoke request
33
- CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE: IDEN3_PROTOCOL + 'proofs/1.0/contract-invoke-request'
33
+ CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE: IDEN3_PROTOCOL + 'proofs/1.0/contract-invoke-request',
34
+ // CredentialOnchainOfferMessageType is type of message with credential onchain offering
35
+ CREDENTIAL_ONCHAIN_OFFER_MESSAGE_TYPE: IDEN3_PROTOCOL + 'credentials/1.0/onchain-offer'
34
36
  });
35
37
  /**
36
38
  * Media types for iden3 comm communication protocol
@@ -5,6 +5,41 @@ import { proving } from '@iden3/js-jwz';
5
5
  import * as uuid from 'uuid';
6
6
  import { byteDecoder, byteEncoder, mergeObjects } from '../../utils';
7
7
  import { getRandomBytes } from '@iden3/js-crypto';
8
+ /**
9
+ * createAuthorizationRequest is a function to create protocol authorization request
10
+ * @param {string} reason - reason to request proof
11
+ * @param {string} sender - sender did
12
+ * @param {string} callbackUrl - callback that user should use to send response
13
+ * @returns `Promise<AuthorizationRequestMessage>`
14
+ */
15
+ export function createAuthorizationRequest(reason, sender, callbackUrl) {
16
+ return createAuthorizationRequestWithMessage(reason, '', sender, callbackUrl);
17
+ }
18
+ /**
19
+ * createAuthorizationRequestWithMessage is a function to create protocol authorization request with explicit message to sign
20
+ * @param {string} reason - reason to request proof
21
+ * @param {string} message - message to sign in the response
22
+ * @param {string} sender - sender did
23
+ * @param {string} callbackUrl - callback that user should use to send response
24
+ * @returns `Promise<AuthorizationRequestMessage>`
25
+ */
26
+ export function createAuthorizationRequestWithMessage(reason, message, sender, callbackUrl) {
27
+ const uuidv4 = uuid.v4();
28
+ const request = {
29
+ id: uuidv4,
30
+ thid: uuidv4,
31
+ from: sender,
32
+ typ: MediaType.PlainMessage,
33
+ type: PROTOCOL_MESSAGE_TYPE.AUTHORIZATION_REQUEST_MESSAGE_TYPE,
34
+ body: {
35
+ reason: reason,
36
+ message: message,
37
+ callbackUrl: callbackUrl,
38
+ scope: []
39
+ }
40
+ };
41
+ return request;
42
+ }
8
43
  /**
9
44
  *
10
45
  * Allows to process AuthorizationRequest protocol message and produce JWZ response.
@@ -26,10 +61,7 @@ export class AuthHandler {
26
61
  this._proofService = _proofService;
27
62
  }
28
63
  /**
29
- * unpacks authorization request
30
- * @public
31
- * @param {Uint8Array} request - raw byte message
32
- * @returns `Promise<AuthorizationRequestMessage>`
64
+ * @inheritdoc IAuthHandler#parseAuthorizationRequest
33
65
  */
34
66
  async parseAuthorizationRequest(request) {
35
67
  const { unpackedMessage: message } = await this._packerMgr.unpack(request);
@@ -40,15 +72,7 @@ export class AuthHandler {
40
72
  return authRequest;
41
73
  }
42
74
  /**
43
- * unpacks authorization request and packs authorization response
44
- * @public
45
- * @param {did} did - sender DID
46
- * @param {Uint8Array} request - raw byte message
47
- * @returns `Promise<{
48
- token: string;
49
- authRequest: AuthorizationRequestMessage;
50
- authResponse: AuthorizationResponseMessage;
51
- }>`
75
+ * @inheritdoc IAuthHandler#handleAuthorizationRequest
52
76
  */
53
77
  async handleAuthorizationRequest(did, request, opts) {
54
78
  const authRequest = await this.parseAuthorizationRequest(request);
@@ -145,4 +169,83 @@ export class AuthHandler {
145
169
  }));
146
170
  return { authRequest, authResponse, token };
147
171
  }
172
+ /**
173
+ * @inheritdoc IAuthHandler#handleAuthorizationResponse
174
+ */
175
+ async handleAuthorizationResponse(response, request, opts) {
176
+ if ((request.body.message ?? '') !== (response.body.message ?? '')) {
177
+ throw new Error('message for signing from request is not presented in response');
178
+ }
179
+ if (request.from !== response.to) {
180
+ throw new Error(`sender of the request is not a target of response - expected ${request.from}, given ${response.to}`);
181
+ }
182
+ this.verifyAuthRequest(request);
183
+ const requestScope = request.body.scope;
184
+ if (!response.from) {
185
+ throw new Error(`proof response doesn't contain from field`);
186
+ }
187
+ const groupIdToLinkIdMap = new Map();
188
+ // group requests by query group id
189
+ for (const proofRequest of requestScope) {
190
+ const groupId = proofRequest.query.groupId;
191
+ const proofResp = response.body.scope.find((resp) => resp.id === proofRequest.id);
192
+ if (!proofResp) {
193
+ throw new Error(`proof is not given for requestId ${proofRequest.id}`);
194
+ }
195
+ const circuitId = proofResp.circuitId;
196
+ if (circuitId !== proofRequest.circuitId) {
197
+ throw new Error(`proof is not given for requested circuit expected: ${proofRequest.circuitId}, given ${circuitId}`);
198
+ }
199
+ const params = proofRequest.params ?? {};
200
+ params.verifierDid = DID.parse(request.from);
201
+ const { linkID } = await this._proofService.verifyZKPResponse(proofResp, {
202
+ query: proofRequest.query,
203
+ sender: response.from,
204
+ params,
205
+ opts
206
+ });
207
+ // write linkId to the proof response
208
+ // const pubSig = pubSignals as unknown as { linkID?: number };
209
+ if (linkID && groupId) {
210
+ groupIdToLinkIdMap.set(groupId, [
211
+ ...(groupIdToLinkIdMap.get(groupId) ?? []),
212
+ { linkID: linkID, requestId: proofResp.id }
213
+ ]);
214
+ }
215
+ }
216
+ // verify grouping links
217
+ for (const [groupId, metas] of groupIdToLinkIdMap.entries()) {
218
+ // check that all linkIds are the same
219
+ if (metas.some((meta) => meta.linkID !== metas[0].linkID)) {
220
+ throw new Error(`Link id validation failed for group ${groupId}, request linkID to requestIds info: ${JSON.stringify(metas)}`);
221
+ }
222
+ }
223
+ return { request, response };
224
+ }
225
+ verifyAuthRequest(request) {
226
+ const groupIdValidationMap = {};
227
+ const requestScope = request.body.scope;
228
+ for (const proofRequest of requestScope) {
229
+ const groupId = proofRequest.query.groupId;
230
+ if (groupId) {
231
+ const existingRequests = groupIdValidationMap[groupId] ?? [];
232
+ //validate that all requests in the group have the same schema, issuer and circuit
233
+ for (const existingRequest of existingRequests) {
234
+ if (existingRequest.query.type !== proofRequest.query.type) {
235
+ throw new Error(`all requests in the group should have the same type`);
236
+ }
237
+ if (existingRequest.query.context !== proofRequest.query.context) {
238
+ throw new Error(`all requests in the group should have the same context`);
239
+ }
240
+ const allowedIssuers = proofRequest.query.allowedIssuers;
241
+ const existingRequestAllowedIssuers = existingRequest.query.allowedIssuers;
242
+ if (!(allowedIssuers.includes('*') ||
243
+ allowedIssuers.every((issuer) => existingRequestAllowedIssuers.includes(issuer)))) {
244
+ throw new Error(`all requests in the group should have the same issuer`);
245
+ }
246
+ }
247
+ groupIdValidationMap[groupId] = [...(groupIdValidationMap[groupId] ?? []), proofRequest];
248
+ }
249
+ }
250
+ }
148
251
  }
@@ -24,8 +24,11 @@ export class Sec256k1Provider {
24
24
  * @param {Uint8Array} seed - byte array seed
25
25
  * @returns kms key identifier
26
26
  */
27
- async newPrivateKeyFromSeed() {
28
- const keyPair = this._ec.genKeyPair();
27
+ async newPrivateKeyFromSeed(seed) {
28
+ if (seed.length !== 32) {
29
+ throw new Error('Seed should be 32 bytes');
30
+ }
31
+ const keyPair = this._ec.keyFromPrivate(seed);
29
32
  const kmsId = {
30
33
  type: this.keyType,
31
34
  id: providerHelpers.keyPath(this.keyType, keyPair.getPublic().encode('hex', false))
@@ -1,8 +1,7 @@
1
1
  import { Hash, Proof, ZERO_HASH } from '@iden3/js-merkletree';
2
2
  import { buildTreeState, isValidOperation, QueryOperators } from '../circuits';
3
- import { buildFieldPath } from '../verifiable';
3
+ import { buildFieldPath, getSerializationAttrFromContext, getFieldSlotIndex } from '../verifiable';
4
4
  import { Merklizer, Path } from '@iden3/js-jsonld-merklization';
5
- import { Parser } from '../schema-processor/json';
6
5
  import { byteEncoder } from '../utils';
7
6
  import { poseidon } from '@iden3/js-crypto';
8
7
  /**
@@ -60,7 +59,7 @@ export const toGISTProof = (smtProof) => {
60
59
  export const parseCredentialSubject = (credentialSubject) => {
61
60
  // credentialSubject is empty
62
61
  if (!credentialSubject) {
63
- return [{ operator: QueryOperators.$eq, fieldName: '' }];
62
+ return [{ operator: QueryOperators.$noop, fieldName: '' }];
64
63
  }
65
64
  const queries = [];
66
65
  const entries = Object.entries(credentialSubject);
@@ -95,7 +94,7 @@ export const parseQueryMetadata = async (propertyQuery, ldContextJSON, credentia
95
94
  values: [],
96
95
  path: new Path()
97
96
  };
98
- const serAttr = await Parser.getSerializationAttrFromContext(JSON.parse(ldContextJSON), options, credentialType);
97
+ const serAttr = await getSerializationAttrFromContext(JSON.parse(ldContextJSON), options, credentialType);
99
98
  if (!serAttr) {
100
99
  query.merklizedSchema = true;
101
100
  }
@@ -103,7 +102,7 @@ export const parseQueryMetadata = async (propertyQuery, ldContextJSON, credentia
103
102
  // and not a position of merklization root.
104
103
  // it has no influence on check in the off-chain circuits, but it aligns with onchain verification standard
105
104
  if (!query.merklizedSchema) {
106
- query.slotIndex = await Parser.getFieldSlotIndex(propertyQuery.fieldName, credentialType, byteEncoder.encode(ldContextJSON));
105
+ query.slotIndex = await getFieldSlotIndex(propertyQuery.fieldName, credentialType, byteEncoder.encode(ldContextJSON));
107
106
  }
108
107
  else {
109
108
  try {
@@ -1,3 +1,4 @@
1
1
  export * from './proof-service';
2
- export * from './prover';
2
+ export * from './provers';
3
3
  export * from './common';
4
+ export * from './verifiers';
@@ -4,11 +4,12 @@ import { Hash } from '@iden3/js-merkletree';
4
4
  import { AuthV2Inputs, CircuitId, Operators, Query, StateTransitionInputs, ValueProof } from '../circuits';
5
5
  import { createVerifiablePresentation } from '../verifiable';
6
6
  import { parseCredentialSubject, parseQueryMetadata, toGISTProof, transformQueryValueToBigInts } from './common';
7
- import { NativeProver } from './prover';
7
+ import { NativeProver } from './provers/prover';
8
8
  import { getDocumentLoader } from '@iden3/js-jsonld-merklization';
9
9
  import { cacheLoader } from '../schema-processor';
10
10
  import { byteDecoder, byteEncoder } from '../utils/encoding';
11
- import { InputGenerator } from './inputs-generator';
11
+ import { InputGenerator } from './provers/inputs-generator';
12
+ import { PubSignalsVerifier } from './verifiers/pub-signals-verifier';
12
13
  /**
13
14
  * Proof service is an implementation of IProofService
14
15
  * that works with a native groth16 prover
@@ -32,11 +33,30 @@ export class ProofService {
32
33
  this._prover = opts?.prover ?? new NativeProver(_circuitStorage);
33
34
  this._ldOptions = { ...opts, documentLoader: opts?.documentLoader ?? cacheLoader(opts) };
34
35
  this._inputsGenerator = new InputGenerator(_identityWallet, _credentialWallet, _stateStorage);
36
+ this._pubSignalsVerifier = new PubSignalsVerifier(opts?.documentLoader ?? cacheLoader(opts), _stateStorage);
35
37
  }
36
38
  /** {@inheritdoc IProofService.verifyProof} */
37
39
  async verifyProof(zkp, circuitId) {
38
40
  return this._prover.verify(zkp, circuitId);
39
41
  }
42
+ /** {@inheritdoc IProofService.verify} */
43
+ async verifyZKPResponse(proofResp, opts) {
44
+ const proofValid = await this._prover.verify(proofResp, proofResp.circuitId);
45
+ if (!proofValid) {
46
+ throw Error(`Proof with circuit id ${proofResp.circuitId} and request id ${proofResp.id} is not valid`);
47
+ }
48
+ const verifyContext = {
49
+ pubSignals: proofResp.pub_signals,
50
+ query: opts.query,
51
+ verifiablePresentation: proofResp.vp,
52
+ sender: opts.sender,
53
+ challenge: BigInt(proofResp.id),
54
+ opts: opts.opts,
55
+ params: opts.params
56
+ };
57
+ const pubSignals = await this._pubSignalsVerifier.verify(proofResp.circuitId, verifyContext);
58
+ return { linkID: pubSignals.linkID };
59
+ }
40
60
  /** {@inheritdoc IProofService.generateProof} */
41
61
  async generateProof(proofReq, identifier, opts) {
42
62
  if (!opts) {
@@ -0,0 +1,3 @@
1
+ export * from './inputs-generator';
2
+ export * from './prover';
3
+ export * from './witness_calculator';
@@ -1,19 +1,28 @@
1
1
  import { DID, Id, getUnixTimestamp } from '@iden3/js-iden3-core';
2
- import { ProofType } from '../verifiable';
3
- import { AtomicQueryMTPV2Inputs, AtomicQueryMTPV2OnChainInputs, AtomicQuerySigV2Inputs, AtomicQuerySigV2OnChainInputs, AtomicQueryV3Inputs, AtomicQueryV3OnChainInputs, CircuitClaim, CircuitId, LinkedMultiQueryInputs, LinkedNullifierInputs, Operators } from '../circuits';
4
- import { toClaimNonRevStatus, toGISTProof } from './common';
5
- import { getUserDIDFromCredential } from '../credentials';
6
- const circuitValidator = {
7
- [CircuitId.AtomicQueryMTPV2]: { maxQueriesCount: 1 },
8
- [CircuitId.AtomicQueryMTPV2OnChain]: { maxQueriesCount: 1 },
9
- [CircuitId.AtomicQuerySigV2]: { maxQueriesCount: 1 },
10
- [CircuitId.AtomicQuerySigV2OnChain]: { maxQueriesCount: 1 },
11
- [CircuitId.AtomicQueryV3]: { maxQueriesCount: 1 },
12
- [CircuitId.AtomicQueryV3OnChain]: { maxQueriesCount: 1 },
13
- [CircuitId.AuthV2]: { maxQueriesCount: 0 },
14
- [CircuitId.StateTransition]: { maxQueriesCount: 0 },
15
- [CircuitId.LinkedNullifier]: { maxQueriesCount: 1 },
16
- [CircuitId.LinkedMultiQuery10]: { maxQueriesCount: 10 }
2
+ import { ProofType } from '../../verifiable';
3
+ import { AtomicQueryMTPV2Inputs, AtomicQueryMTPV2OnChainInputs, AtomicQuerySigV2Inputs, AtomicQuerySigV2OnChainInputs, AtomicQueryV3Inputs, AtomicQueryV3OnChainInputs, CircuitClaim, CircuitId, defaultValueArraySize, LinkedMultiQueryInputs, Operators, QueryOperators } from '../../circuits';
4
+ import { toClaimNonRevStatus, toGISTProof } from '../common';
5
+ import { getUserDIDFromCredential } from '../../credentials';
6
+ const allOperations = Object.values(QueryOperators);
7
+ const v2Operations = [
8
+ Operators.NOOP,
9
+ Operators.EQ,
10
+ Operators.LT,
11
+ Operators.GT,
12
+ Operators.IN,
13
+ Operators.NIN,
14
+ Operators.NE
15
+ ];
16
+ export const circuitValidator = {
17
+ [CircuitId.AtomicQueryMTPV2]: { maxQueriesCount: 1, supportedOperations: v2Operations },
18
+ [CircuitId.AtomicQueryMTPV2OnChain]: { maxQueriesCount: 1, supportedOperations: v2Operations },
19
+ [CircuitId.AtomicQuerySigV2]: { maxQueriesCount: 1, supportedOperations: v2Operations },
20
+ [CircuitId.AtomicQuerySigV2OnChain]: { maxQueriesCount: 1, supportedOperations: v2Operations },
21
+ [CircuitId.AtomicQueryV3]: { maxQueriesCount: 1, supportedOperations: allOperations },
22
+ [CircuitId.AtomicQueryV3OnChain]: { maxQueriesCount: 1, supportedOperations: allOperations },
23
+ [CircuitId.AuthV2]: { maxQueriesCount: 0, supportedOperations: [] },
24
+ [CircuitId.StateTransition]: { maxQueriesCount: 0, supportedOperations: [] },
25
+ [CircuitId.LinkedMultiQuery10]: { maxQueriesCount: 10, supportedOperations: allOperations }
17
26
  };
18
27
  export class InputGenerator {
19
28
  constructor(_identityWallet, _credentialWallet, _stateStorage) {
@@ -27,7 +36,7 @@ export class InputGenerator {
27
36
  circuitInputs.id = DID.idFromDID(identifier);
28
37
  circuitInputs.requestID = BigInt(proofReq.id);
29
38
  const query = circuitQueries[0];
30
- query.operator = query.operator === Operators.SD ? Operators.EQ : query.operator;
39
+ query.operator = this.transformV2QueryOperator(query.operator);
31
40
  circuitInputs.query = query;
32
41
  circuitInputs.claim = {
33
42
  issuerID: circuitClaimData.issuerId,
@@ -74,7 +83,7 @@ export class InputGenerator {
74
83
  circuitInputs.signature = signature;
75
84
  circuitInputs.challenge = params.challenge;
76
85
  const query = circuitQueries[0];
77
- query.operator = query.operator === Operators.SD ? Operators.EQ : query.operator;
86
+ query.operator = this.transformV2QueryOperator(query.operator);
78
87
  circuitInputs.query = query;
79
88
  circuitInputs.claim = {
80
89
  issuerID: circuitClaimData.issuerId,
@@ -104,7 +113,7 @@ export class InputGenerator {
104
113
  circuitInputs.profileNonce = BigInt(params.authProfileNonce);
105
114
  circuitInputs.skipClaimRevocationCheck = params.skipRevocation;
106
115
  const query = circuitQueries[0];
107
- query.operator = query.operator === Operators.SD ? Operators.EQ : query.operator;
116
+ query.operator = this.transformV2QueryOperator(query.operator);
108
117
  circuitInputs.query = query;
109
118
  circuitInputs.currentTimeStamp = getUnixTimestamp(new Date());
110
119
  return circuitInputs.inputsMarshal();
@@ -131,7 +140,7 @@ export class InputGenerator {
131
140
  circuitInputs.profileNonce = BigInt(params.authProfileNonce);
132
141
  circuitInputs.skipClaimRevocationCheck = params.skipRevocation;
133
142
  const query = circuitQueries[0];
134
- query.operator = query.operator === Operators.SD ? Operators.EQ : query.operator;
143
+ query.operator = this.transformV2QueryOperator(query.operator);
135
144
  circuitInputs.query = query;
136
145
  circuitInputs.currentTimeStamp = getUnixTimestamp(new Date());
137
146
  if (authClaimData.treeState) {
@@ -193,7 +202,10 @@ export class InputGenerator {
193
202
  circuitInputs.profileNonce = BigInt(params.authProfileNonce);
194
203
  circuitInputs.skipClaimRevocationCheck = params.skipRevocation;
195
204
  const query = circuitQueries[0];
196
- query.values = query.operator === Operators.SD ? new Array(64).fill(0) : query.values;
205
+ query.values =
206
+ query.operator === Operators.SD || query.operator === Operators.NOOP
207
+ ? new Array(defaultValueArraySize).fill(0)
208
+ : query.values;
197
209
  circuitInputs.query = query;
198
210
  circuitInputs.currentTimeStamp = getUnixTimestamp(new Date());
199
211
  circuitInputs.proofType = proofType;
@@ -241,7 +253,10 @@ export class InputGenerator {
241
253
  circuitInputs.profileNonce = BigInt(params.authProfileNonce);
242
254
  circuitInputs.skipClaimRevocationCheck = params.skipRevocation;
243
255
  const query = circuitQueries[0];
244
- query.values = query.operator === Operators.SD ? new Array(64).fill(0) : query.values;
256
+ query.values =
257
+ query.operator === Operators.SD || query.operator === Operators.NOOP
258
+ ? new Array(defaultValueArraySize).fill(0)
259
+ : query.values;
245
260
  circuitInputs.query = query;
246
261
  circuitInputs.currentTimeStamp = getUnixTimestamp(new Date());
247
262
  circuitInputs.proofType = proofType;
@@ -281,28 +296,13 @@ export class InputGenerator {
281
296
  }
282
297
  return circuitInputs.inputsMarshal();
283
298
  };
284
- this.linkedNullifierPrepareInputs = async ({ preparedCredential, identifier, proofReq, params }) => {
285
- const circuitClaimData = await this.newCircuitClaimData(preparedCredential);
286
- circuitClaimData.nonRevProof = toClaimNonRevStatus(preparedCredential.revStatus);
287
- const circuitInputs = new LinkedNullifierInputs();
288
- circuitInputs.linkNonce = params.linkNonce ?? BigInt(0);
289
- circuitInputs.issuerClaim = circuitClaimData.claim;
290
- circuitInputs.id = DID.idFromDID(identifier);
291
- circuitInputs.claimSubjectProfileNonce = BigInt(params.credentialSubjectProfileNonce);
292
- circuitInputs.verifierID = params.verifierDid ? DID.idFromDID(params.verifierDid) : undefined;
293
- circuitInputs.nullifierSessionID = proofReq.params?.nullifierSessionID
294
- ? BigInt(proofReq.params?.nullifierSessionID?.toString())
295
- : BigInt(0);
296
- return circuitInputs.inputsMarshal();
297
- };
298
- this.linkedMultiQuery10PrepareInputs = async ({ preparedCredential, proofReq, params, circuitQueries }) => {
299
+ this.linkedMultiQuery10PrepareInputs = async ({ preparedCredential, params, circuitQueries }) => {
299
300
  const circuitClaimData = await this.newCircuitClaimData(preparedCredential);
300
301
  circuitClaimData.nonRevProof = toClaimNonRevStatus(preparedCredential.revStatus);
301
302
  const circuitInputs = new LinkedMultiQueryInputs();
302
303
  circuitInputs.linkNonce = params.linkNonce ?? BigInt(0);
303
304
  circuitInputs.claim = circuitClaimData.claim;
304
305
  circuitInputs.query = circuitQueries;
305
- circuitInputs.queryLength = circuitValidator[proofReq.circuitId].maxQueriesCount;
306
306
  return circuitInputs.inputsMarshal();
307
307
  };
308
308
  }
@@ -386,4 +386,7 @@ export class InputGenerator {
386
386
  coreClaim: authCoreClaim
387
387
  };
388
388
  }
389
+ transformV2QueryOperator(operator) {
390
+ return operator === Operators.SD || operator === Operators.NOOP ? Operators.EQ : operator;
391
+ }
389
392
  }
@@ -1,7 +1,7 @@
1
1
  import { witnessBuilder } from './witness_calculator';
2
- import { byteDecoder } from '../utils';
3
2
  import { groth16 } from 'snarkjs';
4
3
  import { getCurveFromName } from 'ffjavascript';
4
+ import { byteDecoder } from '../../utils';
5
5
  /**
6
6
  * NativeProver service responsible for zk generation and verification of groth16 algorithm with bn128 curve
7
7
  * @public
@@ -0,0 +1,2 @@
1
+ export * from './pub-signals-verifier';
2
+ export * from './query';