@mysten/seal 0.2.0 → 0.3.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.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/bcs.d.ts +132 -0
- package/dist/cjs/bcs.js +67 -0
- package/dist/cjs/bcs.js.map +7 -0
- package/dist/cjs/client.d.ts +83 -0
- package/dist/cjs/client.js +283 -0
- package/dist/cjs/client.js.map +7 -0
- package/dist/cjs/decrypt.d.ts +15 -0
- package/dist/cjs/decrypt.js +94 -0
- package/dist/cjs/decrypt.js.map +7 -0
- package/dist/cjs/dem.d.ts +36 -0
- package/dist/cjs/dem.js +173 -0
- package/dist/cjs/dem.js.map +7 -0
- package/dist/cjs/elgamal.js.map +2 -2
- package/dist/cjs/encrypt.d.ts +14 -5
- package/dist/cjs/encrypt.js +52 -22
- package/dist/cjs/encrypt.js.map +3 -3
- package/dist/cjs/error.d.ts +58 -0
- package/dist/cjs/error.js +175 -0
- package/dist/cjs/error.js.map +7 -0
- package/dist/cjs/ibe.d.ts +13 -17
- package/dist/cjs/ibe.js +25 -28
- package/dist/cjs/ibe.js.map +2 -2
- package/dist/cjs/index.d.ts +3 -5
- package/dist/cjs/index.js +5 -11
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/kdf.d.ts +7 -2
- package/dist/cjs/kdf.js +37 -2
- package/dist/cjs/kdf.js.map +3 -3
- package/dist/cjs/key-server.d.ts +5 -5
- package/dist/cjs/key-server.js +24 -21
- package/dist/cjs/key-server.js.map +2 -2
- package/dist/cjs/keys.d.ts +17 -0
- package/dist/cjs/keys.js +61 -0
- package/dist/cjs/keys.js.map +7 -0
- package/dist/cjs/session-key.d.ts +20 -14
- package/dist/cjs/session-key.js +90 -23
- package/dist/cjs/session-key.js.map +2 -2
- package/dist/cjs/types.d.ts +1 -86
- package/dist/cjs/types.js +0 -32
- package/dist/cjs/types.js.map +2 -2
- package/dist/cjs/utils.d.ts +2 -1
- package/dist/cjs/utils.js +17 -5
- package/dist/cjs/utils.js.map +2 -2
- package/dist/cjs/version.d.ts +1 -0
- package/dist/cjs/version.js +25 -0
- package/dist/cjs/version.js.map +7 -0
- package/dist/esm/bcs.d.ts +132 -0
- package/dist/esm/bcs.js +47 -0
- package/dist/esm/bcs.js.map +7 -0
- package/dist/esm/client.d.ts +83 -0
- package/dist/esm/client.js +268 -0
- package/dist/esm/client.js.map +7 -0
- package/dist/esm/decrypt.d.ts +15 -0
- package/dist/esm/decrypt.js +74 -0
- package/dist/esm/decrypt.js.map +7 -0
- package/dist/esm/dem.d.ts +36 -0
- package/dist/esm/dem.js +153 -0
- package/dist/esm/dem.js.map +7 -0
- package/dist/esm/elgamal.js.map +2 -2
- package/dist/esm/encrypt.d.ts +14 -5
- package/dist/esm/encrypt.js +49 -19
- package/dist/esm/encrypt.js.map +3 -3
- package/dist/esm/error.d.ts +58 -0
- package/dist/esm/error.js +155 -0
- package/dist/esm/error.js.map +7 -0
- package/dist/esm/ibe.d.ts +13 -17
- package/dist/esm/ibe.js +25 -28
- package/dist/esm/ibe.js.map +2 -2
- package/dist/esm/index.d.ts +3 -5
- package/dist/esm/index.js +5 -16
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/kdf.d.ts +7 -2
- package/dist/esm/kdf.js +37 -2
- package/dist/esm/kdf.js.map +3 -3
- package/dist/esm/key-server.d.ts +5 -5
- package/dist/esm/key-server.js +29 -21
- package/dist/esm/key-server.js.map +2 -2
- package/dist/esm/keys.d.ts +17 -0
- package/dist/esm/keys.js +41 -0
- package/dist/esm/keys.js.map +7 -0
- package/dist/esm/session-key.d.ts +20 -14
- package/dist/esm/session-key.js +95 -24
- package/dist/esm/session-key.js.map +2 -2
- package/dist/esm/types.d.ts +1 -86
- package/dist/esm/types.js +0 -28
- package/dist/esm/types.js.map +3 -3
- package/dist/esm/utils.d.ts +2 -1
- package/dist/esm/utils.js +17 -5
- package/dist/esm/utils.js.map +2 -2
- package/dist/esm/version.d.ts +1 -0
- package/dist/esm/version.js +5 -0
- package/dist/esm/version.js.map +7 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -5
- package/dist/cjs/aes.d.ts +0 -18
- package/dist/cjs/aes.js +0 -111
- package/dist/cjs/aes.js.map +0 -7
- package/dist/cjs/key-store.d.ts +0 -49
- package/dist/cjs/key-store.js +0 -203
- package/dist/cjs/key-store.js.map +0 -7
- package/dist/esm/aes.d.ts +0 -18
- package/dist/esm/aes.js +0 -91
- package/dist/esm/aes.js.map +0 -7
- package/dist/esm/key-store.d.ts +0 -49
- package/dist/esm/key-store.js +0 -183
- package/dist/esm/key-store.js.map +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export declare const IBEEncryptions: import("@mysten/bcs").BcsType<{
|
|
2
|
+
BonehFranklinBLS12381: {
|
|
3
|
+
nonce: Uint8Array<ArrayBufferLike>;
|
|
4
|
+
encryptedShares: Uint8Array<ArrayBufferLike>[];
|
|
5
|
+
encryptedRandomness: Uint8Array<ArrayBufferLike>;
|
|
6
|
+
};
|
|
7
|
+
$kind: "BonehFranklinBLS12381";
|
|
8
|
+
}, {
|
|
9
|
+
BonehFranklinBLS12381: {
|
|
10
|
+
nonce: Iterable<number>;
|
|
11
|
+
encryptedShares: Iterable<Iterable<number>> & {
|
|
12
|
+
length: number;
|
|
13
|
+
};
|
|
14
|
+
encryptedRandomness: Iterable<number>;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
export declare const Ciphertext: import("@mysten/bcs").BcsType<import("@mysten/bcs").EnumOutputShapeWithKeys<{
|
|
18
|
+
Aes256Gcm: {
|
|
19
|
+
blob: number[];
|
|
20
|
+
aad: number[] | null;
|
|
21
|
+
};
|
|
22
|
+
Hmac256Ctr: {
|
|
23
|
+
blob: number[];
|
|
24
|
+
aad: number[] | null;
|
|
25
|
+
mac: Uint8Array<ArrayBufferLike>;
|
|
26
|
+
};
|
|
27
|
+
Plain: {};
|
|
28
|
+
}, "Aes256Gcm" | "Hmac256Ctr" | "Plain">, import("@mysten/bcs").EnumInputShape<{
|
|
29
|
+
Aes256Gcm: {
|
|
30
|
+
blob: Iterable<number> & {
|
|
31
|
+
length: number;
|
|
32
|
+
};
|
|
33
|
+
aad: (Iterable<number> & {
|
|
34
|
+
length: number;
|
|
35
|
+
}) | null | undefined;
|
|
36
|
+
};
|
|
37
|
+
Hmac256Ctr: {
|
|
38
|
+
blob: Iterable<number> & {
|
|
39
|
+
length: number;
|
|
40
|
+
};
|
|
41
|
+
aad: (Iterable<number> & {
|
|
42
|
+
length: number;
|
|
43
|
+
}) | null | undefined;
|
|
44
|
+
mac: Iterable<number>;
|
|
45
|
+
};
|
|
46
|
+
Plain: {};
|
|
47
|
+
}>>;
|
|
48
|
+
/**
|
|
49
|
+
* The encrypted object format. Should be aligned with the Rust implementation.
|
|
50
|
+
*/
|
|
51
|
+
export declare const EncryptedObject: import("@mysten/bcs").BcsType<{
|
|
52
|
+
version: number;
|
|
53
|
+
packageId: string;
|
|
54
|
+
id: string;
|
|
55
|
+
services: [string, number][];
|
|
56
|
+
threshold: number;
|
|
57
|
+
encryptedShares: {
|
|
58
|
+
BonehFranklinBLS12381: {
|
|
59
|
+
nonce: Uint8Array<ArrayBufferLike>;
|
|
60
|
+
encryptedShares: Uint8Array<ArrayBufferLike>[];
|
|
61
|
+
encryptedRandomness: Uint8Array<ArrayBufferLike>;
|
|
62
|
+
};
|
|
63
|
+
$kind: "BonehFranklinBLS12381";
|
|
64
|
+
};
|
|
65
|
+
ciphertext: import("@mysten/bcs").EnumOutputShapeWithKeys<{
|
|
66
|
+
Aes256Gcm: {
|
|
67
|
+
blob: number[];
|
|
68
|
+
aad: number[] | null;
|
|
69
|
+
};
|
|
70
|
+
Hmac256Ctr: {
|
|
71
|
+
blob: number[];
|
|
72
|
+
aad: number[] | null;
|
|
73
|
+
mac: Uint8Array<ArrayBufferLike>;
|
|
74
|
+
};
|
|
75
|
+
Plain: {};
|
|
76
|
+
}, "Aes256Gcm" | "Hmac256Ctr" | "Plain">;
|
|
77
|
+
}, {
|
|
78
|
+
version: number;
|
|
79
|
+
packageId: string | Uint8Array<ArrayBufferLike>;
|
|
80
|
+
id: string;
|
|
81
|
+
services: Iterable<readonly [string | Uint8Array<ArrayBufferLike>, number]> & {
|
|
82
|
+
length: number;
|
|
83
|
+
};
|
|
84
|
+
threshold: number;
|
|
85
|
+
encryptedShares: {
|
|
86
|
+
BonehFranklinBLS12381: {
|
|
87
|
+
nonce: Iterable<number>;
|
|
88
|
+
encryptedShares: Iterable<Iterable<number>> & {
|
|
89
|
+
length: number;
|
|
90
|
+
};
|
|
91
|
+
encryptedRandomness: Iterable<number>;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
ciphertext: import("@mysten/bcs").EnumInputShape<{
|
|
95
|
+
Aes256Gcm: {
|
|
96
|
+
blob: Iterable<number> & {
|
|
97
|
+
length: number;
|
|
98
|
+
};
|
|
99
|
+
aad: (Iterable<number> & {
|
|
100
|
+
length: number;
|
|
101
|
+
}) | null | undefined;
|
|
102
|
+
};
|
|
103
|
+
Hmac256Ctr: {
|
|
104
|
+
blob: Iterable<number> & {
|
|
105
|
+
length: number;
|
|
106
|
+
};
|
|
107
|
+
aad: (Iterable<number> & {
|
|
108
|
+
length: number;
|
|
109
|
+
}) | null | undefined;
|
|
110
|
+
mac: Iterable<number>;
|
|
111
|
+
};
|
|
112
|
+
Plain: {};
|
|
113
|
+
}>;
|
|
114
|
+
}>;
|
|
115
|
+
/**
|
|
116
|
+
* The Move struct for the KeyServer object.
|
|
117
|
+
*/
|
|
118
|
+
export declare const KeyServerMove: import("@mysten/bcs").BcsType<{
|
|
119
|
+
id: string;
|
|
120
|
+
name: string;
|
|
121
|
+
url: string;
|
|
122
|
+
keyType: number;
|
|
123
|
+
pk: number[];
|
|
124
|
+
}, {
|
|
125
|
+
id: string | Uint8Array<ArrayBufferLike>;
|
|
126
|
+
name: string;
|
|
127
|
+
url: string;
|
|
128
|
+
keyType: number;
|
|
129
|
+
pk: Iterable<number> & {
|
|
130
|
+
length: number;
|
|
131
|
+
};
|
|
132
|
+
}>;
|
package/dist/cjs/bcs.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
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 bcs_exports = {};
|
|
20
|
+
__export(bcs_exports, {
|
|
21
|
+
Ciphertext: () => Ciphertext,
|
|
22
|
+
EncryptedObject: () => EncryptedObject,
|
|
23
|
+
IBEEncryptions: () => IBEEncryptions,
|
|
24
|
+
KeyServerMove: () => KeyServerMove
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(bcs_exports);
|
|
27
|
+
var import_bcs = require("@mysten/bcs");
|
|
28
|
+
var import_bcs2 = require("@mysten/sui/bcs");
|
|
29
|
+
const IBEEncryptions = import_bcs2.bcs.enum("IBEEncryptions", {
|
|
30
|
+
BonehFranklinBLS12381: import_bcs2.bcs.struct("BonehFranklinBLS12381", {
|
|
31
|
+
nonce: import_bcs2.bcs.bytes(96),
|
|
32
|
+
encryptedShares: import_bcs2.bcs.vector(import_bcs2.bcs.bytes(32)),
|
|
33
|
+
encryptedRandomness: import_bcs2.bcs.bytes(32)
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
const Ciphertext = import_bcs2.bcs.enum("Ciphertext", {
|
|
37
|
+
Aes256Gcm: import_bcs2.bcs.struct("Aes256Gcm", {
|
|
38
|
+
blob: import_bcs2.bcs.vector(import_bcs2.bcs.U8),
|
|
39
|
+
aad: import_bcs2.bcs.option(import_bcs2.bcs.vector(import_bcs2.bcs.U8))
|
|
40
|
+
}),
|
|
41
|
+
Hmac256Ctr: import_bcs2.bcs.struct("Hmac256Ctr", {
|
|
42
|
+
blob: import_bcs2.bcs.vector(import_bcs2.bcs.U8),
|
|
43
|
+
aad: import_bcs2.bcs.option(import_bcs2.bcs.vector(import_bcs2.bcs.U8)),
|
|
44
|
+
mac: import_bcs2.bcs.bytes(32)
|
|
45
|
+
}),
|
|
46
|
+
Plain: import_bcs2.bcs.struct("Plain", {})
|
|
47
|
+
});
|
|
48
|
+
const EncryptedObject = import_bcs2.bcs.struct("EncryptedObject", {
|
|
49
|
+
version: import_bcs2.bcs.U8,
|
|
50
|
+
packageId: import_bcs2.bcs.Address,
|
|
51
|
+
id: import_bcs2.bcs.vector(import_bcs2.bcs.U8).transform({
|
|
52
|
+
output: (val) => (0, import_bcs.toHex)(new Uint8Array(val)),
|
|
53
|
+
input: (val) => (0, import_bcs.fromHex)(val)
|
|
54
|
+
}),
|
|
55
|
+
services: import_bcs2.bcs.vector(import_bcs2.bcs.tuple([import_bcs2.bcs.Address, import_bcs2.bcs.U8])),
|
|
56
|
+
threshold: import_bcs2.bcs.U8,
|
|
57
|
+
encryptedShares: IBEEncryptions,
|
|
58
|
+
ciphertext: Ciphertext
|
|
59
|
+
});
|
|
60
|
+
const KeyServerMove = import_bcs2.bcs.struct("KeyServer", {
|
|
61
|
+
id: import_bcs2.bcs.Address,
|
|
62
|
+
name: import_bcs2.bcs.string(),
|
|
63
|
+
url: import_bcs2.bcs.string(),
|
|
64
|
+
keyType: import_bcs2.bcs.u8(),
|
|
65
|
+
pk: import_bcs2.bcs.vector(import_bcs2.bcs.u8())
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=bcs.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/bcs.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromHex, toHex } from '@mysten/bcs';\nimport { bcs } from '@mysten/sui/bcs';\n\nexport const IBEEncryptions = bcs.enum('IBEEncryptions', {\n\tBonehFranklinBLS12381: bcs.struct('BonehFranklinBLS12381', {\n\t\tnonce: bcs.bytes(96),\n\t\tencryptedShares: bcs.vector(bcs.bytes(32)),\n\t\tencryptedRandomness: bcs.bytes(32),\n\t}),\n});\n\nexport const Ciphertext = bcs.enum('Ciphertext', {\n\tAes256Gcm: bcs.struct('Aes256Gcm', {\n\t\tblob: bcs.vector(bcs.U8),\n\t\taad: bcs.option(bcs.vector(bcs.U8)),\n\t}),\n\tHmac256Ctr: bcs.struct('Hmac256Ctr', {\n\t\tblob: bcs.vector(bcs.U8),\n\t\taad: bcs.option(bcs.vector(bcs.U8)),\n\t\tmac: bcs.bytes(32),\n\t}),\n\tPlain: bcs.struct('Plain', {}),\n});\n\n/**\n * The encrypted object format. Should be aligned with the Rust implementation.\n */\nexport const EncryptedObject = bcs.struct('EncryptedObject', {\n\tversion: bcs.U8,\n\tpackageId: bcs.Address,\n\tid: bcs.vector(bcs.U8).transform({\n\t\toutput: (val) => toHex(new Uint8Array(val)),\n\t\tinput: (val: string) => fromHex(val),\n\t}),\n\tservices: bcs.vector(bcs.tuple([bcs.Address, bcs.U8])),\n\tthreshold: bcs.U8,\n\tencryptedShares: IBEEncryptions,\n\tciphertext: Ciphertext,\n});\n\n/**\n * The Move struct for the KeyServer object.\n */\nexport const KeyServerMove = bcs.struct('KeyServer', {\n\tid: bcs.Address,\n\tname: bcs.string(),\n\turl: bcs.string(),\n\tkeyType: bcs.u8(),\n\tpk: bcs.vector(bcs.u8()),\n});\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAA+B;AAC/B,IAAAA,cAAoB;AAEb,MAAM,iBAAiB,gBAAI,KAAK,kBAAkB;AAAA,EACxD,uBAAuB,gBAAI,OAAO,yBAAyB;AAAA,IAC1D,OAAO,gBAAI,MAAM,EAAE;AAAA,IACnB,iBAAiB,gBAAI,OAAO,gBAAI,MAAM,EAAE,CAAC;AAAA,IACzC,qBAAqB,gBAAI,MAAM,EAAE;AAAA,EAClC,CAAC;AACF,CAAC;AAEM,MAAM,aAAa,gBAAI,KAAK,cAAc;AAAA,EAChD,WAAW,gBAAI,OAAO,aAAa;AAAA,IAClC,MAAM,gBAAI,OAAO,gBAAI,EAAE;AAAA,IACvB,KAAK,gBAAI,OAAO,gBAAI,OAAO,gBAAI,EAAE,CAAC;AAAA,EACnC,CAAC;AAAA,EACD,YAAY,gBAAI,OAAO,cAAc;AAAA,IACpC,MAAM,gBAAI,OAAO,gBAAI,EAAE;AAAA,IACvB,KAAK,gBAAI,OAAO,gBAAI,OAAO,gBAAI,EAAE,CAAC;AAAA,IAClC,KAAK,gBAAI,MAAM,EAAE;AAAA,EAClB,CAAC;AAAA,EACD,OAAO,gBAAI,OAAO,SAAS,CAAC,CAAC;AAC9B,CAAC;AAKM,MAAM,kBAAkB,gBAAI,OAAO,mBAAmB;AAAA,EAC5D,SAAS,gBAAI;AAAA,EACb,WAAW,gBAAI;AAAA,EACf,IAAI,gBAAI,OAAO,gBAAI,EAAE,EAAE,UAAU;AAAA,IAChC,QAAQ,CAAC,YAAQ,kBAAM,IAAI,WAAW,GAAG,CAAC;AAAA,IAC1C,OAAO,CAAC,YAAgB,oBAAQ,GAAG;AAAA,EACpC,CAAC;AAAA,EACD,UAAU,gBAAI,OAAO,gBAAI,MAAM,CAAC,gBAAI,SAAS,gBAAI,EAAE,CAAC,CAAC;AAAA,EACrD,WAAW,gBAAI;AAAA,EACf,iBAAiB;AAAA,EACjB,YAAY;AACb,CAAC;AAKM,MAAM,gBAAgB,gBAAI,OAAO,aAAa;AAAA,EACpD,IAAI,gBAAI;AAAA,EACR,MAAM,gBAAI,OAAO;AAAA,EACjB,KAAK,gBAAI,OAAO;AAAA,EAChB,SAAS,gBAAI,GAAG;AAAA,EAChB,IAAI,gBAAI,OAAO,gBAAI,GAAG,CAAC;AACxB,CAAC;",
|
|
6
|
+
"names": ["import_bcs"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { SuiClient } from '@mysten/sui/client';
|
|
2
|
+
import { DemType, KemType } from './encrypt.js';
|
|
3
|
+
import type { KeyServer } from './key-server.js';
|
|
4
|
+
import type { SessionKey } from './session-key.js';
|
|
5
|
+
/**
|
|
6
|
+
* Configuration options for initializing a SealClient
|
|
7
|
+
* @property serverObjectIds: Array of object IDs for the key servers to use.
|
|
8
|
+
* @property verifyKeyServers: Whether to verify the key servers' authenticity.
|
|
9
|
+
* Should be false if servers are pre-verified (e.g., getAllowlistedKeyServers).
|
|
10
|
+
* Defaults to true.
|
|
11
|
+
* @property timeout: Timeout in milliseconds for network requests. Defaults to 10 seconds.
|
|
12
|
+
*/
|
|
13
|
+
export interface SealClientOptions {
|
|
14
|
+
suiClient: SuiClient;
|
|
15
|
+
serverObjectIds: string[];
|
|
16
|
+
verifyKeyServers?: boolean;
|
|
17
|
+
timeout?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class SealClient {
|
|
20
|
+
#private;
|
|
21
|
+
constructor(options: SealClientOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Return an encrypted message under the identity.
|
|
24
|
+
*
|
|
25
|
+
* @param kemType - The type of KEM to use.
|
|
26
|
+
* @param demType - The type of DEM to use.
|
|
27
|
+
* @param threshold - The threshold for the TSS encryption.
|
|
28
|
+
* @param packageId - the packageId namespace.
|
|
29
|
+
* @param id - the identity to use.
|
|
30
|
+
* @param data - the data to encrypt.
|
|
31
|
+
* @param aad - optional additional authenticated data.
|
|
32
|
+
* @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.
|
|
33
|
+
* Since the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.
|
|
34
|
+
*/
|
|
35
|
+
encrypt({ kemType, demType, threshold, packageId, id, data, aad, }: {
|
|
36
|
+
kemType?: KemType;
|
|
37
|
+
demType?: DemType;
|
|
38
|
+
threshold: number;
|
|
39
|
+
packageId: string;
|
|
40
|
+
id: string;
|
|
41
|
+
data: Uint8Array;
|
|
42
|
+
aad?: Uint8Array;
|
|
43
|
+
}): Promise<{
|
|
44
|
+
encryptedObject: Uint8Array;
|
|
45
|
+
key: Uint8Array;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Decrypt the given encrypted bytes using cached keys.
|
|
49
|
+
* Calls fetchKeys in case one or more of the required keys is not cached yet.
|
|
50
|
+
* The function throws an error if the client's key servers are not a subset of
|
|
51
|
+
* the encrypted object's key servers (including the same weights) or if the
|
|
52
|
+
* threshold cannot be met.
|
|
53
|
+
*
|
|
54
|
+
* @param data - The encrypted bytes to decrypt.
|
|
55
|
+
* @param sessionKey - The session key to use.
|
|
56
|
+
* @param txBytes - The transaction bytes to use (that calls seal_approve* functions).
|
|
57
|
+
* @returns - The decrypted plaintext corresponding to ciphertext.
|
|
58
|
+
*/
|
|
59
|
+
decrypt({ data, sessionKey, txBytes, }: {
|
|
60
|
+
data: Uint8Array;
|
|
61
|
+
sessionKey: SessionKey;
|
|
62
|
+
txBytes: Uint8Array;
|
|
63
|
+
}): Promise<Uint8Array<ArrayBufferLike>>;
|
|
64
|
+
getKeyServers(): Promise<KeyServer[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Fetch keys from the key servers and update the cache.
|
|
67
|
+
*
|
|
68
|
+
* It is recommended to call this function once for all ids of all encrypted obejcts if
|
|
69
|
+
* there are multiple, then call decrypt for each object. This avoids calling fetchKey
|
|
70
|
+
* individually for each decrypt.
|
|
71
|
+
*
|
|
72
|
+
* @param ids - The ids of the encrypted objects.
|
|
73
|
+
* @param txBytes - The transaction bytes to use (that calls seal_approve* functions).
|
|
74
|
+
* @param sessionKey - The session key to use.
|
|
75
|
+
* @param threshold - The threshold for the TSS encryptions. The function returns when a threshold of key servers had returned keys for all ids.
|
|
76
|
+
*/
|
|
77
|
+
fetchKeys({ ids, txBytes, sessionKey, threshold, }: {
|
|
78
|
+
ids: string[];
|
|
79
|
+
txBytes: Uint8Array;
|
|
80
|
+
sessionKey: SessionKey;
|
|
81
|
+
threshold: number;
|
|
82
|
+
}): Promise<void>;
|
|
83
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
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 __typeError = (msg) => {
|
|
7
|
+
throw TypeError(msg);
|
|
8
|
+
};
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
23
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
24
|
+
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);
|
|
25
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
26
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
27
|
+
var client_exports = {};
|
|
28
|
+
__export(client_exports, {
|
|
29
|
+
SealClient: () => SealClient
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(client_exports);
|
|
32
|
+
var import_bcs = require("./bcs.js");
|
|
33
|
+
var import_bls12381 = require("./bls12381.js");
|
|
34
|
+
var import_decrypt = require("./decrypt.js");
|
|
35
|
+
var import_dem = require("./dem.js");
|
|
36
|
+
var import_encrypt = require("./encrypt.js");
|
|
37
|
+
var import_error = require("./error.js");
|
|
38
|
+
var import_ibe = require("./ibe.js");
|
|
39
|
+
var import_key_server = require("./key-server.js");
|
|
40
|
+
var import_keys = require("./keys.js");
|
|
41
|
+
var import_utils = require("./utils.js");
|
|
42
|
+
var _suiClient, _serverObjectIds, _verifyKeyServers, _keyServers, _cachedKeys, _timeout, _SealClient_instances, createEncryptionInput_fn, validateEncryptionServices_fn, loadKeyServers_fn;
|
|
43
|
+
class SealClient {
|
|
44
|
+
constructor(options) {
|
|
45
|
+
__privateAdd(this, _SealClient_instances);
|
|
46
|
+
__privateAdd(this, _suiClient);
|
|
47
|
+
__privateAdd(this, _serverObjectIds);
|
|
48
|
+
__privateAdd(this, _verifyKeyServers);
|
|
49
|
+
__privateAdd(this, _keyServers, null);
|
|
50
|
+
// A caching map for: fullId:object_id -> partial key.
|
|
51
|
+
__privateAdd(this, _cachedKeys, /* @__PURE__ */ new Map());
|
|
52
|
+
__privateAdd(this, _timeout);
|
|
53
|
+
__privateSet(this, _suiClient, options.suiClient);
|
|
54
|
+
__privateSet(this, _serverObjectIds, options.serverObjectIds);
|
|
55
|
+
__privateSet(this, _verifyKeyServers, options.verifyKeyServers ?? true);
|
|
56
|
+
__privateSet(this, _timeout, options.timeout ?? 1e4);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Return an encrypted message under the identity.
|
|
60
|
+
*
|
|
61
|
+
* @param kemType - The type of KEM to use.
|
|
62
|
+
* @param demType - The type of DEM to use.
|
|
63
|
+
* @param threshold - The threshold for the TSS encryption.
|
|
64
|
+
* @param packageId - the packageId namespace.
|
|
65
|
+
* @param id - the identity to use.
|
|
66
|
+
* @param data - the data to encrypt.
|
|
67
|
+
* @param aad - optional additional authenticated data.
|
|
68
|
+
* @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.
|
|
69
|
+
* Since the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.
|
|
70
|
+
*/
|
|
71
|
+
async encrypt({
|
|
72
|
+
kemType = import_encrypt.KemType.BonehFranklinBLS12381DemCCA,
|
|
73
|
+
demType = import_encrypt.DemType.AesGcm256,
|
|
74
|
+
threshold,
|
|
75
|
+
packageId,
|
|
76
|
+
id,
|
|
77
|
+
data,
|
|
78
|
+
aad = new Uint8Array()
|
|
79
|
+
}) {
|
|
80
|
+
return (0, import_encrypt.encrypt)({
|
|
81
|
+
keyServers: await this.getKeyServers(),
|
|
82
|
+
kemType,
|
|
83
|
+
threshold,
|
|
84
|
+
packageId,
|
|
85
|
+
id,
|
|
86
|
+
encryptionInput: __privateMethod(this, _SealClient_instances, createEncryptionInput_fn).call(this, demType, data, aad)
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Decrypt the given encrypted bytes using cached keys.
|
|
91
|
+
* Calls fetchKeys in case one or more of the required keys is not cached yet.
|
|
92
|
+
* The function throws an error if the client's key servers are not a subset of
|
|
93
|
+
* the encrypted object's key servers (including the same weights) or if the
|
|
94
|
+
* threshold cannot be met.
|
|
95
|
+
*
|
|
96
|
+
* @param data - The encrypted bytes to decrypt.
|
|
97
|
+
* @param sessionKey - The session key to use.
|
|
98
|
+
* @param txBytes - The transaction bytes to use (that calls seal_approve* functions).
|
|
99
|
+
* @returns - The decrypted plaintext corresponding to ciphertext.
|
|
100
|
+
*/
|
|
101
|
+
async decrypt({
|
|
102
|
+
data,
|
|
103
|
+
sessionKey,
|
|
104
|
+
txBytes
|
|
105
|
+
}) {
|
|
106
|
+
const encryptedObject = import_bcs.EncryptedObject.parse(data);
|
|
107
|
+
__privateMethod(this, _SealClient_instances, validateEncryptionServices_fn).call(this, encryptedObject.services.map((s) => s[0]), encryptedObject.threshold);
|
|
108
|
+
await this.fetchKeys({
|
|
109
|
+
ids: [encryptedObject.id],
|
|
110
|
+
txBytes,
|
|
111
|
+
sessionKey,
|
|
112
|
+
threshold: encryptedObject.threshold
|
|
113
|
+
});
|
|
114
|
+
return (0, import_decrypt.decrypt)({ encryptedObject, keys: __privateGet(this, _cachedKeys) });
|
|
115
|
+
}
|
|
116
|
+
async getKeyServers() {
|
|
117
|
+
if (!__privateGet(this, _keyServers)) {
|
|
118
|
+
__privateSet(this, _keyServers, __privateMethod(this, _SealClient_instances, loadKeyServers_fn).call(this).catch((error) => {
|
|
119
|
+
__privateSet(this, _keyServers, null);
|
|
120
|
+
throw error;
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
return __privateGet(this, _keyServers);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Fetch keys from the key servers and update the cache.
|
|
127
|
+
*
|
|
128
|
+
* It is recommended to call this function once for all ids of all encrypted obejcts if
|
|
129
|
+
* there are multiple, then call decrypt for each object. This avoids calling fetchKey
|
|
130
|
+
* individually for each decrypt.
|
|
131
|
+
*
|
|
132
|
+
* @param ids - The ids of the encrypted objects.
|
|
133
|
+
* @param txBytes - The transaction bytes to use (that calls seal_approve* functions).
|
|
134
|
+
* @param sessionKey - The session key to use.
|
|
135
|
+
* @param threshold - The threshold for the TSS encryptions. The function returns when a threshold of key servers had returned keys for all ids.
|
|
136
|
+
*/
|
|
137
|
+
async fetchKeys({
|
|
138
|
+
ids,
|
|
139
|
+
txBytes,
|
|
140
|
+
sessionKey,
|
|
141
|
+
threshold
|
|
142
|
+
}) {
|
|
143
|
+
const keyServers = await this.getKeyServers();
|
|
144
|
+
if (threshold > keyServers.length || threshold < 1 || keyServers.length < 1) {
|
|
145
|
+
throw new import_error.InvalidThresholdError(
|
|
146
|
+
`Invalid threshold ${threshold} for ${keyServers.length} servers`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
let completedServerCount = 0;
|
|
150
|
+
const remainingKeyServers = /* @__PURE__ */ new Set();
|
|
151
|
+
const fullIds = ids.map((id) => (0, import_utils.createFullId)(import_ibe.DST, sessionKey.getPackageId(), id));
|
|
152
|
+
for (const server of keyServers) {
|
|
153
|
+
let hasAllKeys = true;
|
|
154
|
+
for (const fullId of fullIds) {
|
|
155
|
+
if (!__privateGet(this, _cachedKeys).has(`${fullId}:${server.objectId}`)) {
|
|
156
|
+
hasAllKeys = false;
|
|
157
|
+
remainingKeyServers.add(server);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (hasAllKeys) {
|
|
162
|
+
completedServerCount++;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (completedServerCount >= threshold) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
for (const server of remainingKeyServers) {
|
|
169
|
+
if (server.keyType !== import_key_server.KeyServerType.BonehFranklinBLS12381) {
|
|
170
|
+
throw new import_error.InvalidKeyServerError(
|
|
171
|
+
`Server ${server.objectId} has invalid key type: ${server.keyType}`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const cert = await sessionKey.getCertificate();
|
|
176
|
+
const signedRequest = await sessionKey.createRequestParams(txBytes);
|
|
177
|
+
const controller = new AbortController();
|
|
178
|
+
const errors = [];
|
|
179
|
+
const keyFetches = [...remainingKeyServers].map(async (server) => {
|
|
180
|
+
try {
|
|
181
|
+
const allKeys = await (0, import_keys.fetchKeysForAllIds)(
|
|
182
|
+
server.url,
|
|
183
|
+
signedRequest.requestSignature,
|
|
184
|
+
txBytes,
|
|
185
|
+
signedRequest.decryptionKey,
|
|
186
|
+
cert,
|
|
187
|
+
__privateGet(this, _timeout),
|
|
188
|
+
controller.signal
|
|
189
|
+
);
|
|
190
|
+
let receivedIds = /* @__PURE__ */ new Set();
|
|
191
|
+
for (const { fullId, key } of allKeys) {
|
|
192
|
+
const keyElement = import_bls12381.G1Element.fromBytes(key);
|
|
193
|
+
if (!import_ibe.BonehFranklinBLS12381Services.verifyUserSecretKey(
|
|
194
|
+
keyElement,
|
|
195
|
+
fullId,
|
|
196
|
+
import_bls12381.G2Element.fromBytes(server.pk)
|
|
197
|
+
)) {
|
|
198
|
+
console.warn("Received invalid key from key server " + server.objectId);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
__privateGet(this, _cachedKeys).set(`${fullId}:${server.objectId}`, keyElement);
|
|
202
|
+
receivedIds.add(fullId);
|
|
203
|
+
}
|
|
204
|
+
const expectedIds = new Set(fullIds);
|
|
205
|
+
const hasAllKeys = receivedIds.size === expectedIds.size && [...receivedIds].every((id) => expectedIds.has(id));
|
|
206
|
+
if (hasAllKeys) {
|
|
207
|
+
completedServerCount++;
|
|
208
|
+
if (completedServerCount >= threshold) {
|
|
209
|
+
controller.abort();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
} catch (error) {
|
|
213
|
+
if (!controller.signal.aborted) {
|
|
214
|
+
errors.push(error);
|
|
215
|
+
}
|
|
216
|
+
if (remainingKeyServers.size - errors.length < threshold - completedServerCount) {
|
|
217
|
+
controller.abort(error);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
await Promise.allSettled(keyFetches);
|
|
222
|
+
if (completedServerCount < threshold) {
|
|
223
|
+
throw (0, import_error.toMajorityError)(errors);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
_suiClient = new WeakMap();
|
|
228
|
+
_serverObjectIds = new WeakMap();
|
|
229
|
+
_verifyKeyServers = new WeakMap();
|
|
230
|
+
_keyServers = new WeakMap();
|
|
231
|
+
_cachedKeys = new WeakMap();
|
|
232
|
+
_timeout = new WeakMap();
|
|
233
|
+
_SealClient_instances = new WeakSet();
|
|
234
|
+
createEncryptionInput_fn = function(type, data, aad) {
|
|
235
|
+
switch (type) {
|
|
236
|
+
case import_encrypt.DemType.AesGcm256:
|
|
237
|
+
return new import_dem.AesGcm256(data, aad);
|
|
238
|
+
case import_encrypt.DemType.Hmac256Ctr:
|
|
239
|
+
return new import_dem.Hmac256Ctr(data, aad);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
validateEncryptionServices_fn = function(services, threshold) {
|
|
243
|
+
const serverObjectIdsMap = /* @__PURE__ */ new Map();
|
|
244
|
+
for (const objectId of __privateGet(this, _serverObjectIds)) {
|
|
245
|
+
serverObjectIdsMap.set(objectId, (serverObjectIdsMap.get(objectId) ?? 0) + 1);
|
|
246
|
+
}
|
|
247
|
+
const servicesMap = /* @__PURE__ */ new Map();
|
|
248
|
+
for (const service of services) {
|
|
249
|
+
servicesMap.set(service, (servicesMap.get(service) ?? 0) + 1);
|
|
250
|
+
}
|
|
251
|
+
for (const [objectId, count] of serverObjectIdsMap) {
|
|
252
|
+
if (servicesMap.get(objectId) !== count) {
|
|
253
|
+
throw new import_error.InconsistentKeyServersError(
|
|
254
|
+
`Client's key servers must be a subset of the encrypted object's key servers`
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (threshold > __privateGet(this, _serverObjectIds).length) {
|
|
259
|
+
throw new import_error.InvalidThresholdError(
|
|
260
|
+
`Invalid threshold ${threshold} for ${__privateGet(this, _serverObjectIds).length} servers`
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
loadKeyServers_fn = async function() {
|
|
265
|
+
const keyServers = await (0, import_key_server.retrieveKeyServers)({
|
|
266
|
+
objectIds: __privateGet(this, _serverObjectIds),
|
|
267
|
+
client: __privateGet(this, _suiClient)
|
|
268
|
+
});
|
|
269
|
+
if (keyServers.length === 0) {
|
|
270
|
+
throw new import_error.InvalidKeyServerError("No key servers found");
|
|
271
|
+
}
|
|
272
|
+
if (__privateGet(this, _verifyKeyServers)) {
|
|
273
|
+
await Promise.all(
|
|
274
|
+
keyServers.map(async (server) => {
|
|
275
|
+
if (!await (0, import_key_server.verifyKeyServer)(server, __privateGet(this, _timeout))) {
|
|
276
|
+
throw new import_error.InvalidKeyServerError(`Key server ${server.objectId} is not valid`);
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
return keyServers;
|
|
282
|
+
};
|
|
283
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
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 type { SuiClient } from '@mysten/sui/client';\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\tInvalidKeyServerError,\n\tInvalidThresholdError,\n\ttoMajorityError,\n} from './error.js';\nimport { BonehFranklinBLS12381Services, DST } from './ibe.js';\nimport { KeyServerType, retrieveKeyServers, verifyKeyServer } from './key-server.js';\nimport type { KeyServer } from './key-server.js';\nimport { fetchKeysForAllIds } from './keys.js';\nimport type { SessionKey } from './session-key.js';\nimport type { KeyCacheKey } from './types.js';\nimport { createFullId } from './utils.js';\n\n/**\n * Configuration options for initializing a SealClient\n * @property serverObjectIds: Array of object IDs for the key servers to use.\n * @property verifyKeyServers: Whether to verify the key servers' authenticity.\n * \t Should be false if servers are pre-verified (e.g., getAllowlistedKeyServers).\n * \t Defaults to true.\n * @property timeout: Timeout in milliseconds for network requests. Defaults to 10 seconds.\n */\nexport interface SealClientOptions {\n\tsuiClient: SuiClient;\n\tserverObjectIds: string[];\n\tverifyKeyServers?: boolean;\n\ttimeout?: number;\n}\n\nexport class SealClient {\n\t#suiClient: SuiClient;\n\t#serverObjectIds: string[];\n\t#verifyKeyServers: boolean;\n\t#keyServers: Promise<KeyServer[]> | null = null;\n\t// A caching map for: fullId:object_id -> partial key.\n\t#cachedKeys = new Map<KeyCacheKey, G1Element>();\n\t#timeout: number;\n\n\tconstructor(options: SealClientOptions) {\n\t\tthis.#suiClient = options.suiClient;\n\t\tthis.#serverObjectIds = options.serverObjectIds;\n\t\tthis.#verifyKeyServers = options.verifyKeyServers ?? true;\n\t\tthis.#timeout = options.timeout ?? 10_000;\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}: {\n\t\tkemType?: KemType;\n\t\tdemType?: DemType;\n\t\tthreshold: number;\n\t\tpackageId: string;\n\t\tid: string;\n\t\tdata: Uint8Array;\n\t\taad?: Uint8Array;\n\t}) {\n\t\t// TODO: Verify that packageId is first version of its package (else throw error).\n\t\treturn encrypt({\n\t\t\tkeyServers: await this.getKeyServers(),\n\t\t\tkemType,\n\t\t\tthreshold,\n\t\t\tpackageId,\n\t\t\tid,\n\t\t\tencryptionInput: this.#createEncryptionInput(demType, data, aad),\n\t\t});\n\t}\n\n\t#createEncryptionInput(type: DemType, data: Uint8Array, aad: Uint8Array): 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 (including the same weights) or if the\n\t * threshold cannot be met.\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 * @returns - The decrypted plaintext corresponding to ciphertext.\n\t */\n\tasync decrypt({\n\t\tdata,\n\t\tsessionKey,\n\t\ttxBytes,\n\t}: {\n\t\tdata: Uint8Array;\n\t\tsessionKey: SessionKey;\n\t\ttxBytes: Uint8Array;\n\t}) {\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\treturn decrypt({ encryptedObject, keys: this.#cachedKeys });\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\tconst serverObjectIdsMap = new Map<string, number>();\n\t\tfor (const objectId of this.#serverObjectIds) {\n\t\t\tserverObjectIdsMap.set(objectId, (serverObjectIdsMap.get(objectId) ?? 0) + 1);\n\t\t}\n\t\tconst servicesMap = new Map<string, number>();\n\t\tfor (const service of services) {\n\t\t\tservicesMap.set(service, (servicesMap.get(service) ?? 0) + 1);\n\t\t}\n\t\tfor (const [objectId, count] of serverObjectIdsMap) {\n\t\t\tif (servicesMap.get(objectId) !== count) {\n\t\t\t\tthrow new InconsistentKeyServersError(\n\t\t\t\t\t`Client's key servers must be a subset of the encrypted object's key servers`,\n\t\t\t\t);\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.#serverObjectIds.length) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${this.#serverObjectIds.length} servers`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync getKeyServers() {\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\n\t\treturn this.#keyServers;\n\t}\n\n\tasync #loadKeyServers(): Promise<KeyServer[]> {\n\t\tconst keyServers = await retrieveKeyServers({\n\t\t\tobjectIds: this.#serverObjectIds,\n\t\t\tclient: this.#suiClient,\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\tif (!(await verifyKeyServer(server, this.#timeout))) {\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\n\t\treturn keyServers;\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 obejcts 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({\n\t\tids,\n\t\ttxBytes,\n\t\tsessionKey,\n\t\tthreshold,\n\t}: {\n\t\tids: string[];\n\t\ttxBytes: Uint8Array;\n\t\tsessionKey: SessionKey;\n\t\tthreshold: number;\n\t}) {\n\t\tconst keyServers = await this.getKeyServers();\n\t\tif (threshold > keyServers.length || threshold < 1 || keyServers.length < 1) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${keyServers.length} servers`,\n\t\t\t);\n\t\t}\n\n\t\tlet completedServerCount = 0;\n\t\tconst remainingKeyServers = new Set<KeyServer>();\n\t\tconst fullIds = ids.map((id) => createFullId(DST, 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\tfor (const server of keyServers) {\n\t\t\tlet hasAllKeys = true;\n\t\t\tfor (const fullId of fullIds) {\n\t\t\t\tif (!this.#cachedKeys.has(`${fullId}:${server.objectId}`)) {\n\t\t\t\t\thasAllKeys = false;\n\t\t\t\t\tremainingKeyServers.add(server);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hasAllKeys) {\n\t\t\t\tcompletedServerCount++;\n\t\t\t}\n\t\t}\n\n\t\t// Return early if we have enough keys from cache.\n\t\tif (completedServerCount >= threshold) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check server validities.\n\t\tfor (const server of remainingKeyServers) {\n\t\t\tif (server.keyType !== KeyServerType.BonehFranklinBLS12381) {\n\t\t\t\tthrow new InvalidKeyServerError(\n\t\t\t\t\t`Server ${server.objectId} has invalid key type: ${server.keyType}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst cert = 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 (server) => {\n\t\t\ttry {\n\t\t\t\tconst allKeys = await fetchKeysForAllIds(\n\t\t\t\t\tserver.url,\n\t\t\t\t\tsignedRequest.requestSignature,\n\t\t\t\t\ttxBytes,\n\t\t\t\t\tsignedRequest.decryptionKey,\n\t\t\t\t\tcert,\n\t\t\t\t\tthis.#timeout,\n\t\t\t\t\tcontroller.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\tlet receivedIds = new Set<string>();\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\treceivedIds.add(fullId);\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\tconst expectedIds = new Set(fullIds);\n\t\t\t\tconst hasAllKeys =\n\t\t\t\t\treceivedIds.size === expectedIds.size &&\n\t\t\t\t\t[...receivedIds].every((id) => expectedIds.has(id));\n\n\t\t\t\t// Return early if the completed servers is more than threshold.\n\t\t\t\tif (hasAllKeys) {\n\t\t\t\t\tcompletedServerCount++;\n\t\t\t\t\tif (completedServerCount >= 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\t// If there are too many errors that the threshold is not attainable, return early with error.\n\t\t\t\tif (remainingKeyServers.size - errors.length < threshold - completedServerCount) {\n\t\t\t\t\tcontroller.abort(error);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.allSettled(keyFetches);\n\n\t\tif (completedServerCount < threshold) {\n\t\t\tthrow toMajorityError(errors);\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { EncryptedObject } from './bcs.js';
|
|
2
|
+
import type { G1Element } from './bls12381.js';
|
|
3
|
+
import type { KeyCacheKey } from './types.js';
|
|
4
|
+
export interface DecryptOptions {
|
|
5
|
+
encryptedObject: typeof EncryptedObject.$inferType;
|
|
6
|
+
keys: Map<KeyCacheKey, G1Element>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Decrypt the given encrypted bytes with the given cached secret keys for the full ID.
|
|
10
|
+
* It's assumed that fetchKeys has been called to fetch the secret keys for enough key servers
|
|
11
|
+
* otherwise, this will throw an error.
|
|
12
|
+
*
|
|
13
|
+
* @returns - The decrypted plaintext corresponding to ciphertext.
|
|
14
|
+
*/
|
|
15
|
+
export declare function decrypt({ encryptedObject, keys }: DecryptOptions): Promise<Uint8Array>;
|