@reclaimprotocol/attestor-core 3.1.1 → 4.0.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 (88) hide show
  1. package/lib/avs/contracts/index.js +18 -8
  2. package/lib/avs/utils/tasks.d.ts +1 -1
  3. package/lib/client/create-claim.d.ts +2 -2
  4. package/lib/client/create-claim.js +89 -33
  5. package/lib/client/utils/client-socket.d.ts +3 -1
  6. package/lib/client/utils/client-socket.js +25 -8
  7. package/lib/config/index.d.ts +4 -0
  8. package/lib/config/index.js +8 -3
  9. package/lib/index.js +18 -8
  10. package/lib/proto/api.d.ts +80 -2
  11. package/lib/proto/api.js +853 -101
  12. package/lib/providers/http/index.js +180 -109
  13. package/lib/providers/http/utils.d.ts +3 -6
  14. package/lib/providers/http/utils.js +13 -11
  15. package/lib/providers/index.js +1 -3
  16. package/lib/scripts/generate-receipt.js +6 -3
  17. package/lib/scripts/generate-toprf-keys.d.ts +1 -0
  18. package/lib/scripts/generate-toprf-keys.js +23 -0
  19. package/lib/server/create-server.js +14 -7
  20. package/lib/server/handlers/claimTunnel.js +33 -10
  21. package/lib/server/handlers/createTunnel.js +44 -8
  22. package/lib/server/handlers/disconnectTunnel.js +2 -2
  23. package/lib/server/handlers/index.js +4 -2
  24. package/lib/server/handlers/init.js +17 -2
  25. package/lib/server/handlers/toprf.d.ts +2 -0
  26. package/lib/server/handlers/toprf.js +21 -0
  27. package/lib/server/socket.d.ts +5 -3
  28. package/lib/server/socket.js +25 -5
  29. package/lib/server/tunnels/make-tcp-tunnel.js +10 -24
  30. package/lib/server/utils/apm.js +1 -1
  31. package/lib/server/utils/assert-valid-claim-request.d.ts +2 -2
  32. package/lib/server/utils/assert-valid-claim-request.js +17 -9
  33. package/lib/server/utils/dns.d.ts +1 -0
  34. package/lib/server/utils/dns.js +22 -0
  35. package/lib/server/utils/generics.d.ts +1 -1
  36. package/lib/tests/describe-with-server.d.ts +0 -2
  37. package/lib/tests/describe-with-server.js +1 -4
  38. package/lib/tests/mock-provider-server.d.ts +1 -1
  39. package/lib/tests/test.auth.d.ts +1 -0
  40. package/lib/tests/test.auth.js +75 -0
  41. package/lib/tests/test.bgp-listener.d.ts +1 -0
  42. package/lib/tests/test.bgp-listener.js +169 -0
  43. package/lib/tests/test.claim-creation.js +100 -7
  44. package/lib/tests/test.http-parser.d.ts +1 -1
  45. package/lib/tests/test.http-parser.js +7 -5
  46. package/lib/tests/test.http-provider-utils.js +155 -30
  47. package/lib/tests/test.http-provider.js +50 -7
  48. package/lib/tests/test.zk.js +54 -4
  49. package/lib/tests/utils.d.ts +6 -0
  50. package/lib/tests/utils.js +16 -1
  51. package/lib/types/bgp.d.ts +11 -0
  52. package/lib/types/bgp.js +3 -0
  53. package/lib/types/claims.d.ts +14 -5
  54. package/lib/types/client.d.ts +30 -3
  55. package/lib/types/general.d.ts +12 -0
  56. package/lib/types/handlers.d.ts +4 -4
  57. package/lib/types/index.d.ts +1 -0
  58. package/lib/types/index.js +2 -1
  59. package/lib/types/providers.d.ts +9 -9
  60. package/lib/types/providers.gen.d.ts +12 -152
  61. package/lib/types/providers.gen.js +2 -6
  62. package/lib/types/zk.d.ts +11 -2
  63. package/lib/utils/auth.d.ts +7 -0
  64. package/lib/utils/auth.js +64 -0
  65. package/lib/utils/b64-json.d.ts +2 -0
  66. package/lib/utils/b64-json.js +23 -0
  67. package/lib/utils/bgp-listener.d.ts +7 -0
  68. package/lib/utils/bgp-listener.js +126 -0
  69. package/lib/utils/claims.js +3 -3
  70. package/lib/utils/generics.d.ts +5 -5
  71. package/lib/utils/generics.js +3 -3
  72. package/lib/utils/index.d.ts +2 -0
  73. package/lib/utils/index.js +3 -1
  74. package/lib/utils/redactions.d.ts +19 -6
  75. package/lib/utils/redactions.js +41 -4
  76. package/lib/utils/socket-base.d.ts +3 -2
  77. package/lib/utils/socket-base.js +7 -2
  78. package/lib/utils/ws.d.ts +5 -5
  79. package/lib/utils/ws.js +27 -10
  80. package/lib/utils/zk.d.ts +12 -7
  81. package/lib/utils/zk.js +197 -42
  82. package/lib/window-rpc/setup-window-rpc.js +29 -8
  83. package/lib/window-rpc/types.d.ts +16 -21
  84. package/lib/window-rpc/utils.d.ts +2 -1
  85. package/lib/window-rpc/utils.js +27 -1
  86. package/lib/window-rpc/window-rpc-zk.d.ts +8 -3
  87. package/lib/window-rpc/window-rpc-zk.js +58 -45
  88. package/package.json +24 -22
@@ -1,16 +1,17 @@
1
1
  import { InitRequest, RPCMessage, RPCMessages } from '../proto/api';
2
2
  import { IAttestorSocket, Logger, RPCEvent, RPCEventMap } from '../types';
