@mysten/seal 0.4.2 → 0.4.4

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 (82) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/bls12381.d.ts +5 -0
  3. package/dist/cjs/bls12381.js +38 -23
  4. package/dist/cjs/bls12381.js.map +2 -2
  5. package/dist/cjs/client.d.ts +21 -6
  6. package/dist/cjs/client.js +111 -55
  7. package/dist/cjs/client.js.map +2 -2
  8. package/dist/cjs/decrypt.js +7 -20
  9. package/dist/cjs/decrypt.js.map +2 -2
  10. package/dist/cjs/dem.js +20 -16
  11. package/dist/cjs/dem.js.map +2 -2
  12. package/dist/cjs/elgamal.d.ts +1 -1
  13. package/dist/cjs/elgamal.js +5 -5
  14. package/dist/cjs/elgamal.js.map +2 -2
  15. package/dist/cjs/encrypt.js +14 -16
  16. package/dist/cjs/encrypt.js.map +2 -2
  17. package/dist/cjs/error.d.ts +6 -0
  18. package/dist/cjs/error.js +9 -0
  19. package/dist/cjs/error.js.map +2 -2
  20. package/dist/cjs/ibe.d.ts +3 -1
  21. package/dist/cjs/ibe.js +4 -4
  22. package/dist/cjs/ibe.js.map +2 -2
  23. package/dist/cjs/index.d.ts +1 -1
  24. package/dist/cjs/index.js.map +2 -2
  25. package/dist/cjs/kdf.js +6 -16
  26. package/dist/cjs/kdf.js.map +2 -2
  27. package/dist/cjs/key-server.d.ts +14 -0
  28. package/dist/cjs/key-server.js +11 -1
  29. package/dist/cjs/key-server.js.map +2 -2
  30. package/dist/cjs/keys.js +1 -1
  31. package/dist/cjs/keys.js.map +2 -2
  32. package/dist/cjs/session-key.d.ts +5 -2
  33. package/dist/cjs/session-key.js +10 -8
  34. package/dist/cjs/session-key.js.map +2 -2
  35. package/dist/cjs/utils.d.ts +9 -0
  36. package/dist/cjs/utils.js +16 -8
  37. package/dist/cjs/utils.js.map +3 -3
  38. package/dist/cjs/version.d.ts +1 -1
  39. package/dist/cjs/version.js +1 -1
  40. package/dist/cjs/version.js.map +1 -1
  41. package/dist/esm/bls12381.d.ts +5 -0
  42. package/dist/esm/bls12381.js +38 -23
  43. package/dist/esm/bls12381.js.map +2 -2
  44. package/dist/esm/client.d.ts +21 -6
  45. package/dist/esm/client.js +121 -58
  46. package/dist/esm/client.js.map +2 -2
  47. package/dist/esm/decrypt.js +8 -21
  48. package/dist/esm/decrypt.js.map +2 -2
  49. package/dist/esm/dem.js +22 -18
  50. package/dist/esm/dem.js.map +2 -2
  51. package/dist/esm/elgamal.d.ts +1 -1
  52. package/dist/esm/elgamal.js +5 -5
  53. package/dist/esm/elgamal.js.map +2 -2
  54. package/dist/esm/encrypt.js +14 -16
  55. package/dist/esm/encrypt.js.map +2 -2
  56. package/dist/esm/error.d.ts +6 -0
  57. package/dist/esm/error.js +9 -0
  58. package/dist/esm/error.js.map +2 -2
  59. package/dist/esm/ibe.d.ts +3 -1
  60. package/dist/esm/ibe.js +4 -4
  61. package/dist/esm/ibe.js.map +2 -2
  62. package/dist/esm/index.d.ts +1 -1
  63. package/dist/esm/index.js.map +2 -2
  64. package/dist/esm/kdf.js +6 -16
  65. package/dist/esm/kdf.js.map +2 -2
  66. package/dist/esm/key-server.d.ts +14 -0
  67. package/dist/esm/key-server.js +13 -3
  68. package/dist/esm/key-server.js.map +2 -2
  69. package/dist/esm/keys.js +1 -1
  70. package/dist/esm/keys.js.map +2 -2
  71. package/dist/esm/session-key.d.ts +5 -2
  72. package/dist/esm/session-key.js +10 -8
  73. package/dist/esm/session-key.js.map +2 -2
  74. package/dist/esm/utils.d.ts +9 -0
  75. package/dist/esm/utils.js +16 -8
  76. package/dist/esm/utils.js.map +3 -3
  77. package/dist/esm/version.d.ts +1 -1
  78. package/dist/esm/version.js +1 -1
  79. package/dist/esm/version.js.map +1 -1
  80. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  81. package/dist/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +2 -2
@@ -1,86 +1,101 @@
1
1
  import { toHex } from "@mysten/bcs";
2
2
  import { bls12_381 } from "@noble/curves/bls12-381";
