@mysten/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.
- package/CHANGELOG.md +13 -0
- package/README.md +4 -0
- package/dist/cjs/aes.d.ts +18 -0
- package/dist/cjs/aes.js +111 -0
- package/dist/cjs/aes.js.map +7 -0
- package/dist/cjs/bls12381.d.ts +37 -0
- package/dist/cjs/bls12381.js +110 -0
- package/dist/cjs/bls12381.js.map +7 -0
- package/dist/cjs/elgamal.d.ts +11 -0
- package/dist/cjs/elgamal.js +46 -0
- package/dist/cjs/elgamal.js.map +7 -0
- package/dist/cjs/encrypt.d.ts +24 -0
- package/dist/cjs/encrypt.js +88 -0
- package/dist/cjs/encrypt.js.map +7 -0
- package/dist/cjs/ibe.d.ts +67 -0
- package/dist/cjs/ibe.js +107 -0
- package/dist/cjs/ibe.js.map +7 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.js +37 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/kdf.d.ts +9 -0
- package/dist/cjs/kdf.js +29 -0
- package/dist/cjs/kdf.js.map +7 -0
- package/dist/cjs/key-server.d.ts +38 -0
- package/dist/cjs/key-server.js +98 -0
- package/dist/cjs/key-server.js.map +7 -0
- package/dist/cjs/key-store.d.ts +49 -0
- package/dist/cjs/key-store.js +203 -0
- package/dist/cjs/key-store.js.map +7 -0
- package/dist/cjs/package.json +5 -0
- package/dist/cjs/session-key.d.ts +36 -0
- package/dist/cjs/session-key.js +73 -0
- package/dist/cjs/session-key.js.map +7 -0
- package/dist/cjs/types.d.ts +86 -0
- package/dist/cjs/types.js +49 -0
- package/dist/cjs/types.js.map +7 -0
- package/dist/cjs/utils.d.ts +9 -0
- package/dist/cjs/utils.js +39 -0
- package/dist/cjs/utils.js.map +7 -0
- package/dist/esm/aes.d.ts +18 -0
- package/dist/esm/aes.js +91 -0
- package/dist/esm/aes.js.map +7 -0
- package/dist/esm/bls12381.d.ts +37 -0
- package/dist/esm/bls12381.js +90 -0
- package/dist/esm/bls12381.js.map +7 -0
- package/dist/esm/elgamal.d.ts +11 -0
- package/dist/esm/elgamal.js +26 -0
- package/dist/esm/elgamal.js.map +7 -0
- package/dist/esm/encrypt.d.ts +24 -0
- package/dist/esm/encrypt.js +68 -0
- package/dist/esm/encrypt.js.map +7 -0
- package/dist/esm/ibe.d.ts +67 -0
- package/dist/esm/ibe.js +87 -0
- package/dist/esm/ibe.js.map +7 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.js +17 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/kdf.d.ts +9 -0
- package/dist/esm/kdf.js +9 -0
- package/dist/esm/kdf.js.map +7 -0
- package/dist/esm/key-server.d.ts +38 -0
- package/dist/esm/key-server.js +78 -0
- package/dist/esm/key-server.js.map +7 -0
- package/dist/esm/key-store.d.ts +49 -0
- package/dist/esm/key-store.js +183 -0
- package/dist/esm/key-store.js.map +7 -0
- package/dist/esm/package.json +5 -0
- package/dist/esm/session-key.d.ts +36 -0
- package/dist/esm/session-key.js +53 -0
- package/dist/esm/session-key.js.map +7 -0
- package/dist/esm/types.d.ts +86 -0
- package/dist/esm/types.js +29 -0
- package/dist/esm/types.js.map +7 -0
- package/dist/esm/utils.d.ts +9 -0
- package/dist/esm/utils.js +19 -0
- package/dist/esm/utils.js.map +7 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +58 -0
package/dist/cjs/ibe.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
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: () => DST,
|
|
23
|
+
DST_POP: () => DST_POP,
|
|
24
|
+
IBEServers: () => IBEServers
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(ibe_exports);
|
|
27
|
+
var import_bls12381 = require("./bls12381.js");
|
|
28
|
+
var import_kdf = require("./kdf.js");
|
|
29
|
+
var import_utils = require("./utils.js");
|
|
30
|
+
const DST = new TextEncoder().encode("SUI-SEAL-IBE-BLS12381-00");
|
|
31
|
+
const DST_POP = new TextEncoder().encode("SUI-SEAL-IBE-BLS12381-00-POP");
|
|
32
|
+
class IBEServers {
|
|
33
|
+
constructor(object_ids) {
|
|
34
|
+
this.object_ids = object_ids;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The object IDs of the key servers.
|
|
38
|
+
*/
|
|
39
|
+
getObjectIds() {
|
|
40
|
+
return this.object_ids;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The number of key servers.
|
|
44
|
+
*/
|
|
45
|
+
size() {
|
|
46
|
+
return this.object_ids.length;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
class BonehFranklinBLS12381Services extends IBEServers {
|
|
50
|
+
constructor(services) {
|
|
51
|
+
super(services.map((service) => service.objectId));
|
|
52
|
+
this.public_keys = services.map((service) => import_bls12381.G2Element.fromBytes(service.pk));
|
|
53
|
+
}
|
|
54
|
+
encryptBatched(id, msg_and_infos) {
|
|
55
|
+
if (this.public_keys.length === 0 || this.public_keys.length !== msg_and_infos.length) {
|
|
56
|
+
throw new Error("Invalid input");
|
|
57
|
+
}
|
|
58
|
+
const [nonce, keys] = encapBatched(this.public_keys, id);
|
|
59
|
+
const encrypted_msgs = msg_and_infos.map(
|
|
60
|
+
(msg_and_info, i) => (0, import_utils.xor)(msg_and_info.msg, (0, import_kdf.kdf)(keys[i], msg_and_info.info))
|
|
61
|
+
);
|
|
62
|
+
return {
|
|
63
|
+
BonehFranklinBLS12381: {
|
|
64
|
+
encapsulation: nonce.toBytes(),
|
|
65
|
+
shares: encrypted_msgs
|
|
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(user_secret_key, id, public_key) {
|
|
78
|
+
const lhs = user_secret_key.pairing(import_bls12381.G2Element.generator()).toBytes();
|
|
79
|
+
const rhs = import_bls12381.G1Element.hashToCurve(id).pairing(public_key).toBytes();
|
|
80
|
+
return lhs.length === rhs.length && lhs.every((value, index) => value === rhs[index]);
|
|
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 info An info parameter also included in the KDF.
|
|
89
|
+
* @returns The decrypted message.
|
|
90
|
+
*/
|
|
91
|
+
static decrypt(nonce, sk, ciphertext, info) {
|
|
92
|
+
return (0, import_utils.xor)(ciphertext, (0, import_kdf.kdf)(decap(nonce, sk), info));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function encapBatched(public_keys, id) {
|
|
96
|
+
if (public_keys.length === 0) {
|
|
97
|
+
throw new Error("Invalid input");
|
|
98
|
+
}
|
|
99
|
+
const r = import_bls12381.Scalar.random();
|
|
100
|
+
const nonce = import_bls12381.G2Element.generator().multiply(r);
|
|
101
|
+
const gid = import_bls12381.G1Element.hashToCurve(id).multiply(r);
|
|
102
|
+
return [nonce, public_keys.map((public_key) => gid.pairing(public_key))];
|
|
103
|
+
}
|
|
104
|
+
function decap(nonce, usk) {
|
|
105
|
+
return usk.pairing(nonce);
|
|
106
|
+
}
|
|
107
|
+
//# 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 type { GTElement } from './bls12381.js';\nimport { G1Element, G2Element, Scalar } from './bls12381.js';\nimport { kdf } from './kdf.js';\nimport type { KeyServer } from './key-server.js';\nimport type { IBEEncryptionsType } from './types.js';\nimport { xor } from './utils.js';\n\n/**\n * The domain separation tag for the hash-to-group function.\n */\nexport const DST: Uint8Array = new TextEncoder().encode('SUI-SEAL-IBE-BLS12381-00');\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-00-POP');\n\n/**\n * The interface for the key servers.\n */\nexport abstract class IBEServers {\n\tprotected readonly object_ids: Uint8Array[];\n\n\tprotected constructor(object_ids: Uint8Array[]) {\n\t\tthis.object_ids = object_ids;\n\t}\n\n\t/**\n\t * The object IDs of the key servers.\n\t */\n\tgetObjectIds(): Uint8Array[] {\n\t\treturn this.object_ids;\n\t}\n\n\t/**\n\t * The number of key servers.\n\t */\n\tsize(): number {\n\t\treturn this.object_ids.length;\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 msg_and_infos The messages and an additional info parameter which will be included in the KDF.\n\t * @returns The encrypted messages.\n\t */\n\tabstract encryptBatched(\n\t\tid: Uint8Array,\n\t\tmsg_and_infos: { msg: Uint8Array; info: Uint8Array }[],\n\t): IBEEncryptionsType;\n}\n\n/**\n * Identity-based encryption based on the Boneh-Franklin IBE scheme.\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 public_keys: G2Element[];\n\n\tconstructor(services: KeyServer[]) {\n\t\tsuper(services.map((service) => service.objectId));\n\t\tthis.public_keys = services.map((service) => G2Element.fromBytes(service.pk));\n\t}\n\n\tencryptBatched(\n\t\tid: Uint8Array,\n\t\tmsg_and_infos: { msg: Uint8Array; info: Uint8Array }[],\n\t): IBEEncryptionsType {\n\t\tif (this.public_keys.length === 0 || this.public_keys.length !== msg_and_infos.length) {\n\t\t\tthrow new Error('Invalid input');\n\t\t}\n\t\tconst [nonce, keys] = encapBatched(this.public_keys, id);\n\t\tconst encrypted_msgs = msg_and_infos.map((msg_and_info, i) =>\n\t\t\txor(msg_and_info.msg, kdf(keys[i], msg_and_info.info)),\n\t\t);\n\n\t\treturn {\n\t\t\tBonehFranklinBLS12381: {\n\t\t\t\tencapsulation: nonce.toBytes(),\n\t\t\t\tshares: encrypted_msgs,\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(\n\t\tuser_secret_key: G1Element,\n\t\tid: Uint8Array,\n\t\tpublic_key: G2Element,\n\t): boolean {\n\t\tconst lhs = user_secret_key.pairing(G2Element.generator()).toBytes();\n\t\tconst rhs = G1Element.hashToCurve(id).pairing(public_key).toBytes();\n\t\treturn lhs.length === rhs.length && lhs.every((value, index) => value === rhs[index]);\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 info An info parameter also included in the KDF.\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\tinfo: Uint8Array,\n\t): Uint8Array {\n\t\treturn xor(ciphertext, kdf(decap(nonce, sk), info));\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 public_keys Public keys for a set of key servers.\n * @param id The identity used to encapsulate the keys.\n * @returns A common nonce of the keys and a list of keys, 32 bytes each.\n */\nfunction encapBatched(public_keys: G2Element[], id: Uint8Array): [G2Element, GTElement[]] {\n\tif (public_keys.length === 0) {\n\t\tthrow new Error('Invalid input');\n\t}\n\tconst r = Scalar.random();\n\tconst nonce = G2Element.generator().multiply(r);\n\tconst gid = G1Element.hashToCurve(id).multiply(r);\n\treturn [nonce, public_keys.map((public_key) => gid.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"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAA6C;AAC7C,iBAAoB;AAGpB,mBAAoB;AAKb,MAAM,MAAkB,IAAI,YAAY,EAAE,OAAO,0BAA0B;AAK3E,MAAM,UAAsB,IAAI,YAAY,EAAE,OAAO,8BAA8B;AAKnF,MAAe,WAAW;AAAA,EAGtB,YAAY,YAA0B;AAC/C,SAAK,aAAa;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,eAA6B;AAC5B,WAAO,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe;AACd,WAAO,KAAK,WAAW;AAAA,EACxB;AAaD;AAMO,MAAM,sCAAsC,WAAW;AAAA,EAG7D,YAAY,UAAuB;AAClC,UAAM,SAAS,IAAI,CAAC,YAAY,QAAQ,QAAQ,CAAC;AACjD,SAAK,cAAc,SAAS,IAAI,CAAC,YAAY,0BAAU,UAAU,QAAQ,EAAE,CAAC;AAAA,EAC7E;AAAA,EAEA,eACC,IACA,eACqB;AACrB,QAAI,KAAK,YAAY,WAAW,KAAK,KAAK,YAAY,WAAW,cAAc,QAAQ;AACtF,YAAM,IAAI,MAAM,eAAe;AAAA,IAChC;AACA,UAAM,CAAC,OAAO,IAAI,IAAI,aAAa,KAAK,aAAa,EAAE;AACvD,UAAM,iBAAiB,cAAc;AAAA,MAAI,CAAC,cAAc,UACvD,kBAAI,aAAa,SAAK,gBAAI,KAAK,CAAC,GAAG,aAAa,IAAI,CAAC;AAAA,IACtD;AAEA,WAAO;AAAA,MACN,uBAAuB;AAAA,QACtB,eAAe,MAAM,QAAQ;AAAA,QAC7B,QAAQ;AAAA,MACT;AAAA,MACA,OAAO;AAAA,IACR;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,oBACN,iBACA,IACA,YACU;AACV,UAAM,MAAM,gBAAgB,QAAQ,0BAAU,UAAU,CAAC,EAAE,QAAQ;AACnE,UAAM,MAAM,0BAAU,YAAY,EAAE,EAAE,QAAQ,UAAU,EAAE,QAAQ;AAClE,WAAO,IAAI,WAAW,IAAI,UAAU,IAAI,MAAM,CAAC,OAAO,UAAU,UAAU,IAAI,KAAK,CAAC;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,QACN,OACA,IACA,YACA,MACa;AACb,eAAO,kBAAI,gBAAY,gBAAI,MAAM,OAAO,EAAE,GAAG,IAAI,CAAC;AAAA,EACnD;AACD;AASA,SAAS,aAAa,aAA0B,IAA0C;AACzF,MAAI,YAAY,WAAW,GAAG;AAC7B,UAAM,IAAI,MAAM,eAAe;AAAA,EAChC;AACA,QAAM,IAAI,uBAAO,OAAO;AACxB,QAAM,QAAQ,0BAAU,UAAU,EAAE,SAAS,CAAC;AAC9C,QAAM,MAAM,0BAAU,YAAY,EAAE,EAAE,SAAS,CAAC;AAChD,SAAO,CAAC,OAAO,YAAY,IAAI,CAAC,eAAe,IAAI,QAAQ,UAAU,CAAC,CAAC;AACxE;AASA,SAAS,MAAM,OAAkB,KAA2B;AAC3D,SAAO,IAAI,QAAQ,KAAK;AACzB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AesGcm256 } from './aes.js';
|
|
2
|
+
export { encrypt } from './encrypt.js';
|
|
3
|
+
export { getAllowlistedKeyServers, retrieveKeyServers, verifyKeyServer } from './key-server.js';
|
|
4
|
+
export { KeyStore } from './key-store.js';
|
|
5
|
+
export { SessionKey } from './session-key.js';
|
|
6
|
+
export { EncryptedObject } from './types.js';
|
|
@@ -0,0 +1,37 @@
|
|
|
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 index_exports = {};
|
|
20
|
+
__export(index_exports, {
|
|
21
|
+
AesGcm256: () => import_aes.AesGcm256,
|
|
22
|
+
EncryptedObject: () => import_types.EncryptedObject,
|
|
23
|
+
KeyStore: () => import_key_store.KeyStore,
|
|
24
|
+
SessionKey: () => import_session_key.SessionKey,
|
|
25
|
+
encrypt: () => import_encrypt.encrypt,
|
|
26
|
+
getAllowlistedKeyServers: () => import_key_server.getAllowlistedKeyServers,
|
|
27
|
+
retrieveKeyServers: () => import_key_server.retrieveKeyServers,
|
|
28
|
+
verifyKeyServer: () => import_key_server.verifyKeyServer
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(index_exports);
|
|
31
|
+
var import_aes = require("./aes.js");
|
|
32
|
+
var import_encrypt = require("./encrypt.js");
|
|
33
|
+
var import_key_server = require("./key-server.js");
|
|
34
|
+
var import_key_store = require("./key-store.js");
|
|
35
|
+
var import_session_key = require("./session-key.js");
|
|
36
|
+
var import_types = require("./types.js");
|
|
37
|
+
//# 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 { AesGcm256 } from './aes.js';\nexport { encrypt } from './encrypt.js';\nexport { getAllowlistedKeyServers, retrieveKeyServers, verifyKeyServer } from './key-server.js';\nexport { KeyStore } from './key-store.js';\nexport { SessionKey } from './session-key.js';\nexport { EncryptedObject } from './types.js';\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAA0B;AAC1B,qBAAwB;AACxB,wBAA8E;AAC9E,uBAAyB;AACzB,yBAA2B;AAC3B,mBAAgC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GTElement } from './bls12381.js';
|
|
2
|
+
/**
|
|
3
|
+
* The default key derivation function.
|
|
4
|
+
*
|
|
5
|
+
* @param element The GTElement to derive the key from.
|
|
6
|
+
* @param info Optional context and application specific information.
|
|
7
|
+
* @returns The derived key.
|
|
8
|
+
*/
|
|
9
|
+
export declare function kdf(element: GTElement, info: Uint8Array): Uint8Array;
|
package/dist/cjs/kdf.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
kdf: () => kdf
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(kdf_exports);
|
|
24
|
+
var import_hkdf = require("@noble/hashes/hkdf");
|
|
25
|
+
var import_sha3 = require("@noble/hashes/sha3");
|
|
26
|
+
function kdf(element, info) {
|
|
27
|
+
return (0, import_hkdf.hkdf)(import_sha3.sha3_256, element.toBytes(), "", info, 32);
|
|
28
|
+
}
|
|
29
|
+
//# 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 { hkdf } from '@noble/hashes/hkdf';\nimport { sha3_256 } from '@noble/hashes/sha3';\n\nimport type { GTElement } from './bls12381.js';\n\n/**\n * The default key derivation function.\n *\n * @param element The GTElement to derive the key from.\n * @param info Optional context and application specific information.\n * @returns The derived key.\n */\nexport function kdf(element: GTElement, info: Uint8Array): Uint8Array {\n\treturn hkdf(sha3_256, element.toBytes(), '', info, 32);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAqB;AACrB,kBAAyB;AAWlB,SAAS,IAAI,SAAoB,MAA8B;AACrE,aAAO,kBAAK,sBAAU,QAAQ,QAAQ,GAAG,IAAI,MAAM,EAAE;AACtD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { SuiClient } from '@mysten/sui/client';
|
|
2
|
+
export type KeyServer = {
|
|
3
|
+
objectId: Uint8Array;
|
|
4
|
+
name: string;
|
|
5
|
+
url: string;
|
|
6
|
+
keyType: KeyServerType;
|
|
7
|
+
pk: Uint8Array;
|
|
8
|
+
};
|
|
9
|
+
export declare enum KeyServerType {
|
|
10
|
+
BonehFranklinBLS12381 = 0
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Returns a static list of Seal key server object ids that the dapp can choose to use.
|
|
14
|
+
* @param network - The network to use.
|
|
15
|
+
* @returns The object id's of the key servers.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getAllowlistedKeyServers(network: 'testnet' | 'mainnet'): Uint8Array[];
|
|
18
|
+
/**
|
|
19
|
+
* Given a list of key server object IDs, returns a list of SealKeyServer
|
|
20
|
+
* from onchain state containing name, objectId, URL and pk.
|
|
21
|
+
*
|
|
22
|
+
* @param objectIds - The key server object IDs.
|
|
23
|
+
* @param client - The SuiClient to use.
|
|
24
|
+
* @returns - An array of SealKeyServer.
|
|
25
|
+
*/
|
|
26
|
+
export declare function retrieveKeyServers({ objectIds, client, }: {
|
|
27
|
+
objectIds: Uint8Array[];
|
|
28
|
+
client: SuiClient;
|
|
29
|
+
}): Promise<KeyServer[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Given a KeyServer, fetch the proof of possesion (PoP) from the URL and verify it
|
|
32
|
+
* against the pubkey. This should be used only rarely when the dapp uses a dynamic
|
|
33
|
+
* set of key servers.
|
|
34
|
+
*
|
|
35
|
+
* @param server - The KeyServer to verify.
|
|
36
|
+
* @returns - True if the key server is valid, false otherwise.
|
|
37
|
+
*/
|
|
38
|
+
export declare function verifyKeyServer(server: KeyServer): Promise<boolean>;
|
|
@@ -0,0 +1,98 @@
|
|
|
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
|
+
KeyServerType: () => KeyServerType,
|
|
22
|
+
getAllowlistedKeyServers: () => getAllowlistedKeyServers,
|
|
23
|
+
retrieveKeyServers: () => retrieveKeyServers,
|
|
24
|
+
verifyKeyServer: () => verifyKeyServer
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(key_server_exports);
|
|
27
|
+
var import_bcs = require("@mysten/bcs");
|
|
28
|
+
var import_bcs2 = require("@mysten/sui/bcs");
|
|
29
|
+
var import_bls12_381 = require("@noble/curves/bls12-381");
|
|
30
|
+
var import_ibe = require("./ibe.js");
|
|
31
|
+
var KeyServerType = /* @__PURE__ */ ((KeyServerType2) => {
|
|
32
|
+
KeyServerType2[KeyServerType2["BonehFranklinBLS12381"] = 0] = "BonehFranklinBLS12381";
|
|
33
|
+
return KeyServerType2;
|
|
34
|
+
})(KeyServerType || {});
|
|
35
|
+
const KeyServerMove = import_bcs2.bcs.struct("KeyServer", {
|
|
36
|
+
id: import_bcs2.bcs.Address,
|
|
37
|
+
name: import_bcs2.bcs.string(),
|
|
38
|
+
url: import_bcs2.bcs.string(),
|
|
39
|
+
key_type: import_bcs2.bcs.u8(),
|
|
40
|
+
pk: import_bcs2.bcs.vector(import_bcs2.bcs.u8())
|
|
41
|
+
});
|
|
42
|
+
function getAllowlistedKeyServers(network) {
|
|
43
|
+
if (network === "testnet") {
|
|
44
|
+
return [
|
|
45
|
+
(0, import_bcs.fromHex)("0xb35a7228d8cf224ad1e828c0217c95a5153bafc2906d6f9c178197dce26fbcf8"),
|
|
46
|
+
(0, import_bcs.fromHex)("0x2d6cde8a9d9a65bde3b0a346566945a63b4bfb70e9a06c41bdb70807e2502b06")
|
|
47
|
+
];
|
|
48
|
+
} else {
|
|
49
|
+
throw new Error("Network not supported");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function retrieveKeyServers({
|
|
53
|
+
objectIds,
|
|
54
|
+
client
|
|
55
|
+
}) {
|
|
56
|
+
return await Promise.all(
|
|
57
|
+
objectIds.map(async (objectId) => {
|
|
58
|
+
const res = await client.getObject({
|
|
59
|
+
id: (0, import_bcs.toHex)(objectId),
|
|
60
|
+
options: {
|
|
61
|
+
showBcs: true
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
if (!res || res.error || !res.data) {
|
|
65
|
+
throw new Error(`KeyServer ${objectId} not found; ${res.error}`);
|
|
66
|
+
}
|
|
67
|
+
if (!res.data.bcs || !("bcsBytes" in res.data.bcs)) {
|
|
68
|
+
throw new Error(`Invalid KeyServer query: ${objectId}, expected object, got package`);
|
|
69
|
+
}
|
|
70
|
+
let ks = KeyServerMove.parse((0, import_bcs.fromBase64)(res.data.bcs.bcsBytes));
|
|
71
|
+
if (ks.key_type !== 0) {
|
|
72
|
+
throw new Error("Unsupported key type");
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
objectId,
|
|
76
|
+
name: ks.name,
|
|
77
|
+
url: ks.url,
|
|
78
|
+
keyType: 0 /* BonehFranklinBLS12381 */,
|
|
79
|
+
pk: new Uint8Array(ks.pk)
|
|
80
|
+
};
|
|
81
|
+
})
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
async function verifyKeyServer(server) {
|
|
85
|
+
const response = await fetch(server.url + "/v1/service", {
|
|
86
|
+
method: "GET",
|
|
87
|
+
headers: {
|
|
88
|
+
"Content-Type": "application/json"
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const serviceResponse = await response.json();
|
|
92
|
+
if (serviceResponse.service_id !== server.objectId) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
const fullMsg = new Uint8Array([...import_ibe.DST_POP, ...server.pk, ...server.objectId]);
|
|
96
|
+
return import_bls12_381.bls12_381.verifyShortSignature((0, import_bcs.fromBase64)(serviceResponse.pop), fullMsg, server.pk);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=key-server.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/key-server.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { fromBase64, fromHex, toHex } from '@mysten/bcs';\nimport { bcs } from '@mysten/sui/bcs';\nimport type { SuiClient } from '@mysten/sui/client';\nimport { bls12_381 } from '@noble/curves/bls12-381';\n\nimport { DST_POP } from './ibe.js';\n\nexport type KeyServer = {\n\tobjectId: Uint8Array;\n\tname: string;\n\turl: string;\n\tkeyType: KeyServerType;\n\tpk: Uint8Array;\n};\n\nexport enum KeyServerType {\n\tBonehFranklinBLS12381 = 0,\n}\n\n// The Move struct for the KeyServer object.\nconst KeyServerMove = bcs.struct('KeyServer', {\n\tid: bcs.Address,\n\tname: bcs.string(),\n\turl: bcs.string(),\n\tkey_type: bcs.u8(),\n\tpk: bcs.vector(bcs.u8()),\n});\n\n/**\n * Returns a static list of Seal key server object ids that the dapp can choose to use.\n * @param network - The network to use.\n * @returns The object id's of the key servers.\n */\nexport function getAllowlistedKeyServers(network: 'testnet' | 'mainnet'): Uint8Array[] {\n\tif (network === 'testnet') {\n\t\treturn [\n\t\t\tfromHex('0xb35a7228d8cf224ad1e828c0217c95a5153bafc2906d6f9c178197dce26fbcf8'),\n\t\t\tfromHex('0x2d6cde8a9d9a65bde3b0a346566945a63b4bfb70e9a06c41bdb70807e2502b06'),\n\t\t];\n\t} else {\n\t\tthrow new Error('Network not supported');\n\t}\n}\n\n/**\n * Given a list of key server object IDs, returns a list of SealKeyServer\n * from onchain state containing name, objectId, URL and pk.\n *\n * @param objectIds - The key server object IDs.\n * @param client - The SuiClient to use.\n * @returns - An array of SealKeyServer.\n */\nexport async function retrieveKeyServers({\n\tobjectIds,\n\tclient,\n}: {\n\tobjectIds: Uint8Array[];\n\tclient: SuiClient;\n}): Promise<KeyServer[]> {\n\treturn await Promise.all(\n\t\tobjectIds.map(async (objectId) => {\n\t\t\tconst res = await client.getObject({\n\t\t\t\tid: toHex(objectId),\n\t\t\t\toptions: {\n\t\t\t\t\tshowBcs: true,\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (!res || res.error || !res.data) {\n\t\t\t\tthrow new Error(`KeyServer ${objectId} not found; ${res.error}`);\n\t\t\t}\n\n\t\t\tif (!res.data.bcs || !('bcsBytes' in res.data.bcs)) {\n\t\t\t\tthrow new Error(`Invalid KeyServer query: ${objectId}, expected object, got package`);\n\t\t\t}\n\n\t\t\tlet ks = KeyServerMove.parse(fromBase64(res.data.bcs!.bcsBytes));\n\t\t\tif (ks.key_type !== 0) {\n\t\t\t\tthrow new Error('Unsupported key type');\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tobjectId,\n\t\t\t\tname: ks.name,\n\t\t\t\turl: ks.url,\n\t\t\t\tkeyType: KeyServerType.BonehFranklinBLS12381,\n\t\t\t\tpk: new Uint8Array(ks.pk),\n\t\t\t};\n\t\t}),\n\t);\n}\n\n/**\n * Given a KeyServer, fetch the proof of possesion (PoP) from the URL and verify it\n * against the pubkey. This should be used only rarely when the dapp uses a dynamic\n * set of key servers.\n *\n * @param server - The KeyServer to verify.\n * @returns - True if the key server is valid, false otherwise.\n */\nexport async function verifyKeyServer(server: KeyServer): Promise<boolean> {\n\tconst response = await fetch(server.url! + '/v1/service', {\n\t\tmethod: 'GET',\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json',\n\t\t},\n\t});\n\tconst serviceResponse = await response.json();\n\n\tif (serviceResponse.service_id !== server.objectId) {\n\t\treturn false;\n\t}\n\tconst fullMsg = new Uint8Array([...DST_POP, ...server.pk, ...server.objectId]);\n\treturn bls12_381.verifyShortSignature(fromBase64(serviceResponse.pop), fullMsg, server.pk);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAA2C;AAC3C,IAAAA,cAAoB;AAEpB,uBAA0B;AAE1B,iBAAwB;AAUjB,IAAK,gBAAL,kBAAKC,mBAAL;AACN,EAAAA,8BAAA,2BAAwB,KAAxB;AADW,SAAAA;AAAA,GAAA;AAKZ,MAAM,gBAAgB,gBAAI,OAAO,aAAa;AAAA,EAC7C,IAAI,gBAAI;AAAA,EACR,MAAM,gBAAI,OAAO;AAAA,EACjB,KAAK,gBAAI,OAAO;AAAA,EAChB,UAAU,gBAAI,GAAG;AAAA,EACjB,IAAI,gBAAI,OAAO,gBAAI,GAAG,CAAC;AACxB,CAAC;AAOM,SAAS,yBAAyB,SAA8C;AACtF,MAAI,YAAY,WAAW;AAC1B,WAAO;AAAA,UACN,oBAAQ,oEAAoE;AAAA,UAC5E,oBAAQ,oEAAoE;AAAA,IAC7E;AAAA,EACD,OAAO;AACN,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACxC;AACD;AAUA,eAAsB,mBAAmB;AAAA,EACxC;AAAA,EACA;AACD,GAGyB;AACxB,SAAO,MAAM,QAAQ;AAAA,IACpB,UAAU,IAAI,OAAO,aAAa;AACjC,YAAM,MAAM,MAAM,OAAO,UAAU;AAAA,QAClC,QAAI,kBAAM,QAAQ;AAAA,QAClB,SAAS;AAAA,UACR,SAAS;AAAA,QACV;AAAA,MACD,CAAC;AACD,UAAI,CAAC,OAAO,IAAI,SAAS,CAAC,IAAI,MAAM;AACnC,cAAM,IAAI,MAAM,aAAa,QAAQ,eAAe,IAAI,KAAK,EAAE;AAAA,MAChE;AAEA,UAAI,CAAC,IAAI,KAAK,OAAO,EAAE,cAAc,IAAI,KAAK,MAAM;AACnD,cAAM,IAAI,MAAM,4BAA4B,QAAQ,gCAAgC;AAAA,MACrF;AAEA,UAAI,KAAK,cAAc,UAAM,uBAAW,IAAI,KAAK,IAAK,QAAQ,CAAC;AAC/D,UAAI,GAAG,aAAa,GAAG;AACtB,cAAM,IAAI,MAAM,sBAAsB;AAAA,MACvC;AAEA,aAAO;AAAA,QACN;AAAA,QACA,MAAM,GAAG;AAAA,QACT,KAAK,GAAG;AAAA,QACR,SAAS;AAAA,QACT,IAAI,IAAI,WAAW,GAAG,EAAE;AAAA,MACzB;AAAA,IACD,CAAC;AAAA,EACF;AACD;AAUA,eAAsB,gBAAgB,QAAqC;AAC1E,QAAM,WAAW,MAAM,MAAM,OAAO,MAAO,eAAe;AAAA,IACzD,QAAQ;AAAA,IACR,SAAS;AAAA,MACR,gBAAgB;AAAA,IACjB;AAAA,EACD,CAAC;AACD,QAAM,kBAAkB,MAAM,SAAS,KAAK;AAE5C,MAAI,gBAAgB,eAAe,OAAO,UAAU;AACnD,WAAO;AAAA,EACR;AACA,QAAM,UAAU,IAAI,WAAW,CAAC,GAAG,oBAAS,GAAG,OAAO,IAAI,GAAG,OAAO,QAAQ,CAAC;AAC7E,SAAO,2BAAU,yBAAqB,uBAAW,gBAAgB,GAAG,GAAG,SAAS,OAAO,EAAE;AAC1F;",
|
|
6
|
+
"names": ["import_bcs", "KeyServerType"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { G1Element } from './bls12381.js';
|
|
2
|
+
import type { KeyServer } from './key-server.js';
|
|
3
|
+
import type { SessionKey } from './session-key.js';
|
|
4
|
+
import type { EncryptedObject } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* A class to cache user secret keys after they have been fetched from key servers.
|
|
7
|
+
*/
|
|
8
|
+
export declare class KeyStore {
|
|
9
|
+
private readonly keys_map;
|
|
10
|
+
constructor();
|
|
11
|
+
private createMapKey;
|
|
12
|
+
/** @internal */
|
|
13
|
+
addKey(fullId: Uint8Array, objectId: Uint8Array, key: G1Element): void;
|
|
14
|
+
/**
|
|
15
|
+
* Get a key from this KeyStore or undefined if the key is not found.
|
|
16
|
+
*
|
|
17
|
+
* @param fullId The full ID used to derive the key.
|
|
18
|
+
* @param objectId The object ID of the key server holding the key.
|
|
19
|
+
*/
|
|
20
|
+
private getKey;
|
|
21
|
+
/**
|
|
22
|
+
* Check if the key store has a key for the given full ID and object ID.
|
|
23
|
+
*
|
|
24
|
+
* @param fullId The full ID used to derive the key.
|
|
25
|
+
* @param objectId The object ID of the key server holding the key.
|
|
26
|
+
*/
|
|
27
|
+
private hasKey;
|
|
28
|
+
/**
|
|
29
|
+
* Look up URLs of key servers and fetch key from servers with request signature,
|
|
30
|
+
* cert and ephPk, then updates the caching keys_map.
|
|
31
|
+
*/
|
|
32
|
+
fetchKeys({ keyServers, threshold: _threshold, packageId, ids, txBytes, sessionKey, }: {
|
|
33
|
+
keyServers: KeyServer[];
|
|
34
|
+
threshold: number;
|
|
35
|
+
packageId: Uint8Array;
|
|
36
|
+
ids: Uint8Array[];
|
|
37
|
+
txBytes: Uint8Array;
|
|
38
|
+
sessionKey: SessionKey;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Decrypt the given encrypted bytes with the given cached secret keys for the full ID.
|
|
42
|
+
* It's assumed that fetchKeys has been called to fetch the secret keys for enough key servers
|
|
43
|
+
* otherwise, this will throw an error.
|
|
44
|
+
*
|
|
45
|
+
* @param encryptedObject - EncryptedObject.
|
|
46
|
+
* @returns - The decrypted plaintext corresponding to ciphertext.
|
|
47
|
+
*/
|
|
48
|
+
decrypt(encryptedObject: typeof EncryptedObject.$inferType): Promise<Uint8Array>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
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_store_exports = {};
|
|
20
|
+
__export(key_store_exports, {
|
|
21
|
+
KeyStore: () => KeyStore
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(key_store_exports);
|
|
24
|
+
var import_bcs = require("@mysten/bcs");
|
|
25
|
+
var import_shamir_secret_sharing = require("shamir-secret-sharing");
|
|
26
|
+
var import_aes = require("./aes.js");
|
|
27
|
+
var import_bls12381 = require("./bls12381.js");
|
|
28
|
+
var import_elgamal = require("./elgamal.js");
|
|
29
|
+
var import_ibe = require("./ibe.js");
|
|
30
|
+
var import_key_server = require("./key-server.js");
|
|
31
|
+
var import_utils = require("./utils.js");
|
|
32
|
+
class KeyStore {
|
|
33
|
+
constructor() {
|
|
34
|
+
this.keys_map = /* @__PURE__ */ new Map();
|
|
35
|
+
}
|
|
36
|
+
createMapKey(fullId, objectId) {
|
|
37
|
+
return (0, import_bcs.toHex)(fullId) + ":" + (0, import_bcs.toHex)(objectId);
|
|
38
|
+
}
|
|
39
|
+
/** @internal */
|
|
40
|
+
addKey(fullId, objectId, key) {
|
|
41
|
+
this.keys_map.set(this.createMapKey(fullId, objectId), key);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get a key from this KeyStore or undefined if the key is not found.
|
|
45
|
+
*
|
|
46
|
+
* @param fullId The full ID used to derive the key.
|
|
47
|
+
* @param objectId The object ID of the key server holding the key.
|
|
48
|
+
*/
|
|
49
|
+
getKey(fullId, objectId) {
|
|
50
|
+
return this.keys_map.get(this.createMapKey(fullId, objectId));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if the key store has a key for the given full ID and object ID.
|
|
54
|
+
*
|
|
55
|
+
* @param fullId The full ID used to derive the key.
|
|
56
|
+
* @param objectId The object ID of the key server holding the key.
|
|
57
|
+
*/
|
|
58
|
+
hasKey(fullId, objectId) {
|
|
59
|
+
return this.keys_map.has(this.createMapKey(fullId, objectId));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Look up URLs of key servers and fetch key from servers with request signature,
|
|
63
|
+
* cert and ephPk, then updates the caching keys_map.
|
|
64
|
+
*/
|
|
65
|
+
async fetchKeys({
|
|
66
|
+
keyServers,
|
|
67
|
+
threshold: _threshold,
|
|
68
|
+
packageId,
|
|
69
|
+
ids,
|
|
70
|
+
txBytes,
|
|
71
|
+
sessionKey
|
|
72
|
+
}) {
|
|
73
|
+
if (ids.length !== 1) {
|
|
74
|
+
throw new Error("Only one ID is supported");
|
|
75
|
+
}
|
|
76
|
+
const fullId = (0, import_utils.createFullId)(import_ibe.DST, packageId, ids[0]);
|
|
77
|
+
const remainingKeyServers = keyServers.filter((ks) => !this.hasKey(fullId, ks.objectId));
|
|
78
|
+
if (remainingKeyServers.length === 0) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const cert = sessionKey.getCertificate();
|
|
82
|
+
const signedRequest = await sessionKey.createRequestParams(txBytes);
|
|
83
|
+
await Promise.all(
|
|
84
|
+
remainingKeyServers.map(async (server) => {
|
|
85
|
+
if (server.keyType !== import_key_server.KeyServerType.BonehFranklinBLS12381) {
|
|
86
|
+
console.warn("Server has invalid key type: " + server.keyType);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const res = await fetchKey(
|
|
90
|
+
server.url,
|
|
91
|
+
signedRequest.request_signature,
|
|
92
|
+
txBytes,
|
|
93
|
+
signedRequest.decryption_key,
|
|
94
|
+
cert
|
|
95
|
+
);
|
|
96
|
+
const key = import_bls12381.G1Element.fromBytes(res.key);
|
|
97
|
+
if (!import_ibe.BonehFranklinBLS12381Services.verifyUserSecretKey(
|
|
98
|
+
key,
|
|
99
|
+
fullId,
|
|
100
|
+
import_bls12381.G2Element.fromBytes(server.pk)
|
|
101
|
+
)) {
|
|
102
|
+
console.warn("Received invalid key from key server " + server.objectId);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
this.addKey(fullId, server.objectId, key);
|
|
106
|
+
})
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Decrypt the given encrypted bytes with the given cached secret keys for the full ID.
|
|
111
|
+
* It's assumed that fetchKeys has been called to fetch the secret keys for enough key servers
|
|
112
|
+
* otherwise, this will throw an error.
|
|
113
|
+
*
|
|
114
|
+
* @param encryptedObject - EncryptedObject.
|
|
115
|
+
* @returns - The decrypted plaintext corresponding to ciphertext.
|
|
116
|
+
*/
|
|
117
|
+
async decrypt(encryptedObject) {
|
|
118
|
+
if (!encryptedObject.encrypted_shares.BonehFranklinBLS12381) {
|
|
119
|
+
throw new Error("Encryption mode not supported");
|
|
120
|
+
}
|
|
121
|
+
const fullId = (0, import_utils.createFullId)(
|
|
122
|
+
import_ibe.DST,
|
|
123
|
+
encryptedObject.package_id,
|
|
124
|
+
new Uint8Array(encryptedObject.id)
|
|
125
|
+
);
|
|
126
|
+
const in_keystore = encryptedObject.services.map((_, i) => i).filter((i) => this.hasKey(fullId, encryptedObject.services[i][0]));
|
|
127
|
+
if (in_keystore.length < encryptedObject.threshold) {
|
|
128
|
+
throw new Error("Not enough shares. Please fetch more keys.");
|
|
129
|
+
}
|
|
130
|
+
const encryptedShares = encryptedObject.encrypted_shares.BonehFranklinBLS12381.shares;
|
|
131
|
+
if (encryptedShares.length !== encryptedObject.services.length) {
|
|
132
|
+
throw new Error("Invalid input");
|
|
133
|
+
}
|
|
134
|
+
const nonce = import_bls12381.G2Element.fromBytes(
|
|
135
|
+
encryptedObject.encrypted_shares.BonehFranklinBLS12381.encapsulation
|
|
136
|
+
);
|
|
137
|
+
const shares = in_keystore.map((i) => {
|
|
138
|
+
const [objectId, index] = encryptedObject.services[i];
|
|
139
|
+
const info = new Uint8Array([index]);
|
|
140
|
+
let share = import_ibe.BonehFranklinBLS12381Services.decrypt(
|
|
141
|
+
nonce,
|
|
142
|
+
this.getKey(fullId, objectId),
|
|
143
|
+
encryptedShares[i],
|
|
144
|
+
info
|
|
145
|
+
);
|
|
146
|
+
return { index, share };
|
|
147
|
+
});
|
|
148
|
+
const key = await combine(shares);
|
|
149
|
+
if (encryptedObject.ciphertext.Aes256Gcm) {
|
|
150
|
+
try {
|
|
151
|
+
return import_aes.AesGcm256.decrypt(key, encryptedObject.ciphertext);
|
|
152
|
+
} catch {
|
|
153
|
+
throw new Error("Decryption failed");
|
|
154
|
+
}
|
|
155
|
+
} else if (encryptedObject.ciphertext.Plain) {
|
|
156
|
+
return key;
|
|
157
|
+
} else {
|
|
158
|
+
throw new Error("Invalid encrypted object");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async function fetchKey(url, requestSig, txBytes, enc_key, certificate) {
|
|
163
|
+
const enc_key_pk = (0, import_elgamal.toPublicKey)(enc_key);
|
|
164
|
+
const enc_verification_key = (0, import_elgamal.toVerificationKey)(enc_key);
|
|
165
|
+
const body = {
|
|
166
|
+
ptb: (0, import_bcs.toBase64)(txBytes.slice(1)),
|
|
167
|
+
// removes the byte of the transaction type version
|
|
168
|
+
enc_key: (0, import_bcs.toBase64)(enc_key_pk),
|
|
169
|
+
enc_verification_key: (0, import_bcs.toBase64)(enc_verification_key),
|
|
170
|
+
request_signature: requestSig,
|
|
171
|
+
// already b64
|
|
172
|
+
certificate
|
|
173
|
+
};
|
|
174
|
+
const response = await fetch(url + "/v1/fetch_key", {
|
|
175
|
+
method: "POST",
|
|
176
|
+
headers: {
|
|
177
|
+
"Content-Type": "application/json"
|
|
178
|
+
},
|
|
179
|
+
body: JSON.stringify(body)
|
|
180
|
+
});
|
|
181
|
+
const resp = await response.json();
|
|
182
|
+
const key = (0, import_elgamal.elgamalDecrypt)(enc_key, resp.decryption_keys[0].encrypted_key.map(import_bcs.fromBase64));
|
|
183
|
+
return {
|
|
184
|
+
fullId: resp.decryption_keys[0].fullId,
|
|
185
|
+
key
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
async function combine(shares) {
|
|
189
|
+
if (shares.length === 0) {
|
|
190
|
+
throw new Error("Invalid input");
|
|
191
|
+
} else if (shares.length === 1) {
|
|
192
|
+
return Promise.resolve(shares[0].share);
|
|
193
|
+
}
|
|
194
|
+
return (0, import_shamir_secret_sharing.combine)(
|
|
195
|
+
shares.map(({ index, share }) => {
|
|
196
|
+
const packedShare = new Uint8Array(share.length + 1);
|
|
197
|
+
packedShare.set(share, 0);
|
|
198
|
+
packedShare[share.length] = index;
|
|
199
|
+
return packedShare;
|
|
200
|
+
})
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=key-store.js.map
|