3
+ import type { WebSocket as WSWebSocket } from 'ws';
3
4
  /**
4
5
  * Common AttestorSocket class used on the client & server side as the
5
6
  * base for their respective socket implementations.
6
7
  */
7
8
  export declare class AttestorSocket implements IAttestorSocket {
8
- protected socket: WebSocket;
9
+ protected socket: WebSocket | WSWebSocket;
9
10
  metadata: InitRequest;
10
11
  logger: Logger;
11
12
  private eventTarget;
12
13
  isInitialised: boolean;
13
- constructor(socket: WebSocket, metadata: InitRequest, logger: Logger);
14
+ constructor(socket: WebSocket | WSWebSocket, metadata: InitRequest, logger: Logger);
14
15
  get isOpen(): boolean;
15
16
  get isClosed(): boolean;
16
17
  sendMessage(...msgs: Partial<RPCMessage>[]): Promise<RPCMessages>;
@@ -47,7 +47,12 @@ class AttestorSocket {
47
47
  }
48
48
  const msg = (0, utils_1.packRpcMessages)(...msgs);
49
49
  const bytes = api_1.RPCMessages.encode(msg).finish();
50
- await this.socket.send(bytes);
50
+ if ('sendPromise' in this.socket && this.socket.sendPromise) {
51
+ await this.socket.sendPromise(bytes);
52
+ }
53
+ else {
54
+ this.socket.send(bytes);
55
+ }
51
56
  return msg;
52
57
  }
53
58
  dispatchRPCEvent(type, data) {
@@ -86,4 +91,4 @@ class AttestorSocket {
86
91
  }
87
92
  }
88
93
  exports.AttestorSocket = AttestorSocket;
89
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ja2V0LWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvc29ja2V0LWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsc0VBQW1FO0FBQ25FLHVDQUFvRTtBQUVwRSxxQ0FBd0U7QUFFeEU7OztHQUdHO0FBQ0gsTUFBYSxjQUFjO0lBTTFCLFlBQ1csTUFBaUIsRUFDcEIsUUFBcUIsRUFDckIsTUFBYztRQUZYLFdBQU0sR0FBTixNQUFNLENBQVc7UUFDcEIsYUFBUSxHQUFSLFFBQVEsQ0FBYTtRQUNyQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBUGQsZ0JBQVcsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO1FBRXZDLGtCQUFhLEdBQUcsS0FBSyxDQUFBO1FBT3BCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDdEQsTUFBTSxNQUFNLEdBQUcscUJBQWEsQ0FBQyxTQUFTLENBQ3JDLEtBQUssQ0FBQyxLQUFLO21CQUNQLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FDNUIsQ0FBQTtZQUNELE1BQU0sQ0FBQyxJQUFJLEdBQUcscUJBQXFCLENBQUE7WUFFbkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLHVCQUF1QixFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ3ZELENBQUMsQ0FBQyxDQUFBO1FBRUYsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUN0QyxJQUFJLENBQUMsZ0JBQWdCLENBQ3BCLHVCQUF1QixFQUN2QixJQUFJLHFCQUFhLENBQ2hCLGdCQUFnQixFQUNoQixtQkFBbUIsQ0FDbkIsQ0FDRCxDQUNELENBQUMsQ0FBQTtRQUVGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRTtZQUNwRCxJQUFJLENBQUM7Z0JB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
94
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ja2V0LWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvc29ja2V0LWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsc0VBQW1FO0FBQ25FLHVDQUFvRTtBQUVwRSxxQ0FBd0U7QUFHeEU7OztHQUdHO0FBQ0gsTUFBYSxjQUFjO0lBTTFCLFlBQ1csTUFBK0IsRUFDbEMsUUFBcUIsRUFDckIsTUFBYztRQUZYLFdBQU0sR0FBTixNQUFNLENBQXlCO1FBQ2xDLGFBQVEsR0FBUixRQUFRLENBQWE7UUFDckIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQVBkLGdCQUFXLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQTtRQUV2QyxrQkFBYSxHQUFHLEtBQUssQ0FBQTtRQU9wQixNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDMUMsTUFBTSxNQUFNLEdBQUcscUJBQWEsQ0FBQyxTQUFTLENBQ3JDLEtBQUssQ0FBQyxLQUFLO21CQUNQLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FDNUIsQ0FBQTtZQUNELE1BQU0sQ0FBQyxJQUFJLEdBQUcscUJBQXFCLENBQUE7WUFFbkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLHVCQUF1QixFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ3ZELENBQUMsQ0FBQyxDQUFBO1FBRUYsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUN0QyxJQUFJLENBQUMsZ0JBQWdCLENBQ3BCLHVCQUF1QixFQUN2QixJQUFJLHFCQUFhLENBQ2hCLGdCQUFnQixFQUNoQixtQkFBbUIsQ0FDbkIsQ0FDRCxDQUNELENBQUMsQ0FBQTtRQUVGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRTtZQUNwRCxJQUFJLENBQUM7Z0JB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
package/lib/utils/ws.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { AnyWebSocketConstructor } from '../types';
1
+ import type { WebSocket as WSWebSocket } from 'ws';
2
2
  /**
3
3
  * Default WebSocket implementation, uses `ws` package
4
4
  * for Node.js and the native WebSocket for the browser & other
5
5
  * environments.
6
6
  */
7
- export declare let Websocket: AnyWebSocketConstructor;
7
+ export declare function makeWebSocket(url: string): WebSocket | WSWebSocket;
8
8
  /**
9
- * Replace the default WebSocket implementation utilised
10
- * by the Attestor client.
9
+ * Adds the "sendPromise" fn to the given WebSocket instance,
10
+ * if not already present.
11
11
  */