3
- class G1Element {
3
+ import { flatten } from "./utils.js";
4
+ const _G1Element = class _G1Element {
4
5
  constructor(point) {
5
6
  this.point = point;
6
7
  }
7
8
  static generator() {
8
- return new G1Element(bls12_381.G1.ProjectivePoint.BASE);
9
+ return new _G1Element(bls12_381.G1.ProjectivePoint.BASE);
9
10
  }
10
11
  static fromBytes(bytes) {
11
- return new G1Element(bls12_381.G1.ProjectivePoint.fromHex(toHex(bytes)));
12
+ return new _G1Element(bls12_381.G1.ProjectivePoint.fromHex(toHex(bytes)));
12
13
  }
13
14
  toBytes() {
14
15
  return this.point.toRawBytes();
15
16
  }
16
17
  multiply(scalar) {
17
- return new G1Element(this.point.multiply(scalar.scalar));
18
+ return new _G1Element(this.point.multiply(scalar.scalar));
18
19
  }
19
20
  add(other) {
20
- return new G1Element(this.point.add(other.point));
21
+ return new _G1Element(this.point.add(other.point));
21
22
  }
22
23
  subtract(other) {
23
- return new G1Element(this.point.subtract(other.point));
24
+ return new _G1Element(this.point.subtract(other.point));
24
25
  }
25
26
  static hashToCurve(data) {
26
- return new G1Element(
27
+ return new _G1Element(
27
28
  bls12_381.G1.ProjectivePoint.fromAffine(bls12_381.G1.hashToCurve(data).toAffine())
28
29
  );
29
30
  }
30
31
  pairing(other) {
31
32
  return new GTElement(bls12_381.pairing(this.point, other.point));
32
33
  }
33
- }
34
- class G2Element {
34
+ };
35
+ _G1Element.SIZE = 48;
36
+ let G1Element = _G1Element;
37
+ const _G2Element = class _G2Element {
35
38
  constructor(point) {
36
39
  this.point = point;
37
40
  }
38
41
  static generator() {
39
- return new G2Element(bls12_381.G2.ProjectivePoint.BASE);
42
+ return new _G2Element(bls12_381.G2.ProjectivePoint.BASE);
40
43
  }
41
44
  static fromBytes(bytes) {
42
- return new G2Element(bls12_381.G2.ProjectivePoint.fromHex(toHex(bytes)));
45
+ return new _G2Element(bls12_381.G2.ProjectivePoint.fromHex(toHex(bytes)));
43
46
  }
44
47
  toBytes() {
45
48
  return this.point.toRawBytes();
46
49
  }
47
50
  multiply(scalar) {
48
- return new G2Element(this.point.multiply(scalar.scalar));
51
+ return new _G2Element(this.point.multiply(scalar.scalar));
49
52
  }
50
53
  add(other) {
51
- return new G2Element(this.point.add(other.point));
54
+ return new _G2Element(this.point.add(other.point));
52
55
  }
53
56
  hashToCurve(data) {
54
- return new G2Element(
57
+ return new _G2Element(
55
58
  bls12_381.G2.ProjectivePoint.fromAffine(bls12_381.G2.hashToCurve(data).toAffine())
56
59
  );
57
60
  }
58
- }
59
- class GTElement {
61
+ };
62
+ _G2Element.SIZE = 96;
63
+ let G2Element = _G2Element;
64
+ const _GTElement = class _GTElement {
60
65
  constructor(element) {
61
66
  this.element = element;
62
67
  }
63
68
  toBytes() {
64
- return bls12_381.fields.Fp12.toBytes(this.element);
69
+ const P = [0, 3, 1, 4, 2, 5];
70
+ const PAIR_SIZE = _GTElement.SIZE / P.length;
71
+ const bytes = bls12_381.fields.Fp12.toBytes(this.element);
72
+ return flatten(P.map((p) => bytes.subarray(p * PAIR_SIZE, (p + 1) * PAIR_SIZE)));
73
+ }
74
+ equals(other) {
75
+ return bls12_381.fields.Fp12.eql(this.element, other.element);
65
76
  }
66
- }
67
- class Scalar {
77
+ };
78
+ _GTElement.SIZE = 576;
79
+ let GTElement = _GTElement;
80
+ const _Scalar = class _Scalar {
68
81
  constructor(scalar) {
69
82
  this.scalar = scalar;
70
83
  }
71
84
  static random() {
72
- return Scalar.fromBytes(bls12_381.utils.randomPrivateKey());
85
+ return _Scalar.fromBytes(bls12_381.utils.randomPrivateKey());
73
86
  }
74
87
  toBytes() {
75
88
  return new Uint8Array(bls12_381.fields.Fr.toBytes(this.scalar));
76
89
  }
77
90
  static fromBytes(bytes) {
78
- return new Scalar(bls12_381.fields.Fr.fromBytes(bytes));
91
+ return new _Scalar(bls12_381.fields.Fr.fromBytes(bytes));
79
92
  }
80
93
  static fromNumber(num) {
81
- return new Scalar(BigInt(num));
94
+ return new _Scalar(BigInt(num));
82
95
  }
83
- }
96
+ };
97
+ _Scalar.SIZE = 32;
98
+ let Scalar = _Scalar;
84
99
  export {
85
100
  G1Element,
86
101
  G2Element,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/bls12381.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { toHex } from '@mysten/bcs';\nimport type { Fp2, Fp12 } from '@noble/curves/abstract/tower';\nimport type { ProjPointType } from '@noble/curves/abstract/weierstrass';\nimport { bls12_381 } from '@noble/curves/bls12-381';\n\nexport class G1Element {\n\tpoint: ProjPointType<bigint>;\n\n\tconstructor(point: ProjPointType<bigint>) {\n\t\tthis.point = point;\n\t}\n\n\tstatic generator(): G1Element {\n\t\treturn new G1Element(bls12_381.G1.ProjectivePoint.BASE);\n\t}\n\n\tstatic fromBytes(bytes: Uint8Array): G1Element {\n\t\treturn new G1Element(bls12_381.G1.ProjectivePoint.fromHex(toHex(bytes)));\n\t}\n\n\ttoBytes(): Uint8Array {\n\t\treturn this.point.toRawBytes();\n\t}\n\n\tmultiply(scalar: Scalar): G1Element {\n\t\treturn new G1Element(this.point.multiply(scalar.scalar));\n\t}\n\n\tadd(other: G1Element): G1Element {\n\t\treturn new G1Element(this.point.add(other.point));\n\t}\n\n\tsubtract(other: G1Element): G1Element {\n\t\treturn new G1Element(this.point.subtract(other.point));\n\t}\n\n\tstatic hashToCurve(data: Uint8Array): G1Element {\n\t\treturn new G1Element(\n\t\t\tbls12_381.G1.ProjectivePoint.fromAffine(bls12_381.G1.hashToCurve(data).toAffine()),\n\t\t);\n\t}\n\n\tpairing(other: G2Element): GTElement {\n\t\treturn new GTElement(bls12_381.pairing(this.point, other.point));\n\t}\n}\n\nexport class G2Element {\n\tpoint: ProjPointType<Fp2>;\n\n\tconstructor(point: ProjPointType<Fp2>) {\n\t\tthis.point = point;\n\t}\n\n\tstatic generator(): G2Element {\n\t\treturn new G2Element(bls12_381.G2.ProjectivePoint.BASE);\n\t}\n\n\tstatic fromBytes(bytes: Uint8Array): G2Element {\n\t\treturn new G2Element(bls12_381.G2.ProjectivePoint.fromHex(toHex(bytes)));\n\t}\n\n\ttoBytes(): Uint8Array {\n\t\treturn this.point.toRawBytes();\n\t}\n\n\tmultiply(scalar: Scalar): G2Element {\n\t\treturn new G2Element(this.point.multiply(scalar.scalar));\n\t}\n\n\tadd(other: G2Element): G2Element {\n\t\treturn new G2Element(this.point.add(other.point));\n\t}\n\n\thashToCurve(data: Uint8Array): G2Element {\n\t\treturn new G2Element(\n\t\t\tbls12_381.G2.ProjectivePoint.fromAffine(bls12_381.G2.hashToCurve(data).toAffine()),\n\t\t);\n\t}\n}\n\nexport class GTElement {\n\telement: Fp12;\n\n\tconstructor(element: Fp12) {\n\t\tthis.element = element;\n\t}\n\n\ttoBytes(): Uint8Array {\n\t\treturn bls12_381.fields.Fp12.toBytes(this.element);\n\t}\n}\n\nexport class Scalar {\n\tscalar: bigint;\n\n\tconstructor(scalar: bigint) {\n\t\tthis.scalar = scalar;\n\t}\n\n\tstatic random(): Scalar {\n\t\treturn Scalar.fromBytes(bls12_381.utils.randomPrivateKey());\n\t}\n\n\ttoBytes(): Uint8Array {\n\t\treturn new Uint8Array(bls12_381.fields.Fr.toBytes(this.scalar));\n\t}\n\n\tstatic fromBytes(bytes: Uint8Array): Scalar {\n\t\treturn new Scalar(bls12_381.fields.Fr.fromBytes(bytes));\n\t}\n\n\tstatic fromNumber(num: number): Scalar {\n\t\treturn new Scalar(BigInt(num));\n\t}\n}\n"],
5
- "mappings": "AAGA,SAAS,aAAa;AAGtB,SAAS,iBAAiB;AAEnB,MAAM,UAAU;AAAA,EAGtB,YAAY,OAA8B;AACzC,SAAK,QAAQ;AAAA,EACd;AAAA,EAEA,OAAO,YAAuB;AAC7B,WAAO,IAAI,UAAU,UAAU,GAAG,gBAAgB,IAAI;AAAA,EACvD;AAAA,EAEA,OAAO,UAAU,OAA8B;AAC9C,WAAO,IAAI,UAAU,UAAU,GAAG,gBAAgB,QAAQ,MAAM,KAAK,CAAC,CAAC;AAAA,EACxE;AAAA,EAEA,UAAsB;AACrB,WAAO,KAAK,MAAM,WAAW;AAAA,EAC9B;AAAA,EAEA,SAAS,QAA2B;AACnC,WAAO,IAAI,UAAU,KAAK,MAAM,SAAS,OAAO,MAAM,CAAC;AAAA,EACxD;AAAA,EAEA,IAAI,OAA6B;AAChC,WAAO,IAAI,UAAU,KAAK,MAAM,IAAI,MAAM,KAAK,CAAC;AAAA,EACjD;AAAA,EAEA,SAAS,OAA6B;AACrC,WAAO,IAAI,UAAU,KAAK,MAAM,SAAS,MAAM,KAAK,CAAC;AAAA,EACtD;AAAA,EAEA,OAAO,YAAY,MAA6B;AAC/C,WAAO,IAAI;AAAA,MACV,UAAU,GAAG,gBAAgB,WAAW,UAAU,GAAG,YAAY,IAAI,EAAE,SAAS,CAAC;AAAA,IAClF;AAAA,EACD;AAAA,EAEA,QAAQ,OAA6B;AACpC,WAAO,IAAI,UAAU,UAAU,QAAQ,KAAK,OAAO,MAAM,KAAK,CAAC;AAAA,EAChE;AACD;AAEO,MAAM,UAAU;AAAA,EAGtB,YAAY,OAA2B;AACtC,SAAK,QAAQ;AAAA,EACd;AAAA,EAEA,OAAO,YAAuB;AAC7B,WAAO,IAAI,UAAU,UAAU,GAAG,gBAAgB,IAAI;AAAA,EACvD;AAAA,EAEA,OAAO,UAAU,OAA8B;AAC9C,WAAO,IAAI,UAAU,UAAU,GAAG,gBAAgB,QAAQ,MAAM,KAAK,CAAC,CAAC;AAAA,EACxE;AAAA,EAEA,UAAsB;AACrB,WAAO,KAAK,MAAM,WAAW;AAAA,EAC9B;AAAA,EAEA,SAAS,QAA2B;AACnC,WAAO,IAAI,UAAU,KAAK,MAAM,SAAS,OAAO,MAAM,CAAC;AAAA,EACxD;AAAA,EAEA,IAAI,OAA6B;AAChC,WAAO,IAAI,UAAU,KAAK,MAAM,IAAI,MAAM,KAAK,CAAC;AAAA,EACjD;AAAA,EAEA,YAAY,MAA6B;AACxC,WAAO,IAAI;AAAA,MACV,UAAU,GAAG,gBAAgB,WAAW,UAAU,GAAG,YAAY,IAAI,EAAE,SAAS,CAAC;AAAA,IAClF;AAAA,EACD;AACD;AAEO,MAAM,UAAU;AAAA,EAGtB,YAAY,SAAe;AAC1B,SAAK,UAAU;AAAA,EAChB;AAAA,EAEA,UAAsB;AACrB,WAAO,UAAU,OAAO,KAAK,QAAQ,KAAK,OAAO;AAAA,EAClD;AACD;AAEO,MAAM,OAAO;AAAA,EAGnB,YAAY,QAAgB;AAC3B,SAAK,SAAS;AAAA,EACf;AAAA,EAEA,OAAO,SAAiB;AACvB,WAAO,OAAO,UAAU,UAAU,MAAM,iBAAiB,CAAC;AAAA,EAC3D;AAAA,EAEA,UAAsB;AACrB,WAAO,IAAI,WAAW,UAAU,OAAO,GAAG,QAAQ,KAAK,MAAM,CAAC;AAAA,EAC/D;AAAA,EAEA,OAAO,UAAU,OAA2B;AAC3C,WAAO,IAAI,OAAO,UAAU,OAAO,GAAG,UAAU,KAAK,CAAC;AAAA,EACvD;AAAA,EAEA,OAAO,WAAW,KAAqB;AACtC,WAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,EAC9B;AACD;",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { toHex } from '@mysten/bcs';\nimport type { Fp2, Fp12 } from '@noble/curves/abstract/tower';\nimport type { ProjPointType } from '@noble/curves/abstract/weierstrass';\nimport { bls12_381 } from '@noble/curves/bls12-381';\nimport { flatten } from './utils.js';\n\nexport class G1Element {\n\tpoint: ProjPointType<bigint>;\n\n\tpublic static readonly SIZE = 48;\n\n\tconstructor(point: ProjPointType<bigint>) {\n\t\tthis.point = point;\n\t}\n\n\tstatic generator(): G1Element {\n\t\treturn new G1Element(bls12_381.G1.ProjectivePoint.BASE);\n\t}\n\n\tstatic fromBytes(bytes: Uint8Array): G1Element {\n\t\treturn new G1Element(bls12_381.G1.ProjectivePoint.fromHex(toHex(bytes)));\n\t}\n\n\ttoBytes(): Uint8Array {\n\t\treturn this.point.toRawBytes();\n\t}\n\n\tmultiply(scalar: Scalar): G1Element {\n\t\treturn new G1Element(this.point.multiply(scalar.scalar));\n\t}\n\n\tadd(other: G1Element): G1Element {\n\t\treturn new G1Element(this.point.add(other.point));\n\t}\n\n\tsubtract(other: G1Element): G1Element {\n\t\treturn new G1Element(this.point.subtract(other.point));\n\t}\n\n\tstatic hashToCurve(data: Uint8Array): G1Element {\n\t\treturn new G1Element(\n\t\t\tbls12_381.G1.ProjectivePoint.fromAffine(bls12_381.G1.hashToCurve(data).toAffine()),\n\t\t);\n\t}\n\n\tpairing(other: G2Element): GTElement {\n\t\treturn new GTElement(bls12_381.pairing(this.point, other.point));\n\t}\n}\n\nexport class G2Element {\n\tpoint: ProjPointType<Fp2>;\n\n\tpublic static readonly SIZE = 96;\n\n\tconstructor(point: ProjPointType<Fp2>) {\n\t\tthis.point = point;\n\t}\n\n\tstatic generator(): G2Element {\n\t\treturn new G2Element(bls12_381.G2.ProjectivePoint.BASE);\n\t}\n\n\tstatic fromBytes(bytes: Uint8Array): G2Element {\n\t\treturn new G2Element(bls12_381.G2.ProjectivePoint.fromHex(toHex(bytes)));\n\t}\n\n\ttoBytes(): Uint8Array {\n\t\treturn this.point.toRawBytes();\n\t}\n\n\tmultiply(scalar: Scalar): G2Element {\n\t\treturn new G2Element(this.point.multiply(scalar.scalar));\n\t}\n\n\tadd(other: G2Element): G2Element {\n\t\treturn new G2Element(this.point.add(other.point));\n\t}\n\n\thashToCurve(data: Uint8Array): G2Element {\n\t\treturn new G2Element(\n\t\t\tbls12_381.G2.ProjectivePoint.fromAffine(bls12_381.G2.hashToCurve(data).toAffine()),\n\t\t);\n\t}\n}\n\nexport class GTElement {\n\telement: Fp12;\n\n\tpublic static readonly SIZE = 576;\n\n\tconstructor(element: Fp12) {\n\t\tthis.element = element;\n\t}\n\n\ttoBytes(): Uint8Array {\n\t\t// This permutation reorders the 6 pairs of coefficients of the GT element for compatability with the Rust and Move implementations.\n\t\t//\n\t\t// The permutation P may be computed as:\n\t\t// for i in 0..3 {\n\t\t// for j in 0..2 {\n\t\t// P[2 * i + j] = i + 3 * j;\n\t\t// }\n\t\t// }\n\t\tconst P = [0, 3, 1, 4, 2, 5];\n\t\tconst PAIR_SIZE = GTElement.SIZE / P.length;\n\n\t\tconst bytes = bls12_381.fields.Fp12.toBytes(this.element);\n\t\treturn flatten(P.map((p) => bytes.subarray(p * PAIR_SIZE, (p + 1) * PAIR_SIZE)));\n\t}\n\n\tequals(other: GTElement): boolean {\n\t\treturn bls12_381.fields.Fp12.eql(this.element, other.element);\n\t}\n}\n\nexport class Scalar {\n\tscalar: bigint;\n\n\tpublic static readonly SIZE = 32;\n\n\tconstructor(scalar: bigint) {\n\t\tthis.scalar = scalar;\n\t}\n\n\tstatic random(): Scalar {\n\t\treturn Scalar.fromBytes(bls12_381.utils.randomPrivateKey());\n\t}\n\n\ttoBytes(): Uint8Array {\n\t\treturn new Uint8Array(bls12_381.fields.Fr.toBytes(this.scalar));\n\t}\n\n\tstatic fromBytes(bytes: Uint8Array): Scalar {\n\t\treturn new Scalar(bls12_381.fields.Fr.fromBytes(bytes));\n\t}\n\n\tstatic fromNumber(num: number): Scalar {\n\t\treturn new Scalar(BigInt(num));\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,5 @@
1
1
  import { DemType, KemType } from './encrypt.js';
2
- import type { KeyServer } from './key-server.js';
2
+ import type { DerivedKey, KeyServer } from './key-server.js';
3
3
  import type { SessionKey } from './session-key.js';
4
4
  import type { SealCompatibleClient } from './types.js';
5
5
  /**
@@ -11,7 +11,7 @@ import type { SealCompatibleClient } from './types.js';
11
11
  * @property timeout: Timeout in milliseconds for network requests. Defaults to 10 seconds.
12
12
  */
13
13
  export interface SealClientExtensionOptions {
14
- serverObjectIds: string[];
14
+ serverObjectIds: [string, number][];
15
15
  verifyKeyServers?: boolean;
16
16
  timeout?: number;
17
17
  }
@@ -54,8 +54,7 @@ export declare class SealClient {
54
54
  * Decrypt the given encrypted bytes using cached keys.
55
55
  * Calls fetchKeys in case one or more of the required keys is not cached yet.
56
56
  * The function throws an error if the client's key servers are not a subset of
57
- * the encrypted object's key servers (including the same weights) or if the
58
- * threshold cannot be met.
57
+ * the encrypted object's key servers or if the threshold cannot be met.
59
58
  *
60
59
  * @param data - The encrypted bytes to decrypt.
61
60
  * @param sessionKey - The session key to use.
@@ -67,11 +66,11 @@ export declare class SealClient {
67
66
  sessionKey: SessionKey;
68
67
  txBytes: Uint8Array;
69
68
  }): Promise<Uint8Array<ArrayBufferLike>>;
70
- getKeyServers(): Promise<KeyServer[]>;
69
+ getKeyServers(): Promise<Map<string, KeyServer>>;
71
70
  /**
72
71
  * Fetch keys from the key servers and update the cache.
73
72
  *
74
- * It is recommended to call this function once for all ids of all encrypted obejcts if
73
+ * It is recommended to call this function once for all ids of all encrypted objects if
75
74
  * there are multiple, then call decrypt for each object. This avoids calling fetchKey
76
75
  * individually for each decrypt.
77
76
  *
@@ -86,4 +85,20 @@ export declare class SealClient {
86
85
  sessionKey: SessionKey;
87
86
  threshold: number;
88
87
  }): Promise<void>;
88
+ /**
89
+ * Get derived keys from the given services.
90
+ *
91
+ * @param id - The id of the encrypted object.
92
+ * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).
93
+ * @param sessionKey - The session key to use.
94
+ * @param threshold - The threshold.
95
+ * @returns - Derived keys for the given services that are in the cache as a "service object ID" -> derived key map. If the call is succesful, exactly threshold keys will be returned.
96
+ */
97
+ getDerivedKeys({ kemType, id, txBytes, sessionKey, threshold, }: {
98
+ kemType?: KemType;
99
+ id: string;
100
+ txBytes: Uint8Array;
101
+ sessionKey: SessionKey;
102
+ threshold: number;
103
+ }): Promise<Map<string, DerivedKey>>;
89
104
  }
@@ -6,7 +6,7 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
6
6
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
7
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
8
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
9
- var _suiClient, _serverObjectIds, _verifyKeyServers, _keyServers, _cachedKeys, _timeout, _SealClient_instances, createEncryptionInput_fn, validateEncryptionServices_fn, loadKeyServers_fn;
9
+ var _suiClient, _weights, _keyServers, _verifyKeyServers, _cachedKeys, _timeout, _totalWeight, _SealClient_instances, createEncryptionInput_fn, weight_fn, validateEncryptionServices_fn, getWeightedKeyServers_fn, loadKeyServers_fn;
10
10
  import { EncryptedObject } from "./bcs.js";
11
11
  import { G1Element, G2Element } from "./bls12381.js";
12
12
  import { decrypt } from "./decrypt.js";
@@ -14,26 +14,38 @@ import { AesGcm256, Hmac256Ctr } from "./dem.js";
14
14
  import { DemType, encrypt, KemType } from "./encrypt.js";
15
15
  import {
16
16
  InconsistentKeyServersError,
17
+ InvalidClientOptionsError,
17
18
  InvalidKeyServerError,
18
19
  InvalidThresholdError,
19
- toMajorityError
20
+ toMajorityError,
21
+ TooManyFailedFetchKeyRequestsError
20
22
  } from "./error.js";
21
23
  import { BonehFranklinBLS12381Services, DST } from "./ibe.js";
22
- import { KeyServerType, retrieveKeyServers, verifyKeyServer } from "./key-server.js";
24
+ import {
25
+ BonehFranklinBLS12381DerivedKey,
26
+ KeyServerType,
27
+ retrieveKeyServers,
28
+ verifyKeyServer
29
+ } from "./key-server.js";
23
30
  import { fetchKeysForAllIds } from "./keys.js";
24
- import { createFullId } from "./utils.js";
31
+ import { createFullId, count } from "./utils.js";
25
32
  const _SealClient = class _SealClient {
26
33
  constructor(options) {
27
34
  __privateAdd(this, _SealClient_instances);
28
35
  __privateAdd(this, _suiClient);
29
- __privateAdd(this, _serverObjectIds);
30
- __privateAdd(this, _verifyKeyServers);
36
+ __privateAdd(this, _weights);
31
37
  __privateAdd(this, _keyServers, null);
38
+ __privateAdd(this, _verifyKeyServers);
32
39
  // A caching map for: fullId:object_id -> partial key.
33
40
  __privateAdd(this, _cachedKeys, /* @__PURE__ */ new Map());
34
41
  __privateAdd(this, _timeout);
42
+ __privateAdd(this, _totalWeight);
35
43
  __privateSet(this, _suiClient, options.suiClient);
36
- __privateSet(this, _serverObjectIds, options.serverObjectIds);
44
+ if (new Set(options.serverObjectIds.map(([objectId, _]) => objectId)).size !== options.serverObjectIds.length) {
45
+ throw new InvalidClientOptionsError("Duplicate object IDs");
46
+ }
47
+ __privateSet(this, _weights, new Map(options.serverObjectIds));
48
+ __privateSet(this, _totalWeight, options.serverObjectIds.map(([_, weight]) => weight).reduce((sum, term) => sum + term, 0));
37
49
  __privateSet(this, _verifyKeyServers, options.verifyKeyServers ?? true);
38
50
  __privateSet(this, _timeout, options.timeout ?? 1e4);
39
51
  }
@@ -71,7 +83,7 @@ const _SealClient = class _SealClient {
71
83
  aad = new Uint8Array()
72
84
  }) {
73
85
  return encrypt({
74
- keyServers: await this.getKeyServers(),
86
+ keyServers: await __privateMethod(this, _SealClient_instances, getWeightedKeyServers_fn).call(this),
75
87
  kemType,
76
88
  threshold,
77
89
  packageId,
@@ -83,8 +95,7 @@ const _SealClient = class _SealClient {
83
95
  * Decrypt the given encrypted bytes using cached keys.
84
96
  * Calls fetchKeys in case one or more of the required keys is not cached yet.
85
97
  * The function throws an error if the client's key servers are not a subset of
86
- * the encrypted object's key servers (including the same weights) or if the
87
- * threshold cannot be met.
98
+ * the encrypted object's key servers or if the threshold cannot be met.
88
99
  *
89
100
  * @param data - The encrypted bytes to decrypt.
90
101
  * @param sessionKey - The session key to use.
@@ -118,7 +129,7 @@ const _SealClient = class _SealClient {
118
129
  /**
119
130
  * Fetch keys from the key servers and update the cache.
120
131
  *
121
- * It is recommended to call this function once for all ids of all encrypted obejcts if
132
+ * It is recommended to call this function once for all ids of all encrypted objects if
122
133
  * there are multiple, then call decrypt for each object. This avoids calling fetchKey
123
134
  * individually for each decrypt.
124
135
  *
@@ -133,32 +144,29 @@ const _SealClient = class _SealClient {
133
144
  sessionKey,
134
145
  threshold
135
146
  }) {
136
- const keyServers = await this.getKeyServers();
137
- if (threshold > keyServers.length || threshold < 1 || keyServers.length < 1) {
147
+ if (threshold > __privateGet(this, _totalWeight) || threshold < 1) {
138
148
  throw new InvalidThresholdError(
139
- `Invalid threshold ${threshold} for ${keyServers.length} servers`
149
+ `Invalid threshold ${threshold} servers with weights ${__privateGet(this, _weights)}`
140
150
  );
141
151
  }
142
- let completedServerCount = 0;
143
- const remainingKeyServers = /* @__PURE__ */ new Set();
152
+ const keyServers = await this.getKeyServers();
144
153
  const fullIds = ids.map((id) => createFullId(DST, sessionKey.getPackageId(), id));
145
- for (const server of keyServers) {
146
- let hasAllKeys = true;
147
- for (const fullId of fullIds) {
148
- if (!__privateGet(this, _cachedKeys).has(`${fullId}:${server.objectId}`)) {
149
- hasAllKeys = false;
150
- remainingKeyServers.add(server);
151
- break;
152
- }
153
- }
154
- if (hasAllKeys) {
155
- completedServerCount++;
154
+ let completedWeight = 0;
155
+ const remainingKeyServers = [];
156
+ let remainingKeyServersWeight = 0;
157
+ for (const objectId of keyServers.keys()) {
158
+ if (fullIds.every((fullId) => __privateGet(this, _cachedKeys).has(`${fullId}:${objectId}`))) {
159
+ completedWeight += __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
160
+ } else {
161
+ remainingKeyServers.push(objectId);
162
+ remainingKeyServersWeight += __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
156
163
  }
157
164
  }
158
- if (completedServerCount >= threshold) {
165
+ if (completedWeight >= threshold) {
159
166
  return;
160
167
  }
161
- for (const server of remainingKeyServers) {
168
+ for (const objectId of remainingKeyServers) {
169
+ const server = keyServers.get(objectId);
162
170
  if (server.keyType !== KeyServerType.BonehFranklinBLS12381) {
163
171
  throw new InvalidKeyServerError(
164
172
  `Server ${server.objectId} has invalid key type: ${server.keyType}`
@@ -169,7 +177,8 @@ const _SealClient = class _SealClient {
169
177
  const signedRequest = await sessionKey.createRequestParams(txBytes);
170
178
  const controller = new AbortController();
171
179
  const errors = [];
172
- const keyFetches = [...remainingKeyServers].map(async (server) => {
180
+ const keyFetches = remainingKeyServers.map(async (objectId) => {
181
+ const server = keyServers.get(objectId);
173
182
  try {
174
183
  const allKeys = await fetchKeysForAllIds(
175
184
  server.url,
@@ -194,11 +203,9 @@ const _SealClient = class _SealClient {
194
203
  __privateGet(this, _cachedKeys).set(`${fullId}:${server.objectId}`, keyElement);
195
204
  receivedIds.add(fullId);
196
205
  }
197
- const expectedIds = new Set(fullIds);
198
- const hasAllKeys = receivedIds.size === expectedIds.size && [...receivedIds].every((id) => expectedIds.has(id));
199
- if (hasAllKeys) {
200
- completedServerCount++;
201
- if (completedServerCount >= threshold) {
206
+ if (fullIds.every((fullId) => receivedIds.has(fullId))) {
207
+ completedWeight += __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
208
+ if (completedWeight >= threshold) {
202
209
  controller.abort();
203
210
  }
204
211
  }
@@ -206,23 +213,72 @@ const _SealClient = class _SealClient {
206
213
  if (!controller.signal.aborted) {
207
214
  errors.push(error);
208
215
  }
209
- if (remainingKeyServers.size - errors.length < threshold - completedServerCount) {
210
- controller.abort(error);
216
+ } finally {
217
+ remainingKeyServersWeight -= __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
218
+ if (remainingKeyServersWeight < threshold - completedWeight) {
219
+ controller.abort(new TooManyFailedFetchKeyRequestsError());
211
220
  }
212
221
  }
213
222
  });
214
223
  await Promise.allSettled(keyFetches);
215
- if (completedServerCount < threshold) {
224
+ if (completedWeight < threshold) {
216
225
  throw toMajorityError(errors);
217
226
  }
218
227
  }
228
+ /**
229
+ * Get derived keys from the given services.
230
+ *
231
+ * @param id - The id of the encrypted object.
232
+ * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).
233
+ * @param sessionKey - The session key to use.
234
+ * @param threshold - The threshold.
235
+ * @returns - Derived keys for the given services that are in the cache as a "service object ID" -> derived key map. If the call is succesful, exactly threshold keys will be returned.
236
+ */
237
+ async getDerivedKeys({
238
+ kemType = KemType.BonehFranklinBLS12381DemCCA,
239
+ id,
240
+ txBytes,
241
+ sessionKey,
242
+ threshold
243
+ }) {
244
+ switch (kemType) {
245
+ case KemType.BonehFranklinBLS12381DemCCA:
246
+ const keyServers = await this.getKeyServers();
247
+ if (threshold > __privateGet(this, _totalWeight)) {
248
+ throw new InvalidThresholdError(
249
+ `Invalid threshold ${threshold} for ${__privateGet(this, _totalWeight)} servers`
250
+ );
251
+ }
252
+ await this.fetchKeys({
253
+ ids: [id],
254
+ txBytes,
255
+ sessionKey,
256
+ threshold
257
+ });
258
+ const fullId = createFullId(DST, sessionKey.getPackageId(), id);
259
+ const derivedKeys = /* @__PURE__ */ new Map();
260
+ let weight = 0;
261
+ for (const objectId of keyServers.keys()) {
262
+ const cachedKey = __privateGet(this, _cachedKeys).get(`${fullId}:${objectId}`);
263
+ if (cachedKey) {
264
+ derivedKeys.set(objectId, new BonehFranklinBLS12381DerivedKey(cachedKey));
265
+ weight += __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
266
+ if (weight >= threshold) {
267
+ break;
268
+ }
269
+ }
270
+ }
271
+ return derivedKeys;
272
+ }
273
+ }
219
274
  };
220
275
  _suiClient = new WeakMap();
221
- _serverObjectIds = new WeakMap();
222
- _verifyKeyServers = new WeakMap();
276
+ _weights = new WeakMap();
223
277
  _keyServers = new WeakMap();
278
+ _verifyKeyServers = new WeakMap();
224
279
  _cachedKeys = new WeakMap();
225
280
  _timeout = new WeakMap();
281
+ _totalWeight = new WeakMap();
226
282
  _SealClient_instances = new WeakSet();
227
283
  createEncryptionInput_fn = function(type, data, aad) {
228
284
  switch (type) {
@@ -232,31 +288,38 @@ createEncryptionInput_fn = function(type, data, aad) {
232
288
  return new Hmac256Ctr(data, aad);
233
289
  }
234
290
  };
291
+ weight_fn = function(objectId) {
292
+ return __privateGet(this, _weights).get(objectId) ?? 0;
293
+ };
235
294
  validateEncryptionServices_fn = function(services, threshold) {
236
- const serverObjectIdsMap = /* @__PURE__ */ new Map();
237
- for (const objectId of __privateGet(this, _serverObjectIds)) {
238
- serverObjectIdsMap.set(objectId, (serverObjectIdsMap.get(objectId) ?? 0) + 1);
239
- }
240
- const servicesMap = /* @__PURE__ */ new Map();
241
- for (const service of services) {
242
- servicesMap.set(service, (servicesMap.get(service) ?? 0) + 1);
243
- }
244
- for (const [objectId, count] of serverObjectIdsMap) {
245
- if (servicesMap.get(objectId) !== count) {
246
- throw new InconsistentKeyServersError(
247
- `Client's key servers must be a subset of the encrypted object's key servers`
248
- );
249
- }
295
+ if (services.some((objectId) => {
296
+ const countInClient = __privateMethod(this, _SealClient_instances, weight_fn).call(this, objectId);
297
+ return countInClient > 0 && countInClient !== count(services, objectId);
298
+ })) {
299
+ throw new InconsistentKeyServersError(
300
+ `Client's key servers must be a subset of the encrypted object's key servers`
301
+ );
250
302
  }
251
- if (threshold > __privateGet(this, _serverObjectIds).length) {
303
+ if (threshold > __privateGet(this, _totalWeight)) {
252
304
  throw new InvalidThresholdError(
253
- `Invalid threshold ${threshold} for ${__privateGet(this, _serverObjectIds).length} servers`
305
+ `Invalid threshold ${threshold} for ${__privateGet(this, _totalWeight)} servers`
254
306
  );
255
307
  }
256
308
  };
309
+ getWeightedKeyServers_fn = async function() {
310
+ const keyServers = await this.getKeyServers();
311
+ const keyServersWithMultiplicity = [];
312
+ for (const [objectId, weight] of __privateGet(this, _weights)) {
313
+ const keyServer = keyServers.get(objectId);
314
+ for (let i = 0; i < weight; i++) {
315
+ keyServersWithMultiplicity.push(keyServer);
316
+ }
317
+ }
318
+ return keyServersWithMultiplicity;
319
+ };
257
320
  loadKeyServers_fn = async function() {
258
321
  const keyServers = await retrieveKeyServers({
259
- objectIds: __privateGet(this, _serverObjectIds),
322
+ objectIds: [...__privateGet(this, _weights)].map(([objectId]) => objectId),
260
323
  client: __privateGet(this, _suiClient)
261
324
  });
262
325
  if (keyServers.length === 0) {
@@ -271,7 +334,7 @@ loadKeyServers_fn = async function() {
271
334
  })
272
335
  );
273
336
  }
274
- return keyServers;
337
+ return new Map(keyServers.map((server) => [server.objectId, server]));
275
338
  };
276
339
  let SealClient = _SealClient;
277
340
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/client.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { EncryptedObject } from './bcs.js';\nimport { G1Element, G2Element } from './bls12381.js';\nimport { decrypt } from './decrypt.js';\nimport type { EncryptionInput } from './dem.js';\nimport { AesGcm256, Hmac256Ctr } from './dem.js';\nimport { DemType, encrypt, KemType } from './encrypt.js';\nimport {\n\tInconsistentKeyServersError,\n\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, SealCompatibleClient } 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 */\n\nexport interface SealClientExtensionOptions {\n\tserverObjectIds: string[];\n\tverifyKeyServers?: boolean;\n\ttimeout?: number;\n}\n\nexport interface SealClientOptions extends SealClientExtensionOptions {\n\tsuiClient: SealCompatibleClient;\n}\n\nexport class SealClient {\n\t#suiClient: SealCompatibleClient;\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\tstatic experimental_asClientExtension(options: SealClientExtensionOptions) {\n\t\treturn {\n\t\t\tname: 'seal' as const,\n\t\t\tregister: (client: SealCompatibleClient) => {\n\t\t\t\treturn new SealClient({\n\t\t\t\t\tsuiClient: client,\n\t\t\t\t\t...options,\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Return an encrypted message under the identity.\n\t *\n\t * @param kemType - The type of KEM to use.\n\t * @param demType - The type of DEM to use.\n\t * @param threshold - The threshold for the TSS encryption.\n\t * @param packageId - the packageId namespace.\n\t * @param id - the identity to use.\n\t * @param data - the data to encrypt.\n\t * @param aad - optional additional authenticated data.\n\t * @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.\n\t * \tSince the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.\n\t */\n\tasync encrypt({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tdemType = DemType.AesGcm256,\n\t\tthreshold,\n\t\tpackageId,\n\t\tid,\n\t\tdata,\n\t\taad = new Uint8Array(),\n\t}: {\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\tconst 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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",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { EncryptedObject } from './bcs.js';\nimport { G1Element, G2Element } from './bls12381.js';\nimport { decrypt } from './decrypt.js';\nimport type { EncryptionInput } from './dem.js';\nimport { AesGcm256, Hmac256Ctr } from './dem.js';\nimport { DemType, encrypt, KemType } from './encrypt.js';\nimport {\n\tInconsistentKeyServersError,\n\tInvalidClientOptionsError,\n\tInvalidKeyServerError,\n\tInvalidThresholdError,\n\ttoMajorityError,\n\tTooManyFailedFetchKeyRequestsError,\n} from './error.js';\nimport { BonehFranklinBLS12381Services, DST } from './ibe.js';\nimport {\n\tBonehFranklinBLS12381DerivedKey,\n\tKeyServerType,\n\tretrieveKeyServers,\n\tverifyKeyServer,\n} from './key-server.js';\nimport type { DerivedKey, KeyServer } from './key-server.js';\nimport { fetchKeysForAllIds } from './keys.js';\nimport type { SessionKey } from './session-key.js';\nimport type { KeyCacheKey, SealCompatibleClient } from './types.js';\nimport { createFullId, count } 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 */\n\nexport interface SealClientExtensionOptions {\n\tserverObjectIds: [string, number][];\n\tverifyKeyServers?: boolean;\n\ttimeout?: number;\n}\n\nexport interface SealClientOptions extends SealClientExtensionOptions {\n\tsuiClient: SealCompatibleClient;\n}\n\nexport class SealClient {\n\t#suiClient: SealCompatibleClient;\n\t#weights: Map<string, number>;\n\t#keyServers: Promise<Map<string, KeyServer>> | null = null;\n\t#verifyKeyServers: boolean;\n\t// A caching map for: fullId:object_id -> partial key.\n\t#cachedKeys = new Map<KeyCacheKey, G1Element>();\n\t#timeout: number;\n\t#totalWeight: number;\n\n\tconstructor(options: SealClientOptions) {\n\t\tthis.#suiClient = options.suiClient;\n\n\t\tif (\n\t\t\tnew Set(options.serverObjectIds.map(([objectId, _]) => objectId)).size !==\n\t\t\toptions.serverObjectIds.length\n\t\t) {\n\t\t\tthrow new InvalidClientOptionsError('Duplicate object IDs');\n\t\t}\n\n\t\tthis.#weights = new Map(options.serverObjectIds);\n\t\tthis.#totalWeight = options.serverObjectIds\n\t\t\t.map(([_, weight]) => weight)\n\t\t\t.reduce((sum, term) => sum + term, 0);\n\n\t\tthis.#verifyKeyServers = options.verifyKeyServers ?? true;\n\t\tthis.#timeout = options.timeout ?? 10_000;\n\t}\n\n\tstatic experimental_asClientExtension(options: SealClientExtensionOptions) {\n\t\treturn {\n\t\t\tname: 'seal' as const,\n\t\t\tregister: (client: SealCompatibleClient) => {\n\t\t\t\treturn new SealClient({\n\t\t\t\t\tsuiClient: client,\n\t\t\t\t\t...options,\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Return an encrypted message under the identity.\n\t *\n\t * @param kemType - The type of KEM to use.\n\t * @param demType - The type of DEM to use.\n\t * @param threshold - The threshold for the TSS encryption.\n\t * @param packageId - the packageId namespace.\n\t * @param id - the identity to use.\n\t * @param data - the data to encrypt.\n\t * @param aad - optional additional authenticated data.\n\t * @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.\n\t * \tSince the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.\n\t */\n\tasync encrypt({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tdemType = DemType.AesGcm256,\n\t\tthreshold,\n\t\tpackageId,\n\t\tid,\n\t\tdata,\n\t\taad = new Uint8Array(),\n\t}: {\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.#getWeightedKeyServers(),\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 or if the 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#weight(objectId: string) {\n\t\treturn this.#weights.get(objectId) ?? 0;\n\t}\n\n\t#validateEncryptionServices(services: string[], threshold: number) {\n\t\t// Check that the client's key servers are a subset of the encrypted object's key servers.\n\t\tif (\n\t\t\tservices.some((objectId) => {\n\t\t\t\tconst countInClient = this.#weight(objectId);\n\t\t\t\treturn countInClient > 0 && countInClient !== count(services, objectId);\n\t\t\t})\n\t\t) {\n\t\t\tthrow new InconsistentKeyServersError(\n\t\t\t\t`Client's key servers must be a subset of the encrypted object's key servers`,\n\t\t\t);\n\t\t}\n\t\t// Check that the threshold can be met with the client's key servers.\n\t\tif (threshold > this.#totalWeight) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${this.#totalWeight} servers`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync getKeyServers(): Promise<Map<string, KeyServer>> {\n\t\tif (!this.#keyServers) {\n\t\t\tthis.#keyServers = this.#loadKeyServers().catch((error) => {\n\t\t\t\tthis.#keyServers = null;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t}\n\t\treturn this.#keyServers;\n\t}\n\n\t/**\n\t * Returns a list of key servers with multiplicity according to their weights.\n\t * The list is used for encryption.\n\t */\n\tasync #getWeightedKeyServers() {\n\t\tconst keyServers = await this.getKeyServers();\n\t\tconst keyServersWithMultiplicity = [];\n\t\tfor (const [objectId, weight] of this.#weights) {\n\t\t\tconst keyServer = keyServers.get(objectId)!;\n\t\t\tfor (let i = 0; i < weight; i++) {\n\t\t\t\tkeyServersWithMultiplicity.push(keyServer);\n\t\t\t}\n\t\t}\n\t\treturn keyServersWithMultiplicity;\n\t}\n\n\tasync #loadKeyServers(): Promise<Map<string, KeyServer>> {\n\t\tconst keyServers = await retrieveKeyServers({\n\t\t\tobjectIds: [...this.#weights].map(([objectId]) => objectId),\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\t\treturn new Map(keyServers.map((server) => [server.objectId, server]));\n\t}\n\n\t/**\n\t * Fetch keys from the key servers and update the cache.\n\t *\n\t * It is recommended to call this function once for all ids of all encrypted objects if\n\t * there are multiple, then call decrypt for each object. This avoids calling fetchKey\n\t * individually for each decrypt.\n\t *\n\t * @param ids - The ids of the encrypted objects.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold for the TSS encryptions. The function returns when a threshold of key servers had returned keys for all ids.\n\t */\n\tasync fetchKeys({\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\tif (threshold > this.#totalWeight || threshold < 1) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} servers with weights ${this.#weights}`,\n\t\t\t);\n\t\t}\n\t\tconst keyServers = await this.getKeyServers();\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\tlet completedWeight = 0;\n\t\tconst remainingKeyServers = [];\n\t\tlet remainingKeyServersWeight = 0;\n\t\tfor (const objectId of keyServers.keys()) {\n\t\t\tif (fullIds.every((fullId) => this.#cachedKeys.has(`${fullId}:${objectId}`))) {\n\t\t\t\tcompletedWeight += this.#weight(objectId)!;\n\t\t\t} else {\n\t\t\t\tremainingKeyServers.push(objectId);\n\t\t\t\tremainingKeyServersWeight += this.#weight(objectId)!;\n\t\t\t}\n\t\t}\n\n\t\t// Return early if we have enough keys from cache.\n\t\tif (completedWeight >= threshold) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check server validities.\n\t\tfor (const objectId of remainingKeyServers) {\n\t\t\tconst server = keyServers.get(objectId)!;\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 (objectId) => {\n\t\t\tconst server = keyServers.get(objectId)!;\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\tconst 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\tif (fullIds.every((fullId) => receivedIds.has(fullId))) {\n\t\t\t\t\tcompletedWeight += this.#weight(objectId)!;\n\n\t\t\t\t\t// Return early if the completed servers is more than the threshold.\n\t\t\t\t\tif (completedWeight >= threshold) {\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (!controller.signal.aborted) {\n\t\t\t\t\terrors.push(error as Error);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// If there are too many errors that the threshold is not attainable, return early with error.\n\t\t\t\tremainingKeyServersWeight -= this.#weight(objectId)!;\n\t\t\t\tif (remainingKeyServersWeight < threshold - completedWeight) {\n\t\t\t\t\tcontroller.abort(new TooManyFailedFetchKeyRequestsError());\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.allSettled(keyFetches);\n\n\t\tif (completedWeight < threshold) {\n\t\t\tthrow toMajorityError(errors);\n\t\t}\n\t}\n\n\t/**\n\t * Get derived keys from the given services.\n\t *\n\t * @param id - The id of the encrypted object.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold.\n\t * @returns - Derived keys for the given services that are in the cache as a \"service object ID\" -> derived key map. If the call is succesful, exactly threshold keys will be returned.\n\t */\n\tasync getDerivedKeys({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tid,\n\t\ttxBytes,\n\t\tsessionKey,\n\t\tthreshold,\n\t}: {\n\t\tkemType?: KemType;\n\t\tid: string;\n\t\ttxBytes: Uint8Array;\n\t\tsessionKey: SessionKey;\n\t\tthreshold: number;\n\t}): Promise<Map<string, DerivedKey>> {\n\t\tswitch (kemType) {\n\t\t\tcase KemType.BonehFranklinBLS12381DemCCA:\n\t\t\t\tconst keyServers = await this.getKeyServers();\n\t\t\t\tif (threshold > this.#totalWeight) {\n\t\t\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t\t\t`Invalid threshold ${threshold} for ${this.#totalWeight} servers`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait this.fetchKeys({\n\t\t\t\t\tids: [id],\n\t\t\t\t\ttxBytes,\n\t\t\t\t\tsessionKey,\n\t\t\t\t\tthreshold,\n\t\t\t\t});\n\n\t\t\t\t// After calling fetchKeys, we can be sure that there are at least `threshold` of the required keys in the cache.\n\t\t\t\t// It is also checked there that the KeyServerType is BonehFranklinBLS12381 for all services.\n\n\t\t\t\tconst fullId = createFullId(DST, sessionKey.getPackageId(), id);\n\n\t\t\t\tconst derivedKeys = new Map();\n\t\t\t\tlet weight = 0;\n\t\t\t\tfor (const objectId of keyServers.keys()) {\n\t\t\t\t\t// The code below assumes that the KeyServerType is BonehFranklinBLS12381.\n\t\t\t\t\tconst cachedKey = this.#cachedKeys.get(`${fullId}:${objectId}`);\n\t\t\t\t\tif (cachedKey) {\n\t\t\t\t\t\tderivedKeys.set(objectId, new BonehFranklinBLS12381DerivedKey(cachedKey));\n\t\t\t\t\t\tweight += this.#weight(objectId)!;\n\t\t\t\t\t\tif (weight >= threshold) {\n\t\t\t\t\t\t\t// We have enough keys, so we can stop.\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn derivedKeys;\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }