@mysten/seal 0.10.0 → 1.0.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.
Files changed (157) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/bcs.d.mts +40 -0
  3. package/dist/bcs.d.mts.map +1 -0
  4. package/dist/bcs.mjs +89 -0
  5. package/dist/bcs.mjs.map +1 -0
  6. package/dist/bls12381.d.mts +30 -0
  7. package/dist/bls12381.d.mts.map +1 -0
  8. package/dist/bls12381.mjs +135 -0
  9. package/dist/bls12381.mjs.map +1 -0
  10. package/dist/client.d.mts +106 -0
  11. package/dist/client.d.mts.map +1 -0
  12. package/dist/client.mjs +274 -0
  13. package/dist/client.mjs.map +1 -0
  14. package/dist/decrypt.mjs +53 -0
  15. package/dist/decrypt.mjs.map +1 -0
  16. package/dist/dem.d.mts +1 -0
  17. package/dist/dem.mjs +134 -0
  18. package/dist/dem.mjs.map +1 -0
  19. package/dist/elgamal.mjs +35 -0
  20. package/dist/elgamal.mjs.map +1 -0
  21. package/dist/encrypt.d.mts +15 -0
  22. package/dist/encrypt.d.mts.map +1 -0
  23. package/dist/encrypt.mjs +61 -0
  24. package/dist/encrypt.mjs.map +1 -0
  25. package/dist/error.d.mts +75 -0
  26. package/dist/error.d.mts.map +1 -0
  27. package/dist/error.mjs +150 -0
  28. package/dist/error.mjs.map +1 -0
  29. package/dist/ibe.mjs +176 -0
  30. package/dist/ibe.mjs.map +1 -0
  31. package/dist/index.d.mts +7 -0
  32. package/dist/index.mjs +7 -0
  33. package/dist/kdf.mjs +81 -0
  34. package/dist/kdf.mjs.map +1 -0
  35. package/dist/key-server.d.mts +22 -0
  36. package/dist/key-server.d.mts.map +1 -0
  37. package/dist/key-server.mjs +195 -0
  38. package/dist/key-server.mjs.map +1 -0
  39. package/dist/session-key.d.mts +83 -0
  40. package/dist/session-key.d.mts.map +1 -0
  41. package/dist/session-key.mjs +171 -0
  42. package/dist/session-key.mjs.map +1 -0
  43. package/dist/shamir.mjs +730 -0
  44. package/dist/shamir.mjs.map +1 -0
  45. package/dist/types.d.mts +79 -0
  46. package/dist/types.d.mts.map +1 -0
  47. package/dist/utils.mjs +89 -0
  48. package/dist/utils.mjs.map +1 -0
  49. package/dist/version.mjs +6 -0
  50. package/dist/version.mjs.map +1 -0
  51. package/package.json +22 -20
  52. package/dist/cjs/bcs.d.ts +0 -147
  53. package/dist/cjs/bcs.js +0 -104
  54. package/dist/cjs/bcs.js.map +0 -7
  55. package/dist/cjs/bls12381.d.ts +0 -44
  56. package/dist/cjs/bls12381.js +0 -151
  57. package/dist/cjs/bls12381.js.map +0 -7
  58. package/dist/cjs/client.d.ts +0 -84
  59. package/dist/cjs/client.js +0 -419
  60. package/dist/cjs/client.js.map +0 -7
  61. package/dist/cjs/decrypt.d.ts +0 -22
  62. package/dist/cjs/decrypt.js +0 -109
  63. package/dist/cjs/decrypt.js.map +0 -7
  64. package/dist/cjs/dem.d.ts +0 -38
  65. package/dist/cjs/dem.js +0 -185
  66. package/dist/cjs/dem.js.map +0 -7
  67. package/dist/cjs/elgamal.d.ts +0 -13
  68. package/dist/cjs/elgamal.js +0 -46
  69. package/dist/cjs/elgamal.js.map +0 -7
  70. package/dist/cjs/encrypt.d.ts +0 -32
  71. package/dist/cjs/encrypt.js +0 -104
  72. package/dist/cjs/encrypt.js.map +0 -7
  73. package/dist/cjs/error.d.ts +0 -86
  74. package/dist/cjs/error.js +0 -239
  75. package/dist/cjs/error.js.map +0 -7
  76. package/dist/cjs/ibe.d.ts +0 -98
  77. package/dist/cjs/ibe.js +0 -167
  78. package/dist/cjs/ibe.js.map +0 -7
  79. package/dist/cjs/index.d.ts +0 -6
  80. package/dist/cjs/index.js +0 -33
  81. package/dist/cjs/index.js.map +0 -7
  82. package/dist/cjs/kdf.d.ts +0 -30
  83. package/dist/cjs/kdf.js +0 -97
  84. package/dist/cjs/kdf.js.map +0 -7
  85. package/dist/cjs/key-server.d.ts +0 -105
  86. package/dist/cjs/key-server.js +0 -230
  87. package/dist/cjs/key-server.js.map +0 -7
  88. package/dist/cjs/package.json +0 -5
  89. package/dist/cjs/session-key.d.ts +0 -74
  90. package/dist/cjs/session-key.js +0 -245
  91. package/dist/cjs/session-key.js.map +0 -7
  92. package/dist/cjs/shamir.d.ts +0 -91
  93. package/dist/cjs/shamir.js +0 -770
  94. package/dist/cjs/shamir.js.map +0 -7
  95. package/dist/cjs/types.d.ts +0 -86
  96. package/dist/cjs/types.js +0 -17
  97. package/dist/cjs/types.js.map +0 -7
  98. package/dist/cjs/utils.d.ts +0 -47
  99. package/dist/cjs/utils.js +0 -106
  100. package/dist/cjs/utils.js.map +0 -7
  101. package/dist/cjs/version.d.ts +0 -1
  102. package/dist/cjs/version.js +0 -25
  103. package/dist/cjs/version.js.map +0 -7
  104. package/dist/esm/bcs.d.ts +0 -147
  105. package/dist/esm/bcs.js +0 -84
  106. package/dist/esm/bcs.js.map +0 -7
  107. package/dist/esm/bls12381.d.ts +0 -44
  108. package/dist/esm/bls12381.js +0 -131
  109. package/dist/esm/bls12381.js.map +0 -7
  110. package/dist/esm/client.d.ts +0 -84
  111. package/dist/esm/client.js +0 -412
  112. package/dist/esm/client.js.map +0 -7
  113. package/dist/esm/decrypt.d.ts +0 -22
  114. package/dist/esm/decrypt.js +0 -94
  115. package/dist/esm/decrypt.js.map +0 -7
  116. package/dist/esm/dem.d.ts +0 -38
  117. package/dist/esm/dem.js +0 -165
  118. package/dist/esm/dem.js.map +0 -7
  119. package/dist/esm/elgamal.d.ts +0 -13
  120. package/dist/esm/elgamal.js +0 -26
  121. package/dist/esm/elgamal.js.map +0 -7
  122. package/dist/esm/encrypt.d.ts +0 -32
  123. package/dist/esm/encrypt.js +0 -84
  124. package/dist/esm/encrypt.js.map +0 -7
  125. package/dist/esm/error.d.ts +0 -86
  126. package/dist/esm/error.js +0 -219
  127. package/dist/esm/error.js.map +0 -7
  128. package/dist/esm/ibe.d.ts +0 -98
  129. package/dist/esm/ibe.js +0 -147
  130. package/dist/esm/ibe.js.map +0 -7
  131. package/dist/esm/index.d.ts +0 -6
  132. package/dist/esm/index.js +0 -12
  133. package/dist/esm/index.js.map +0 -7
  134. package/dist/esm/kdf.d.ts +0 -30
  135. package/dist/esm/kdf.js +0 -83
  136. package/dist/esm/kdf.js.map +0 -7
  137. package/dist/esm/key-server.d.ts +0 -105
  138. package/dist/esm/key-server.js +0 -215
  139. package/dist/esm/key-server.js.map +0 -7
  140. package/dist/esm/package.json +0 -5
  141. package/dist/esm/session-key.d.ts +0 -74
  142. package/dist/esm/session-key.js +0 -230
  143. package/dist/esm/session-key.js.map +0 -7
  144. package/dist/esm/shamir.d.ts +0 -91
  145. package/dist/esm/shamir.js +0 -750
  146. package/dist/esm/shamir.js.map +0 -7
  147. package/dist/esm/types.d.ts +0 -86
  148. package/dist/esm/types.js +0 -1
  149. package/dist/esm/types.js.map +0 -7
  150. package/dist/esm/utils.d.ts +0 -47
  151. package/dist/esm/utils.js +0 -86
  152. package/dist/esm/utils.js.map +0 -7
  153. package/dist/esm/version.d.ts +0 -1
  154. package/dist/esm/version.js +0 -5
  155. package/dist/esm/version.js.map +0 -7
  156. package/dist/tsconfig.esm.tsbuildinfo +0 -1
  157. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,412 +0,0 @@