12
- export declare function setWebsocket(ws: AnyWebSocketConstructor): void;
12
+ export declare function promisifySend(ws: WSWebSocket): WSWebSocket;
package/lib/utils/ws.js CHANGED
@@ -1,21 +1,38 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Websocket = void 0;
4
- exports.setWebsocket = setWebsocket;
3
+ exports.makeWebSocket = makeWebSocket;
4
+ exports.promisifySend = promisifySend;
5
+ const config_1 = require("../config");
5
6
  const env_1 = require("../utils/env");
6
7
  /**
7
8
  * Default WebSocket implementation, uses `ws` package
8
9
  * for Node.js and the native WebSocket for the browser & other
9
10
  * environments.
10
11
  */
11
- exports.Websocket = ((0, env_1.detectEnvironment)() === 'node'
12
- ? require('ws').WebSocket
13
- : WebSocket);
12
+ function makeWebSocket(url) {
13
+ if ((0, env_1.detectEnvironment)() === 'node') {
14
+ const ws = require('ws');
15
+ return promisifySend(new ws.WebSocket(url, { maxPayload: config_1.MAX_PAYLOAD_SIZE }));
16
+ }
17
+ return new WebSocket(url);
18
+ }
14
19
  /**
15
- * Replace the default WebSocket implementation utilised
16
- * by the Attestor client.
20
+ * Adds the "sendPromise" fn to the given WebSocket instance,
21
+ * if not already present.
17
22
  */
