@inco/lightning-js 0.0.0-bootstrap.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +587 -0
  3. package/dist/cjs/advancedacl/index.d.ts +2 -0
  4. package/dist/cjs/advancedacl/index.js +19 -0
  5. package/dist/cjs/advancedacl/session-key.d.ts +95 -0
  6. package/dist/cjs/advancedacl/session-key.js +376 -0
  7. package/dist/cjs/advancedacl/types.d.ts +16 -0
  8. package/dist/cjs/advancedacl/types.js +3 -0
  9. package/dist/cjs/attestedcompute/attested-compute.d.ts +65 -0
  10. package/dist/cjs/attestedcompute/attested-compute.js +80 -0
  11. package/dist/cjs/attestedcompute/types.d.ts +35 -0
  12. package/dist/cjs/attestedcompute/types.js +46 -0
  13. package/dist/cjs/attesteddecrypt/attested-decrypt.d.ts +61 -0
  14. package/dist/cjs/attesteddecrypt/attested-decrypt.js +118 -0
  15. package/dist/cjs/attesteddecrypt/index.d.ts +1 -0
  16. package/dist/cjs/attesteddecrypt/index.js +18 -0
  17. package/dist/cjs/attesteddecrypt/types.d.ts +27 -0
  18. package/dist/cjs/attesteddecrypt/types.js +16 -0
  19. package/dist/cjs/attestedreveal/attested-reveal.d.ts +21 -0
  20. package/dist/cjs/attestedreveal/attested-reveal.js +31 -0
  21. package/dist/cjs/attestedreveal/index.d.ts +2 -0
  22. package/dist/cjs/attestedreveal/index.js +21 -0
  23. package/dist/cjs/attestedreveal/types.d.ts +4 -0
  24. package/dist/cjs/attestedreveal/types.js +13 -0
  25. package/dist/cjs/binary.d.ts +104 -0
  26. package/dist/cjs/binary.js +171 -0
  27. package/dist/cjs/chain.d.ts +50 -0
  28. package/dist/cjs/chain.js +62 -0
  29. package/dist/cjs/eip712/eip712.d.ts +18 -0
  30. package/dist/cjs/eip712/eip712.js +51 -0
  31. package/dist/cjs/eip712/index.d.ts +1 -0
  32. package/dist/cjs/eip712/index.js +8 -0
  33. package/dist/cjs/elistattesteddecrypt/elist-attested-decrypt.d.ts +51 -0
  34. package/dist/cjs/elistattesteddecrypt/elist-attested-decrypt.js +94 -0
  35. package/dist/cjs/elistattesteddecrypt/index.d.ts +2 -0
  36. package/dist/cjs/elistattesteddecrypt/index.js +22 -0
  37. package/dist/cjs/elistattesteddecrypt/types.d.ts +31 -0
  38. package/dist/cjs/elistattesteddecrypt/types.js +16 -0
  39. package/dist/cjs/encryption/encryption.d.ts +235 -0
  40. package/dist/cjs/encryption/encryption.js +226 -0
  41. package/dist/cjs/encryption/index.d.ts +1 -0
  42. package/dist/cjs/encryption/index.js +19 -0
  43. package/dist/cjs/generated/abis/add-two.d.ts +117 -0
  44. package/dist/cjs/generated/abis/add-two.js +80 -0
  45. package/dist/cjs/generated/abis/lightning.d.ts +3362 -0
  46. package/dist/cjs/generated/abis/lightning.js +2445 -0
  47. package/dist/cjs/generated/abis/test-elist.d.ts +276 -0
  48. package/dist/cjs/generated/abis/test-elist.js +168 -0
  49. package/dist/cjs/generated/abis/verifier.d.ts +1353 -0
  50. package/dist/cjs/generated/abis/verifier.js +954 -0
  51. package/dist/cjs/generated/es/inco/covalidator/compute/v1/server_pb.d.ts +1494 -0
  52. package/dist/cjs/generated/es/inco/covalidator/compute/v1/server_pb.js +395 -0
  53. package/dist/cjs/generated/es/inco/covalidator/compute/v1/types_pb.d.ts +247 -0
  54. package/dist/cjs/generated/es/inco/covalidator/compute/v1/types_pb.js +80 -0
  55. package/dist/cjs/generated/es/inco/helioswrapper/v1/helioswrapper_pb.d.ts +77 -0
  56. package/dist/cjs/generated/es/inco/helioswrapper/v1/helioswrapper_pb.js +28 -0
  57. package/dist/cjs/generated/es/inco/kms/lite/v1/kms_service_pb.d.ts +685 -0
  58. package/dist/cjs/generated/es/inco/kms/lite/v1/kms_service_pb.js +100 -0
  59. package/dist/cjs/generated/es/inco/kms/lite/v1/types_pb.d.ts +289 -0
  60. package/dist/cjs/generated/es/inco/kms/lite/v1/types_pb.js +136 -0
  61. package/dist/cjs/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.d.ts +371 -0
  62. package/dist/cjs/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.js +88 -0
  63. package/dist/cjs/generated/lightning.d.ts +830 -0
  64. package/dist/cjs/generated/lightning.js +872 -0
  65. package/dist/cjs/generated/local-node.d.ts +50 -0
  66. package/dist/cjs/generated/local-node.js +107 -0
  67. package/dist/cjs/handle.d.ts +123 -0
  68. package/dist/cjs/handle.js +221 -0
  69. package/dist/cjs/index.d.ts +5 -0
  70. package/dist/cjs/index.js +31 -0
  71. package/dist/cjs/kms/client.d.ts +12 -0
  72. package/dist/cjs/kms/client.js +47 -0
  73. package/dist/cjs/kms/quorumClient.d.ts +65 -0
  74. package/dist/cjs/kms/quorumClient.js +463 -0
  75. package/dist/cjs/kms/quorumConsistency.d.ts +82 -0
  76. package/dist/cjs/kms/quorumConsistency.js +269 -0
  77. package/dist/cjs/kms/signatureVerification.d.ts +35 -0
  78. package/dist/cjs/kms/signatureVerification.js +88 -0
  79. package/dist/cjs/kms/thresholdPromises.d.ts +8 -0
  80. package/dist/cjs/kms/thresholdPromises.js +62 -0
  81. package/dist/cjs/lite/attested-compute.d.ts +6 -0
  82. package/dist/cjs/lite/attested-compute.js +8 -0
  83. package/dist/cjs/lite/attested-decrypt.d.ts +4 -0
  84. package/dist/cjs/lite/attested-decrypt.js +6 -0
  85. package/dist/cjs/lite/deployments.d.ts +24 -0
  86. package/dist/cjs/lite/deployments.js +21 -0
  87. package/dist/cjs/lite/hadu.d.ts +4 -0
  88. package/dist/cjs/lite/hadu.js +28 -0
  89. package/dist/cjs/lite/index.d.ts +13 -0
  90. package/dist/cjs/lite/index.js +31 -0
  91. package/dist/cjs/lite/lightning.d.ts +459 -0
  92. package/dist/cjs/lite/lightning.js +696 -0
  93. package/dist/cjs/lite/types.d.ts +47 -0
  94. package/dist/cjs/lite/types.js +3 -0
  95. package/dist/cjs/lite/xwing.d.ts +154 -0
  96. package/dist/cjs/lite/xwing.js +326 -0
  97. package/dist/cjs/local/index.d.ts +1 -0
  98. package/dist/cjs/local/index.js +18 -0
  99. package/dist/cjs/local/local-node.d.ts +37 -0
  100. package/dist/cjs/local/local-node.js +80 -0
  101. package/dist/cjs/reencryption/eip712.d.ts +56 -0
  102. package/dist/cjs/reencryption/eip712.js +90 -0
  103. package/dist/cjs/reencryption/index.d.ts +2 -0
  104. package/dist/cjs/reencryption/index.js +19 -0
  105. package/dist/cjs/reencryption/types.d.ts +48 -0
  106. package/dist/cjs/reencryption/types.js +3 -0
  107. package/dist/cjs/retry.d.ts +30 -0
  108. package/dist/cjs/retry.js +87 -0
  109. package/dist/cjs/schema.d.ts +4 -0
  110. package/dist/cjs/schema.js +19 -0
  111. package/dist/cjs/test/mocks.d.ts +20 -0
  112. package/dist/cjs/test/mocks.js +72 -0
  113. package/dist/cjs/viem.d.ts +1141 -0
  114. package/dist/cjs/viem.js +36 -0
  115. package/dist/esm/advancedacl/index.d.ts +2 -0
  116. package/dist/esm/advancedacl/index.js +3 -0
  117. package/dist/esm/advancedacl/session-key.d.ts +95 -0
  118. package/dist/esm/advancedacl/session-key.js +367 -0
  119. package/dist/esm/advancedacl/types.d.ts +16 -0
  120. package/dist/esm/advancedacl/types.js +2 -0
  121. package/dist/esm/attestedcompute/attested-compute.d.ts +65 -0
  122. package/dist/esm/attestedcompute/attested-compute.js +76 -0
  123. package/dist/esm/attestedcompute/types.d.ts +35 -0
  124. package/dist/esm/attestedcompute/types.js +42 -0
  125. package/dist/esm/attesteddecrypt/attested-decrypt.d.ts +61 -0
  126. package/dist/esm/attesteddecrypt/attested-decrypt.js +112 -0
  127. package/dist/esm/attesteddecrypt/index.d.ts +1 -0
  128. package/dist/esm/attesteddecrypt/index.js +2 -0
  129. package/dist/esm/attesteddecrypt/types.d.ts +27 -0
  130. package/dist/esm/attesteddecrypt/types.js +12 -0
  131. package/dist/esm/attestedreveal/attested-reveal.d.ts +21 -0
  132. package/dist/esm/attestedreveal/attested-reveal.js +28 -0
  133. package/dist/esm/attestedreveal/index.d.ts +2 -0
  134. package/dist/esm/attestedreveal/index.js +3 -0
  135. package/dist/esm/attestedreveal/types.d.ts +4 -0
  136. package/dist/esm/attestedreveal/types.js +9 -0
  137. package/dist/esm/binary.d.ts +104 -0
  138. package/dist/esm/binary.js +155 -0
  139. package/dist/esm/chain.d.ts +50 -0
  140. package/dist/esm/chain.js +58 -0
  141. package/dist/esm/eip712/eip712.d.ts +18 -0
  142. package/dist/esm/eip712/eip712.js +46 -0
  143. package/dist/esm/eip712/index.d.ts +1 -0
  144. package/dist/esm/eip712/index.js +2 -0
  145. package/dist/esm/elistattesteddecrypt/elist-attested-decrypt.d.ts +51 -0
  146. package/dist/esm/elistattesteddecrypt/elist-attested-decrypt.js +89 -0
  147. package/dist/esm/elistattesteddecrypt/index.d.ts +2 -0
  148. package/dist/esm/elistattesteddecrypt/index.js +3 -0
  149. package/dist/esm/elistattesteddecrypt/types.d.ts +31 -0
  150. package/dist/esm/elistattesteddecrypt/types.js +12 -0
  151. package/dist/esm/encryption/encryption.d.ts +235 -0
  152. package/dist/esm/encryption/encryption.js +214 -0
  153. package/dist/esm/encryption/index.d.ts +1 -0
  154. package/dist/esm/encryption/index.js +2 -0
  155. package/dist/esm/generated/abis/add-two.d.ts +117 -0
  156. package/dist/esm/generated/abis/add-two.js +77 -0
  157. package/dist/esm/generated/abis/lightning.d.ts +3362 -0
  158. package/dist/esm/generated/abis/lightning.js +2442 -0
  159. package/dist/esm/generated/abis/test-elist.d.ts +276 -0
  160. package/dist/esm/generated/abis/test-elist.js +165 -0
  161. package/dist/esm/generated/abis/verifier.d.ts +1353 -0
  162. package/dist/esm/generated/abis/verifier.js +951 -0
  163. package/dist/esm/generated/es/inco/covalidator/compute/v1/server_pb.d.ts +1494 -0
  164. package/dist/esm/generated/es/inco/covalidator/compute/v1/server_pb.js +392 -0
  165. package/dist/esm/generated/es/inco/covalidator/compute/v1/types_pb.d.ts +247 -0
  166. package/dist/esm/generated/es/inco/covalidator/compute/v1/types_pb.js +77 -0
  167. package/dist/esm/generated/es/inco/helioswrapper/v1/helioswrapper_pb.d.ts +77 -0
  168. package/dist/esm/generated/es/inco/helioswrapper/v1/helioswrapper_pb.js +25 -0
  169. package/dist/esm/generated/es/inco/kms/lite/v1/kms_service_pb.d.ts +685 -0
  170. package/dist/esm/generated/es/inco/kms/lite/v1/kms_service_pb.js +97 -0
  171. package/dist/esm/generated/es/inco/kms/lite/v1/types_pb.d.ts +289 -0
  172. package/dist/esm/generated/es/inco/kms/lite/v1/types_pb.js +133 -0
  173. package/dist/esm/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.d.ts +371 -0
  174. package/dist/esm/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.js +85 -0
  175. package/dist/esm/generated/lightning.d.ts +830 -0
  176. package/dist/esm/generated/lightning.js +869 -0
  177. package/dist/esm/generated/local-node.d.ts +50 -0
  178. package/dist/esm/generated/local-node.js +104 -0
  179. package/dist/esm/handle.d.ts +123 -0
  180. package/dist/esm/handle.js +212 -0
  181. package/dist/esm/index.d.ts +5 -0
  182. package/dist/esm/index.js +6 -0
  183. package/dist/esm/kms/client.d.ts +12 -0
  184. package/dist/esm/kms/client.js +40 -0
  185. package/dist/esm/kms/quorumClient.d.ts +65 -0
  186. package/dist/esm/kms/quorumClient.js +459 -0
  187. package/dist/esm/kms/quorumConsistency.d.ts +82 -0
  188. package/dist/esm/kms/quorumConsistency.js +260 -0
  189. package/dist/esm/kms/signatureVerification.d.ts +35 -0
  190. package/dist/esm/kms/signatureVerification.js +84 -0
  191. package/dist/esm/kms/thresholdPromises.d.ts +8 -0
  192. package/dist/esm/kms/thresholdPromises.js +59 -0
  193. package/dist/esm/lite/attested-compute.d.ts +6 -0
  194. package/dist/esm/lite/attested-compute.js +4 -0
  195. package/dist/esm/lite/attested-decrypt.d.ts +4 -0
  196. package/dist/esm/lite/attested-decrypt.js +3 -0
  197. package/dist/esm/lite/deployments.d.ts +24 -0
  198. package/dist/esm/lite/deployments.js +17 -0
  199. package/dist/esm/lite/hadu.d.ts +4 -0
  200. package/dist/esm/lite/hadu.js +24 -0
  201. package/dist/esm/lite/index.d.ts +13 -0
  202. package/dist/esm/lite/index.js +10 -0
  203. package/dist/esm/lite/lightning.d.ts +459 -0
  204. package/dist/esm/lite/lightning.js +692 -0
  205. package/dist/esm/lite/types.d.ts +47 -0
  206. package/dist/esm/lite/types.js +2 -0
  207. package/dist/esm/lite/xwing.d.ts +154 -0
  208. package/dist/esm/lite/xwing.js +311 -0
  209. package/dist/esm/local/index.d.ts +1 -0
  210. package/dist/esm/local/index.js +2 -0
  211. package/dist/esm/local/local-node.d.ts +37 -0
  212. package/dist/esm/local/local-node.js +76 -0
  213. package/dist/esm/reencryption/eip712.d.ts +56 -0
  214. package/dist/esm/reencryption/eip712.js +87 -0
  215. package/dist/esm/reencryption/index.d.ts +2 -0
  216. package/dist/esm/reencryption/index.js +3 -0
  217. package/dist/esm/reencryption/types.d.ts +48 -0
  218. package/dist/esm/reencryption/types.js +2 -0
  219. package/dist/esm/retry.d.ts +30 -0
  220. package/dist/esm/retry.js +82 -0
  221. package/dist/esm/schema.d.ts +4 -0
  222. package/dist/esm/schema.js +15 -0
  223. package/dist/esm/test/mocks.d.ts +20 -0
  224. package/dist/esm/test/mocks.js +64 -0
  225. package/dist/esm/viem.d.ts +1141 -0
  226. package/dist/esm/viem.js +32 -0
  227. package/dist/types/advancedacl/index.d.ts +2 -0
  228. package/dist/types/advancedacl/session-key.d.ts +95 -0
  229. package/dist/types/advancedacl/types.d.ts +16 -0
  230. package/dist/types/attestedcompute/attested-compute.d.ts +65 -0
  231. package/dist/types/attestedcompute/types.d.ts +35 -0
  232. package/dist/types/attesteddecrypt/attested-decrypt.d.ts +61 -0
  233. package/dist/types/attesteddecrypt/index.d.ts +1 -0
  234. package/dist/types/attesteddecrypt/types.d.ts +27 -0
  235. package/dist/types/attestedreveal/attested-reveal.d.ts +21 -0
  236. package/dist/types/attestedreveal/index.d.ts +2 -0
  237. package/dist/types/attestedreveal/types.d.ts +4 -0
  238. package/dist/types/binary.d.ts +104 -0
  239. package/dist/types/chain.d.ts +50 -0
  240. package/dist/types/eip712/eip712.d.ts +18 -0
  241. package/dist/types/eip712/index.d.ts +1 -0
  242. package/dist/types/elistattesteddecrypt/elist-attested-decrypt.d.ts +51 -0
  243. package/dist/types/elistattesteddecrypt/index.d.ts +2 -0
  244. package/dist/types/elistattesteddecrypt/types.d.ts +31 -0
  245. package/dist/types/encryption/encryption.d.ts +235 -0
  246. package/dist/types/encryption/index.d.ts +1 -0
  247. package/dist/types/generated/abis/add-two.d.ts +117 -0
  248. package/dist/types/generated/abis/lightning.d.ts +3362 -0
  249. package/dist/types/generated/abis/test-elist.d.ts +276 -0
  250. package/dist/types/generated/abis/verifier.d.ts +1353 -0
  251. package/dist/types/generated/es/inco/covalidator/compute/v1/server_pb.d.ts +1494 -0
  252. package/dist/types/generated/es/inco/covalidator/compute/v1/types_pb.d.ts +247 -0
  253. package/dist/types/generated/es/inco/helioswrapper/v1/helioswrapper_pb.d.ts +77 -0
  254. package/dist/types/generated/es/inco/kms/lite/v1/kms_service_pb.d.ts +685 -0
  255. package/dist/types/generated/es/inco/kms/lite/v1/types_pb.d.ts +289 -0
  256. package/dist/types/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.d.ts +371 -0
  257. package/dist/types/generated/lightning.d.ts +830 -0
  258. package/dist/types/generated/local-node.d.ts +50 -0
  259. package/dist/types/handle.d.ts +123 -0
  260. package/dist/types/index.d.ts +5 -0
  261. package/dist/types/kms/client.d.ts +12 -0
  262. package/dist/types/kms/quorumClient.d.ts +65 -0
  263. package/dist/types/kms/quorumConsistency.d.ts +82 -0
  264. package/dist/types/kms/signatureVerification.d.ts +35 -0
  265. package/dist/types/kms/thresholdPromises.d.ts +8 -0
  266. package/dist/types/lite/attested-compute.d.ts +6 -0
  267. package/dist/types/lite/attested-decrypt.d.ts +4 -0
  268. package/dist/types/lite/deployments.d.ts +24 -0
  269. package/dist/types/lite/hadu.d.ts +4 -0
  270. package/dist/types/lite/index.d.ts +13 -0
  271. package/dist/types/lite/lightning.d.ts +459 -0
  272. package/dist/types/lite/types.d.ts +47 -0
  273. package/dist/types/lite/xwing.d.ts +154 -0
  274. package/dist/types/local/index.d.ts +1 -0
  275. package/dist/types/local/local-node.d.ts +37 -0
  276. package/dist/types/reencryption/eip712.d.ts +56 -0
  277. package/dist/types/reencryption/index.d.ts +2 -0
  278. package/dist/types/reencryption/types.d.ts +48 -0
  279. package/dist/types/retry.d.ts +30 -0
  280. package/dist/types/schema.d.ts +4 -0
  281. package/dist/types/test/mocks.d.ts +20 -0
  282. package/dist/types/viem.d.ts +1141 -0
  283. package/package.json +129 -0