1
- var __typeError = (msg) => {
2
- throw TypeError(msg);
3
- };
4
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
- var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
9
- var _suiClient, _configs, _keyServers, _verifyKeyServers, _cachedKeys, _cachedPublicKeys, _timeout, _totalWeight, _SealClient_instances, createEncryptionInput_fn, weight_fn, validateEncryptionServices_fn, getWeightedKeyServers_fn, loadKeyServers_fn;
10
- import { EncryptedObject } from "./bcs.js";
11
- import { G1Element, G2Element } from "./bls12381.js";
12
- import { decrypt } from "./decrypt.js";
13
- import { AesGcm256, Hmac256Ctr } from "./dem.js";
14
- import { DemType, encrypt, KemType } from "./encrypt.js";
15
- import {
16
- InconsistentKeyServersError,
17
- InvalidClientOptionsError,
18
- InvalidKeyServerError,
19
- InvalidPackageError,
20
- InvalidThresholdError,
21
- toMajorityError,
22
- TooManyFailedFetchKeyRequestsError
23
- } from "./error.js";
24
- import { BonehFranklinBLS12381Services } from "./ibe.js";
25
- import {
26
- BonehFranklinBLS12381DerivedKey,
27
- retrieveKeyServers,
28
- verifyKeyServer,
29
- fetchKeysForAllIds
30
- } from "./key-server.js";
31
- import { createFullId, count } from "./utils.js";
32
- function seal({ name = "seal", ...options }) {
33
- return {
34
- name,
35
- register: (client) => {
36
- return new SealClient({
37
- suiClient: client,
38
- ...options
39
- });
40
- }
41
- };
42
- }
43
- const _SealClient = class _SealClient {
44
- constructor(options) {
45
- __privateAdd(this, _SealClient_instances);
46
- __privateAdd(this, _suiClient);
47
- __privateAdd(this, _configs);
48
- __privateAdd(this, _keyServers, null);
49
- __privateAdd(this, _verifyKeyServers);
50
- // A caching map for: fullId:object_id -> partial key.
51
- __privateAdd(this, _cachedKeys, /* @__PURE__ */ new Map());
52
- __privateAdd(this, _cachedPublicKeys, /* @__PURE__ */ new Map());
53
- __privateAdd(this, _timeout);
54
- __privateAdd(this, _totalWeight);
55
- __privateSet(this, _suiClient, options.suiClient);
56
- if (new Set(options.serverConfigs.map((s) => s.objectId)).size !== options.serverConfigs.length) {
57
- throw new InvalidClientOptionsError("Duplicate object IDs");
58
- }
59
- if (options.serverConfigs.some((s) => s.apiKeyName && !s.apiKey || !s.apiKeyName && s.apiKey)) {
60
- throw new InvalidClientOptionsError(
61
- "Both apiKeyName and apiKey must be provided or not provided for all key servers"
62
- );
63
- }
64
- __privateSet(this, _configs, new Map(options.serverConfigs.map((server) => [server.objectId, server])));
65
- __privateSet(this, _totalWeight, options.serverConfigs.map((server) => server.weight).reduce((sum, term) => sum + term, 0));
66
- __privateSet(this, _verifyKeyServers, options.verifyKeyServers ?? true);
67
- __privateSet(this, _timeout, options.timeout ?? 1e4);
68
- }
69
- /** @deprecated Use `seal()` instead */
70
- static asClientExtension(options) {
71
- return {
72
- name: "seal",
73
- register: (client) => {
74
- return new _SealClient({
75
- suiClient: client,
76
- ...options
77
- });
78
- }
79
- };
80
- }
81
- /**
82
- * Return an encrypted message under the identity.
83
- *
84
- * @param kemType - The type of KEM to use.
85
- * @param demType - The type of DEM to use.
86
- * @param threshold - The threshold for the TSS encryption.
87
- * @param packageId - the packageId namespace.
88
- * @param id - the identity to use.
89
- * @param data - the data to encrypt.
90
- * @param aad - optional additional authenticated data.
91
- * @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.
92
- * Since the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.
93
- */
94
- async encrypt({
95
- kemType = KemType.BonehFranklinBLS12381DemCCA,
96
- demType = DemType.AesGcm256,
97
- threshold,
98
- packageId,
99
- id,
100
- data,
101
- aad = new Uint8Array()
102
- }) {
103
- const packageObj = await __privateGet(this, _suiClient).core.getObject({ objectId: packageId });
104
- if (String(packageObj.object.version) !== "1") {
105
- throw new InvalidPackageError(`Package ${packageId} is not the first version`);
106
- }
107
- return encrypt({
108
- keyServers: await __privateMethod(this, _SealClient_instances, getWeightedKeyServers_fn).call(this),
109
- kemType,
110
- threshold,
111
- packageId,
112
- id,
113
- encryptionInput: __privateMethod(this, _SealClient_instances, createEncryptionInput_fn).call(this, demType, data, aad)
114
- });
115
- }
116
- /**
117
- * Decrypt the given encrypted bytes using cached keys.
118
- * Calls fetchKeys in case one or more of the required keys is not cached yet.
119
- * The function throws an error if the client's key servers are not a subset of
120
- * the encrypted object's key servers or if the threshold cannot be met.
121
- *
122
- * If checkShareConsistency is true, the decrypted shares are checked for consistency, meaning that
123
- * any combination of at least threshold shares should either succesfully combine to the plaintext or fail.
124
- * This is useful in case the encryptor is not trusted and the decryptor wants to ensure all decryptors
125
- * receive the same output (e.g., for onchain encrypted voting).
126
- *
127
- * @param data - The encrypted bytes to decrypt.
128
- * @param sessionKey - The session key to use.
129
- * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).
130
- * @param checkShareConsistency - If true, the shares are checked for consistency.
131
- * @param checkLEEncoding - If true, the encryption is also checked using an LE encoded nonce.
132
- * @returns - The decrypted plaintext corresponding to ciphertext.
133
- */
134
- async decrypt({
135
- data,
136
- sessionKey,
137
- txBytes,
138
- checkShareConsistency,
139
- checkLEEncoding
140
- }) {
141
- const encryptedObject = EncryptedObject.parse(data);
142
- __privateMethod(this, _SealClient_instances, validateEncryptionServices_fn).call(this, encryptedObject.services.map((s) => s[0]), encryptedObject.threshold);
143
- await this.fetchKeys({
144
- ids: [encryptedObject.id],
145
- txBytes,
146
- sessionKey,
147
- threshold: encryptedObject.threshold
148
- });
149
- if (checkShareConsistency) {
150
- const publicKeys = await this.getPublicKeys(
151
- encryptedObject.services.map(([objectId, _]) => objectId)
152
- );
153
- return decrypt({
154
- encryptedObject,
155
- keys: __privateGet(this, _cachedKeys),
156
- publicKeys,
157
- checkLEEncoding: false
158
- // We intentionally do not support other encodings here
159
- });
160
- }
161
- return decrypt({ encryptedObject, keys: __privateGet(this, _cachedKeys), checkLEEncoding });
162
- }
163
- async getKeyServers() {
164
- if (!__privateGet(this, _keyServers)) {
165
- __privateSet(this, _keyServers, __privateMethod(this, _SealClient_instances, loadKeyServers_fn).call(this).catch((error) => {
166
- __privateSet(this, _keyServers, null);
167
- throw error;
168
- }));
169
- }
170
- return __privateGet(this, _keyServers);
171
- }
172
- /**
173
- * Get the public keys for the given services.
174
- * If all public keys are not in the cache, they are retrieved.
175
- *
176
- * @param services - The services to get the public keys for.
177
- * @returns The public keys for the given services in the same order as the given services.
178
- */
179
- async getPublicKeys(services) {
180
- const keyServers = await this.getKeyServers();
181
- const missingKeyServers = services.filter(
182
- (objectId) => !keyServers.has(objectId) && !__privateGet(this, _cachedPublicKeys).has(objectId)
183
- );
184
- if (missingKeyServers.length > 0) {
185
- (await retrieveKeyServers({
186
- objectIds: missingKeyServers,
187
- client: __privateGet(this, _suiClient),
188
- configs: __privateGet(this, _configs)
189
- })).forEach(
190
- (keyServer) => __privateGet(this, _cachedPublicKeys).set(keyServer.objectId, G2Element.fromBytes(keyServer.pk))
191
- );
192
- }
193
- return services.map((objectId) => {
194
- const keyServer = keyServers.get(objectId);
195
- if (keyServer) {
196
- return G2Element.fromBytes(keyServer.pk);
197
- }
198
- return __privateGet(this, _cachedPublicKeys).get(objectId);
199
- });
200
- }
201
- /**
202
- * Fetch keys from the key servers and update the cache.
203
- *
204
- * It is recommended to call this function once for all ids of all encrypted objects if
205
- * there are multiple, then call decrypt for each object. This avoids calling fetchKey
206
- * individually for each decrypt.
207
- *
208
- * @param ids - The ids of the encrypted objects.
209
- * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).
210
- * @param sessionKey - The session key to use.
211
- * @param threshold - The threshold for the TSS encryptions. The function returns when a threshold of key servers had returned keys for all ids.
212
- */
213
- async fetchKeys({ ids, txBytes, sessionKey, threshold }) {
214
- if (threshold > __privateGet(this, _totalWeight) || threshold < 1) {
215
- throw new InvalidThresholdError(
216
- `Invalid threshold ${threshold} servers with weights ${JSON.stringify(__privateGet(this, _configs))}`
217
- );
218
- }
219
- const keyServers = await this.getKeyServers();
220
- const fullIds = ids.map((id) => createFullId(sessionKey.getPackageId(), id));
221
- let completedWeight = 0;
222
- const remainingKeyServers = [];
223
- let remainingKeyServersWeight = 0;
224
- for (const objectId of keyServers.keys()) {
225
- if (fullIds.every((fullId) => __privateGet(this, _cachedKeys).has(`${fullId}:${objectId}`))) {
226
- completedWeight += __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
227
- } else {
228
- remainingKeyServers.push(objectId);
229
- remainingKeyServersWeight += __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
230
- }
231
- }
232
- if (completedWeight >= threshold) {
233
- return;
234
- }
235
- const certificate = await sessionKey.getCertificate();
236
- const signedRequest = await sessionKey.createRequestParams(txBytes);
237
- const controller = new AbortController();
238
- const errors = [];
239
- const keyFetches = remainingKeyServers.map(async (objectId) => {
240
- const server = keyServers.get(objectId);
241
- try {
242
- const config = __privateGet(this, _configs).get(objectId);
243
- const allKeys = await fetchKeysForAllIds({
244
- url: server.url,
245
- requestSignature: signedRequest.requestSignature,
246
- transactionBytes: txBytes,
247
- encKey: signedRequest.encKey,
248
- encKeyPk: signedRequest.encKeyPk,
249
- encVerificationKey: signedRequest.encVerificationKey,
250
- certificate,
251
- timeout: __privateGet(this, _timeout),
252
- apiKeyName: config?.apiKeyName,
253
- apiKey: config?.apiKey,
254
- signal: controller.signal
255
- });
256
- for (const { fullId, key } of allKeys) {
257
- const keyElement = G1Element.fromBytes(key);
258
- if (!BonehFranklinBLS12381Services.verifyUserSecretKey(
259
- keyElement,
260
- fullId,
261
- G2Element.fromBytes(server.pk)
262
- )) {
263
- console.warn("Received invalid key from key server " + server.objectId);
264
- continue;
265
- }
266
- __privateGet(this, _cachedKeys).set(`${fullId}:${server.objectId}`, keyElement);
267
- }
268
- if (fullIds.every((fullId) => __privateGet(this, _cachedKeys).has(`${fullId}:${server.objectId}`))) {
269
- completedWeight += __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
270
- if (completedWeight >= threshold) {
271
- controller.abort();
272
- }
273
- }
274
- } catch (error) {
275
- if (!controller.signal.aborted) {
276
- errors.push(error);
277
- }
278
- } finally {
279
- remainingKeyServersWeight -= __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
280
- if (remainingKeyServersWeight < threshold - completedWeight) {
281
- controller.abort(new TooManyFailedFetchKeyRequestsError());
282
- }
283
- }
284
- });
285
- await Promise.allSettled(keyFetches);
286
- if (completedWeight < threshold) {
287
- throw toMajorityError(errors);
288
- }
289
- }
290
- /**
291
- * Get derived keys from the given services.
292
- *
293
- * @param id - The id of the encrypted object.
294
- * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).
295
- * @param sessionKey - The session key to use.
296
- * @param threshold - The threshold.
297
- * @returns - Derived keys for the given services that are in the cache as a "service object ID" -> derived key map. If the call is succesful, exactly threshold keys will be returned.
298
- */
299
- async getDerivedKeys({
300
- kemType = KemType.BonehFranklinBLS12381DemCCA,
301
- id,
302
- txBytes,
303
- sessionKey,
304
- threshold
305
- }) {
306
- switch (kemType) {
307
- case KemType.BonehFranklinBLS12381DemCCA:
308
- const keyServers = await this.getKeyServers();
309
- if (threshold > __privateGet(this, _totalWeight)) {
310
- throw new InvalidThresholdError(
311
- `Invalid threshold ${threshold} for ${__privateGet(this, _totalWeight)} servers`
312
- );
313
- }
314
- await this.fetchKeys({
315
- ids: [id],
316
- txBytes,
317
- sessionKey,
318
- threshold
319
- });
320
- const fullId = createFullId(sessionKey.getPackageId(), id);
321
- const derivedKeys = /* @__PURE__ */ new Map();
322
- let weight = 0;
323
- for (const objectId of keyServers.keys()) {
324
- const cachedKey = __privateGet(this, _cachedKeys).get(`${fullId}:${objectId}`);
325
- if (cachedKey) {
326
- derivedKeys.set(objectId, new BonehFranklinBLS12381DerivedKey(cachedKey));
327
- weight += __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
328
- if (weight >= threshold) {
329
- break;
330
- }
331
- }
332
- }
333
- return derivedKeys;
334
- }
335
- }
336
- };
337
- _suiClient = new WeakMap();
338
- _configs = new WeakMap();
339
- _keyServers = new WeakMap();
340
- _verifyKeyServers = new WeakMap();
341
- _cachedKeys = new WeakMap();
342
- _cachedPublicKeys = new WeakMap();
343
- _timeout = new WeakMap();
344
- _totalWeight = new WeakMap();
345
- _SealClient_instances = new WeakSet();
346
- createEncryptionInput_fn = function(type, data, aad) {
347
- switch (type) {
348
- case DemType.AesGcm256:
349
- return new AesGcm256(data, aad);
350
- case DemType.Hmac256Ctr:
351
- return new Hmac256Ctr(data, aad);
352
- }
353
- };
354
- weight_fn = function(objectId) {
355
- return __privateGet(this, _configs).get(objectId)?.weight ?? 0;
356
- };
357
- validateEncryptionServices_fn = function(services, threshold) {
358
- if (services.some((objectId) => {
359
- const countInClient = __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
360
- return countInClient > 0 && countInClient !== count(services, objectId);
361
- })) {
362
- throw new InconsistentKeyServersError(
363
- `Client's key servers must be a subset of the encrypted object's key servers`
364
- );
365
- }
366
- if (threshold > __privateGet(this, _totalWeight)) {
367
- throw new InvalidThresholdError(
368
- `Invalid threshold ${threshold} for ${__privateGet(this, _totalWeight)} servers`
369
- );
370
- }
371
- };
372
- getWeightedKeyServers_fn = async function() {
373
- const keyServers = await this.getKeyServers();
374
- const keyServersWithMultiplicity = [];
375
- for (const [objectId, config] of __privateGet(this, _configs)) {
376
- const keyServer = keyServers.get(objectId);
377
- for (let i = 0; i < config.weight; i++) {
378
- keyServersWithMultiplicity.push(keyServer);
379
- }
380
- }
381
- return keyServersWithMultiplicity;
382
- };
383
- loadKeyServers_fn = async function() {
384
- const keyServers = await retrieveKeyServers({
385
- objectIds: [...__privateGet(this, _configs).keys()],
386
- client: __privateGet(this, _suiClient),
387
- configs: __privateGet(this, _configs)
388
- });
389
- if (keyServers.length === 0) {
390
- throw new InvalidKeyServerError("No key servers found");
391
- }
392
- if (__privateGet(this, _verifyKeyServers)) {
393
- await Promise.all(
394
- keyServers.map(async (server) => {
395
- if (server.serverType === "Committee") {
396
- return;
397
- }
398
- const config = __privateGet(this, _configs).get(server.objectId);
399
- if (!await verifyKeyServer(server, __privateGet(this, _timeout), config?.apiKeyName, config?.apiKey)) {
400
- throw new InvalidKeyServerError(`Key server ${server.objectId} is not valid`);
401
- }
402
- })
403
- );
404
- }
405
- return new Map(keyServers.map((server) => [server.objectId, server]));
406
- };
407
- let SealClient = _SealClient;
408
- export {
409
- SealClient,
410
- seal
411
- };
412
- //# sourceMappingURL=client.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/client.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { EncryptedObject } from './bcs.js';\nimport { G1Element, G2Element } from './bls12381.js';\nimport { decrypt } from './decrypt.js';\nimport type { EncryptionInput } from './dem.js';\nimport { AesGcm256, Hmac256Ctr } from './dem.js';\nimport { DemType, encrypt, KemType } from './encrypt.js';\nimport {\n\tInconsistentKeyServersError,\n\tInvalidClientOptionsError,\n\tInvalidKeyServerError,\n\tInvalidPackageError,\n\tInvalidThresholdError,\n\ttoMajorityError,\n\tTooManyFailedFetchKeyRequestsError,\n} from './error.js';\nimport { BonehFranklinBLS12381Services } from './ibe.js';\nimport {\n\tBonehFranklinBLS12381DerivedKey,\n\tretrieveKeyServers,\n\tverifyKeyServer,\n\tfetchKeysForAllIds,\n} from './key-server.js';\nimport type { DerivedKey, KeyServer } from './key-server.js';\nimport type {\n\tDecryptOptions,\n\tEncryptOptions,\n\tFetchKeysOptions,\n\tGetDerivedKeysOptions,\n\tKeyCacheKey,\n\tKeyServerConfig,\n\tSealClientExtensionOptions,\n\tSealClientOptions,\n\tSealCompatibleClient,\n\tSealOptions,\n} from './types.js';\nimport { createFullId, count } from './utils.js';\n\nexport function seal<Name = 'seal'>({ name = 'seal' as Name, ...options }: SealOptions<Name>) {\n\treturn {\n\t\tname,\n\t\tregister: (client: SealCompatibleClient) => {\n\t\t\treturn new SealClient({\n\t\t\t\tsuiClient: client,\n\t\t\t\t...options,\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport class SealClient {\n\t#suiClient: SealCompatibleClient;\n\t#configs: Map<string, KeyServerConfig>;\n\t#keyServers: Promise<Map<string, KeyServer>> | null = null;\n\t#verifyKeyServers: boolean;\n\t// A caching map for: fullId:object_id -> partial key.\n\t#cachedKeys = new Map<KeyCacheKey, G1Element>();\n\t#cachedPublicKeys = new Map<string, G2Element>();\n\t#timeout: number;\n\t#totalWeight: number;\n\n\tconstructor(options: SealClientOptions) {\n\t\tthis.#suiClient = options.suiClient;\n\n\t\tif (\n\t\t\tnew Set(options.serverConfigs.map((s) => s.objectId)).size !== options.serverConfigs.length\n\t\t) {\n\t\t\tthrow new InvalidClientOptionsError('Duplicate object IDs');\n\t\t}\n\n\t\tif (\n\t\t\toptions.serverConfigs.some((s) => (s.apiKeyName && !s.apiKey) || (!s.apiKeyName && s.apiKey))\n\t\t) {\n\t\t\tthrow new InvalidClientOptionsError(\n\t\t\t\t'Both apiKeyName and apiKey must be provided or not provided for all key servers',\n\t\t\t);\n\t\t}\n\n\t\tthis.#configs = new Map(options.serverConfigs.map((server) => [server.objectId, server]));\n\t\tthis.#totalWeight = options.serverConfigs\n\t\t\t.map((server) => server.weight)\n\t\t\t.reduce((sum, term) => sum + term, 0);\n\n\t\tthis.#verifyKeyServers = options.verifyKeyServers ?? true;\n\t\tthis.#timeout = options.timeout ?? 10_000;\n\t}\n\n\t/** @deprecated Use `seal()` instead */\n\tstatic asClientExtension(options: SealClientExtensionOptions) {\n\t\treturn {\n\t\t\tname: 'seal' as const,\n\t\t\tregister: (client: SealCompatibleClient) => {\n\t\t\t\treturn new SealClient({\n\t\t\t\t\tsuiClient: client,\n\t\t\t\t\t...options,\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Return an encrypted message under the identity.\n\t *\n\t * @param kemType - The type of KEM to use.\n\t * @param demType - The type of DEM to use.\n\t * @param threshold - The threshold for the TSS encryption.\n\t * @param packageId - the packageId namespace.\n\t * @param id - the identity to use.\n\t * @param data - the data to encrypt.\n\t * @param aad - optional additional authenticated data.\n\t * @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.\n\t * \tSince the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.\n\t */\n\tasync encrypt({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tdemType = DemType.AesGcm256,\n\t\tthreshold,\n\t\tpackageId,\n\t\tid,\n\t\tdata,\n\t\taad = new Uint8Array(),\n\t}: EncryptOptions) {\n\t\tconst packageObj = await this.#suiClient.core.getObject({ objectId: packageId });\n\t\tif (String(packageObj.object.version) !== '1') {\n\t\t\tthrow new InvalidPackageError(`Package ${packageId} is not the first version`);\n\t\t}\n\n\t\treturn encrypt({\n\t\t\tkeyServers: await this.#getWeightedKeyServers(),\n\t\t\tkemType,\n\t\t\tthreshold,\n\t\t\tpackageId,\n\t\t\tid,\n\t\t\tencryptionInput: this.#createEncryptionInput(\n\t\t\t\tdemType,\n\t\t\t\tdata as Uint8Array<ArrayBuffer>,\n\t\t\t\taad as Uint8Array<ArrayBuffer>,\n\t\t\t),\n\t\t});\n\t}\n\n\t#createEncryptionInput(\n\t\ttype: DemType,\n\t\tdata: Uint8Array<ArrayBuffer>,\n\t\taad: Uint8Array<ArrayBuffer>,\n\t): EncryptionInput {\n\t\tswitch (type) {\n\t\t\tcase DemType.AesGcm256:\n\t\t\t\treturn new AesGcm256(data, aad);\n\t\t\tcase DemType.Hmac256Ctr:\n\t\t\t\treturn new Hmac256Ctr(data, aad);\n\t\t}\n\t}\n\n\t/**\n\t * Decrypt the given encrypted bytes using cached keys.\n\t * Calls fetchKeys in case one or more of the required keys is not cached yet.\n\t * The function throws an error if the client's key servers are not a subset of\n\t * the encrypted object's key servers or if the threshold cannot be met.\n\t *\n\t * If checkShareConsistency is true, the decrypted shares are checked for consistency, meaning that\n\t * any combination of at least threshold shares should either succesfully combine to the plaintext or fail.\n\t * This is useful in case the encryptor is not trusted and the decryptor wants to ensure all decryptors\n\t * receive the same output (e.g., for onchain encrypted voting).\n\t *\n\t * @param data - The encrypted bytes to decrypt.\n\t * @param sessionKey - The session key to use.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param checkShareConsistency - If true, the shares are checked for consistency.\n\t * @param checkLEEncoding - If true, the encryption is also checked using an LE encoded nonce.\n\t * @returns - The decrypted plaintext corresponding to ciphertext.\n\t */\n\tasync decrypt({\n\t\tdata,\n\t\tsessionKey,\n\t\ttxBytes,\n\t\tcheckShareConsistency,\n\t\tcheckLEEncoding,\n\t}: DecryptOptions) {\n\t\tconst encryptedObject = EncryptedObject.parse(data);\n\n\t\tthis.#validateEncryptionServices(\n\t\t\tencryptedObject.services.map((s) => s[0]),\n\t\t\tencryptedObject.threshold,\n\t\t);\n\n\t\tawait this.fetchKeys({\n\t\t\tids: [encryptedObject.id],\n\t\t\ttxBytes,\n\t\t\tsessionKey,\n\t\t\tthreshold: encryptedObject.threshold,\n\t\t});\n\n\t\tif (checkShareConsistency) {\n\t\t\tconst publicKeys = await this.getPublicKeys(\n\t\t\t\tencryptedObject.services.map(([objectId, _]) => objectId),\n\t\t\t);\n\t\t\treturn decrypt({\n\t\t\t\tencryptedObject,\n\t\t\t\tkeys: this.#cachedKeys,\n\t\t\t\tpublicKeys,\n\t\t\t\tcheckLEEncoding: false, // We intentionally do not support other encodings here\n\t\t\t});\n\t\t}\n\t\treturn decrypt({ encryptedObject, keys: this.#cachedKeys, checkLEEncoding });\n\t}\n\n\t#weight(objectId: string) {\n\t\treturn this.#configs.get(objectId)?.weight ?? 0;\n\t}\n\n\t#validateEncryptionServices(services: string[], threshold: number) {\n\t\t// Check that the client's key servers are a subset of the encrypted object's key servers.\n\t\tif (\n\t\t\tservices.some((objectId) => {\n\t\t\t\tconst countInClient = this.#weight(objectId);\n\t\t\t\treturn countInClient > 0 && countInClient !== count(services, objectId);\n\t\t\t})\n\t\t) {\n\t\t\tthrow new InconsistentKeyServersError(\n\t\t\t\t`Client's key servers must be a subset of the encrypted object's key servers`,\n\t\t\t);\n\t\t}\n\t\t// Check that the threshold can be met with the client's key servers.\n\t\tif (threshold > this.#totalWeight) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${this.#totalWeight} servers`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync getKeyServers(): Promise<Map<string, KeyServer>> {\n\t\tif (!this.#keyServers) {\n\t\t\tthis.#keyServers = this.#loadKeyServers().catch((error) => {\n\t\t\t\tthis.#keyServers = null;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t}\n\t\treturn this.#keyServers;\n\t}\n\n\t/**\n\t * Get the public keys for the given services.\n\t * If all public keys are not in the cache, they are retrieved.\n\t *\n\t * @param services - The services to get the public keys for.\n\t * @returns The public keys for the given services in the same order as the given services.\n\t */\n\tasync getPublicKeys(services: string[]): Promise<G2Element[]> {\n\t\tconst keyServers = await this.getKeyServers();\n\n\t\t// Collect the key servers not already in store or cache.\n\t\tconst missingKeyServers = services.filter(\n\t\t\t(objectId) => !keyServers.has(objectId) && !this.#cachedPublicKeys.has(objectId),\n\t\t);\n\n\t\t// If there are missing key servers, retrieve them and update the cache.\n\t\tif (missingKeyServers.length > 0) {\n\t\t\t(\n\t\t\t\tawait retrieveKeyServers({\n\t\t\t\t\tobjectIds: missingKeyServers,\n\t\t\t\t\tclient: this.#suiClient,\n\t\t\t\t\tconfigs: this.#configs,\n\t\t\t\t})\n\t\t\t).forEach((keyServer) =>\n\t\t\t\tthis.#cachedPublicKeys.set(keyServer.objectId, G2Element.fromBytes(keyServer.pk)),\n\t\t\t);\n\t\t}\n\n\t\treturn services.map((objectId) => {\n\t\t\tconst keyServer = keyServers.get(objectId);\n\t\t\tif (keyServer) {\n\t\t\t\treturn G2Element.fromBytes(keyServer.pk);\n\t\t\t}\n\t\t\treturn this.#cachedPublicKeys.get(objectId)!;\n\t\t});\n\t}\n\n\t/**\n\t * Returns a list of key servers with multiplicity according to their weights.\n\t * The list is used for encryption.\n\t */\n\tasync #getWeightedKeyServers() {\n\t\tconst keyServers = await this.getKeyServers();\n\t\tconst keyServersWithMultiplicity = [];\n\t\tfor (const [objectId, config] of this.#configs) {\n\t\t\tconst keyServer = keyServers.get(objectId)!;\n\t\t\tfor (let i = 0; i < config.weight; i++) {\n\t\t\t\tkeyServersWithMultiplicity.push(keyServer);\n\t\t\t}\n\t\t}\n\t\treturn keyServersWithMultiplicity;\n\t}\n\n\tasync #loadKeyServers(): Promise<Map<string, KeyServer>> {\n\t\tconst keyServers = await retrieveKeyServers({\n\t\t\tobjectIds: [...this.#configs.keys()],\n\t\t\tclient: this.#suiClient,\n\t\t\tconfigs: this.#configs,\n\t\t});\n\n\t\tif (keyServers.length === 0) {\n\t\t\tthrow new InvalidKeyServerError('No key servers found');\n\t\t}\n\n\t\tif (this.#verifyKeyServers) {\n\t\t\tawait Promise.all(\n\t\t\t\tkeyServers.map(async (server) => {\n\t\t\t\t\t// Skip /service verification for committee key server type since the request goes through an aggregator.\n\t\t\t\t\tif (server.serverType === 'Committee') {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst config = this.#configs.get(server.objectId);\n\t\t\t\t\tif (!(await verifyKeyServer(server, this.#timeout, config?.apiKeyName, config?.apiKey))) {\n\t\t\t\t\t\tthrow new InvalidKeyServerError(`Key server ${server.objectId} is not valid`);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn new Map(keyServers.map((server) => [server.objectId, server]));\n\t}\n\n\t/**\n\t * Fetch keys from the key servers and update the cache.\n\t *\n\t * It is recommended to call this function once for all ids of all encrypted objects if\n\t * there are multiple, then call decrypt for each object. This avoids calling fetchKey\n\t * individually for each decrypt.\n\t *\n\t * @param ids - The ids of the encrypted objects.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold for the TSS encryptions. The function returns when a threshold of key servers had returned keys for all ids.\n\t */\n\tasync fetchKeys({ ids, txBytes, sessionKey, threshold }: FetchKeysOptions) {\n\t\tif (threshold > this.#totalWeight || threshold < 1) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} servers with weights ${JSON.stringify(this.#configs)}`,\n\t\t\t);\n\t\t}\n\t\tconst keyServers = await this.getKeyServers();\n\t\tconst fullIds = ids.map((id) => createFullId(sessionKey.getPackageId(), id));\n\n\t\t// Count a server as completed if it has keys for all fullIds.\n\t\t// Duplicated key server ids will be counted towards the threshold.\n\t\tlet completedWeight = 0;\n\t\tconst remainingKeyServers = [];\n\t\tlet remainingKeyServersWeight = 0;\n\t\tfor (const objectId of keyServers.keys()) {\n\t\t\tif (fullIds.every((fullId) => this.#cachedKeys.has(`${fullId}:${objectId}`))) {\n\t\t\t\tcompletedWeight += this.#weight(objectId);\n\t\t\t} else {\n\t\t\t\tremainingKeyServers.push(objectId);\n\t\t\t\tremainingKeyServersWeight += this.#weight(objectId);\n\t\t\t}\n\t\t}\n\n\t\t// Return early if we have enough keys from cache.\n\t\tif (completedWeight >= threshold) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst certificate = await sessionKey.getCertificate();\n\t\tconst signedRequest = await sessionKey.createRequestParams(txBytes);\n\n\t\tconst controller = new AbortController();\n\t\tconst errors: Error[] = [];\n\n\t\tconst keyFetches = remainingKeyServers.map(async (objectId) => {\n\t\t\tconst server = keyServers.get(objectId)!;\n\t\t\ttry {\n\t\t\t\tconst config = this.#configs.get(objectId);\n\t\t\t\tconst allKeys = await fetchKeysForAllIds({\n\t\t\t\t\turl: server.url,\n\t\t\t\t\trequestSignature: signedRequest.requestSignature,\n\t\t\t\t\ttransactionBytes: txBytes,\n\t\t\t\t\tencKey: signedRequest.encKey,\n\t\t\t\t\tencKeyPk: signedRequest.encKeyPk,\n\t\t\t\t\tencVerificationKey: signedRequest.encVerificationKey,\n\t\t\t\t\tcertificate,\n\t\t\t\t\ttimeout: this.#timeout,\n\t\t\t\t\tapiKeyName: config?.apiKeyName,\n\t\t\t\t\tapiKey: config?.apiKey,\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t\t// Check validity of the keys and add them to the cache.\n\t\t\t\tfor (const { fullId, key } of allKeys) {\n\t\t\t\t\tconst keyElement = G1Element.fromBytes(key);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!BonehFranklinBLS12381Services.verifyUserSecretKey(\n\t\t\t\t\t\t\tkeyElement,\n\t\t\t\t\t\t\tfullId,\n\t\t\t\t\t\t\tG2Element.fromBytes(server.pk),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tconsole.warn('Received invalid key from key server ' + server.objectId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthis.#cachedKeys.set(`${fullId}:${server.objectId}`, keyElement);\n\t\t\t\t}\n\n\t\t\t\t// Check if all the receivedIds are consistent with the requested fullIds.\n\t\t\t\t// If so, consider the key server got all keys and mark as completed.\n\t\t\t\tif (fullIds.every((fullId) => this.#cachedKeys.has(`${fullId}:${server.objectId}`))) {\n\t\t\t\t\tcompletedWeight += this.#weight(objectId);\n\n\t\t\t\t\t// Return early if the completed servers is more than the threshold.\n\t\t\t\t\tif (completedWeight >= threshold) {\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (!controller.signal.aborted) {\n\t\t\t\t\terrors.push(error as Error);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// If there are too many errors that the threshold is not attainable, return early with error.\n\t\t\t\tremainingKeyServersWeight -= this.#weight(objectId);\n\t\t\t\tif (remainingKeyServersWeight < threshold - completedWeight) {\n\t\t\t\t\tcontroller.abort(new TooManyFailedFetchKeyRequestsError());\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.allSettled(keyFetches);\n\n\t\tif (completedWeight < threshold) {\n\t\t\tthrow toMajorityError(errors);\n\t\t}\n\t}\n\n\t/**\n\t * Get derived keys from the given services.\n\t *\n\t * @param id - The id of the encrypted object.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold.\n\t * @returns - Derived keys for the given services that are in the cache as a \"service object ID\" -> derived key map. If the call is succesful, exactly threshold keys will be returned.\n\t */\n\tasync getDerivedKeys({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tid,\n\t\ttxBytes,\n\t\tsessionKey,\n\t\tthreshold,\n\t}: GetDerivedKeysOptions): Promise<Map<string, DerivedKey>> {\n\t\tswitch (kemType) {\n\t\t\tcase KemType.BonehFranklinBLS12381DemCCA:\n\t\t\t\tconst keyServers = await this.getKeyServers();\n\t\t\t\tif (threshold > this.#totalWeight) {\n\t\t\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t\t\t`Invalid threshold ${threshold} for ${this.#totalWeight} servers`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait this.fetchKeys({\n\t\t\t\t\tids: [id],\n\t\t\t\t\ttxBytes,\n\t\t\t\t\tsessionKey,\n\t\t\t\t\tthreshold,\n\t\t\t\t});\n\n\t\t\t\t// After calling fetchKeys, we can be sure that there are at least `threshold` of the required keys in the cache.\n\t\t\t\t// It is also checked there that the KeyServerType is BonehFranklinBLS12381 for all services.\n\n\t\t\t\tconst fullId = createFullId(sessionKey.getPackageId(), id);\n\n\t\t\t\tconst derivedKeys = new Map();\n\t\t\t\tlet weight = 0;\n\t\t\t\tfor (const objectId of keyServers.keys()) {\n\t\t\t\t\t// The code below assumes that the KeyServerType is BonehFranklinBLS12381.\n\t\t\t\t\tconst cachedKey = this.#cachedKeys.get(`${fullId}:${objectId}`);\n\t\t\t\t\tif (cachedKey) {\n\t\t\t\t\t\tderivedKeys.set(objectId, new BonehFranklinBLS12381DerivedKey(cachedKey));\n\t\t\t\t\t\tweight += this.#weight(objectId);\n\t\t\t\t\t\tif (weight >= threshold) {\n\t\t\t\t\t\t\t// We have enough keys, so we can stop.\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn derivedKeys;\n\t\t}\n\t}\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,22 +0,0 @@
1
- import type { EncryptedObject } from './bcs.js';
2
- import type { G1Element } from './bls12381.js';
3
- import { G2Element } from './bls12381.js';
4
- import type { KeyCacheKey } from './types.js';
5
- export interface DecryptOptions {
6
- encryptedObject: typeof EncryptedObject.$inferType;
7
- keys: Map<KeyCacheKey, G1Element>;
8
- publicKeys?: G2Element[];
9
- checkLEEncoding?: boolean;
10
- }
11
- /**
12
- * Decrypt the given encrypted bytes with the given cached secret keys for the full ID.
13
- * It's assumed that fetchKeys has been called to fetch the secret keys for enough key servers
14
- * otherwise, this will throw an error.
15
- * Also, it's assumed that the keys were verified by the caller.
16
- *
17
- * If publicKeys are provided, the decrypted shares are checked for consistency, meaning that
18
- * any combination of at least threshold shares should either succesfully combine to the plaintext or fail.
19
- *
20
- * @returns - The decrypted plaintext corresponding to ciphertext.
21
- */
22
- export declare function decrypt({ encryptedObject, keys, publicKeys, checkLEEncoding, }: DecryptOptions): Promise<Uint8Array>;
@@ -1,94 +0,0 @@
1
- import { fromHex } from "@mysten/bcs";
2
- import { G2Element } from "./bls12381.js";
3
- import { AesGcm256, Hmac256Ctr } from "./dem.js";
4
- import { InvalidCiphertextError, UnsupportedFeatureError } from "./error.js";
5
- import {
6
- BonehFranklinBLS12381Services,
7
- decryptRandomness,
8
- verifyNonce,
9
- verifyNonceWithLE
10
- } from "./ibe.js";
11
- import { deriveKey, KeyPurpose } from "./kdf.js";
12
- import { createFullId, equals } from "./utils.js";
13
- import { combine, interpolate } from "./shamir.js";
14
- async function decrypt({
15
- encryptedObject,
16
- keys,
17
- publicKeys,
18
- checkLEEncoding
19
- }) {
20
- if (!encryptedObject.encryptedShares.BonehFranklinBLS12381) {
21
- throw new UnsupportedFeatureError("Encryption mode not supported");
22
- }
23
- const fullId = createFullId(encryptedObject.packageId, encryptedObject.id);
24
- const inKeystore = encryptedObject.services.map((_, i) => i).filter((i) => keys.has(`${fullId}:${encryptedObject.services[i][0]}`));
25
- if (inKeystore.length < encryptedObject.threshold) {
26
- throw new Error("Not enough shares. Please fetch more keys.");
27
- }
28
- const encryptedShares = encryptedObject.encryptedShares.BonehFranklinBLS12381.encryptedShares;
29
- if (encryptedShares.length !== encryptedObject.services.length) {
30
- throw new InvalidCiphertextError(
31
- `Mismatched shares ${encryptedShares.length} and services ${encryptedObject.services.length}`
32
- );
33
- }
34
- const nonce = G2Element.fromBytes(encryptedObject.encryptedShares.BonehFranklinBLS12381.nonce);
35
- const shares = inKeystore.map((i) => {
36
- const [objectId, index] = encryptedObject.services[i];
37
- const share = BonehFranklinBLS12381Services.decrypt(
38
- nonce,
39
- keys.get(`${fullId}:${objectId}`),
40
- encryptedShares[i],
41
- fromHex(fullId),
42
- [objectId, index]
43
- );
44
- return { index, share };
45
- });
46
- const baseKey = combine(shares);
47
- const randomnessKey = deriveKey(
48
- KeyPurpose.EncryptedRandomness,
49
- baseKey,
50
- encryptedShares,
51
- encryptedObject.threshold,
52
- encryptedObject.services.map(([objectIds, _]) => objectIds)
53
- );
54
- const randomness = decryptRandomness(
55
- encryptedObject.encryptedShares.BonehFranklinBLS12381.encryptedRandomness,
56
- randomnessKey
57
- );
58
- if (!(checkLEEncoding ? verifyNonceWithLE(nonce, randomness) : verifyNonce(nonce, randomness))) {
59
- throw new InvalidCiphertextError("Invalid nonce");
60
- }
61
- const checkShareConsistency = publicKeys !== void 0;
62
- if (checkShareConsistency) {
63
- const polynomial = interpolate(shares);
64
- const allShares = BonehFranklinBLS12381Services.decryptAllSharesUsingRandomness(
65
- randomness,
66
- encryptedShares,
67
- encryptedObject.services,
68
- publicKeys,
69
- nonce,
70
- fromHex(fullId)
71
- );
72
- if (allShares.some(({ index, share }) => !equals(polynomial(index), share))) {
73
- throw new InvalidCiphertextError("Invalid shares");
74
- }
75
- }
76
- const demKey = deriveKey(
77
- KeyPurpose.DEM,
78
- baseKey,
79
- encryptedShares,
80
- encryptedObject.threshold,
81
- encryptedObject.services.map(([objectId, _]) => objectId)
82
- );
83
- if (encryptedObject.ciphertext.Aes256Gcm) {
84
- return AesGcm256.decrypt(demKey, encryptedObject.ciphertext);
85
- } else if (encryptedObject.ciphertext.Hmac256Ctr) {
86
- return Hmac256Ctr.decrypt(demKey, encryptedObject.ciphertext);
87
- } else {
88
- throw new InvalidCiphertextError("Invalid ciphertext type");
89
- }
90
- }
91
- export {
92
- decrypt
93
- };
94
- //# sourceMappingURL=decrypt.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/decrypt.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromHex } from '@mysten/bcs';\n\nimport type { EncryptedObject } from './bcs.js';\nimport type { G1Element } from './bls12381.js';\nimport { G2Element } from './bls12381.js';\nimport { AesGcm256, Hmac256Ctr } from './dem.js';\nimport { InvalidCiphertextError, UnsupportedFeatureError } from './error.js';\nimport {\n\tBonehFranklinBLS12381Services,\n\tdecryptRandomness,\n\tverifyNonce,\n\tverifyNonceWithLE,\n} from './ibe.js';\nimport { deriveKey, KeyPurpose } from './kdf.js';\nimport type { KeyCacheKey } from './types.js';\nimport { createFullId, equals } from './utils.js';\nimport { combine, interpolate } from './shamir.js';\n\nexport interface DecryptOptions {\n\tencryptedObject: typeof EncryptedObject.$inferType;\n\tkeys: Map<KeyCacheKey, G1Element>;\n\tpublicKeys?: G2Element[];\n\tcheckLEEncoding?: boolean;\n}\n\n/**\n * Decrypt the given encrypted bytes with the given cached secret keys for the full ID.\n * It's assumed that fetchKeys has been called to fetch the secret keys for enough key servers\n * otherwise, this will throw an error.\n * Also, it's assumed that the keys were verified by the caller.\n *\n * If publicKeys are provided, the decrypted shares are checked for consistency, meaning that\n * any combination of at least threshold shares should either succesfully combine to the plaintext or fail.\n *\n * @returns - The decrypted plaintext corresponding to ciphertext.\n */\nexport async function decrypt({\n\tencryptedObject,\n\tkeys,\n\tpublicKeys,\n\tcheckLEEncoding,\n}: DecryptOptions): Promise<Uint8Array> {\n\tif (!encryptedObject.encryptedShares.BonehFranklinBLS12381) {\n\t\tthrow new UnsupportedFeatureError('Encryption mode not supported');\n\t}\n\n\tconst fullId = createFullId(encryptedObject.packageId, encryptedObject.id);\n\n\t// Get the indices of the service whose keys are in the keystore.\n\tconst inKeystore = encryptedObject.services\n\t\t.map((_, i) => i)\n\t\t.filter((i) => keys.has(`${fullId}:${encryptedObject.services[i][0]}`));\n\n\tif (inKeystore.length < encryptedObject.threshold) {\n\t\tthrow new Error('Not enough shares. Please fetch more keys.');\n\t}\n\n\tconst encryptedShares = encryptedObject.encryptedShares.BonehFranklinBLS12381.encryptedShares;\n\tif (encryptedShares.length !== encryptedObject.services.length) {\n\t\tthrow new InvalidCiphertextError(\n\t\t\t`Mismatched shares ${encryptedShares.length} and services ${encryptedObject.services.length}`,\n\t\t);\n\t}\n\n\tconst nonce = G2Element.fromBytes(encryptedObject.encryptedShares.BonehFranklinBLS12381.nonce);\n\n\t// Decrypt each share.\n\tconst shares = inKeystore.map((i) => {\n\t\tconst [objectId, index] = encryptedObject.services[i];\n\t\t// Use the index as the unique info parameter to allow for multiple shares per key server.\n\t\tconst share = BonehFranklinBLS12381Services.decrypt(\n\t\t\tnonce,\n\t\t\tkeys.get(`${fullId}:${objectId}`)!,\n\t\t\tencryptedShares[i],\n\t\t\tfromHex(fullId),\n\t\t\t[objectId, index],\n\t\t) as Uint8Array<ArrayBuffer>;\n\t\treturn { index, share };\n\t});\n\n\t// Combine the decrypted shares into the key\n\tconst baseKey = combine(shares);\n\n\t// Decrypt randomness\n\tconst randomnessKey = deriveKey(\n\t\tKeyPurpose.EncryptedRandomness,\n\t\tbaseKey,\n\t\tencryptedShares,\n\t\tencryptedObject.threshold,\n\t\tencryptedObject.services.map(([objectIds, _]) => objectIds),\n\t);\n\tconst randomness = decryptRandomness(\n\t\tencryptedObject.encryptedShares.BonehFranklinBLS12381.encryptedRandomness,\n\t\trandomnessKey,\n\t);\n\n\t// Verify that the nonce was created with the randomness.\n\tif (!(checkLEEncoding ? verifyNonceWithLE(nonce, randomness) : verifyNonce(nonce, randomness))) {\n\t\tthrow new InvalidCiphertextError('Invalid nonce');\n\t}\n\n\t// If public keys are provided, check consistency of the shares.\n\tconst checkShareConsistency = publicKeys !== undefined;\n\tif (checkShareConsistency) {\n\t\tconst polynomial = interpolate(shares);\n\t\tconst allShares = BonehFranklinBLS12381Services.decryptAllSharesUsingRandomness(\n\t\t\trandomness,\n\t\t\tencryptedShares,\n\t\t\tencryptedObject.services,\n\t\t\tpublicKeys,\n\t\t\tnonce,\n\t\t\tfromHex(fullId),\n\t\t);\n\t\tif (allShares.some(({ index, share }) => !equals(polynomial(index), share))) {\n\t\t\tthrow new InvalidCiphertextError('Invalid shares');\n\t\t}\n\t}\n\n\t// Derive the DEM key\n\tconst demKey = deriveKey(\n\t\tKeyPurpose.DEM,\n\t\tbaseKey,\n\t\tencryptedShares,\n\t\tencryptedObject.threshold,\n\t\tencryptedObject.services.map(([objectId, _]) => objectId),\n\t);\n\n\t// Decrypt the ciphertext\n\tif (encryptedObject.ciphertext.Aes256Gcm) {\n\t\treturn AesGcm256.decrypt(demKey, encryptedObject.ciphertext);\n\t} else if (encryptedObject.ciphertext.Hmac256Ctr) {\n\t\treturn Hmac256Ctr.decrypt(demKey, encryptedObject.ciphertext);\n\t} else {\n\t\tthrow new InvalidCiphertextError('Invalid ciphertext type');\n\t}\n}\n"],
5
- "mappings": "AAGA,SAAS,eAAe;AAIxB,SAAS,iBAAiB;AAC1B,SAAS,WAAW,kBAAkB;AACtC,SAAS,wBAAwB,+BAA+B;AAChE;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,WAAW,kBAAkB;AAEtC,SAAS,cAAc,cAAc;AACrC,SAAS,SAAS,mBAAmB;AAoBrC,eAAsB,QAAQ;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAwC;AACvC,MAAI,CAAC,gBAAgB,gBAAgB,uBAAuB;AAC3D,UAAM,IAAI,wBAAwB,+BAA+B;AAAA,EAClE;AAEA,QAAM,SAAS,aAAa,gBAAgB,WAAW,gBAAgB,EAAE;AAGzE,QAAM,aAAa,gBAAgB,SACjC,IAAI,CAAC,GAAG,MAAM,CAAC,EACf,OAAO,CAAC,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,gBAAgB,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAEvE,MAAI,WAAW,SAAS,gBAAgB,WAAW;AAClD,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC7D;AAEA,QAAM,kBAAkB,gBAAgB,gBAAgB,sBAAsB;AAC9E,MAAI,gBAAgB,WAAW,gBAAgB,SAAS,QAAQ;AAC/D,UAAM,IAAI;AAAA,MACT,qBAAqB,gBAAgB,MAAM,iBAAiB,gBAAgB,SAAS,MAAM;AAAA,IAC5F;AAAA,EACD;AAEA,QAAM,QAAQ,UAAU,UAAU,gBAAgB,gBAAgB,sBAAsB,KAAK;AAG7F,QAAM,SAAS,WAAW,IAAI,CAAC,MAAM;AACpC,UAAM,CAAC,UAAU,KAAK,IAAI,gBAAgB,SAAS,CAAC;AAEpD,UAAM,QAAQ,8BAA8B;AAAA,MAC3C;AAAA,MACA,KAAK,IAAI,GAAG,MAAM,IAAI,QAAQ,EAAE;AAAA,MAChC,gBAAgB,CAAC;AAAA,MACjB,QAAQ,MAAM;AAAA,MACd,CAAC,UAAU,KAAK;AAAA,IACjB;AACA,WAAO,EAAE,OAAO,MAAM;AAAA,EACvB,CAAC;AAGD,QAAM,UAAU,QAAQ,MAAM;AAG9B,QAAM,gBAAgB;AAAA,IACrB,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,gBAAgB,SAAS,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,SAAS;AAAA,EAC3D;AACA,QAAM,aAAa;AAAA,IAClB,gBAAgB,gBAAgB,sBAAsB;AAAA,IACtD;AAAA,EACD;AAGA,MAAI,EAAE,kBAAkB,kBAAkB,OAAO,UAAU,IAAI,YAAY,OAAO,UAAU,IAAI;AAC/F,UAAM,IAAI,uBAAuB,eAAe;AAAA,EACjD;AAGA,QAAM,wBAAwB,eAAe;AAC7C,MAAI,uBAAuB;AAC1B,UAAM,aAAa,YAAY,MAAM;AACrC,UAAM,YAAY,8BAA8B;AAAA,MAC/C;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB;AAAA,MACA;AAAA,MACA,QAAQ,MAAM;AAAA,IACf;AACA,QAAI,UAAU,KAAK,CAAC,EAAE,OAAO,MAAM,MAAM,CAAC,OAAO,WAAW,KAAK,GAAG,KAAK,CAAC,GAAG;AAC5E,YAAM,IAAI,uBAAuB,gBAAgB;AAAA,IAClD;AAAA,EACD;AAGA,QAAM,SAAS;AAAA,IACd,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,gBAAgB,SAAS,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,QAAQ;AAAA,EACzD;AAGA,MAAI,gBAAgB,WAAW,WAAW;AACzC,WAAO,UAAU,QAAQ,QAAQ,gBAAgB,UAAU;AAAA,EAC5D,WAAW,gBAAgB,WAAW,YAAY;AACjD,WAAO,WAAW,QAAQ,QAAQ,gBAAgB,UAAU;AAAA,EAC7D,OAAO;AACN,UAAM,IAAI,uBAAuB,yBAAyB;AAAA,EAC3D;AACD;",
6
- "names": []
7
- }
package/dist/esm/dem.d.ts DELETED
@@ -1,38 +0,0 @@
1
- import type { Ciphertext } from './bcs.js';
2
- export declare const iv: Uint8Array<ArrayBuffer>;
3
- /**
4
- * An interface for supported DEMs.
5
- */
6
- export interface EncryptionInput {
7
- encrypt(key: Uint8Array): Promise<typeof Ciphertext.$inferInput>;
8
- generateKey(): Promise<Uint8Array<ArrayBuffer>>;
9
- }
10
- /**
11
- * AES-GCM encryption.
12
- */
13
- export declare class AesGcm256 implements EncryptionInput {
14
- readonly plaintext: Uint8Array<ArrayBuffer>;
15
- readonly aad: Uint8Array<ArrayBuffer>;
16
- constructor(msg: Uint8Array<ArrayBuffer>, aad: Uint8Array<ArrayBuffer>);
17
- generateKey(): Promise<Uint8Array<ArrayBuffer>>;
18
- encrypt(key: Uint8Array): Promise<typeof Ciphertext.$inferInput>;
19
- static decrypt(key: Uint8Array, ciphertext: typeof Ciphertext.$inferInput): Promise<Uint8Array>;
20
- }
21
- /**
22
- * Authenticated encryption using CTR mode with HMAC-SHA3-256 as a PRF.
23
- * 1. Derive an encryption key, <i>k<sub>1</sub> = <b>hmac</b>(key, 1)</i>.
24
- * 2. Chunk the message into blocks of 32 bytes, <i>m = m<sub>1</sub> || ... || m<sub>n</sub></i>.
25
- * 3. Let the ciphertext be defined by <i>c = c<sub>1</sub> || ... || c<sub>n</sub></i> where <i>c<sub>i</sub> = m<sub>i</sub> ⊕ <b>hmac</b>(k<sub>1</sub>, i)</i>.
26
- * 4. Compute a MAC over the AAD and the ciphertext, <i>mac = <b>hmac</b>(k<sub>2</sub>, aad || c) where k<sub>2</sub> = <b>hmac</b>(key, 2)</i>.
27
- * 5. Return <i>mac || aad || c</i>.
28
- */
29
- export declare class Hmac256Ctr implements EncryptionInput {
30
- readonly plaintext: Uint8Array<ArrayBuffer>;
31
- readonly aad: Uint8Array<ArrayBuffer>;
32
- constructor(msg: Uint8Array<ArrayBuffer>, aad: Uint8Array<ArrayBuffer>);
33
- generateKey(): Promise<Uint8Array<ArrayBuffer>>;
34
- encrypt(key: Uint8Array): Promise<typeof Ciphertext.$inferInput>;
35
- static decrypt(key: Uint8Array, ciphertext: typeof Ciphertext.$inferInput): Promise<Uint8Array>;
36
- private static computeMac;
37
- private static encryptInCtrMode;
38
- }