18
- function setWebsocket(ws) {
19
- exports.Websocket = ws;
23
+ function promisifySend(ws) {
24
+ if (ws.sendPromise) {
25
+ return ws;
26
+ }
27
+ ws.sendPromise = (data) => (new Promise((resolve, reject) => {
28
+ ws.send(data, err => {
29
+ if (err) {
30
+ reject(err);
31
+ return;
32
+ }
33
+ resolve();
34
+ });
35
+ }));
36
+ return ws;
20
37
  }
21
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvd3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBa0JBLG9DQUVDO0FBbkJELHVDQUFpRDtBQUVqRDs7OztHQUlHO0FBQ1EsUUFBQSxTQUFTLEdBQTRCLENBQy9DLElBQUEsdUJBQWlCLEdBQUUsS0FBSyxNQUFNO0lBQzdCLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUztJQUN6QixDQUFDLENBQUMsU0FBUyxDQUNaLENBQUE7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixZQUFZLENBQUMsRUFBMkI7SUFDdkQsaUJBQVMsR0FBRyxFQUFFLENBQUE7QUFDZixDQUFDIn0=
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvd3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFTQSxzQ0FTQztBQU1ELHNDQW1CQztBQTNDRCx1Q0FBNkM7QUFDN0MsdUNBQWlEO0FBR2pEOzs7O0dBSUc7QUFDSCxTQUFnQixhQUFhLENBQUMsR0FBVztJQUN4QyxJQUFHLElBQUEsdUJBQWlCLEdBQUUsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUNuQyxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUF3QixDQUFBO1FBQy9DLE9BQU8sYUFBYSxDQUNuQixJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLEVBQUUsVUFBVSxFQUFFLHlCQUFnQixFQUFFLENBQUMsQ0FDdkQsQ0FBQTtJQUNGLENBQUM7SUFFRCxPQUFPLElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQzFCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixhQUFhLENBQUMsRUFBZTtJQUM1QyxJQUFHLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNuQixPQUFPLEVBQUUsQ0FBQTtJQUNWLENBQUM7SUFFRCxFQUFFLENBQUMsV0FBVyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUMxQixJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUMvQixFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRTtZQUNuQixJQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUNSLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtnQkFDWCxPQUFNO1lBQ1AsQ0FBQztZQUVELE9BQU8sRUFBRSxDQUFBO1FBQ1YsQ0FBQyxDQUFDLENBQUE7SUFDSCxDQUFDLENBQUMsQ0FDRixDQUFBO0lBRUQsT0FBTyxFQUFFLENBQUE7QUFDVixDQUFDIn0=
package/lib/utils/zk.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CipherSuite } from '@reclaimprotocol/tls';
2
- import { EncryptionAlgorithm, PrivateInput, PublicInput, ZKEngine, ZKOperator } from '@reclaimprotocol/zk-symmetric-crypto';
3
- import { MessageReveal_MessageRevealZk as ZKReveal, MessageReveal_ZKProof as ZKProof } from '../proto/api';
4
- import { CompleteTLSPacket, Logger, PrepareZKProofsBaseOpts, ZKOperators, ZKRevealInfo } from '../types';
2
+ import { EncryptionAlgorithm, OPRFOperator, PrivateInput, PublicInput, ZKEngine, ZKOperator } from '@reclaimprotocol/zk-symmetric-crypto';
3
+ import { MessageReveal_MessageRevealZk as ZKReveal, MessageReveal_ZKProof as ZKProof, ZKProofEngine } from '../proto/api';
4
+ import { CompleteTLSPacket, Logger, OPRFOperators, PrepareZKProofsBaseOpts, TOPRFProofParams, ZKOperators, ZKRevealInfo } from '../types';
5
5
  type PrepareZKProofsOpts = {
6
6
  logger?: Logger;
7
7
  cipherSuite: CipherSuite;
@@ -13,6 +13,7 @@ type ZKVerifyOpts = {
13
13
  logger?: Logger;
14
14
  /** get ZK operator for specified algorithm */
15
15
  zkOperators?: ZKOperators;
16
+ oprfOperators?: OPRFOperators;
16
17
  zkEngine?: ZKEngine;
17
18
  iv: Uint8Array;
18
19
  recordNumber: number;
@@ -22,6 +23,7 @@ type ZKProofToGenerate = {
22
23
  redactedPlaintext: Uint8Array;
23
24
  privateInput: PrivateInput;
24
25
  publicInput: PublicInput;
26
+ toprf?: TOPRFProofParams;
25
27
  };
26
28
  type ZKPacketToProve = {
27
29
  onGeneratedProofs(proofs: ZKProof[]): void;
@@ -29,22 +31,25 @@ type ZKPacketToProve = {
29
31
  proofsToGenerate: ZKProofToGenerate[];
30
32
  iv: Uint8Array;
31
33
  };
32
- export declare function makeZkProofGenerator({ zkOperators, logger, zkProofConcurrency, maxZkChunks, cipherSuite, zkEngine }: PrepareZKProofsOpts): Promise<{
34
+ export declare function makeZkProofGenerator({ zkOperators, oprfOperators, logger, zkProofConcurrency, maxZkChunks, cipherSuite, zkEngine }: PrepareZKProofsOpts): Promise<{
33
35
  /**
34
36
  * Adds the given packet to the list of packets to
35
37
  * generate ZK proofs for.
36
38
  *
37
39
  * Call `generateProofs()` to finally generate the proofs
38
40
  */
39
- addPacketToProve(packet: CompleteTLSPacket, reveal: ZKRevealInfo, onGeneratedProofs: ZKPacketToProve["onGeneratedProofs"]): Promise<void>;
41
+ addPacketToProve(packet: CompleteTLSPacket, { redactedPlaintext, toprfs }: ZKRevealInfo, onGeneratedProofs: ZKPacketToProve["onGeneratedProofs"]): Promise<void>;
40
42
  getTotalChunksToProve(): number;
41
43
  generateProofs(onChunkDone?: () => void): Promise<void>;
42
44
  }>;
43
45
  /**
44
46
  * Verify the given ZK proof
45
47
  */
46
- export declare function verifyZkPacket({ cipherSuite, ciphertext, zkReveal, zkOperators, logger, zkEngine, iv, recordNumber }: ZKVerifyOpts): Promise<{
47
- redactedPlaintext: Uint8Array;
48
+ export declare function verifyZkPacket({ cipherSuite, ciphertext, zkReveal, zkOperators, oprfOperators, logger, zkEngine, iv, recordNumber }: ZKVerifyOpts): Promise<{
49
+ redactedPlaintext: Uint8Array<ArrayBuffer>;
48
50
  }>;
49
51
  export declare function makeDefaultZkOperator(algorithm: EncryptionAlgorithm, zkEngine: ZKEngine, logger: Logger): ZKOperator;
52
+ export declare function makeDefaultOPRFOperator(algorithm: EncryptionAlgorithm, zkEngine: ZKEngine, logger: Logger): OPRFOperator;
53
+ export declare function getEngineString(engine: ZKProofEngine): "snarkjs" | "gnark";
54
+ export declare function getEngineProto(engine: ZKEngine): ZKProofEngine.ZK_ENGINE_SNARKJS | ZKProofEngine.ZK_ENGINE_GNARK;
50
55
  export {};
package/lib/utils/zk.js CHANGED
@@ -3,16 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeZkProofGenerator = makeZkProofGenerator;
4
4
  exports.verifyZkPacket = verifyZkPacket;
5
5
  exports.makeDefaultZkOperator = makeDefaultZkOperator;
6
+ exports.makeDefaultOPRFOperator = makeDefaultOPRFOperator;
7
+ exports.getEngineString = getEngineString;
8
+ exports.getEngineProto = getEngineProto;
6
9
  const tls_1 = require("@reclaimprotocol/tls");
7
10
  const zk_symmetric_crypto_1 = require("@reclaimprotocol/zk-symmetric-crypto");
8
11
  const config_1 = require("../config");
12
+ const api_1 = require("../proto/api");
9
13
  const env_1 = require("../utils/env");
14
+ const error_1 = require("../utils/error");
10
15
  const generics_1 = require("../utils/generics");
11
16
  const logger_1 = require("../utils/logger");
12
17
  const redactions_1 = require("../utils/redactions");
13
18
  const ZK_CONCURRENCY = +((0, env_1.getEnvVariable)('ZK_CONCURRENCY')
14
19
  || config_1.DEFAULT_ZK_CONCURRENCY);
15
- async function makeZkProofGenerator({ zkOperators, logger = logger_1.logger, zkProofConcurrency = ZK_CONCURRENCY, maxZkChunks = config_1.MAX_ZK_CHUNKS, cipherSuite, zkEngine = 'snarkjs' }) {
20
+ async function makeZkProofGenerator({ zkOperators, oprfOperators, logger = logger_1.logger, zkProofConcurrency = ZK_CONCURRENCY, maxZkChunks = config_1.MAX_ZK_CHUNKS, cipherSuite, zkEngine = 'snarkjs' }) {
16
21
  const { default: PQueue } = await import('p-queue');
17
22
  const zkQueue = new PQueue({
18
23
  concurrency: zkProofConcurrency,
@@ -28,13 +33,13 @@ async function makeZkProofGenerator({ zkOperators, logger = logger_1.logger, zkP
28
33
  *
29
34
  * Call `generateProofs()` to finally generate the proofs
30
35
  */
31
- async addPacketToProve(packet, reveal, onGeneratedProofs) {
36
+ async addPacketToProve(packet, { redactedPlaintext, toprfs }, onGeneratedProofs) {
32
37
  if (packet.type === 'plaintext') {
33
38
  throw new Error('Cannot generate proof for plaintext');
34
39
  }
35
40
  const alg = (0, generics_1.getZkAlgorithmForCipherSuite)(cipherSuite);
36
41
  const chunkSizeBytes = getChunkSizeBytes(alg);
37
- const { redactedPlaintext } = reveal;
42
+ //const { redactedPlaintext } = reveal
38
43
  const key = await tls_1.crypto.exportKey(packet.encKey);
39
44
  const iv = packet.iv;
40
45
  const ciphertext = (0, generics_1.getPureCiphertext)(packet.ciphertext, cipherSuite);
@@ -43,26 +48,57 @@ async function makeZkProofGenerator({ zkOperators, logger = logger_1.logger, zkP
43
48
  onGeneratedProofs,
44
49
  algorithm: alg,
45
50
  proofsToGenerate: [],
46
- iv: packet.fixedIv
51
+ iv: packet.fixedIv,
47
52
  };
53
+ const chunksDone = new Set();
54
+ // first we'll handle all TOPRF blocks
55
+ // we do these first, because they can span multiple chunks
56
+ // & we need to be able to span the right chunks
57
+ for (const toprf of toprfs || []) {
58
+ const startChunk = Math.floor(toprf.dataLocation.fromIndex / chunkSizeBytes);
59
+ if (chunksDone.has(startChunk)) {
60
+ throw new error_1.AttestorError('ERROR_BAD_REQUEST', `Chunk ${startChunk} contains more than one TOPRF,`
61
+ + ' which is not supported');
62
+ }
63
+ addProofToGenerate(startChunk, {
64
+ ...toprf,
65
+ dataLocation: {
66
+ ...toprf.dataLocation,
67
+ fromIndex: toprf.dataLocation.fromIndex % chunkSizeBytes
68
+ }
69
+ });
70
+ }
48
71
  for (let i = 0; i < chunks; i++) {
49
- const proof = getProofGenerationParamsForChunk(alg, {
72
+ // ignore any TOPRF chunks
73
+ if (chunksDone.has(i)) {
74
+ continue;
75
+ }
76
+ addProofToGenerate(i);
77
+ }
78
+ // generate proofs in order of start index
79
+ packetToProve.proofsToGenerate
80
+ .sort((a, b) => a.startIdx - b.startIdx);
81
+ packetsToProve.push(packetToProve);
82
+ function addProofToGenerate(offsetChunks, toprf) {
83
+ chunksDone.add(offsetChunks);
84
+ const proofParams = getProofGenerationParamsForChunk(alg, {
50
85
  key,
51
86
  iv,
52
87
  ciphertext,
53
88
  redactedPlaintext,
54
- offsetChunks: i,
89
+ offsetChunks,
90
+ toprf,
55
91
  });
56
- if (!proof) {
57
- continue;
92
+ if (!proofParams) {
93
+ return;
58
94
  }
59
- packetToProve.proofsToGenerate.push(proof);
95
+ packetToProve.proofsToGenerate.push(proofParams);
60
96
  zkChunksToProve += 1;
61
97
  if (zkChunksToProve > maxZkChunks) {
62
- throw new Error(`Too many chunks to prove: ${zkChunksToProve} > ${maxZkChunks}`);
98
+ throw new Error('Too many chunks to prove:'
99
+ + ` ${zkChunksToProve} > ${maxZkChunks}`);
63
100
  }
64
101
  }
65
- packetsToProve.push(packetToProve);
66
102
  },
67
103
  getTotalChunksToProve() {
68
104
  return zkChunksToProve;
@@ -103,39 +139,60 @@ async function makeZkProofGenerator({ zkOperators, logger = logger_1.logger, zkP
103
139
  (_a = zkOperator.release) === null || _a === void 0 ? void 0 : _a.call(zkOperator);
104
140
  },
105
141
  };
106
- async function generateProofForChunk(algorithm, { startIdx, redactedPlaintext, privateInput, publicInput }) {
107
- const operator = await getZkOperatorForAlgorithm(algorithm);
142
+ async function generateProofForChunk(algorithm, { startIdx, redactedPlaintext, privateInput, publicInput, toprf, }) {
143
+ const operator = toprf
144
+ ? getOprfOperatorForAlgorithm(algorithm)
145
+ : getZkOperatorForAlgorithm(algorithm);
108
146
  const proof = await (0, zk_symmetric_crypto_1.generateProof)({
109
147
  algorithm,
110
148
  privateInput,
111
149
  publicInput,
112
150
  operator,
113
- logger
151
+ logger,
152
+ ...(toprf
153
+ ? {
154
+ toprf: {
155
+ pos: toprf.dataLocation.fromIndex,
156
+ len: toprf.dataLocation.length,
157
+ output: toprf.nullifier,
158
+ responses: toprf.responses,
159
+ domainSeparator: config_1.TOPRF_DOMAIN_SEPARATOR
160
+ },
161
+ mask: toprf.mask,
162
+ }
163
+ : {})
114
164
  });
115
165
  logger === null || logger === void 0 ? void 0 : logger.debug({ startIdx }, 'generated proof for chunk');
116
166
  return {
117
- proofJson: proof.proofJson,
167
+ // backwards compatibility
168
+ proofJson: '',
169
+ proofData: typeof proof.proofData === 'string'
170
+ ? (0, tls_1.strToUint8Array)(proof.proofData)
171
+ : proof.proofData,
172
+ toprf,
118
173
  decryptedRedactedCiphertext: proof.plaintext,
119
174
  redactedPlaintext,
120
175
  startIdx
121
176
  };
122
177
  }
123
- async function getZkOperatorForAlgorithm(algorithm) {
178
+ function getZkOperatorForAlgorithm(algorithm) {
124
179
  return (zkOperators === null || zkOperators === void 0 ? void 0 : zkOperators[algorithm])
125
- || await makeDefaultZkOperator(algorithm, zkEngine, logger);
180
+ || makeDefaultZkOperator(algorithm, zkEngine, logger);
181
+ }
182
+ function getOprfOperatorForAlgorithm(algorithm) {
183
+ return (oprfOperators === null || oprfOperators === void 0 ? void 0 : oprfOperators[algorithm])
184
+ || makeDefaultOPRFOperator(algorithm, zkEngine, logger);
126
185
  }
127
186
  }
128
187
  /**
129
188
  * Verify the given ZK proof
130
189
  */
131
- async function verifyZkPacket({ cipherSuite, ciphertext, zkReveal, zkOperators, logger = logger_1.logger, zkEngine = 'snarkjs', iv, recordNumber }) {
190
+ async function verifyZkPacket({ cipherSuite, ciphertext, zkReveal, zkOperators, oprfOperators, logger = logger_1.logger, zkEngine = 'snarkjs', iv, recordNumber }) {
132
191
  if (!zkReveal) {
133
192
  throw new Error('No ZK reveal');
134
193
  }
135
194
  const { proofs } = zkReveal;
136
195
  const algorithm = (0, generics_1.getZkAlgorithmForCipherSuite)(cipherSuite);
137
- const operator = (zkOperators === null || zkOperators === void 0 ? void 0 : zkOperators[algorithm])
138
- || await makeDefaultZkOperator(algorithm, zkEngine, logger);
139
196
  const recordIV = (0, generics_1.getRecordIV)(ciphertext, cipherSuite);
140
197
  ciphertext = (0, generics_1.getPureCiphertext)(ciphertext, cipherSuite);
141
198
  /**
@@ -148,8 +205,18 @@ async function verifyZkPacket({ cipherSuite, ciphertext, zkReveal, zkOperators,
148
205
  const realRedactedPlaintext = new Uint8Array(ciphertext.length).fill(redactions_1.REDACTION_CHAR_CODE);
149
206
  const alg = (0, generics_1.getZkAlgorithmForCipherSuite)(cipherSuite);
150
207
  const chunkSizeBytes = getChunkSizeBytes(alg);
151
- const { blocksPerChunk } = zk_symmetric_crypto_1.CONFIG[algorithm];
152
- await Promise.all(proofs.map(async ({ proofJson, decryptedRedactedCiphertext, redactedPlaintext, startIdx }, i) => {
208
+ await Promise.all(proofs.map(async (proof, i) => {
209
+ try {
210
+ await verifyProofPacket(proof);
211
+ }
212
+ catch (e) {
213
+ e.message += ` (chunk ${i}, startIdx ${proof.startIdx})`;
214
+ throw e;
215
+ }
216
+ }));
217
+ return { redactedPlaintext: realRedactedPlaintext };
218
+ async function verifyProofPacket({ proofData, proofJson, decryptedRedactedCiphertext, redactedPlaintext, startIdx, toprf, }) {
219
+ var _a, _b, _c;
153
220
  // get the ciphertext chunk we received from the server
154
221
  // the ZK library, will verify that the decrypted redacted
155
222
  // ciphertext matches the ciphertext received from the server
@@ -163,10 +230,30 @@ async function verifyZkPacket({ cipherSuite, ciphertext, zkReveal, zkOperators,
163
230
  ciphertextChunk[i] = redactions_1.REDACTION_CHAR_CODE;
164
231
  }
165
232
  }
166
- if (!(0, redactions_1.isRedactionCongruent)(redactedPlaintext, decryptedRedactedCiphertext)) {
167
- throw new Error(`redacted ciphertext (${i}) not congruent`);
233
+ // redact OPRF indices -- because they'll incorrectly
234
+ // be marked as incongruent
235
+ let comparePlaintext = redactedPlaintext;
236
+ if (toprf) {
237
+ comparePlaintext = new Uint8Array(redactedPlaintext);
238
+ for (let i = 0; i < toprf.dataLocation.length; i++) {
239
+ comparePlaintext[i + toprf.dataLocation.fromIndex] = redactions_1.REDACTION_CHAR_CODE;
240
+ }
241
+ // the transcript will contain only the stringified
242
+ // nullifier. So here, we'll compare the provable
243
+ // binary nullifier with the stringified nullifier
244
+ // that the user has provided
245
+ const nulliferStr = (0, redactions_1.binaryHashToStr)(toprf.nullifier, toprf.dataLocation.length);
246
+ const txtHash = redactedPlaintext.slice((_a = toprf.dataLocation) === null || _a === void 0 ? void 0 : _a.fromIndex, ((_b = toprf.dataLocation) === null || _b === void 0 ? void 0 : _b.fromIndex)
247
+ + ((_c = toprf.dataLocation) === null || _c === void 0 ? void 0 : _c.length));
248
+ if ((0, generics_1.uint8ArrayToStr)(txtHash) !== nulliferStr
249
+ .slice(0, txtHash.length)) {
250
+ throw new Error('OPRF nullifier not congruent');
251
+ }
252
+ }
253
+ if (!(0, redactions_1.isRedactionCongruent)(comparePlaintext, decryptedRedactedCiphertext)) {
254
+ throw new Error('redacted ciphertext not congruent');
168
255
  }
169
- const chunkIndex = startIdx / chunkSizeBytes * blocksPerChunk;
256
+ const chunkIndex = startIdx / chunkSizeBytes;
170
257
  let nonce = (0, tls_1.concatenateUint8Arrays)([iv, recordIV]);
171
258
  if (!recordIV.length) {
172
259
  nonce = (0, tls_1.generateIV)(nonce, recordNumber);
@@ -174,26 +261,54 @@ async function verifyZkPacket({ cipherSuite, ciphertext, zkReveal, zkOperators,
174
261
  await (0, zk_symmetric_crypto_1.verifyProof)({
175
262
  proof: {
176
263
  algorithm,
177
- proofJson,
264
+ proofData: proofData.length
265
+ ? proofData
266
+ : (0, tls_1.strToUint8Array)(proofJson),
178
267
  plaintext: decryptedRedactedCiphertext,
179
268
  },
180
- publicInput: { ciphertext: ciphertextChunk, iv: nonce, offset: chunkIndex },
181
- operator,
269
+ publicInput: {
270
+ ciphertext: ciphertextChunk,
271
+ iv: nonce,
272
+ offset: chunkIndex
273
+ },
182
274
  logger,
275
+ ...(toprf
276
+ ? {
277
+ operator: getOprfOperator(),
278
+ toprf: {
279
+ pos: toprf.dataLocation.fromIndex,
280
+ len: toprf.dataLocation.length,
281
+ domainSeparator: config_1.TOPRF_DOMAIN_SEPARATOR,
282
+ output: toprf.nullifier,
283
+ responses: toprf.responses,
284
+ }
285
+ }
286
+ : { operator: getZkOperator() })
183
287
  });
184
288
  logger === null || logger === void 0 ? void 0 : logger.debug({ startIdx, endIdx: startIdx + redactedPlaintext.length }, 'verified proof');
185
289
  realRedactedPlaintext.set(redactedPlaintext, startIdx);
186
- }));
187
- return { redactedPlaintext: realRedactedPlaintext };
290
+ }
291
+ function getZkOperator() {
292
+ return (zkOperators === null || zkOperators === void 0 ? void 0 : zkOperators[algorithm])
293
+ || makeDefaultZkOperator(algorithm, zkEngine, logger);
294
+ }
295
+ function getOprfOperator() {
296
+ return (oprfOperators === null || oprfOperators === void 0 ? void 0 : oprfOperators[algorithm])
297
+ || makeDefaultOPRFOperator(algorithm, zkEngine, logger);
298
+ }
188
299
  }
189
300
  function getChunkSizeBytes(alg) {
190
301
  const { chunkSize, bitsPerWord } = zk_symmetric_crypto_1.CONFIG[alg];
191
302
  return chunkSize * bitsPerWord / 8;
192
303
  }
193
304
  const zkEngines = {};
305
+ const oprfEngines = {};
194
306
  const operatorMakers = {
195
307
  'snarkjs': zk_symmetric_crypto_1.makeSnarkJsZKOperator,
196
- 'gnark': zk_symmetric_crypto_1.makeGnarkZkOperator
308
+ 'gnark': zk_symmetric_crypto_1.makeGnarkZkOperator,
309
+ };
310
+ const OPRF_OPERATOR_MAKERS = {
311
+ 'gnark': zk_symmetric_crypto_1.makeGnarkOPRFOperator
197
312
  };
198
313
  function makeDefaultZkOperator(algorithm, zkEngine, logger) {
199
314
  let zkOperators = zkEngines[zkEngine];
@@ -204,23 +319,62 @@ function makeDefaultZkOperator(algorithm, zkEngine, logger) {
204
319
  if (!zkOperators[algorithm]) {
205
320
  const isNode = (0, env_1.detectEnvironment)() === 'node';
206
321
  const opType = isNode ? 'local' : 'remote';
207
- logger === null || logger === void 0 ? void 0 : logger.info({
208
- type: opType,
209
- algorithm
210
- }, 'fetching zk operator');
322
+ logger === null || logger === void 0 ? void 0 : logger.info({ type: opType, algorithm }, 'fetching zk operator');
211
323
  const fetcher = opType === 'local'
212
324
  ? (0, zk_symmetric_crypto_1.makeLocalFileFetch)()
213
325
  : (0, zk_symmetric_crypto_1.makeRemoteFileFetch)({
214
326
  baseUrl: config_1.DEFAULT_REMOTE_FILE_FETCH_BASE_URL,
215
327
  });
216
- zkOperators[algorithm] = operatorMakers[zkEngine]({
217
- algorithm,
218
- fetcher
219
- });
328
+ const maker = operatorMakers[zkEngine];
329
+ if (!maker) {
330
+ throw new Error(`No ZK operator maker for ${zkEngine}`);
331
+ }
332
+ zkOperators[algorithm] = maker({ algorithm, fetcher });
220
333
  }
221
334
  return zkOperators[algorithm];
222
335
  }
223
- function getProofGenerationParamsForChunk(algorithm, { key, iv, ciphertext, redactedPlaintext, offsetChunks, }) {
336
+ function makeDefaultOPRFOperator(algorithm, zkEngine, logger) {
337
+ let operators = oprfEngines[zkEngine];
338
+ if (!operators) {
339
+ oprfEngines[zkEngine] = {};
340
+ operators = oprfEngines[zkEngine];
341
+ }
342
+ if (!operators[algorithm]) {
343
+ const isNode = (0, env_1.detectEnvironment)() === 'node';
344
+ const type = isNode ? 'local' : 'remote';
345
+ logger === null || logger === void 0 ? void 0 : logger.info({ type, algorithm }, 'fetching oprf operator');
346
+ const fetcher = type === 'local'
347
+ ? (0, zk_symmetric_crypto_1.makeLocalFileFetch)()
348
+ : (0, zk_symmetric_crypto_1.makeRemoteFileFetch)({
349
+ baseUrl: config_1.DEFAULT_REMOTE_FILE_FETCH_BASE_URL,
350
+ });
351
+ const maker = OPRF_OPERATOR_MAKERS[zkEngine];
352
+ if (!maker) {
353
+ throw new Error(`No OPRF operator maker for ${zkEngine}`);
354
+ }
355
+ operators[algorithm] = maker({ algorithm, fetcher });
356
+ }
357
+ return operators[algorithm];
358
+ }
359
+ function getEngineString(engine) {
360
+ if (engine === api_1.ZKProofEngine.ZK_ENGINE_GNARK) {
361
+ return 'gnark';
362
+ }
363
+ if (engine === api_1.ZKProofEngine.ZK_ENGINE_SNARKJS) {
364
+ return 'snarkjs';
365
+ }
366
+ throw new Error(`Unknown ZK engine: ${engine}`);
367
+ }
368
+ function getEngineProto(engine) {
369
+ if (engine === 'gnark') {
370
+ return api_1.ZKProofEngine.ZK_ENGINE_GNARK;
371
+ }
372
+ if (engine === 'snarkjs') {
373
+ return api_1.ZKProofEngine.ZK_ENGINE_SNARKJS;
374
+ }
375
+ throw new Error(`Unknown ZK engine: ${engine}`);
376
+ }
377
+ function getProofGenerationParamsForChunk(algorithm, { key, iv, ciphertext, redactedPlaintext, offsetChunks, toprf, }) {
224
378
  const chunkSize = getChunkSizeBytes(algorithm);
225
379
  const startIdx = offsetChunks * chunkSize;
226
380
  const endIdx = (offsetChunks + 1) * chunkSize;
@@ -244,7 +398,8 @@ function getProofGenerationParamsForChunk(algorithm, { key, iv, ciphertext, reda
244
398
  startIdx,
245
399
  redactedPlaintext: plaintextChunk,
246
400
  privateInput: { key },
247
- publicInput: { ciphertext: ciphertextChunk, iv, offset: offsetChunks }
401
+ publicInput: { ciphertext: ciphertextChunk, iv, offset: offsetChunks },
402
+ toprf
248
403
  };
249
404
  }
250
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvemsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUF1RUEsb0RBMEtDO0FBS0Qsd0NBc0dDO0FBb0JELHNEQW1DQztBQW5aRCw4Q0FBOEY7QUFDOUYsOEVBYXlEO0FBQ3pELHVDQUFzRztBQUd0Ryx1Q0FBaUU7QUFDakUsaURBQWlHO0FBQ2pHLDZDQUFtRDtBQUNuRCxxREFBaUc7QUE2Q2pHLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FDdkIsSUFBQSxvQkFBYyxFQUFDLGdCQUFnQixDQUFDO09BQzdCLCtCQUFzQixDQUN6QixDQUFBO0FBRU0sS0FBSyxVQUFVLG9CQUFvQixDQUN6QyxFQUNDLFdBQVcsRUFDWCxNQUFNLEdBQUcsZUFBTSxFQUNmLGtCQUFrQixHQUFHLGNBQWMsRUFDbkMsV0FBVyxHQUFHLHNCQUFhLEVBQzNCLFdBQVcsRUFDWCxRQUFRLEdBQUcsU0FBUyxFQUNDO0lBR3RCLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxNQUFNLENBQUM7UUFDMUIsV0FBVyxFQUFFLGtCQUFrQjtRQUMvQixTQUFTLEVBQUUsSUFBSTtLQUNmLENBQUMsQ0FBQTtJQUVGLE1BQU0sY0FBYyxHQUFzQixFQUFFLENBQUE7SUFFNUMsTUFBTSxHQUFHLENBQUMsTUFBTSxJQUFJLGVBQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUE7SUFDdkUsSUFBSSxlQUFlLEdBQUcsQ0FBQyxDQUFBO0lBRXZCLE9BQU87UUFDTjs7Ozs7V0FLRztRQUNILEtBQUssQ0FBQyxnQkFBZ0IsQ0FDckIsTUFBeUIsRUFDekIsTUFBb0IsRUFDcEIsaUJBQXVEO1lBRXZELElBQUcsTUFBTSxDQUFD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
405
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvemsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUE2RUEsb0RBcVBDO0FBS0Qsd0NBMktDO0FBNEJELHNEQThCQztBQUVELDBEQThCQztBQUVELDBDQVVDO0FBR0Qsd0NBVUM7QUFybUJELDhDQUErRztBQUMvRyw4RUFleUQ7QUFDekQsdUNBQThIO0FBQzlILHVDQUEwSDtBQUUxSCx1Q0FBaUU7QUFDakUsMkNBQStDO0FBQy9DLGlEQUFrSDtBQUNsSCw2Q0FBbUQ7QUFDbkQscURBQWtIO0FBZ0RsSCxNQUFNLGNBQWMsR0FBRyxDQUFDLENBQ3ZCLElBQUEsb0JBQWMsRUFBQyxnQkFBZ0IsQ0FBQztPQUM3QiwrQkFBc0IsQ0FDekIsQ0FBQTtBQUVNLEtBQUssVUFBVSxvQkFBb0IsQ0FDekMsRUFDQyxXQUFXLEVBQ1gsYUFBYSxFQUNiLE1BQU0sR0FBRyxlQUFNLEVBQ2Ysa0JBQWtCLEdBQUcsY0FBYyxFQUNuQyxXQUFXLEdBQUcsc0JBQWEsRUFDM0IsV0FBVyxFQUNYLFFBQVEsR0FBRyxTQUFTLEVBQ0M7SUFHdEIsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUNuRCxNQUFNLE9BQU8sR0FBRyxJQUFJLE1BQU0sQ0FBQztRQUMxQixXQUFXLEVBQUUsa0JBQWtCO1FBQy9CLFNBQVMsRUFBRSxJQUFJO0tBQ2YsQ0FBQyxDQUFBO0lBRUYsTUFBTSxjQUFjLEdBQXNCLEVBQUUsQ0FBQTtJQUU1QyxNQUFNLEdBQUcsQ0FBQyxNQUFNLElBQUksZUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQTtJQUN2RSxJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUE7SUFFdkIsT0FBTztRQUNOOzs7OztXQUtHO1FBQ0gsS0FB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