@haneullabs/seal 0.1.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 (109) hide show
  1. package/CHANGELOG.md +459 -0
  2. package/README.md +4 -0
  3. package/dist/cjs/bcs.d.ts +71 -0
  4. package/dist/cjs/bcs.js +74 -0
  5. package/dist/cjs/bcs.js.map +7 -0
  6. package/dist/cjs/bls12381.d.ts +44 -0
  7. package/dist/cjs/bls12381.js +151 -0
  8. package/dist/cjs/bls12381.js.map +7 -0
  9. package/dist/cjs/client.d.ts +84 -0
  10. package/dist/cjs/client.js +414 -0
  11. package/dist/cjs/client.js.map +7 -0
  12. package/dist/cjs/decrypt.d.ts +22 -0
  13. package/dist/cjs/decrypt.js +109 -0
  14. package/dist/cjs/decrypt.js.map +7 -0
  15. package/dist/cjs/dem.d.ts +38 -0
  16. package/dist/cjs/dem.js +185 -0
  17. package/dist/cjs/dem.js.map +7 -0
  18. package/dist/cjs/elgamal.d.ts +13 -0
  19. package/dist/cjs/elgamal.js +46 -0
  20. package/dist/cjs/elgamal.js.map +7 -0
  21. package/dist/cjs/encrypt.d.ts +32 -0
  22. package/dist/cjs/encrypt.js +104 -0
  23. package/dist/cjs/encrypt.js.map +7 -0
  24. package/dist/cjs/error.d.ts +86 -0
  25. package/dist/cjs/error.js +239 -0
  26. package/dist/cjs/error.js.map +7 -0
  27. package/dist/cjs/ibe.d.ts +98 -0
  28. package/dist/cjs/ibe.js +167 -0
  29. package/dist/cjs/ibe.js.map +7 -0
  30. package/dist/cjs/index.d.ts +6 -0
  31. package/dist/cjs/index.js +33 -0
  32. package/dist/cjs/index.js.map +7 -0
  33. package/dist/cjs/kdf.d.ts +30 -0
  34. package/dist/cjs/kdf.js +97 -0
  35. package/dist/cjs/kdf.js.map +7 -0
  36. package/dist/cjs/key-server.d.ts +98 -0
  37. package/dist/cjs/key-server.js +171 -0
  38. package/dist/cjs/key-server.js.map +7 -0
  39. package/dist/cjs/package.json +5 -0
  40. package/dist/cjs/session-key.d.ts +74 -0
  41. package/dist/cjs/session-key.js +245 -0
  42. package/dist/cjs/session-key.js.map +7 -0
  43. package/dist/cjs/shamir.d.ts +91 -0
  44. package/dist/cjs/shamir.js +770 -0
  45. package/dist/cjs/shamir.js.map +7 -0
  46. package/dist/cjs/types.d.ts +83 -0
  47. package/dist/cjs/types.js +17 -0
  48. package/dist/cjs/types.js.map +7 -0
  49. package/dist/cjs/utils.d.ts +47 -0
  50. package/dist/cjs/utils.js +106 -0
  51. package/dist/cjs/utils.js.map +7 -0
  52. package/dist/cjs/version.d.ts +1 -0
  53. package/dist/cjs/version.js +25 -0
  54. package/dist/cjs/version.js.map +7 -0
  55. package/dist/esm/bcs.d.ts +71 -0
  56. package/dist/esm/bcs.js +54 -0
  57. package/dist/esm/bcs.js.map +7 -0
  58. package/dist/esm/bls12381.d.ts +44 -0
  59. package/dist/esm/bls12381.js +131 -0
  60. package/dist/esm/bls12381.js.map +7 -0
  61. package/dist/esm/client.d.ts +84 -0
  62. package/dist/esm/client.js +407 -0
  63. package/dist/esm/client.js.map +7 -0
  64. package/dist/esm/decrypt.d.ts +22 -0
  65. package/dist/esm/decrypt.js +94 -0
  66. package/dist/esm/decrypt.js.map +7 -0
  67. package/dist/esm/dem.d.ts +38 -0
  68. package/dist/esm/dem.js +165 -0
  69. package/dist/esm/dem.js.map +7 -0
  70. package/dist/esm/elgamal.d.ts +13 -0
  71. package/dist/esm/elgamal.js +26 -0
  72. package/dist/esm/elgamal.js.map +7 -0
  73. package/dist/esm/encrypt.d.ts +32 -0
  74. package/dist/esm/encrypt.js +84 -0
  75. package/dist/esm/encrypt.js.map +7 -0
  76. package/dist/esm/error.d.ts +86 -0
  77. package/dist/esm/error.js +219 -0
  78. package/dist/esm/error.js.map +7 -0
  79. package/dist/esm/ibe.d.ts +98 -0
  80. package/dist/esm/ibe.js +147 -0
  81. package/dist/esm/ibe.js.map +7 -0
  82. package/dist/esm/index.d.ts +6 -0
  83. package/dist/esm/index.js +12 -0
  84. package/dist/esm/index.js.map +7 -0
  85. package/dist/esm/kdf.d.ts +30 -0
  86. package/dist/esm/kdf.js +83 -0
  87. package/dist/esm/kdf.js.map +7 -0
  88. package/dist/esm/key-server.d.ts +98 -0
  89. package/dist/esm/key-server.js +151 -0
  90. package/dist/esm/key-server.js.map +7 -0
  91. package/dist/esm/package.json +5 -0
  92. package/dist/esm/session-key.d.ts +74 -0
  93. package/dist/esm/session-key.js +230 -0
  94. package/dist/esm/session-key.js.map +7 -0
  95. package/dist/esm/shamir.d.ts +91 -0
  96. package/dist/esm/shamir.js +750 -0
  97. package/dist/esm/shamir.js.map +7 -0
  98. package/dist/esm/types.d.ts +83 -0
  99. package/dist/esm/types.js +1 -0
  100. package/dist/esm/types.js.map +7 -0
  101. package/dist/esm/utils.d.ts +47 -0
  102. package/dist/esm/utils.js +86 -0
  103. package/dist/esm/utils.js.map +7 -0
  104. package/dist/esm/version.d.ts +1 -0
  105. package/dist/esm/version.js +5 -0
  106. package/dist/esm/version.js.map +7 -0
  107. package/dist/tsconfig.esm.tsbuildinfo +1 -0
  108. package/dist/tsconfig.tsbuildinfo +1 -0
  109. package/package.json +58 -0
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var ibe_exports = {};
20
+ __export(ibe_exports, {
21
+ BonehFranklinBLS12381Services: () => BonehFranklinBLS12381Services,
22
+ DST_POP: () => DST_POP,
23
+ IBEServers: () => IBEServers,
24
+ decryptRandomness: () => decryptRandomness,
25
+ verifyNonce: () => verifyNonce,
26
+ verifyNonceWithLE: () => verifyNonceWithLE
27
+ });
28
+ module.exports = __toCommonJS(ibe_exports);
29
+ var import_bcs = require("@haneullabs/bcs");
30
+ var import_bls12381 = require("./bls12381.js");
31
+ var import_kdf = require("./kdf.js");
32
+ var import_utils = require("./utils.js");
33
+ var import_error = require("./error.js");
34
+ const DST_POP = new TextEncoder().encode("SUI-SEAL-IBE-BLS12381-POP-00");
35
+ class IBEServers {
36
+ constructor(objectIds) {
37
+ this.objectIds = objectIds;
38
+ }
39
+ }
40
+ class BonehFranklinBLS12381Services extends IBEServers {
41
+ constructor(services) {
42
+ super(services.map((service) => service.objectId));
43
+ this.publicKeys = services.map((service) => import_bls12381.G2Element.fromBytes(service.pk));
44
+ }
45
+ encryptBatched(id, shares, baseKey, threshold) {
46
+ if (this.publicKeys.length === 0 || this.publicKeys.length !== shares.length) {
47
+ throw new Error("Invalid public keys");
48
+ }
49
+ const [r, nonce, keys] = encapBatched(this.publicKeys, id);
50
+ const encryptedShares = shares.map(
51
+ ({ share, index }, i) => (0, import_utils.xor)(share, (0, import_kdf.kdf)(keys[i], nonce, id, this.objectIds[i], index))
52
+ );
53
+ const randomnessKey = (0, import_kdf.deriveKey)(
54
+ import_kdf.KeyPurpose.EncryptedRandomness,
55
+ baseKey,
56
+ encryptedShares,
57
+ threshold,
58
+ this.objectIds
59
+ );
60
+ const encryptedRandomness = (0, import_utils.xor)(randomnessKey, r.toBytes());
61
+ return {
62
+ BonehFranklinBLS12381: {
63
+ nonce: nonce.toBytes(),
64
+ encryptedShares,
65
+ encryptedRandomness
66
+ },
67
+ $kind: "BonehFranklinBLS12381"
68
+ };
69
+ }
70
+ /**
71
+ * Returns true if the user secret key is valid for the given public key and id.
72
+ * @param user_secret_key - The user secret key.
73
+ * @param id - The identity.
74
+ * @param public_key - The public key.
75
+ * @returns True if the user secret key is valid for the given public key and id.
76
+ */
77
+ static verifyUserSecretKey(userSecretKey, id, publicKey) {
78
+ const lhs = userSecretKey.pairing(import_bls12381.G2Element.generator());
79
+ const rhs = (0, import_kdf.hashToG1)((0, import_bcs.fromHex)(id)).pairing(publicKey);
80
+ return lhs.equals(rhs);
81
+ }
82
+ /**
83
+ * Identity-based decryption.
84
+ *
85
+ * @param nonce The encryption nonce.
86
+ * @param sk The user secret key.
87
+ * @param ciphertext The encrypted message.
88
+ * @param id The identity.
89
+ * @param [objectId, index] The object id and index of the share.
90
+ * @returns The decrypted message.
91
+ */
92
+ static decrypt(nonce, sk, ciphertext, id, [objectId, index]) {
93
+ return (0, import_utils.xor)(ciphertext, (0, import_kdf.kdf)(decap(nonce, sk), nonce, id, objectId, index));
94
+ }
95
+ /**
96
+ * Decrypt all shares and verify that the randomness was used to create the given nonce.
97
+ *
98
+ * @param randomness - The randomness.
99
+ * @param encryptedShares - The encrypted shares.
100
+ * @param services - The services.
101
+ * @param publicKeys - The public keys.
102
+ * @param nonce - The nonce.
103
+ * @param id - The id.
104
+ * @returns All decrypted shares.
105
+ */
106
+ static decryptAllSharesUsingRandomness(randomness, encryptedShares, services, publicKeys, nonce, id) {
107
+ if (publicKeys.length !== encryptedShares.length || publicKeys.length !== services.length) {
108
+ throw new Error("The number of public keys, encrypted shares and services must be the same");
109
+ }
110
+ let r;
111
+ try {
112
+ r = import_bls12381.Scalar.fromBytes(randomness);
113
+ } catch {
114
+ throw new import_error.InvalidCiphertextError("Invalid randomness");
115
+ }
116
+ const gid_r = (0, import_kdf.hashToG1)(id).multiply(r);
117
+ return services.map(([objectId, index], i) => {
118
+ return {
119
+ index,
120
+ share: (0, import_utils.xor)(
121
+ encryptedShares[i],
122
+ (0, import_kdf.kdf)(gid_r.pairing(publicKeys[i]), nonce, id, objectId, index)
123
+ )
124
+ };
125
+ });
126
+ }
127
+ }
128
+ function encapBatched(publicKeys, id) {
129
+ if (publicKeys.length === 0) {
130
+ throw new Error("No public keys provided");
131
+ }
132
+ const r = import_bls12381.Scalar.random();
133
+ const nonce = import_bls12381.G2Element.generator().multiply(r);
134
+ const gid_r = (0, import_kdf.hashToG1)(id).multiply(r);
135
+ return [r, nonce, publicKeys.map((public_key) => gid_r.pairing(public_key))];
136
+ }
137
+ function decap(nonce, usk) {
138
+ return usk.pairing(nonce);
139
+ }
140
+ function verifyNonce(nonce, randomness, useBE = true) {
141
+ try {
142
+ const r = decodeRandomness(randomness, useBE);
143
+ return import_bls12381.G2Element.generator().multiply(r).equals(nonce);
144
+ } catch {
145
+ throw new import_error.InvalidCiphertextError("Invalid randomness");
146
+ }
147
+ }
148
+ function decodeRandomness(bytes, useBE) {
149
+ if (useBE) {
150
+ return import_bls12381.Scalar.fromBytes(bytes);
151
+ } else {
152
+ return import_bls12381.Scalar.fromBytesLE(bytes);
153
+ }
154
+ }
155
+ function decryptRandomness(encryptedRandomness, randomnessKey) {
156
+ return (0, import_utils.xor)(encryptedRandomness, randomnessKey);
157
+ }
158
+ function verifyNonceWithLE(nonce, randomness) {
159
+ try {
160
+ if (verifyNonce(nonce, randomness, false)) {
161
+ return true;
162
+ }
163
+ } catch {
164
+ }
165
+ return verifyNonce(nonce, randomness, true);
166
+ }
167
+ //# sourceMappingURL=ibe.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ibe.ts"],
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromHex } from '@haneullabs/bcs';\n\nimport type { IBEEncryptions } from './bcs.js';\nimport type { G1Element, GTElement } from './bls12381.js';\nimport { G2Element, Scalar } from './bls12381.js';\nimport { deriveKey, hashToG1, kdf, KeyPurpose } from './kdf.js';\nimport type { KeyServer } from './key-server.js';\nimport { xor } from './utils.js';\nimport type { Share } from './shamir.js';\nimport { InvalidCiphertextError } from './error.js';\n\n/**\n * The domain separation tag for the signing proof of possession.\n */\nexport const DST_POP: Uint8Array = new TextEncoder().encode('SUI-SEAL-IBE-BLS12381-POP-00');\n\n/**\n * The interface for the key servers.\n */\nexport abstract class IBEServers {\n\tobjectIds: string[];\n\n\tconstructor(objectIds: string[]) {\n\t\tthis.objectIds = objectIds;\n\t}\n\n\t/**\n\t * Encrypt a batch of messages for the given identity.\n\t *\n\t * @param id The identity.\n\t * @param msgAndIndices The messages and the corresponding indices of the share being encrypted.\n\t * @returns The encrypted messages.\n\t */\n\tabstract encryptBatched(\n\t\tid: Uint8Array,\n\t\tshares: Share[],\n\t\tbaseKey: Uint8Array,\n\t\tthreshold: number,\n\t): typeof IBEEncryptions.$inferType;\n}\n\n/**\n * Identity-based encryption based on the Boneh-Franklin IBE scheme (https://eprint.iacr.org/2001/090).\n * Note that this implementation is of the \"BasicIdent\" protocol which on its own is not CCA secure, so this IBE implementation should not be used on its own.\n *\n * This object represents a set of key servers that can be used to encrypt messages for a given identity.\n */\nexport class BonehFranklinBLS12381Services extends IBEServers {\n\treadonly publicKeys: G2Element[];\n\n\tconstructor(services: KeyServer[]) {\n\t\tsuper(services.map((service) => service.objectId));\n\t\tthis.publicKeys = services.map((service) => G2Element.fromBytes(service.pk));\n\t}\n\n\tencryptBatched(\n\t\tid: Uint8Array,\n\t\tshares: Share[],\n\t\tbaseKey: Uint8Array,\n\t\tthreshold: number,\n\t): typeof IBEEncryptions.$inferType {\n\t\tif (this.publicKeys.length === 0 || this.publicKeys.length !== shares.length) {\n\t\t\tthrow new Error('Invalid public keys');\n\t\t}\n\t\tconst [r, nonce, keys] = encapBatched(this.publicKeys, id);\n\t\tconst encryptedShares = shares.map(({ share, index }, i) =>\n\t\t\txor(share, kdf(keys[i], nonce, id, this.objectIds[i], index)),\n\t\t);\n\t\tconst randomnessKey = deriveKey(\n\t\t\tKeyPurpose.EncryptedRandomness,\n\t\t\tbaseKey,\n\t\t\tencryptedShares,\n\t\t\tthreshold,\n\t\t\tthis.objectIds,\n\t\t);\n\t\tconst encryptedRandomness = xor(randomnessKey, r.toBytes());\n\n\t\treturn {\n\t\t\tBonehFranklinBLS12381: {\n\t\t\t\tnonce: nonce.toBytes(),\n\t\t\t\tencryptedShares,\n\t\t\t\tencryptedRandomness,\n\t\t\t},\n\t\t\t$kind: 'BonehFranklinBLS12381',\n\t\t};\n\t}\n\n\t/**\n\t * Returns true if the user secret key is valid for the given public key and id.\n\t * @param user_secret_key - The user secret key.\n\t * @param id - The identity.\n\t * @param public_key - The public key.\n\t * @returns True if the user secret key is valid for the given public key and id.\n\t */\n\tstatic verifyUserSecretKey(userSecretKey: G1Element, id: string, publicKey: G2Element): boolean {\n\t\tconst lhs = userSecretKey.pairing(G2Element.generator());\n\t\tconst rhs = hashToG1(fromHex(id)).pairing(publicKey);\n\t\treturn lhs.equals(rhs);\n\t}\n\n\t/**\n\t * Identity-based decryption.\n\t *\n\t * @param nonce The encryption nonce.\n\t * @param sk The user secret key.\n\t * @param ciphertext The encrypted message.\n\t * @param id The identity.\n\t * @param [objectId, index] The object id and index of the share.\n\t * @returns The decrypted message.\n\t */\n\tstatic decrypt(\n\t\tnonce: G2Element,\n\t\tsk: G1Element,\n\t\tciphertext: Uint8Array,\n\t\tid: Uint8Array,\n\t\t[objectId, index]: [string, number],\n\t): Uint8Array {\n\t\treturn xor(ciphertext, kdf(decap(nonce, sk), nonce, id, objectId, index));\n\t}\n\n\t/**\n\t * Decrypt all shares and verify that the randomness was used to create the given nonce.\n\t *\n\t * @param randomness - The randomness.\n\t * @param encryptedShares - The encrypted shares.\n\t * @param services - The services.\n\t * @param publicKeys - The public keys.\n\t * @param nonce - The nonce.\n\t * @param id - The id.\n\t * @returns All decrypted shares.\n\t */\n\tstatic decryptAllSharesUsingRandomness(\n\t\trandomness: Uint8Array,\n\t\tencryptedShares: Uint8Array[],\n\t\tservices: [string, number][],\n\t\tpublicKeys: G2Element[],\n\t\tnonce: G2Element,\n\t\tid: Uint8Array,\n\t): { index: number; share: Uint8Array }[] {\n\t\tif (publicKeys.length !== encryptedShares.length || publicKeys.length !== services.length) {\n\t\t\tthrow new Error('The number of public keys, encrypted shares and services must be the same');\n\t\t}\n\t\tlet r;\n\t\ttry {\n\t\t\tr = Scalar.fromBytes(randomness);\n\t\t} catch {\n\t\t\tthrow new InvalidCiphertextError('Invalid randomness');\n\t\t}\n\t\tconst gid_r = hashToG1(id).multiply(r);\n\t\treturn services.map(([objectId, index], i) => {\n\t\t\treturn {\n\t\t\t\tindex,\n\t\t\t\tshare: xor(\n\t\t\t\t\tencryptedShares[i],\n\t\t\t\t\tkdf(gid_r.pairing(publicKeys[i]), nonce, id, objectId, index),\n\t\t\t\t),\n\t\t\t};\n\t\t});\n\t}\n}\n\n/**\n * Batched identity-based key-encapsulation mechanism: encapsulate multiple keys for given identity using different key servers.\n *\n * @param publicKeys Public keys for a set of key servers.\n * @param id The identity used to encapsulate the keys.\n * @returns The randomness, a common nonce of the keys and a list of keys.\n */\nfunction encapBatched(publicKeys: G2Element[], id: Uint8Array): [Scalar, G2Element, GTElement[]] {\n\tif (publicKeys.length === 0) {\n\t\tthrow new Error('No public keys provided');\n\t}\n\tconst r = Scalar.random();\n\tconst nonce = G2Element.generator().multiply(r);\n\tconst gid_r = hashToG1(id).multiply(r);\n\treturn [r, nonce, publicKeys.map((public_key) => gid_r.pairing(public_key))];\n}\n\n/**\n * Decapsulate a key using a user secret key and the nonce.\n *\n * @param usk The user secret key.\n * @param nonce The nonce.\n * @returns The encapsulated key.\n */\nfunction decap(nonce: G2Element, usk: G1Element): GTElement {\n\treturn usk.pairing(nonce);\n}\n\n/**\n * Verify that the given randomness was used to crate the nonce.\n * Throws an error if the given randomness is invalid (not a BLS scalar).\n *\n * @param randomness - The randomness.\n * @param nonce - The nonce.\n * @param useBE - Flag to indicate if BE encoding is used for the randomness. Defaults to true.\n * @returns True if the randomness was used to create the nonce, false otherwise.\n */\nexport function verifyNonce(\n\tnonce: G2Element,\n\trandomness: Uint8Array,\n\tuseBE: boolean = true,\n): boolean {\n\ttry {\n\t\tconst r = decodeRandomness(randomness, useBE);\n\t\treturn G2Element.generator().multiply(r).equals(nonce);\n\t} catch {\n\t\tthrow new InvalidCiphertextError('Invalid randomness');\n\t}\n}\n\nfunction decodeRandomness(bytes: Uint8Array, useBE: boolean): Scalar {\n\tif (useBE) {\n\t\treturn Scalar.fromBytes(bytes);\n\t} else {\n\t\treturn Scalar.fromBytesLE(bytes);\n\t}\n}\n\n/**\n * Decrypt the randomness using a key.\n *\n * @param encrypted_randomness - The encrypted randomness.\n * @param derived_key - The derived key.\n * @returns The randomness. Returns both the scalar interpreted in big-endian and little-endian encoding.\n */\nexport function decryptRandomness(\n\tencryptedRandomness: Uint8Array,\n\trandomnessKey: Uint8Array,\n): Uint8Array {\n\treturn xor(encryptedRandomness, randomnessKey);\n}\n\n/**\n * Verify that the given randomness was used to crate the nonce.\n * Check using both big-endian and little-endian encoding of the randomness.\n *\n * Throws an error if the nonce check doesn't pass using LE encoding _and_ the randomness is invalid as a BE encoded scalar.\n *\n * @param randomness - The randomness.\n * @param nonce - The nonce.\n * @returns True if the randomness was used to create the nonce using either LE or BE encoding, false otherwise.\n */\nexport function verifyNonceWithLE(nonce: G2Element, randomness: Uint8Array): boolean {\n\ttry {\n\t\t// First try little-endian encoding\n\t\tif (verifyNonce(nonce, randomness, false)) {\n\t\t\treturn true;\n\t\t}\n\t} catch {\n\t\t// Ignore error and try big-endian encoding\n\t}\n\treturn verifyNonce(nonce, randomness, true);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,6 @@
1
+ export { EncryptedObject } from './bcs.js';
2
+ export { SealClient } from './client.js';
3
+ export { SessionKey, type ExportedSessionKey } from './session-key.js';
4
+ export * from './error.js';
5
+ export type { SealCompatibleClient, SealClientOptions, SealClientExtensionOptions, KeyServerConfig, EncryptOptions, DecryptOptions, FetchKeysOptions, GetDerivedKeysOptions, } from './types.js';
6
+ export { DemType } from './encrypt.js';
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
+ DemType: () => import_encrypt.DemType,
23
+ EncryptedObject: () => import_bcs.EncryptedObject,
24
+ SealClient: () => import_client.SealClient,
25
+ SessionKey: () => import_session_key.SessionKey
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var import_bcs = require("./bcs.js");
29
+ var import_client = require("./client.js");
30
+ var import_session_key = require("./session-key.js");
31
+ __reExport(index_exports, require("./error.js"), module.exports);
32
+ var import_encrypt = require("./encrypt.js");
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/index.ts"],
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nexport { EncryptedObject } from './bcs.js';\nexport { SealClient } from './client.js';\nexport { SessionKey, type ExportedSessionKey } from './session-key.js';\nexport * from './error.js';\nexport type {\n\tSealCompatibleClient,\n\tSealClientOptions,\n\tSealClientExtensionOptions,\n\tKeyServerConfig,\n\tEncryptOptions,\n\tDecryptOptions,\n\tFetchKeysOptions,\n\tGetDerivedKeysOptions,\n} from './types.js';\nexport { DemType } from './encrypt.js';\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAAgC;AAChC,oBAA2B;AAC3B,yBAAoD;AACpD,0BAAc,uBANd;AAiBA,qBAAwB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,30 @@
1
+ import { G1Element } from './bls12381.js';
2
+ import type { G2Element, GTElement } from './bls12381.js';
3
+ /**
4
+ * Hash an id to a G1Element.
5
+ *
6
+ * @param id The id to hash.
7
+ * @returns The G1Element.
8
+ */
9
+ export declare function hashToG1(id: Uint8Array): G1Element;
10
+ /**
11
+ * The default key derivation function.
12
+ *
13
+ * @returns The derived key.
14
+ */
15
+ export declare function kdf(element: GTElement, nonce: G2Element, id: Uint8Array, objectId: string, index: number): Uint8Array;
16
+ export declare enum KeyPurpose {
17
+ EncryptedRandomness = 0,
18
+ DEM = 1
19
+ }
20
+ /**
21
+ * Derive a key from a base key and a list of encrypted shares.
22
+ *
23
+ * @param purpose The purpose of the key.
24
+ * @param baseKey The base key.
25
+ * @param encryptedShares The encrypted shares.
26
+ * @param threshold The threshold.
27
+ * @param keyServers The object ids of the key servers.
28
+ * @returns The derived key.
29
+ */
30
+ export declare function deriveKey(purpose: KeyPurpose, baseKey: Uint8Array, encryptedShares: Uint8Array[], threshold: number, keyServers: string[]): Uint8Array;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var kdf_exports = {};
20
+ __export(kdf_exports, {
21
+ KeyPurpose: () => KeyPurpose,
22
+ deriveKey: () => deriveKey,
23
+ hashToG1: () => hashToG1,
24
+ kdf: () => kdf
25
+ });
26
+ module.exports = __toCommonJS(kdf_exports);
27
+ var import_bcs = require("@haneullabs/bcs");
28
+ var import_sha3 = require("@noble/hashes/sha3");
29
+ var import_bls12381 = require("./bls12381.js");
30
+ var import_utils = require("./utils.js");
31
+ const DST = new TextEncoder().encode("SUI-SEAL-IBE-BLS12381-00");
32
+ const KDF_DST = new TextEncoder().encode("SUI-SEAL-IBE-BLS12381-H2-00");
33
+ const DERIVE_KEY_DST = new TextEncoder().encode("SUI-SEAL-IBE-BLS12381-H3-00");
34
+ function hashToG1(id) {
35
+ return import_bls12381.G1Element.hashToCurve((0, import_utils.flatten)([DST, id]));
36
+ }
37
+ function kdf(element, nonce, id, objectId, index) {
38
+ if (!Number.isInteger(index) || index < 0 || index > import_utils.MAX_U8) {
39
+ throw new Error(`Invalid index ${index}`);
40
+ }
41
+ const objectIdBytes = (0, import_bcs.fromHex)(objectId);
42
+ if (objectIdBytes.length !== import_utils.HANEUL_ADDRESS_LENGTH) {
43
+ throw new Error(`Invalid object id ${objectId}`);
44
+ }
45
+ const hash = import_sha3.sha3_256.create();
46
+ hash.update(KDF_DST);
47
+ hash.update(element.toBytes());
48
+ hash.update(nonce.toBytes());
49
+ hash.update(hashToG1(id).toBytes());
50
+ hash.update(objectIdBytes);
51
+ hash.update(new Uint8Array([index]));
52
+ return hash.digest();
53
+ }
54
+ var KeyPurpose = /* @__PURE__ */ ((KeyPurpose2) => {
55
+ KeyPurpose2[KeyPurpose2["EncryptedRandomness"] = 0] = "EncryptedRandomness";
56
+ KeyPurpose2[KeyPurpose2["DEM"] = 1] = "DEM";
57
+ return KeyPurpose2;
58
+ })(KeyPurpose || {});
59
+ function tag(purpose) {
60
+ switch (purpose) {
61
+ case 0 /* EncryptedRandomness */:
62
+ return new Uint8Array([0]);
63
+ case 1 /* DEM */:
64
+ return new Uint8Array([1]);
65
+ default:
66
+ throw new Error(`Invalid key purpose ${purpose}`);
67
+ }
68
+ }
69
+ function deriveKey(purpose, baseKey, encryptedShares, threshold, keyServers) {
70
+ if (!Number.isInteger(threshold) || threshold <= 0 || threshold > import_utils.MAX_U8) {
71
+ throw new Error(`Invalid threshold ${threshold}`);
72
+ }
73
+ if (encryptedShares.length !== keyServers.length) {
74
+ throw new Error(
75
+ `Mismatched shares ${encryptedShares.length} and key servers ${keyServers.length}`
76
+ );
77
+ }
78
+ const keyServerBytes = keyServers.map((keyServer) => (0, import_bcs.fromHex)(keyServer));
79
+ if (keyServerBytes.some((keyServer) => keyServer.length !== import_utils.HANEUL_ADDRESS_LENGTH)) {
80
+ throw new Error(`Invalid key servers ${keyServers}`);
81
+ }
82
+ if (encryptedShares.some((share) => share.length !== import_utils.ENCRYPTED_SHARE_LENGTH)) {
83
+ throw new Error(`Invalid encrypted shares ${encryptedShares}`);
84
+ }
85
+ if (baseKey.length !== import_utils.KEY_LENGTH) {
86
+ throw new Error(`Invalid base key ${baseKey}`);
87
+ }
88
+ const hash = import_sha3.sha3_256.create();
89
+ hash.update(DERIVE_KEY_DST);
90
+ hash.update(baseKey);
91
+ hash.update(tag(purpose));
92
+ hash.update(new Uint8Array([threshold]));
93
+ encryptedShares.forEach((share) => hash.update(share));
94
+ keyServerBytes.forEach((keyServer) => hash.update(keyServer));
95
+ return hash.digest();
96
+ }
97
+ //# sourceMappingURL=kdf.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/kdf.ts"],
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromHex } from '@haneullabs/bcs';\nimport { sha3_256 } from '@noble/hashes/sha3';\n\nimport { G1Element } from './bls12381.js';\nimport type { G2Element, GTElement } from './bls12381.js';\nimport {\n\tENCRYPTED_SHARE_LENGTH,\n\tflatten,\n\tKEY_LENGTH,\n\tMAX_U8,\n\tHANEUL_ADDRESS_LENGTH,\n} from './utils.js';\n\n/**\n * The domain separation tag for the hash-to-group function.\n */\nconst DST: Uint8Array = new TextEncoder().encode('SUI-SEAL-IBE-BLS12381-00');\nconst KDF_DST = new TextEncoder().encode('SUI-SEAL-IBE-BLS12381-H2-00');\nconst DERIVE_KEY_DST = new TextEncoder().encode('SUI-SEAL-IBE-BLS12381-H3-00');\n\n/**\n * Hash an id to a G1Element.\n *\n * @param id The id to hash.\n * @returns The G1Element.\n */\nexport function hashToG1(id: Uint8Array): G1Element {\n\treturn G1Element.hashToCurve(flatten([DST, id]));\n}\n\n/**\n * The default key derivation function.\n *\n * @returns The derived key.\n */\nexport function kdf(\n\telement: GTElement,\n\tnonce: G2Element,\n\tid: Uint8Array,\n\tobjectId: string,\n\tindex: number,\n): Uint8Array {\n\tif (!Number.isInteger(index) || index < 0 || index > MAX_U8) {\n\t\tthrow new Error(`Invalid index ${index}`);\n\t}\n\tconst objectIdBytes = fromHex(objectId);\n\tif (objectIdBytes.length !== HANEUL_ADDRESS_LENGTH) {\n\t\tthrow new Error(`Invalid object id ${objectId}`);\n\t}\n\tconst hash = sha3_256.create();\n\thash.update(KDF_DST);\n\thash.update(element.toBytes());\n\thash.update(nonce.toBytes());\n\thash.update(hashToG1(id).toBytes());\n\thash.update(objectIdBytes);\n\thash.update(new Uint8Array([index])); // this is safe because index < 256.\n\treturn hash.digest();\n}\n\nexport enum KeyPurpose {\n\tEncryptedRandomness,\n\tDEM,\n}\n\nfunction tag(purpose: KeyPurpose): Uint8Array {\n\tswitch (purpose) {\n\t\tcase KeyPurpose.EncryptedRandomness:\n\t\t\treturn new Uint8Array([0]);\n\t\tcase KeyPurpose.DEM:\n\t\t\treturn new Uint8Array([1]);\n\t\tdefault:\n\t\t\tthrow new Error(`Invalid key purpose ${purpose}`);\n\t}\n}\n\n/**\n * Derive a key from a base key and a list of encrypted shares.\n *\n * @param purpose The purpose of the key.\n * @param baseKey The base key.\n * @param encryptedShares The encrypted shares.\n * @param threshold The threshold.\n * @param keyServers The object ids of the key servers.\n * @returns The derived key.\n */\nexport function deriveKey(\n\tpurpose: KeyPurpose,\n\tbaseKey: Uint8Array,\n\tencryptedShares: Uint8Array[],\n\tthreshold: number,\n\tkeyServers: string[],\n): Uint8Array {\n\tif (!Number.isInteger(threshold) || threshold <= 0 || threshold > MAX_U8) {\n\t\tthrow new Error(`Invalid threshold ${threshold}`);\n\t}\n\n\tif (encryptedShares.length !== keyServers.length) {\n\t\tthrow new Error(\n\t\t\t`Mismatched shares ${encryptedShares.length} and key servers ${keyServers.length}`,\n\t\t);\n\t}\n\tconst keyServerBytes = keyServers.map((keyServer) => fromHex(keyServer));\n\tif (keyServerBytes.some((keyServer) => keyServer.length !== HANEUL_ADDRESS_LENGTH)) {\n\t\tthrow new Error(`Invalid key servers ${keyServers}`);\n\t}\n\tif (encryptedShares.some((share) => share.length !== ENCRYPTED_SHARE_LENGTH)) {\n\t\tthrow new Error(`Invalid encrypted shares ${encryptedShares}`);\n\t}\n\n\tif (baseKey.length !== KEY_LENGTH) {\n\t\tthrow new Error(`Invalid base key ${baseKey}`);\n\t}\n\n\tconst hash = sha3_256.create();\n\thash.update(DERIVE_KEY_DST);\n\thash.update(baseKey);\n\thash.update(tag(purpose));\n\thash.update(new Uint8Array([threshold]));\n\tencryptedShares.forEach((share) => hash.update(share));\n\tkeyServerBytes.forEach((keyServer) => hash.update(keyServer));\n\treturn hash.digest();\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAAwB;AACxB,kBAAyB;AAEzB,sBAA0B;AAE1B,mBAMO;AAKP,MAAM,MAAkB,IAAI,YAAY,EAAE,OAAO,0BAA0B;AAC3E,MAAM,UAAU,IAAI,YAAY,EAAE,OAAO,6BAA6B;AACtE,MAAM,iBAAiB,IAAI,YAAY,EAAE,OAAO,6BAA6B;AAQtE,SAAS,SAAS,IAA2B;AACnD,SAAO,0BAAU,gBAAY,sBAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;AAChD;AAOO,SAAS,IACf,SACA,OACA,IACA,UACA,OACa;AACb,MAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,qBAAQ;AAC5D,UAAM,IAAI,MAAM,iBAAiB,KAAK,EAAE;AAAA,EACzC;AACA,QAAM,oBAAgB,oBAAQ,QAAQ;AACtC,MAAI,cAAc,WAAW,oCAAuB;AACnD,UAAM,IAAI,MAAM,qBAAqB,QAAQ,EAAE;AAAA,EAChD;AACA,QAAM,OAAO,qBAAS,OAAO;AAC7B,OAAK,OAAO,OAAO;AACnB,OAAK,OAAO,QAAQ,QAAQ,CAAC;AAC7B,OAAK,OAAO,MAAM,QAAQ,CAAC;AAC3B,OAAK,OAAO,SAAS,EAAE,EAAE,QAAQ,CAAC;AAClC,OAAK,OAAO,aAAa;AACzB,OAAK,OAAO,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;AACnC,SAAO,KAAK,OAAO;AACpB;AAEO,IAAK,aAAL,kBAAKA,gBAAL;AACN,EAAAA,wBAAA;AACA,EAAAA,wBAAA;AAFW,SAAAA;AAAA,GAAA;AAKZ,SAAS,IAAI,SAAiC;AAC7C,UAAQ,SAAS;AAAA,IAChB,KAAK;AACJ,aAAO,IAAI,WAAW,CAAC,CAAC,CAAC;AAAA,IAC1B,KAAK;AACJ,aAAO,IAAI,WAAW,CAAC,CAAC,CAAC;AAAA,IAC1B;AACC,YAAM,IAAI,MAAM,uBAAuB,OAAO,EAAE;AAAA,EAClD;AACD;AAYO,SAAS,UACf,SACA,SACA,iBACA,WACA,YACa;AACb,MAAI,CAAC,OAAO,UAAU,SAAS,KAAK,aAAa,KAAK,YAAY,qBAAQ;AACzE,UAAM,IAAI,MAAM,qBAAqB,SAAS,EAAE;AAAA,EACjD;AAEA,MAAI,gBAAgB,WAAW,WAAW,QAAQ;AACjD,UAAM,IAAI;AAAA,MACT,qBAAqB,gBAAgB,MAAM,oBAAoB,WAAW,MAAM;AAAA,IACjF;AAAA,EACD;AACA,QAAM,iBAAiB,WAAW,IAAI,CAAC,kBAAc,oBAAQ,SAAS,CAAC;AACvE,MAAI,eAAe,KAAK,CAAC,cAAc,UAAU,WAAW,kCAAqB,GAAG;AACnF,UAAM,IAAI,MAAM,uBAAuB,UAAU,EAAE;AAAA,EACpD;AACA,MAAI,gBAAgB,KAAK,CAAC,UAAU,MAAM,WAAW,mCAAsB,GAAG;AAC7E,UAAM,IAAI,MAAM,4BAA4B,eAAe,EAAE;AAAA,EAC9D;AAEA,MAAI,QAAQ,WAAW,yBAAY;AAClC,UAAM,IAAI,MAAM,oBAAoB,OAAO,EAAE;AAAA,EAC9C;AAEA,QAAM,OAAO,qBAAS,OAAO;AAC7B,OAAK,OAAO,cAAc;AAC1B,OAAK,OAAO,OAAO;AACnB,OAAK,OAAO,IAAI,OAAO,CAAC;AACxB,OAAK,OAAO,IAAI,WAAW,CAAC,SAAS,CAAC,CAAC;AACvC,kBAAgB,QAAQ,CAAC,UAAU,KAAK,OAAO,KAAK,CAAC;AACrD,iBAAe,QAAQ,CAAC,cAAc,KAAK,OAAO,SAAS,CAAC;AAC5D,SAAO,KAAK,OAAO;AACpB;",
6
+ "names": ["KeyPurpose"]
7
+ }
@@ -0,0 +1,98 @@
1
+ import type { SealCompatibleClient } from './types.js';
2
+ import type { G1Element } from './bls12381.js';
3
+ import { Version } from './utils.js';
4
+ import type { Certificate } from './session-key.js';
5
+ export type KeyServer = {
6
+ objectId: string;
7
+ name: string;
8
+ url: string;
9
+ keyType: KeyServerType;
10
+ pk: Uint8Array<ArrayBuffer>;
11
+ };
12
+ export declare enum KeyServerType {
13
+ BonehFranklinBLS12381 = 0
14
+ }
15
+ export declare const SERVER_VERSION_REQUIREMENT: Version;
16
+ /**
17
+ * Given a list of key server object IDs, returns a list of SealKeyServer
18
+ * from onchain state containing name, objectId, URL and pk.
19
+ *
20
+ * @param objectIds - The key server object IDs.
21
+ * @param client - The HaneulClient to use.
22
+ * @returns - An array of SealKeyServer.
23
+ */
24
+ export declare function retrieveKeyServers({ objectIds, client, }: {
25
+ objectIds: string[];
26
+ client: SealCompatibleClient;
27
+ }): Promise<KeyServer[]>;
28
+ /**
29
+ * Given a KeyServer, fetch the proof of possession (PoP) from the URL and verify it
30
+ * against the pubkey. This should be used only rarely when the dapp uses a dynamic
31
+ * set of key servers.
32
+ *
33
+ * @param server - The KeyServer to verify.
34
+ * @returns - True if the key server is valid, false otherwise.
35
+ */
36
+ export declare function verifyKeyServer(server: KeyServer, timeout: number, apiKeyName?: string, apiKey?: string): Promise<boolean>;
37
+ /**
38
+ * Verify the key server version. Throws an `InvalidKeyServerError` if the version is not supported.
39
+ *
40
+ * @param response - The response from the key server.
41
+ */
42
+ export declare function verifyKeyServerVersion(response: Response): void;
43
+ export interface DerivedKey {
44
+ toString(): string;
45
+ }
46
+ /**
47
+ * A user secret key for the Boneh-Franklin BLS12381 scheme.
48
+ * This is a wrapper around the G1Element type.
49
+ */
50
+ export declare class BonehFranklinBLS12381DerivedKey implements DerivedKey {
51
+ key: G1Element;
52
+ representation: string;
53
+ constructor(key: G1Element);
54
+ toString(): string;
55
+ }
56
+ /**
57
+ * Options for fetching keys from the key server.
58
+ */
59
+ export interface FetchKeysOptions {
60
+ /** The URL of the key server. */
61
+ url: string;
62
+ /** The Base64 string of request signature. */
63
+ requestSignature: string;
64
+ /** The transaction bytes. */
65
+ transactionBytes: Uint8Array;
66
+ /** The ephemeral secret key. */
67
+ encKey: Uint8Array<ArrayBuffer>;
68
+ /** The ephemeral public key. */
69
+ encKeyPk: Uint8Array<ArrayBuffer>;
70
+ /** The ephemeral verification key. */
71
+ encVerificationKey: Uint8Array;
72
+ /** The certificate. */
73
+ certificate: Certificate;
74
+ /** Request timeout in milliseconds. */
75
+ timeout: number;
76
+ /** Optional API key name. */
77
+ apiKeyName?: string;
78
+ /** Optional API key. */
79
+ apiKey?: string;
80
+ /** Optional abort signal for cancellation. */
81
+ signal?: AbortSignal;
82
+ }
83
+ /**
84
+ * Helper function to request all keys from URL with requestSig, txBytes, ephemeral pubkey.
85
+ * Then decrypt the Seal key with ephemeral secret key. Returns a list decryption keys with
86
+ * their full IDs.
87
+ *
88
+ * @param url - The URL of the key server.
89
+ * @param requestSig - The Base64 string of request signature.
90
+ * @param txBytes - The transaction bytes.
91
+ * @param encKey - The ephemeral secret key.
92
+ * @param certificate - The certificate.
93
+ * @returns - A list of full ID and the decrypted key.
94
+ */
95
+ export declare function fetchKeysForAllIds({ url, requestSignature, transactionBytes, encKey, encKeyPk, encVerificationKey, certificate, timeout, apiKeyName, apiKey, signal, }: FetchKeysOptions): Promise<{
96
+ fullId: string;
97
+ key: Uint8Array<ArrayBuffer>;
98
+ }[]>;
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var key_server_exports = {};
20
+ __export(key_server_exports, {
21
+ BonehFranklinBLS12381DerivedKey: () => BonehFranklinBLS12381DerivedKey,
22
+ KeyServerType: () => KeyServerType,
23
+ SERVER_VERSION_REQUIREMENT: () => SERVER_VERSION_REQUIREMENT,
24
+ fetchKeysForAllIds: () => fetchKeysForAllIds,
25
+ retrieveKeyServers: () => retrieveKeyServers,
26
+ verifyKeyServer: () => verifyKeyServer,
27
+ verifyKeyServerVersion: () => verifyKeyServerVersion
28
+ });
29
+ module.exports = __toCommonJS(key_server_exports);
30
+ var import_bcs = require("@haneullabs/bcs");
31
+ var import_bls12_381 = require("@noble/curves/bls12-381");
32
+ var import_bcs2 = require("./bcs.js");
33
+ var import_error = require("./error.js");
34
+ var import_ibe = require("./ibe.js");
35
+ var import_version = require("./version.js");
36
+ var import_utils = require("./utils.js");
37
+ var import_elgamal = require("./elgamal.js");
38
+ const EXPECTED_SERVER_VERSION = 1;
39
+ var KeyServerType = /* @__PURE__ */ ((KeyServerType2) => {
40
+ KeyServerType2[KeyServerType2["BonehFranklinBLS12381"] = 0] = "BonehFranklinBLS12381";
41
+ return KeyServerType2;
42
+ })(KeyServerType || {});
43
+ const SERVER_VERSION_REQUIREMENT = new import_utils.Version("0.4.1");
44
+ async function retrieveKeyServers({
45
+ objectIds,
46
+ client
47
+ }) {
48
+ return await Promise.all(
49
+ objectIds.map(async (objectId) => {
50
+ const res = await client.core.getObject({
51
+ objectId
52
+ });
53
+ const ks = import_bcs2.KeyServerMove.parse(await res.object.content);
54
+ if (EXPECTED_SERVER_VERSION < Number(ks.firstVersion) || EXPECTED_SERVER_VERSION > Number(ks.lastVersion)) {
55
+ throw new import_error.InvalidKeyServerVersionError(
56
+ `Key server ${objectId} supports versions between ${ks.firstVersion} and ${ks.lastVersion} (inclusive), but SDK expects version ${EXPECTED_SERVER_VERSION}`
57
+ );
58
+ }
59
+ const resVersionedKs = await client.core.getDynamicField({
60
+ parentId: objectId,
61
+ name: {
62
+ type: "u64",
63
+ bcs: import_bcs.bcs.u64().serialize(EXPECTED_SERVER_VERSION).toBytes()
64
+ }
65
+ });
66
+ const ksVersioned = import_bcs2.KeyServerMoveV1.parse(resVersionedKs.dynamicField.value.bcs);
67
+ if (ksVersioned.keyType !== 0 /* BonehFranklinBLS12381 */) {
68
+ throw new import_error.InvalidKeyServerError(
69
+ `Server ${objectId} has invalid key type: ${ksVersioned.keyType}`
70
+ );
71
+ }
72
+ return {
73
+ objectId,
74
+ name: ksVersioned.name,
75
+ url: ksVersioned.url,
76
+ keyType: ksVersioned.keyType,
77
+ pk: new Uint8Array(ksVersioned.pk)
78
+ };
79
+ })
80
+ );
81
+ }
82
+ async function verifyKeyServer(server, timeout, apiKeyName, apiKey) {
83
+ const requestId = crypto.randomUUID();
84
+ const response = await fetch(server.url + "/v1/service?service_id=" + server.objectId, {
85
+ method: "GET",
86
+ headers: {
87
+ "Content-Type": "application/json",
88
+ "Request-Id": requestId,
89
+ "Client-Sdk-Type": "typescript",
90
+ "Client-Sdk-Version": import_version.PACKAGE_VERSION,
91
+ ...apiKeyName && apiKey ? { [apiKeyName]: apiKey } : {}
92
+ },
93
+ signal: AbortSignal.timeout(timeout)
94
+ });
95
+ await import_error.SealAPIError.assertResponse(response, requestId);
96
+ verifyKeyServerVersion(response);
97
+ const serviceResponse = await response.json();
98
+ if (serviceResponse.service_id !== server.objectId) {
99
+ return false;
100
+ }
101
+ const fullMsg = (0, import_utils.flatten)([import_ibe.DST_POP, server.pk, (0, import_bcs.fromHex)(server.objectId)]);
102
+ return import_bls12_381.bls12_381.verifyShortSignature((0, import_bcs.fromBase64)(serviceResponse.pop), fullMsg, server.pk);
103
+ }
104
+ function verifyKeyServerVersion(response) {
105
+ const keyServerVersion = response.headers.get("X-KeyServer-Version");
106
+ if (keyServerVersion == null) {
107
+ throw new import_error.InvalidKeyServerVersionError("Key server version not found");
108
+ }
109
+ if (new import_utils.Version(keyServerVersion).older_than(SERVER_VERSION_REQUIREMENT)) {
110
+ throw new import_error.InvalidKeyServerVersionError(
111
+ `Key server version ${keyServerVersion} is not supported`
112
+ );
113
+ }
114
+ }
115
+ class BonehFranklinBLS12381DerivedKey {
116
+ constructor(key) {
117
+ this.key = key;
118
+ this.representation = (0, import_bcs.toHex)(key.toBytes());
119
+ }
120
+ toString() {
121
+ return this.representation;
122
+ }
123
+ }
124
+ async function fetchKeysForAllIds({
125
+ url,
126
+ requestSignature,
127
+ transactionBytes,
128
+ encKey,
129
+ encKeyPk,
130
+ encVerificationKey,
131
+ certificate,
132
+ timeout,
133
+ apiKeyName,
134
+ apiKey,
135
+ signal
136
+ }) {
137
+ const body = {
138
+ ptb: (0, import_bcs.toBase64)(transactionBytes.slice(1)),
139
+ // removes the byte of the transaction type version
140
+ enc_key: (0, import_bcs.toBase64)(encKeyPk),
141
+ enc_verification_key: (0, import_bcs.toBase64)(encVerificationKey),
142
+ request_signature: requestSignature,
143
+ // already b64
144
+ certificate
145
+ };
146
+ const timeoutSignal = AbortSignal.timeout(timeout);
147
+ const combinedSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
148
+ const requestId = crypto.randomUUID();
149
+ const response = await fetch(url + "/v1/fetch_key", {
150
+ method: "POST",
151
+ headers: {
152
+ "Content-Type": "application/json",
153
+ "Request-Id": requestId,
154
+ "Client-Sdk-Type": "typescript",
155
+ "Client-Sdk-Version": import_version.PACKAGE_VERSION,
156
+ ...apiKeyName && apiKey ? { [apiKeyName]: apiKey } : {}
157
+ },
158
+ body: JSON.stringify(body),
159
+ signal: combinedSignal
160
+ });
161
+ await import_error.SealAPIError.assertResponse(response, requestId);
162
+ const resp = await response.json();
163
+ verifyKeyServerVersion(response);
164
+ return resp.decryption_keys.map(
165
+ (dk) => ({
166
+ fullId: (0, import_bcs.toHex)(dk.id),
167
+ key: (0, import_elgamal.elgamalDecrypt)(encKey, dk.encrypted_key.map(import_bcs.fromBase64))
168
+ })
169
+ );
170
+ }
171
+ //# sourceMappingURL=key-server.js.map