@@ -0,0 +1,459 @@
1
+ import { keccak256 } from 'viem';
2
+ import { bytesToBigInt, bytesToHex, parseHex, } from '../binary.js';
3
+ import { EListAttestedDecryptError, } from '../elistattesteddecrypt/types.js';
4
+ import { bigintToPlaintext, encryptionSchemes, } from '../encryption/encryption.js';
5
+ import { getEListElementType, getHandleType, handleTypes } from '../handle.js';
6
+ import { decrypt } from '../lite/xwing.js';
7
+ import { retryWithBackoff } from '../retry.js';
8
+ import { getKmsClient } from './client.js';
9
+ import { verifyComputeResponseConsistency, verifyDecryptResponseConsistency, verifyEListResponseConsistency, } from './quorumConsistency.js';
10
+ import { verifyPlaintextAttestationSignatures, verifyReencryptionAttestationSignatures, } from './signatureVerification.js';
11
+ import { executeWithThreshold } from './thresholdPromises.js';
12
+ /**
13
+ * Checks if the threshold is at least a majority of signers and throws an error if not.
14
+ * This is important to ensure that the quorum client provides the expected security guarantees.
15
+ */
16
+ function checkMajorityThreshold(threshold, signerCount) {
17
+ const majority = Math.floor(signerCount / 2) + 1;
18
+ if (threshold < majority) {
19
+ throw new Error(`Threshold (${threshold}) must be at least a majority (${majority}) of ${signerCount} signers to ensure security guarantees.`);
20
+ }
21
+ }
22
+ export class KmsQuorumClient {
23
+ kmss;
24
+ threshold;
25
+ // Implementation
26
+ constructor(attestersOrClients, threshold) {
27
+ if (attestersOrClients.length === 0) {
28
+ throw new Error('At least one attester or KMS client is required');
29
+ }
30
+ if (threshold < 1 || threshold > attestersOrClients.length) {
31
+ throw new Error(`Threshold must be between 1 and ${attestersOrClients.length}`);
32
+ }
33
+ checkMajorityThreshold(threshold, attestersOrClients.length);
34
+ // Check if first element is a KmsClient (has attestedDecrypt method) or an attester object
35
+ if (attestersOrClients.length > 0 &&
36
+ 'attestedDecrypt' in attestersOrClients[0]) {
37
+ // Handle KmsClient[] case
38
+ const kmsClients = attestersOrClients;
39
+ this.kmss = kmsClients.map((client) => ({
40
+ client,
41
+ signer: client.signerAddress,
42
+ }));
43
+ }
44
+ else {
45
+ // Handle { url: string; signer: Address }[] case
46
+ const attesters = attestersOrClients;
47
+ this.kmss = attesters.map((attester) => {
48
+ return {
49
+ client: getKmsClient(attester.url, attester.signer),
50
+ signer: attester.signer,
51
+ };
52
+ });
53
+ }
54
+ this.threshold = threshold;
55
+ }
56
+ /**
57
+ * Creates a KmsQuorumClient from an array of URLs.
58
+ * Requires signer addresses and threshold to be explicitly provided.
59
+ *
60
+ * @param urls - Array of KMS endpoint URLs
61
+ * @param signers - Array of signer addresses, must match the length of URLs
62
+ * @param threshold - Number of successful responses required (must be between 1 and urls.length)
63
+ * @throws {Error} If URLs array is empty, signers length doesn't match URLs length, or threshold is invalid
64
+ */
65
+ static fromUrls(urls, signers, threshold) {
66
+ if (urls.length === 0) {
67
+ throw new Error('At least one URL is required');
68
+ }
69
+ if (signers.length !== urls.length) {
70
+ throw new Error(`Signers array length (${signers.length}) must match URLs array length (${urls.length})`);
71
+ }
72
+ if (threshold < 1 || threshold > urls.length) {
73
+ throw new Error(`Threshold must be between 1 and ${urls.length} (number of URLs)`);
74
+ }
75
+ const attesters = urls.map((url, index) => {
76
+ return { url, signer: signers[index] };
77
+ });
78
+ return new KmsQuorumClient(attesters, threshold);
79
+ }
80
+ /**
81
+ * Creates a KmsQuorumClient from an array of KmsClient instances.
82
+ * Each KmsClient must have a signerAddress property.
83
+ *
84
+ * @param kmsClients - Array of KMS client instances
85
+ * @param threshold - Number of successful responses required (must be between 1 and kmsClients.length)
86
+ * @throws {Error} If KMS clients array is empty or threshold is invalid
87
+ */
88
+ static fromKmsClients(kmsClients, threshold) {
89
+ if (kmsClients.length === 0) {
90
+ throw new Error('At least one KMS client is required');
91
+ }
92
+ if (threshold < 1 || threshold > kmsClients.length) {
93
+ throw new Error(`Threshold must be between 1 and ${kmsClients.length} (number of KMS clients)`);
94
+ }
95
+ return new KmsQuorumClient(kmsClients, threshold);
96
+ }
97
+ async attestedDecrypt(request, executorAddress, client, backoffConfig, reencryptKeypair) {
98
+ const thresholdResults = await this.executeKmsOperationWithThreshold(async (kms) => {
99
+ return await kms.client.attestedDecrypt(request);
100
+ }, backoffConfig);
101
+ // Verify that responses are consistent across quorum (plaintext or ciphertext)
102
+ const { reference, winningResults } = await verifyDecryptResponseConsistency(thresholdResults, this.threshold, reencryptKeypair);
103
+ return this.buildAggregatedAttestations(reference, winningResults.map((r) => r.response), winningResults.map((r) => r.signer), executorAddress, client);
104
+ }
105
+ async attestedCompute(request, executorAddress, client, backoffConfig, reencryptKeypair) {
106
+ const thresholdResults = await this.executeKmsOperationWithThreshold(async (kms) => {
107
+ return await kms.client.attestedCompute(request);
108
+ }, backoffConfig);
109
+ // Verify that responses are consistent across quorum
110
+ const { reference, winningResults } = await verifyComputeResponseConsistency(thresholdResults, this.threshold, request, reencryptKeypair);
111
+ return this.buildAggregatedComputeAttestation(reference, winningResults.map((r) => r.response), winningResults.map((r) => r.signer), executorAddress, client);
112
+ }
113
+ async attestedReveal(request, executorAddress, client, backoffConfig) {
114
+ const thresholdResults = await this.executeKmsOperationWithThreshold(async (kms) => {
115
+ return await kms.client.attestedReveal(request);
116
+ }, backoffConfig);
117
+ // Verify that responses are consistent across quorum (plaintext only for reveal)
118
+ const { reference, winningResults } = await verifyDecryptResponseConsistency(thresholdResults, this.threshold);
119
+ return this.buildAggregatedAttestations(reference, winningResults.map((r) => r.response), winningResults.map((r) => r.signer), executorAddress, client);
120
+ }
121
+ async eListAttestedDecrypt(request, executorAddress, client, backoffConfig, reencryptKeypair) {
122
+ const thresholdResults = await this.executeKmsOperationWithThreshold(async (kms) => {
123
+ return await kms.client.eListAttestedDecrypt(request);
124
+ }, backoffConfig);
125
+ const { reference, winningResults } = await verifyEListResponseConsistency(thresholdResults, this.threshold, reencryptKeypair);
126
+ const elistHandle = request.elistHandleWithProof?.handle;
127
+ if (!elistHandle) {
128
+ throw new EListAttestedDecryptError('Missing elistHandleWithProof.handle in request');
129
+ }
130
+ return this.buildAggregatedEListAttestation(elistHandle, reference, winningResults.map((r) => r.response), winningResults.map((r) => r.signer), executorAddress, client, reencryptKeypair);
131
+ }
132
+ async eListAttestedReveal(request, executorAddress, client, backoffConfig) {
133
+ const thresholdResults = await this.executeKmsOperationWithThreshold(async (kms) => {
134
+ return await kms.client.eListAttestedReveal(request);
135
+ }, backoffConfig);
136
+ const { reference, winningResults } = await verifyEListResponseConsistency(thresholdResults, this.threshold);
137
+ return this.buildAggregatedEListAttestation(request.handle, reference, winningResults.map((r) => r.response), winningResults.map((r) => r.signer), executorAddress, client);
138
+ }
139
+ /**
140
+ * Generic method to execute a KMS operation across all clients with retry and threshold logic.
141
+ * Returns results with both the response and signer address.
142
+ */
143
+ async executeKmsOperationWithThreshold(operation, backoffConfig) {
144
+ // Create promises for all KMS clients, tracking signer addresses
145
+ // Each client call is wrapped with retry logic
146
+ const promises = this.kmss.map(async (kms, index) => {
147
+ try {
148
+ const response = await retryWithBackoff(async () => {
149
+ return await operation(kms);
150
+ }, backoffConfig);
151
+ return { response, signer: kms.signer };
152
+ }
153
+ catch (error) {
154
+ throw new Error(`KMS client ${index} (signer: ${kms.signer}) failed: ${error}`);
155
+ }
156
+ });
157
+ return await executeWithThreshold(promises, this.threshold);
158
+ }
159
+ /**
160
+ * Collects signatures from responses and sorts them by signer address (ascending).
161
+ * This is required by SignatureVerifier.
162
+ */
163
+ collectAndSortSignatures(signatures, signers) {
164
+ const signaturesWithSigners = signatures.map((signature, idx) => ({
165
+ signature,
166
+ signer: signers[idx],
167
+ }));
168
+ // Sort by signer address in ascending order (as required by SignatureVerifier)
169
+ signaturesWithSigners.sort((a, b) => {
170
+ const aBigInt = BigInt(a.signer);
171
+ const bBigInt = BigInt(b.signer);
172
+ if (aBigInt < bBigInt)
173
+ return -1;
174
+ if (aBigInt > bBigInt)
175
+ return 1;
176
+ return 0;
177
+ });
178
+ // Extract sorted signatures
179
+ return signaturesWithSigners.map((item) => item.signature);
180
+ }
181
+ /**
182
+ * Builds a plaintext attestation from a DecryptionAttestation proto message.
183
+ */
184
+ buildPlaintextAttestation(decryptionAttestation, covalidatorSignatures) {
185
+ if (!decryptionAttestation.value ||
186
+ decryptionAttestation.value.case !== 'plaintext') {
187
+ throw new Error('Expected plaintext attestation');
188
+ }
189
+ const plaintextBytes = decryptionAttestation.value.value.value;
190
+ const handle = decryptionAttestation.handle;
191
+ const handleType = getHandleType(handle);
192
+ const bigIntValue = bytesToBigInt(plaintextBytes);
193
+ const plaintext = bigintToPlaintext(encryptionSchemes.xwing, handleType, bigIntValue);
194
+ return {
195
+ handle,
196
+ plaintext,
197
+ covalidatorSignatures,
198
+ };
199
+ }
200
+ async buildAggregatedAttestations(reference, thresholdResponses, signers, executorAddress, client) {
201
+ const attestationCount = reference.decryptionAttestations.length;
202
+ const results = [];
203
+ for (let i = 0; i < attestationCount; i++) {
204
+ const refAtt = reference.decryptionAttestations[i];
205
+ if (!refAtt.value) {
206
+ throw new Error('No value in attestation');
207
+ }
208
+ // Collect signatures and sort by signer address
209
+ const signatures = thresholdResponses.map((resp) => resp.decryptionAttestations[i].signature);
210
+ const covalidatorSignatures = this.collectAndSortSignatures(signatures, signers);
211
+ if (refAtt.value.case === 'plaintext') {
212
+ // Verify covalidator signatures over the plaintext attestation
213
+ // executorAddress and client are only undefined when using a non-real client (e.g. in tests)
214
+ if (executorAddress && client) {
215
+ await verifyPlaintextAttestationSignatures(refAtt.handle, refAtt.value.value.value, covalidatorSignatures, executorAddress, client);
216
+ }
217
+ results.push(this.buildPlaintextAttestation(refAtt, covalidatorSignatures));
218
+ }
219
+ else if (refAtt.value.case === 'reencryption') {
220
+ // Collect per-covalidator encrypted signatures and ciphertexts
221
+ const encryptedSignatures = [];
222
+ const perCovalidatorCiphertexts = [];
223
+ for (const resp of thresholdResponses) {
224
+ const attValue = resp.decryptionAttestations[i].value;
225
+ if (attValue?.case === 'reencryption') {
226
+ encryptedSignatures.push(attValue.value.encryptedSignature);
227
+ perCovalidatorCiphertexts.push(attValue.value.userCiphertext);
228
+ }
229
+ else {
230
+ throw new Error(`Expected reencryption attestation but received '${attValue?.case}'`);
231
+ }
232
+ }
233
+ const encryptedCovalidatorSignatures = this.collectAndSortSignatures(encryptedSignatures, signers);
234
+ const sortedCiphertexts = this.collectAndSortSignatures(perCovalidatorCiphertexts, signers);
235
+ // executorAddress and client are only undefined when using a non-real client (e.g. in tests)
236
+ if (executorAddress && client) {
237
+ await verifyReencryptionAttestationSignatures(refAtt.handle, sortedCiphertexts, encryptedCovalidatorSignatures, covalidatorSignatures, executorAddress, client);
238
+ }
239
+ const reencryption = refAtt.value.value;
240
+ const ct = reencryption.userCiphertext;
241
+ const handleType = getHandleType(parseHex(refAtt.handle));
242
+ results.push({
243
+ handle: refAtt.handle,
244
+ encryptedPlaintext: {
245
+ ciphertext: {
246
+ value: bytesToHex(ct),
247
+ scheme: encryptionSchemes.xwing, // EncryptionScheme: XWING
248
+ type: handleType,
249
+ },
250
+ },
251
+ encryptedSignatures: encryptedCovalidatorSignatures,
252
+ covalidatorSignatures,
253
+ });
254
+ }
255
+ else {
256
+ throw new Error(`Unexpected attestation type: ${refAtt.value.case}, expected 'plaintext' or 'reencryption'`);
257
+ }
258
+ }
259
+ return results;
260
+ }
261
+ async buildAggregatedComputeAttestation(reference, thresholdResponses, signers, executorAddress, client) {
262
+ const refAtt = reference.decryptionAttestation;
263
+ if (!refAtt) {
264
+ throw new Error('No decryption attestation in reference response');
265
+ }
266
+ if (!refAtt.value) {
267
+ throw new Error('No value in reference attestation');
268
+ }
269
+ // Collect signatures and sort by signer address
270
+ // All responses are guaranteed to have decryption attestations by verifyComputeResponseConsistency
271
+ const signatures = [];
272
+ for (const resp of thresholdResponses) {
273
+ const att = resp.decryptionAttestation;
274
+ if (!att)
275
+ throw new Error('Missing decryption attestation in winning response');
276
+ signatures.push(att.signature);
277
+ }
278
+ const covalidatorSignatures = this.collectAndSortSignatures(signatures, signers);
279
+ if (refAtt.value.case === 'plaintext') {
280
+ // Verify covalidator signatures over the plaintext attestation
281
+ // executorAddress and client are only undefined when using a non-real client (e.g. in tests)
282
+ if (executorAddress && client) {
283
+ await verifyPlaintextAttestationSignatures(refAtt.handle, refAtt.value.value.value, covalidatorSignatures, executorAddress, client);
284
+ }
285
+ return this.buildPlaintextAttestation(refAtt, covalidatorSignatures);
286
+ }
287
+ if (refAtt.value.case === 'reencryption') {
288
+ // Reencryption envelope signatures are verified per-covalidator via
289
+ // isValidReencryptionAttestation on-chain (each has a unique digest).
290
+ const reencryption = refAtt.value.value;
291
+ const ct = reencryption.userCiphertext;
292
+ if (!ct) {
293
+ throw new Error('No ciphertext in reencryption');
294
+ }
295
+ const handleType = getHandleType(parseHex(refAtt.handle));
296
+ // Collect per-covalidator encrypted signatures and ciphertexts
297
+ const encryptedSignatures = [];
298
+ const perCovalidatorCiphertexts = [];
299
+ for (const resp of thresholdResponses) {
300
+ if (resp.decryptionAttestation?.value.case === 'reencryption') {
301
+ const reenc = resp.decryptionAttestation.value.value;
302
+ encryptedSignatures.push(reenc.encryptedSignature);
303
+ perCovalidatorCiphertexts.push(reenc.userCiphertext);
304
+ }
305
+ else {
306
+ throw new Error(`Expected reencryption attestation but received '${resp.decryptionAttestation?.value.case}'`);
307
+ }
308
+ }
309
+ const encryptedCovalidatorSignatures = this.collectAndSortSignatures(encryptedSignatures, signers);
310
+ const sortedCiphertexts = this.collectAndSortSignatures(perCovalidatorCiphertexts, signers);
311
+ // executorAddress and client are only undefined when using a non-real client (e.g. in tests)
312
+ if (executorAddress && client) {
313
+ await verifyReencryptionAttestationSignatures(refAtt.handle, sortedCiphertexts, encryptedCovalidatorSignatures, covalidatorSignatures, executorAddress, client);
314
+ }
315
+ return {
316
+ handle: refAtt.handle,
317
+ encryptedPlaintext: {
318
+ ciphertext: {
319
+ value: bytesToHex(ct),
320
+ scheme: encryptionSchemes.xwing, // EncryptionScheme: XWING
321
+ type: handleType,
322
+ },
323
+ },
324
+ encryptedSignatures: encryptedCovalidatorSignatures,
325
+ covalidatorSignatures,
326
+ };
327
+ }
328
+ throw new Error(`Unexpected attestation type: ${refAtt.value.case}, expected 'plaintext' or 'reencryption'`);
329
+ }
330
+ async buildAggregatedEListAttestation(elistHandle, reference, thresholdResponses, signers, executorAddress, client, reencryptKeypair) {
331
+ const refProofAtt = reference.commitmentProofAttestation;
332
+ if (!refProofAtt) {
333
+ throw new Error('No commitmentProofAttestation in reference response');
334
+ }
335
+ if (!refProofAtt.value) {
336
+ throw new Error('No value in commitmentProofAttestation');
337
+ }
338
+ // Collect and sort commitment proof signatures
339
+ const proofSignatures = thresholdResponses.map((resp) => resp.commitmentProofAttestation.signature);
340
+ const covalidatorSignatures = this.collectAndSortSignatures(proofSignatures, signers);
341
+ // Build commitment proof from the attestation
342
+ // The commitment proof is always a keccak256 hash (uint256), regardless of the elist handle type.
343
+ let commitmentProof;
344
+ if (refProofAtt.value.case === 'plaintext') {
345
+ const proofBytes = refProofAtt.value.value.value;
346
+ const proofHandle = refProofAtt.handle;
347
+ // Verify commitment proof signatures
348
+ if (executorAddress && client) {
349
+ await verifyPlaintextAttestationSignatures(proofHandle, proofBytes, covalidatorSignatures, executorAddress, client);
350
+ }
351
+ commitmentProof = bigintToPlaintext(encryptionSchemes.xwing, handleTypes.euint256, bytesToBigInt(proofBytes));
352
+ }
353
+ else {
354
+ throw new Error(`Unexpected commitmentProofAttestation type: ${refProofAtt.value.case}`);
355
+ }
356
+ // Verify proof hashes: per-element and aggregate
357
+ await this.verifyElementProofHashes(reference, refProofAtt.value.value.value, reencryptKeypair);
358
+ // Build values and commitments from EListElements
359
+ const elementType = getEListElementType(elistHandle);
360
+ const commitments = [];
361
+ const isReencryption = reference.values.length > 0 &&
362
+ reference.values[0].value.case === 'reencryption';
363
+ if (isReencryption) {
364
+ const values = [];
365
+ for (const elem of reference.values) {
366
+ commitments.push(elem.commitment);
367
+ if (elem.value.case !== 'reencryption') {
368
+ throw new Error(`Expected reencryption elist element but got '${elem.value.case}'`);
369
+ }
370
+ const ct = elem.value.value.userCiphertext;
371
+ values.push({
372
+ ciphertext: {
373
+ value: bytesToHex(ct),
374
+ scheme: encryptionSchemes.xwing,
375
+ type: elementType,
376
+ },
377
+ });
378
+ }
379
+ return {
380
+ handle: elistHandle,
381
+ commitmentProof,
382
+ values,
383
+ covalidatorSignatures,
384
+ commitments,
385
+ };
386
+ }
387
+ else {
388
+ const values = [];
389
+ for (const elem of reference.values) {
390
+ commitments.push(elem.commitment);
391
+ if (elem.value.case !== 'plaintext') {
392
+ throw new Error(`Expected plaintext elist element but got '${elem.value.case}'`);
393
+ }
394
+ const plaintextBytes = elem.value.value.value;
395
+ values.push(bigintToPlaintext(encryptionSchemes.xwing, elementType, bytesToBigInt(plaintextBytes)));
396
+ }
397
+ return {
398
+ handle: elistHandle,
399
+ commitmentProof,
400
+ values,
401
+ covalidatorSignatures,
402
+ commitments,
403
+ };
404
+ }
405
+ }
406
+ /**
407
+ * Verifies proof hashes at two levels:
408
+ * 1. Aggregate: keccak256(concat(proofHashes)) must equal the attested commitmentProof
409
+ * 2. Per-element:
410
+ * - For plaintext (reveal): proofHash[i] = keccak256(value[i])
411
+ * - For reencryption (decrypt): proofHash[i] = keccak256(commitment[i] || plaintext[i])
412
+ * — requires reencryptKeypair to decrypt the ciphertext first.
413
+ */
414
+ async verifyElementProofHashes(reference, commitmentProofBytes, reencryptKeypair) {
415
+ // Aggregate check: keccak256(concat(proofHashes)) must match the attested commitment proof
416
+ const proofHashesConcat = new Uint8Array(reference.proofHashes.reduce((acc, h) => acc + h.length, 0));
417
+ let offset = 0;
418
+ for (const h of reference.proofHashes) {
419
+ proofHashesConcat.set(h, offset);
420
+ offset += h.length;
421
+ }
422
+ const computedProof = keccak256(bytesToHex(proofHashesConcat));
423
+ const attestedProof = bytesToHex(commitmentProofBytes);
424
+ if (computedProof !== attestedProof) {
425
+ throw new EListAttestedDecryptError(`Commitment proof verification failed: computed ${computedProof} but attested value is ${attestedProof}`);
426
+ }
427
+ // Per-element check
428
+ if (reference.proofHashes.length !== reference.values.length) {
429
+ throw new EListAttestedDecryptError(`proofHashes length (${reference.proofHashes.length}) does not match values length (${reference.values.length})`);
430
+ }
431
+ for (let i = 0; i < reference.values.length; i++) {
432
+ const elem = reference.values[i];
433
+ let preimage;
434
+ if (elem.value.case === 'reencryption') {
435
+ if (!reencryptKeypair) {
436
+ // Can't verify without keypair; aggregate check + signatures still hold
437
+ continue;
438
+ }
439
+ const plaintext = await decrypt(reencryptKeypair, elem.value.value.userCiphertext);
440
+ const combined = new Uint8Array(elem.commitment.length + plaintext.length);
441
+ combined.set(elem.commitment, 0);
442
+ combined.set(plaintext, elem.commitment.length);
443
+ preimage = combined;
444
+ }
445
+ else if (elem.value.case === 'plaintext') {
446
+ preimage = elem.value.value.value;
447
+ }
448
+ else {
449
+ throw new EListAttestedDecryptError(`Unexpected elist element type at index ${i}: ${elem.value.case}`);
450
+ }
451
+ const computedHash = keccak256(bytesToHex(preimage));
452
+ const expectedHash = bytesToHex(reference.proofHashes[i]);
453
+ if (computedHash !== expectedHash) {
454
+ throw new EListAttestedDecryptError(`Element proof hash mismatch at index ${i}: computed ${computedHash} but expected ${expectedHash}`);
455
+ }
456
+ }
457
+ }
458
+ }
459
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvcnVtQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2ttcy9xdW9ydW1DbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFLL0MsT0FBTyxFQUNMLGFBQWEsRUFDYixVQUFVLEVBQ1YsUUFBUSxHQUVULE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFDTCx5QkFBeUIsR0FHMUIsTUFBTSxrQ0FBa0MsQ0FBQztBQU0xQyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLGlCQUFpQixHQUNsQixNQUFNLDZCQUE2QixDQUFDO0FBY3JDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQy9FLE9BQU8sRUFBRSxPQUFPLEVBQXFCLE1BQU0sa0JBQWtCLENBQUM7QUFFOUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQy9DLE9BQU8sRUFBRSxZQUFZLEVBQWtCLE1BQU0sYUFBYSxDQUFDO0FBQzNELE9BQU8sRUFDTCxnQ0FBZ0MsRUFDaEMsZ0NBQWdDLEVBQ2hDLDhCQUE4QixHQUMvQixNQUFNLHdCQUF3QixDQUFDO0FBR2hDLE9BQU8sRUFDTCxvQ0FBb0MsRUFDcEMsdUNBQXVDLEdBQ3hDLE1BQU0sNEJBQTRCLENBQUM7QUFDcEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFPOUQ7OztHQUdHO0FBQ0gsU0FBUyxzQkFBc0IsQ0FBQyxTQUFpQixFQUFFLFdBQW1CO0lBQ3BFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqRCxJQUFJLFNBQVMsR0FBRyxRQUFRLEVBQUUsQ0FBQztRQUN6QixNQUFNLElBQUksS0FBSyxDQUNiLGNBQWMsU0FBUyxr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
@@ -0,0 +1,82 @@
1
+ import type { Address } from 'viem';
2
+ import type { AttestedComputeRequest, AttestedComputeResponse, AttestedDecryptResponse, AttestedRevealResponse, EListAttestedDecryptResponse, EListAttestedRevealResponse, DecryptionAttestation as ProtoDecryptionAttestation } from '../generated/es/inco/kms/lite/v1/kms_service_pb.js';
3
+ import type { XwingKeypair } from '../lite/xwing.js';
4
+ /**
5
+ * Computes a canonical key for a single attestation.
6
+ * For plaintext/reencryption+keypair, the key is handle:hex(value).
7
+ * For reencryption without a keypair (XWing ciphertexts are non-deterministic),
8
+ * falls back to handle:op-type as a structural stand-in.
9
+ */
10
+ export declare function computeAttestationKey(att: ProtoDecryptionAttestation, reencryptKeypair?: XwingKeypair): Promise<string>;
11
+ /**
12
+ * Validates that all responses in a winning bucket have the same attestation
13
+ * count and types as the quorum-elected reference (bucket[0]).
14
+ */
15
+ export declare function validateDecryptResponseStructure<T extends AttestedDecryptResponse | AttestedRevealResponse>(bucket: Array<{
16
+ response: T;
17
+ signer: Address;
18
+ }>): void;
19
+ /**
20
+ * Validates that all responses in a winning bucket have a decryption
21
+ * attestation with the same case as the quorum-elected reference (bucket[0]),
22
+ * and that the case is consistent with the request's reencryptPubKey.
23
+ */
24
+ export declare function validateComputeResponseStructure(bucket: Array<{
25
+ response: AttestedComputeResponse;
26
+ signer: Address;
27
+ }>, request?: AttestedComputeRequest): void;
28
+ /**
29
+ * Verifies decrypt/reveal response consistency using hash-bucket voting.
30
+ * Collects all N responses, buckets them by content key, and returns the
31
+ * winning bucket (the first one with >= threshold votes).
32
+ *
33
+ * This is robust against a faulty first-responding node: even if responses[0]
34
+ * disagrees, a quorum of agreeing responses will form a winning bucket.
35
+ */
36
+ export declare function verifyDecryptResponseConsistency<T extends AttestedDecryptResponse | AttestedRevealResponse>(allResults: Array<{
37
+ response: T;
38
+ signer: Address;
39
+ }>, threshold: number, reencryptKeypair?: XwingKeypair): Promise<{
40
+ reference: T;
41
+ winningResults: Array<{
42
+ response: T;
43
+ signer: Address;
44
+ }>;
45
+ }>;
46
+ type EListResponse = EListAttestedDecryptResponse | EListAttestedRevealResponse;
47
+ /**
48
+ * Validates that all elist responses in a winning bucket have the same
49
+ * number of values and matching indices.
50
+ */
51
+ export declare function validateEListResponseStructure<T extends EListResponse>(bucket: Array<{
52
+ response: T;
53
+ signer: Address;
54
+ }>): void;
55
+ /**
56
+ * Verifies elist response consistency using hash-bucket voting.
57
+ * Works for both EListAttestedDecryptResponse and EListAttestedRevealResponse.
58
+ */
59
+ export declare function verifyEListResponseConsistency<T extends EListResponse>(allResults: Array<{
60
+ response: T;
61
+ signer: Address;
62
+ }>, threshold: number, reencryptKeypair?: XwingKeypair): Promise<{
63
+ reference: T;
64
+ winningResults: Array<{
65
+ response: T;
66
+ signer: Address;
67
+ }>;
68
+ }>;
69
+ /**
70
+ * Verifies compute response consistency using hash-bucket voting.
71
+ */
72
+ export declare function verifyComputeResponseConsistency(allResults: Array<{
73
+ response: AttestedComputeResponse;
74
+ signer: Address;
75
+ }>, threshold: number, request?: AttestedComputeRequest, reencryptKeypair?: XwingKeypair): Promise<{
76
+ reference: AttestedComputeResponse;
77
+ winningResults: Array<{
78
+ response: AttestedComputeResponse;
79
+ signer: Address;
80
+ }>;
81
+ }>;
82
+ export {};