@reclaimprotocol/attestor-core 4.0.3 → 5.0.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +660 -660
- package/README.md +1 -2
- package/lib/avs/abis/avsDirectoryABI.js +341 -342
- package/lib/avs/abis/delegationABI.js +4 -5
- package/lib/avs/abis/registryABI.js +722 -723
- package/lib/avs/client/create-claim-on-avs.d.ts +5 -5
- package/lib/avs/client/create-claim-on-avs.js +160 -139
- package/lib/avs/config.d.ts +1 -1
- package/lib/avs/config.js +25 -23
- package/lib/avs/contracts/ReclaimServiceManager.d.ts +436 -532
- package/lib/avs/contracts/ReclaimServiceManager.js +0 -3
- package/lib/avs/contracts/common.d.ts +40 -11
- package/lib/avs/contracts/common.js +0 -3
- package/lib/avs/contracts/factories/ReclaimServiceManager__factory.d.ts +13 -11
- package/lib/avs/contracts/factories/ReclaimServiceManager__factory.js +1157 -1148
- package/lib/avs/contracts/factories/index.d.ts +1 -1
- package/lib/avs/contracts/factories/index.js +4 -9
- package/lib/avs/contracts/index.d.ts +3 -3
- package/lib/avs/contracts/index.js +6 -40
- package/lib/avs/types/index.d.ts +6 -6
- package/lib/avs/types/index.js +0 -3
- package/lib/avs/utils/contracts.d.ts +14 -14
- package/lib/avs/utils/contracts.js +50 -35
- package/lib/avs/utils/register.d.ts +3 -3
- package/lib/avs/utils/register.js +71 -79
- package/lib/avs/utils/tasks.d.ts +4 -4
- package/lib/avs/utils/tasks.js +44 -41
- package/lib/client/create-claim.d.ts +2 -2
- package/lib/client/create-claim.js +437 -400
- package/lib/client/index.d.ts +3 -3
- package/lib/client/index.js +3 -20
- package/lib/client/tunnels/make-rpc-tcp-tunnel.d.ts +2 -2
- package/lib/client/tunnels/make-rpc-tcp-tunnel.js +49 -56
- package/lib/client/tunnels/make-rpc-tls-tunnel.d.ts +4 -3
- package/lib/client/tunnels/make-rpc-tls-tunnel.js +123 -131
- package/lib/client/utils/attestor-pool.d.ts +3 -1
- package/lib/client/utils/attestor-pool.js +21 -25
- package/lib/client/utils/client-socket.d.ts +4 -4
- package/lib/client/utils/client-socket.js +114 -94
- package/lib/client/utils/message-handler.d.ts +2 -2
- package/lib/client/utils/message-handler.js +89 -86
- package/lib/config/index.d.ts +6 -3
- package/lib/config/index.js +60 -37
- package/lib/external-rpc/benchmark.d.ts +1 -0
- package/lib/external-rpc/benchmark.js +82 -0
- package/lib/external-rpc/event-bus.d.ts +7 -0
- package/lib/external-rpc/event-bus.js +17 -0
- package/lib/external-rpc/global.d.js +0 -0
- package/lib/external-rpc/handle-incoming-msg.d.ts +2 -0
- package/lib/external-rpc/handle-incoming-msg.js +241 -0
- package/lib/external-rpc/index.d.ts +3 -0
- package/lib/external-rpc/index.js +3 -0
- package/lib/external-rpc/jsc-polyfills/1.d.ts +14 -0
- package/lib/external-rpc/jsc-polyfills/1.js +80 -0
- package/lib/external-rpc/jsc-polyfills/2.js +15 -0
- package/lib/external-rpc/jsc-polyfills/event.d.ts +10 -0
- package/lib/external-rpc/jsc-polyfills/event.js +19 -0
- package/lib/external-rpc/jsc-polyfills/index.d.ts +2 -0
- package/lib/external-rpc/jsc-polyfills/index.js +2 -0
- package/lib/external-rpc/jsc-polyfills/ws.d.ts +21 -0
- package/lib/external-rpc/jsc-polyfills/ws.js +83 -0
- package/lib/external-rpc/setup-browser.d.ts +6 -0
- package/lib/external-rpc/setup-browser.js +33 -0
- package/lib/external-rpc/setup-jsc.d.ts +24 -0
- package/lib/external-rpc/setup-jsc.js +22 -0
- package/lib/{window-rpc → external-rpc}/types.d.ts +56 -35
- package/lib/external-rpc/types.js +0 -0
- package/lib/external-rpc/utils.d.ts +20 -0
- package/lib/external-rpc/utils.js +100 -0
- package/lib/external-rpc/zk.d.ts +14 -0
- package/lib/external-rpc/zk.js +58 -0
- package/lib/index.d.ts +8 -9
- package/lib/index.js +12 -49
- package/lib/mechain/abis/governanceABI.js +460 -461
- package/lib/mechain/abis/taskABI.js +505 -506
- package/lib/mechain/client/create-claim-on-mechain.d.ts +3 -3
- package/lib/mechain/client/create-claim-on-mechain.js +31 -30
- package/lib/mechain/client/index.d.ts +1 -1
- package/lib/mechain/client/index.js +1 -18
- package/lib/mechain/constants/index.js +8 -7
- package/lib/mechain/index.d.ts +2 -2
- package/lib/mechain/index.js +2 -19
- package/lib/mechain/types/index.d.ts +2 -2
- package/lib/mechain/types/index.js +0 -3
- package/lib/proto/api.d.ts +182 -39
- package/lib/proto/api.js +4105 -3555
- package/lib/proto/tee-bundle.d.ts +156 -0
- package/lib/proto/tee-bundle.js +1296 -0
- package/lib/providers/http/index.d.ts +16 -1
- package/lib/providers/http/index.js +603 -576
- package/lib/providers/http/patch-parse5-tree.d.ts +6 -0
- package/lib/providers/http/patch-parse5-tree.js +34 -0
- package/lib/providers/http/utils.d.ts +7 -4
- package/lib/providers/http/utils.js +240 -317
- package/lib/providers/index.d.ts +1 -1
- package/lib/providers/index.js +5 -9
- package/lib/scripts/check-avs-registration.d.ts +1 -1
- package/lib/scripts/check-avs-registration.js +24 -25
- package/lib/scripts/fallbacks/crypto.d.ts +1 -0
- package/lib/scripts/fallbacks/crypto.js +4 -0
- package/lib/scripts/fallbacks/empty.d.ts +3 -0
- package/lib/scripts/fallbacks/empty.js +4 -0
- package/lib/scripts/fallbacks/re2.d.ts +1 -0
- package/lib/scripts/fallbacks/re2.js +7 -0
- package/lib/scripts/fallbacks/snarkjs.d.ts +1 -0
- package/lib/scripts/fallbacks/snarkjs.js +10 -0
- package/lib/scripts/fallbacks/stwo.d.ts +6 -0
- package/lib/scripts/fallbacks/stwo.js +159 -0
- package/lib/scripts/generate-provider-types.js +92 -73
- package/lib/scripts/generate-receipt.d.ts +2 -2
- package/lib/scripts/generate-receipt.js +94 -83
- package/lib/scripts/generate-toprf-keys.js +17 -16
- package/lib/scripts/jsc-cli-rpc.d.ts +1 -0
- package/lib/scripts/jsc-cli-rpc.js +35 -0
- package/lib/scripts/register-avs-operator.d.ts +1 -1
- package/lib/scripts/register-avs-operator.js +3 -7
- package/lib/scripts/start-server.d.ts +1 -1
- package/lib/scripts/start-server.js +9 -11
- package/lib/scripts/update-avs-metadata.d.ts +1 -1
- package/lib/scripts/update-avs-metadata.js +17 -19
- package/lib/scripts/utils.js +8 -9
- package/lib/scripts/whitelist-operator.d.ts +1 -1
- package/lib/scripts/whitelist-operator.js +13 -15
- package/lib/server/create-server.d.ts +3 -2
- package/lib/server/create-server.js +98 -85
- package/lib/server/handlers/claimTeeBundle.d.ts +6 -0
- package/lib/server/handlers/claimTeeBundle.js +232 -0
- package/lib/server/handlers/claimTunnel.d.ts +1 -1
- package/lib/server/handlers/claimTunnel.js +75 -73
- package/lib/server/handlers/completeClaimOnChain.d.ts +1 -1
- package/lib/server/handlers/completeClaimOnChain.js +27 -26
- package/lib/server/handlers/createClaimOnChain.d.ts +1 -1
- package/lib/server/handlers/createClaimOnChain.js +30 -29
- package/lib/server/handlers/createTaskOnMechain.d.ts +1 -1
- package/lib/server/handlers/createTaskOnMechain.js +54 -49
- package/lib/server/handlers/createTunnel.d.ts +1 -1
- package/lib/server/handlers/createTunnel.js +91 -94
- package/lib/server/handlers/disconnectTunnel.d.ts +1 -1
- package/lib/server/handlers/disconnectTunnel.js +6 -8
- package/lib/server/handlers/fetchCertificateBytes.d.ts +2 -0
- package/lib/server/handlers/fetchCertificateBytes.js +57 -0
- package/lib/server/handlers/index.d.ts +1 -1
- package/lib/server/handlers/index.js +24 -21
- package/lib/server/handlers/init.d.ts +1 -1
- package/lib/server/handlers/init.js +31 -34
- package/lib/server/handlers/toprf.d.ts +1 -1
- package/lib/server/handlers/toprf.js +17 -19
- package/lib/server/index.d.ts +4 -4
- package/lib/server/index.js +4 -21
- package/lib/server/socket.d.ts +7 -7
- package/lib/server/socket.js +104 -106
- package/lib/server/tunnels/make-tcp-tunnel.d.ts +5 -3
- package/lib/server/tunnels/make-tcp-tunnel.js +189 -162
- package/lib/server/utils/apm.d.ts +1 -1
- package/lib/server/utils/apm.js +26 -40
- package/lib/server/utils/assert-valid-claim-request.d.ts +6 -5
- package/lib/server/utils/assert-valid-claim-request.js +339 -185
- package/lib/server/utils/config-env.js +4 -7
- package/lib/server/utils/dns.js +18 -16
- package/lib/server/utils/gcp-attestation.d.ts +17 -0
- package/lib/server/utils/gcp-attestation.js +237 -0
- package/lib/server/utils/generics.d.ts +3 -3
- package/lib/server/utils/generics.js +37 -51
- package/lib/server/utils/iso.js +255 -256
- package/lib/server/utils/keep-alive.d.ts +2 -2
- package/lib/server/utils/keep-alive.js +36 -40
- package/lib/server/utils/nitro-attestation.d.ts +33 -0
- package/lib/server/utils/nitro-attestation.js +249 -0
- package/lib/server/utils/oprf-raw.d.ts +21 -0
- package/lib/server/utils/oprf-raw.js +61 -0
- package/lib/server/utils/process-handshake.d.ts +3 -3
- package/lib/server/utils/process-handshake.js +217 -175
- package/lib/server/utils/proxy-session.d.ts +1 -0
- package/lib/server/utils/proxy-session.js +6 -0
- package/lib/server/utils/tee-oprf-mpc-verification.d.ts +16 -0
- package/lib/server/utils/tee-oprf-mpc-verification.js +86 -0
- package/lib/server/utils/tee-oprf-verification.d.ts +24 -0
- package/lib/server/utils/tee-oprf-verification.js +151 -0
- package/lib/server/utils/tee-transcript-reconstruction.d.ts +24 -0
- package/lib/server/utils/tee-transcript-reconstruction.js +140 -0
- package/lib/server/utils/tee-verification.d.ts +28 -0
- package/lib/server/utils/tee-verification.js +358 -0
- package/lib/{utils → server/utils}/validation.d.ts +1 -1
- package/lib/server/utils/validation.js +45 -0
- package/lib/types/bgp.js +0 -3
- package/lib/types/claims.d.ts +7 -10
- package/lib/types/claims.js +0 -3
- package/lib/types/client.d.ts +5 -5
- package/lib/types/client.js +0 -3
- package/lib/types/general.d.ts +29 -4
- package/lib/types/general.js +0 -3
- package/lib/types/handlers.d.ts +3 -3
- package/lib/types/handlers.js +0 -3
- package/lib/types/index.d.ts +10 -10
- package/lib/types/index.js +10 -27
- package/lib/types/providers.d.ts +15 -4
- package/lib/types/providers.gen.d.ts +15 -1
- package/lib/types/providers.gen.js +15 -13
- package/lib/types/providers.js +0 -3
- package/lib/types/rpc.d.ts +2 -2
- package/lib/types/rpc.js +0 -3
- package/lib/types/signatures.js +0 -3
- package/lib/types/tunnel.d.ts +2 -2
- package/lib/types/tunnel.js +0 -3
- package/lib/types/zk.d.ts +17 -2
- package/lib/types/zk.js +0 -3
- package/lib/utils/auth.d.ts +2 -1
- package/lib/utils/auth.js +66 -59
- package/lib/utils/b64-json.js +13 -19
- package/lib/utils/bgp-listener.d.ts +1 -1
- package/lib/utils/bgp-listener.js +111 -114
- package/lib/utils/claims.d.ts +3 -3
- package/lib/utils/claims.js +78 -101
- package/lib/utils/env.js +15 -16
- package/lib/utils/error.d.ts +6 -7
- package/lib/utils/error.js +50 -39
- package/lib/utils/generics.d.ts +15 -13
- package/lib/utils/generics.js +217 -297
- package/lib/utils/http-parser.d.ts +1 -1
- package/lib/utils/http-parser.js +186 -237
- package/lib/utils/index.d.ts +13 -12
- package/lib/utils/index.js +13 -29
- package/lib/utils/logger.d.ts +1 -1
- package/lib/utils/logger.js +69 -87
- package/lib/utils/prepare-packets.d.ts +3 -3
- package/lib/utils/prepare-packets.js +66 -58
- package/lib/utils/redactions.d.ts +20 -1
- package/lib/utils/redactions.js +116 -129
- package/lib/utils/retries.d.ts +1 -1
- package/lib/utils/retries.js +24 -26
- package/lib/utils/signatures/eth.d.ts +1 -1
- package/lib/utils/signatures/eth.js +28 -30
- package/lib/utils/signatures/index.d.ts +3 -3
- package/lib/utils/signatures/index.js +11 -10
- package/lib/utils/socket-base.d.ts +6 -5
- package/lib/utils/socket-base.js +89 -88
- package/lib/utils/tls.d.ts +1 -1
- package/lib/utils/tls.js +54 -28
- package/lib/utils/ws.d.ts +1 -6
- package/lib/utils/ws.js +17 -33
- package/lib/utils/zk.d.ts +28 -12
- package/lib/utils/zk.js +587 -406
- package/package.json +72 -60
- package/lib/avs/tests/test.operator.d.ts +0 -11
- package/lib/avs/tests/test.operator.js +0 -313
- package/lib/avs/tests/utils.d.ts +0 -2
- package/lib/avs/tests/utils.js +0 -50
- package/lib/scripts/verify-root-ca.d.ts +0 -1
- package/lib/scripts/verify-root-ca.js +0 -51
- package/lib/tests/describe-with-server.d.ts +0 -20
- package/lib/tests/describe-with-server.js +0 -64
- package/lib/tests/mock-provider-server.d.ts +0 -13
- package/lib/tests/mock-provider-server.js +0 -65
- package/lib/tests/mocks.d.ts +0 -4
- package/lib/tests/mocks.js +0 -23
- package/lib/tests/test.auth.js +0 -75
- package/lib/tests/test.bgp-listener.js +0 -169
- package/lib/tests/test.claim-creation.js +0 -280
- package/lib/tests/test.http-parser.d.ts +0 -1
- package/lib/tests/test.http-parser.js +0 -120
- package/lib/tests/test.http-provider-utils.js +0 -2416
- package/lib/tests/test.http-provider.d.ts +0 -1
- package/lib/tests/test.http-provider.js +0 -114
- package/lib/tests/test.rpc-communication.d.ts +0 -1
- package/lib/tests/test.rpc-communication.js +0 -64
- package/lib/tests/test.rpc-tunnel.d.ts +0 -1
- package/lib/tests/test.rpc-tunnel.js +0 -172
- package/lib/tests/test.signatures.d.ts +0 -1
- package/lib/tests/test.signatures.js +0 -24
- package/lib/tests/test.tcp-tunnel.d.ts +0 -1
- package/lib/tests/test.tcp-tunnel.js +0 -64
- package/lib/tests/test.zk.d.ts +0 -1
- package/lib/tests/test.zk.js +0 -337
- package/lib/tests/utils.d.ts +0 -18
- package/lib/tests/utils.js +0 -64
- package/lib/utils/atomic-operations.d.ts +0 -24
- package/lib/utils/atomic-operations.js +0 -65
- package/lib/utils/benchmark.d.ts +0 -1
- package/lib/utils/benchmark.js +0 -70
- package/lib/utils/connection-state-machine.d.ts +0 -43
- package/lib/utils/connection-state-machine.js +0 -129
- package/lib/utils/resource-monitor.d.ts +0 -61
- package/lib/utils/resource-monitor.js +0 -107
- package/lib/utils/validation.js +0 -46
- package/lib/window-rpc/index.d.ts +0 -3
- package/lib/window-rpc/index.js +0 -20
- package/lib/window-rpc/setup-window-rpc.d.ts +0 -5
- package/lib/window-rpc/setup-window-rpc.js +0 -291
- package/lib/window-rpc/types.js +0 -3
- package/lib/window-rpc/utils.d.ts +0 -14
- package/lib/window-rpc/utils.js +0 -102
- package/lib/window-rpc/window-rpc-zk.d.ts +0 -15
- package/lib/window-rpc/window-rpc-zk.js +0 -85
- /package/lib/{tests/test.auth.d.ts → external-rpc/jsc-polyfills/2.d.ts} +0 -0
- /package/lib/{tests/test.bgp-listener.d.ts → scripts/build-browser.d.ts} +0 -0
- /package/lib/{tests/test.claim-creation.d.ts → scripts/build-jsc.d.ts} +0 -0
- /package/lib/{tests/test.http-provider-utils.d.ts → scripts/build-lib.d.ts} +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import bs58 from "bs58";
|
|
2
|
+
import { AttestorError } from "../../utils/error.js";
|
|
3
|
+
import { makeDefaultOPRFOperator } from "../../utils/zk.js";
|
|
4
|
+
async function verifyOprfProofs(bundleData, logger) {
|
|
5
|
+
if (!bundleData.oprfVerifications || bundleData.oprfVerifications.length === 0) {
|
|
6
|
+
logger.debug("No OPRF verifications present in bundle");
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const { tOutputPayload } = bundleData;
|
|
10
|
+
const consolidatedCiphertext = tOutputPayload.consolidatedResponseCiphertext;
|
|
11
|
+
if (!consolidatedCiphertext || consolidatedCiphertext.length === 0) {
|
|
12
|
+
throw new AttestorError("ERROR_INVALID_CLAIM", "No consolidated ciphertext for OPRF verification");
|
|
13
|
+
}
|
|
14
|
+
const results = [];
|
|
15
|
+
logger.info(`Verifying ${bundleData.oprfVerifications.length} OPRF proofs`);
|
|
16
|
+
for (const [idx, oprfData] of bundleData.oprfVerifications.entries()) {
|
|
17
|
+
try {
|
|
18
|
+
const result = await verifySingleOprfProof(
|
|
19
|
+
oprfData,
|
|
20
|
+
consolidatedCiphertext,
|
|
21
|
+
idx,
|
|
22
|
+
logger
|
|
23
|
+
);
|
|
24
|
+
results.push(result);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
logger.error({ error, index: idx }, "OPRF proof verification failed");
|
|
27
|
+
throw new AttestorError(
|
|
28
|
+
"ERROR_INVALID_CLAIM",
|
|
29
|
+
`OPRF verification failed at index ${idx}: ${error.message}`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
logger.info(`Successfully verified ${results.length} OPRF proofs`);
|
|
34
|
+
return results;
|
|
35
|
+
}
|
|
36
|
+
async function verifySingleOprfProof(oprfData, consolidatedCiphertext, index, logger) {
|
|
37
|
+
const publicSignalsJson = JSON.parse(new TextDecoder().decode(oprfData.publicSignalsJson));
|
|
38
|
+
const { proof, publicSignals, cipher } = publicSignalsJson;
|
|
39
|
+
if (!proof || !publicSignals) {
|
|
40
|
+
throw new Error("Missing proof or public signals in OPRF data");
|
|
41
|
+
}
|
|
42
|
+
const ciphertextChunk = consolidatedCiphertext.slice(
|
|
43
|
+
oprfData.streamPos,
|
|
44
|
+
oprfData.streamPos + oprfData.streamLength
|
|
45
|
+
);
|
|
46
|
+
const completePublicSignals = {
|
|
47
|
+
out: publicSignals.out || Uint8Array.from([]),
|
|
48
|
+
// Replace null input with extracted ciphertext
|
|
49
|
+
in: ciphertextChunk,
|
|
50
|
+
// Convert base64 nonces and counters
|
|
51
|
+
noncesAndCounters: publicSignals.blocks?.map((block) => ({
|
|
52
|
+
nonce: Buffer.from(block.nonce || "", "base64"),
|
|
53
|
+
counter: block.counter || 0,
|
|
54
|
+
boundary: block.boundary || ""
|
|
55
|
+
})) || [],
|
|
56
|
+
// Process TOPRF data
|
|
57
|
+
toprf: publicSignals.toprf ? {
|
|
58
|
+
...publicSignals.toprf,
|
|
59
|
+
// Convert domain separator from base64
|
|
60
|
+
domainSeparator: publicSignals.toprf.domainSeparator ? Buffer.from(publicSignals.toprf.domainSeparator, "base64").toString("utf8") : "reclaim",
|
|
61
|
+
// Convert output from base64
|
|
62
|
+
output: publicSignals.toprf.output ? Buffer.from(publicSignals.toprf.output, "base64") : new Uint8Array(),
|
|
63
|
+
// Convert response fields from base64
|
|
64
|
+
responses: publicSignals.toprf.responses?.map((resp) => ({
|
|
65
|
+
publicKeyShare: Buffer.from(resp.publicKeyShare || "", "base64"),
|
|
66
|
+
evaluated: Buffer.from(resp.evaluated || "", "base64"),
|
|
67
|
+
c: Buffer.from(resp.c || "", "base64"),
|
|
68
|
+
r: Buffer.from(resp.r || "", "base64")
|
|
69
|
+
})) || [],
|
|
70
|
+
// Locations are already in correct format
|
|
71
|
+
locations: publicSignals.toprf.locations || []
|
|
72
|
+
} : void 0
|
|
73
|
+
};
|
|
74
|
+
const algorithm = cipher.replace("-toprf", "");
|
|
75
|
+
const zkEngine = "gnark";
|
|
76
|
+
const oprfOperator = makeDefaultOPRFOperator(algorithm, zkEngine, logger);
|
|
77
|
+
const proofBytes = Buffer.from(proof, "base64");
|
|
78
|
+
const isValid = await oprfOperator.groth16Verify(
|
|
79
|
+
completePublicSignals,
|
|
80
|
+
proofBytes,
|
|
81
|
+
logger
|
|
82
|
+
);
|
|
83
|
+
if (!isValid) {
|
|
84
|
+
throw new Error("OPRF proof verification failed");
|
|
85
|
+
}
|
|
86
|
+
logger.debug(`OPRF ${index}: Proof verified successfully`);
|
|
87
|
+
const oprfOutput = completePublicSignals.toprf?.output;
|
|
88
|
+
if (!oprfOutput || oprfOutput.length === 0) {
|
|
89
|
+
throw new Error("No OPRF output found in verified proof");
|
|
90
|
+
}
|
|
91
|
+
const oprfLocation = completePublicSignals.toprf?.locations?.[0];
|
|
92
|
+
if (!oprfLocation) {
|
|
93
|
+
throw new Error("No OPRF location found in public signals");
|
|
94
|
+
}
|
|
95
|
+
logger.info(`OPRF #${index}: streamPos=${oprfData.streamPos}, locationPos=${oprfLocation.pos}, finalPos=${oprfData.streamPos + oprfLocation.pos}, len=${oprfLocation.len}`);
|
|
96
|
+
return {
|
|
97
|
+
// The position in the plaintext where to replace (stream position + OPRF location within chunk)
|
|
98
|
+
position: oprfData.streamPos + oprfLocation.pos,
|
|
99
|
+
length: oprfLocation.len,
|
|
100
|
+
output: oprfOutput
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function replaceOprfRanges(plaintext, oprfResults, logger) {
|
|
104
|
+
if (oprfResults.length === 0) {
|
|
105
|
+
return plaintext;
|
|
106
|
+
}
|
|
107
|
+
const replacements = oprfResults.map((result) => {
|
|
108
|
+
let outputBytes;
|
|
109
|
+
let encodedOutput;
|
|
110
|
+
if (result.isMPC) {
|
|
111
|
+
encodedOutput = bs58.encode(result.output);
|
|
112
|
+
outputBytes = new TextEncoder().encode(encodedOutput);
|
|
113
|
+
} else {
|
|
114
|
+
encodedOutput = Buffer.from(result.output).toString("base64");
|
|
115
|
+
const truncated = encodedOutput.substring(0, result.length);
|
|
116
|
+
outputBytes = new TextEncoder().encode(truncated);
|
|
117
|
+
}
|
|
118
|
+
return { result, outputBytes, encodedOutput };
|
|
119
|
+
});
|
|
120
|
+
replacements.sort((a, b) => a.result.position - b.result.position);
|
|
121
|
+
let newSize = plaintext.length;
|
|
122
|
+
for (const { result, outputBytes } of replacements) {
|
|
123
|
+
const sizeDiff = outputBytes.length - result.length;
|
|
124
|
+
newSize += sizeDiff;
|
|
125
|
+
}
|
|
126
|
+
logger.info(`Transcript size: ${plaintext.length} -> ${newSize} (${newSize - plaintext.length >= 0 ? "+" : ""}${newSize - plaintext.length} bytes)`);
|
|
127
|
+
const newPlaintext = new Uint8Array(newSize);
|
|
128
|
+
let srcPos = 0;
|
|
129
|
+
let dstPos = 0;
|
|
130
|
+
for (const [idx, { result, outputBytes, encodedOutput }] of replacements.entries()) {
|
|
131
|
+
const segmentLength = result.position - srcPos;
|
|
132
|
+
if (segmentLength > 0) {
|
|
133
|
+
newPlaintext.set(plaintext.slice(srcPos, result.position), dstPos);
|
|
134
|
+
dstPos += segmentLength;
|
|
135
|
+
}
|
|
136
|
+
const currentContent = plaintext.slice(result.position, result.position + result.length);
|
|
137
|
+
logger.info(`OPRF #${idx} at pos ${result.position}: "${Buffer.from(currentContent).toString("utf8")}" (${result.length}b) -> "${encodedOutput}" (${outputBytes.length}b)${result.isMPC ? " [MPC/base58]" : ""}`);
|
|
138
|
+
newPlaintext.set(outputBytes, dstPos);
|
|
139
|
+
dstPos += outputBytes.length;
|
|
140
|
+
srcPos = result.position + result.length;
|
|
141
|
+
}
|
|
142
|
+
if (srcPos < plaintext.length) {
|
|
143
|
+
newPlaintext.set(plaintext.slice(srcPos), dstPos);
|
|
144
|
+
}
|
|
145
|
+
logger.info(`Replaced ${oprfResults.length} OPRF ranges in plaintext`);
|
|
146
|
+
return newPlaintext;
|
|
147
|
+
}
|
|
148
|
+
export {
|
|
149
|
+
replaceOprfRanges,
|
|
150
|
+
verifyOprfProofs
|
|
151
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TLS Transcript Reconstruction from TEE data
|
|
3
|
+
*/
|
|
4
|
+
import type { CertificateInfo } from '#src/proto/tee-bundle.ts';
|
|
5
|
+
import type { TeeBundleData } from '#src/server/utils/tee-verification.ts';
|
|
6
|
+
import type { Logger } from '#src/types/general.ts';
|
|
7
|
+
export interface TeeTranscriptData {
|
|
8
|
+
revealedRequest: Uint8Array;
|
|
9
|
+
reconstructedResponse: Uint8Array;
|
|
10
|
+
certificateInfo?: CertificateInfo;
|
|
11
|
+
responseTrimOffset?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reconstructs TLS transcript from TEE bundle data
|
|
15
|
+
* @param bundleData - Validated TEE bundle data
|
|
16
|
+
* @param logger - Logger instance
|
|
17
|
+
* @param oprfResults - Optional OPRF results to apply during reconstruction
|
|
18
|
+
* @returns Reconstructed transcript data
|
|
19
|
+
*/
|
|
20
|
+
export declare function reconstructTlsTranscript(bundleData: TeeBundleData, logger: Logger, oprfResults?: Array<{
|
|
21
|
+
position: number;
|
|
22
|
+
length: number;
|
|
23
|
+
output: Uint8Array;
|
|
24
|
+
}>): Promise<TeeTranscriptData>;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { AttestorError } from "../../utils/error.js";
|
|
2
|
+
import { REDACTION_CHAR_CODE } from "../../utils/index.js";
|
|
3
|
+
async function reconstructTlsTranscript(bundleData, logger, oprfResults) {
|
|
4
|
+
try {
|
|
5
|
+
const revealedRequest = reconstructRequest(bundleData, logger);
|
|
6
|
+
const reconstructedResponse = await reconstructConsolidatedResponse(bundleData, logger, oprfResults);
|
|
7
|
+
const certificateInfo = bundleData.kOutputPayload.certificateInfo;
|
|
8
|
+
logger.info("TLS transcript reconstruction completed successfully", {
|
|
9
|
+
requestSize: revealedRequest.length,
|
|
10
|
+
responseSize: reconstructedResponse.length,
|
|
11
|
+
hasCertificateInfo: !!certificateInfo
|
|
12
|
+
});
|
|
13
|
+
return {
|
|
14
|
+
revealedRequest,
|
|
15
|
+
reconstructedResponse,
|
|
16
|
+
certificateInfo
|
|
17
|
+
};
|
|
18
|
+
} catch (error) {
|
|
19
|
+
logger.error({ error }, "TLS transcript reconstruction failed");
|
|
20
|
+
throw new AttestorError("ERROR_INVALID_CLAIM", `Transcript reconstruction failed: ${error.message}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function reconstructRequest(bundleData, logger) {
|
|
24
|
+
const { kOutputPayload } = bundleData;
|
|
25
|
+
if (!kOutputPayload.requestRedactionRanges || kOutputPayload.requestRedactionRanges.length === 0) {
|
|
26
|
+
logger.warn("No request redaction ranges - using redacted request as-is");
|
|
27
|
+
return kOutputPayload.redactedRequest;
|
|
28
|
+
}
|
|
29
|
+
const revealedRequest = new Uint8Array(kOutputPayload.redactedRequest);
|
|
30
|
+
const prettyRequest = new Uint8Array(revealedRequest);
|
|
31
|
+
for (const range of kOutputPayload.requestRedactionRanges) {
|
|
32
|
+
if (!range.type.includes("proof")) {
|
|
33
|
+
const start = range.start;
|
|
34
|
+
const length = range.length;
|
|
35
|
+
for (let i = 0; i < length && start + i < prettyRequest.length; i++) {
|
|
36
|
+
prettyRequest[start + i] = REDACTION_CHAR_CODE;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return prettyRequest;
|
|
41
|
+
}
|
|
42
|
+
async function reconstructConsolidatedResponse(bundleData, logger, oprfResults) {
|
|
43
|
+
const { kOutputPayload, tOutputPayload } = bundleData;
|
|
44
|
+
const consolidatedKeystream = kOutputPayload.consolidatedResponseKeystream;
|
|
45
|
+
const consolidatedCiphertext = tOutputPayload.consolidatedResponseCiphertext;
|
|
46
|
+
if (!consolidatedKeystream || consolidatedKeystream.length === 0) {
|
|
47
|
+
throw new AttestorError("ERROR_INVALID_CLAIM", "No consolidated response keystream available");
|
|
48
|
+
}
|
|
49
|
+
if (!consolidatedCiphertext || consolidatedCiphertext.length === 0) {
|
|
50
|
+
throw new AttestorError("ERROR_INVALID_CLAIM", "No consolidated response ciphertext available");
|
|
51
|
+
}
|
|
52
|
+
if (consolidatedKeystream.length !== consolidatedCiphertext.length) {
|
|
53
|
+
logger.warn("Keystream and ciphertext length mismatch", {
|
|
54
|
+
keystreamLength: consolidatedKeystream.length,
|
|
55
|
+
ciphertextLength: consolidatedCiphertext.length
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const minLength = Math.min(consolidatedKeystream.length, consolidatedCiphertext.length);
|
|
59
|
+
const reconstructedResponse = new Uint8Array(minLength);
|
|
60
|
+
for (let i = 0; i < minLength; i++) {
|
|
61
|
+
reconstructedResponse[i] = consolidatedKeystream[i] ^ consolidatedCiphertext[i];
|
|
62
|
+
}
|
|
63
|
+
logger.info(`Reconstructed response: ${reconstructedResponse.length} bytes, ${kOutputPayload.responseRedactionRanges?.length || 0} redaction ranges`);
|
|
64
|
+
let processedResponse = applyResponseRedactionRanges(reconstructedResponse, kOutputPayload.responseRedactionRanges, logger);
|
|
65
|
+
if (oprfResults && oprfResults.length > 0) {
|
|
66
|
+
logger.info(`Applying ${oprfResults.length} OPRF replacements before trimming`);
|
|
67
|
+
const { replaceOprfRanges } = await import("../../server/utils/tee-oprf-verification.js");
|
|
68
|
+
processedResponse = replaceOprfRanges(processedResponse, oprfResults, logger);
|
|
69
|
+
}
|
|
70
|
+
let leadingAsterisks = 0;
|
|
71
|
+
for (const element of processedResponse) {
|
|
72
|
+
if (element === REDACTION_CHAR_CODE) {
|
|
73
|
+
leadingAsterisks++;
|
|
74
|
+
} else {
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
let trailingAsterisks = 0;
|
|
79
|
+
for (let i = processedResponse.length - 1; i >= leadingAsterisks; i--) {
|
|
80
|
+
if (processedResponse[i] === REDACTION_CHAR_CODE) {
|
|
81
|
+
trailingAsterisks++;
|
|
82
|
+
} else {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const finalLength = processedResponse.length - leadingAsterisks - trailingAsterisks;
|
|
87
|
+
logger.info(`After processing: ${processedResponse.length} bytes, ${leadingAsterisks} leading and ${trailingAsterisks} trailing asterisks trimmed, final: ${finalLength} bytes`);
|
|
88
|
+
return processedResponse.slice(leadingAsterisks, processedResponse.length - trailingAsterisks);
|
|
89
|
+
}
|
|
90
|
+
function applyResponseRedactionRanges(response, redactionRanges, logger) {
|
|
91
|
+
if (!redactionRanges || redactionRanges.length === 0) {
|
|
92
|
+
return response;
|
|
93
|
+
}
|
|
94
|
+
const result = new Uint8Array(response);
|
|
95
|
+
const consolidatedRanges = consolidateRedactionRanges(redactionRanges);
|
|
96
|
+
if (logger) {
|
|
97
|
+
logger.info(`Applying ${consolidatedRanges.length} redaction ranges to ${response.length} byte response`);
|
|
98
|
+
}
|
|
99
|
+
for (const [idx, range] of consolidatedRanges.entries()) {
|
|
100
|
+
const rangeStart = range.start;
|
|
101
|
+
const rangeEnd = range.start + range.length;
|
|
102
|
+
if (rangeStart < 0 || rangeEnd > result.length) {
|
|
103
|
+
if (logger) {
|
|
104
|
+
logger.warn(`Redaction range #${idx} out of bounds: [${rangeStart}-${rangeEnd}] vs ${result.length}`);
|
|
105
|
+
}
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (logger && idx < 3) {
|
|
109
|
+
logger.info(`Redaction range #${idx}: [${rangeStart}-${rangeEnd}]`);
|
|
110
|
+
}
|
|
111
|
+
for (let i = rangeStart; i < rangeEnd; i++) {
|
|
112
|
+
result[i] = REDACTION_CHAR_CODE;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
function consolidateRedactionRanges(ranges) {
|
|
118
|
+
if (ranges.length === 0) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
const sortedRanges = [...ranges].sort((a, b) => a.start - b.start);
|
|
122
|
+
const consolidated = [];
|
|
123
|
+
let current = { ...sortedRanges[0] };
|
|
124
|
+
for (let i = 1; i < sortedRanges.length; i++) {
|
|
125
|
+
const next = sortedRanges[i];
|
|
126
|
+
if (next.start <= current.start + current.length) {
|
|
127
|
+
const endCurrent = current.start + current.length;
|
|
128
|
+
const endNext = next.start + next.length;
|
|
129
|
+
current.length = Math.max(endCurrent, endNext) - current.start;
|
|
130
|
+
} else {
|
|
131
|
+
consolidated.push(current);
|
|
132
|
+
current = { ...next };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
consolidated.push(current);
|
|
136
|
+
return consolidated;
|
|
137
|
+
}
|
|
138
|
+
export {
|
|
139
|
+
reconstructTlsTranscript
|
|
140
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TEE Bundle verification utilities
|
|
3
|
+
* Handles validation of TEE verification bundles including attestations and signatures
|
|
4
|
+
*/
|
|
5
|
+
import type { SignedMessage } from '#src/proto/tee-bundle.ts';
|
|
6
|
+
import { KOutputPayload, TOutputPayload } from '#src/proto/tee-bundle.ts';
|
|
7
|
+
import type { Logger } from '#src/types/general.ts';
|
|
8
|
+
export interface TeeBundleData {
|
|
9
|
+
teekSigned: SignedMessage;
|
|
10
|
+
teetSigned: SignedMessage;
|
|
11
|
+
kOutputPayload: KOutputPayload;
|
|
12
|
+
tOutputPayload: TOutputPayload;
|
|
13
|
+
teekPcr0: string;
|
|
14
|
+
teetPcr0: string;
|
|
15
|
+
teeSessionId: string;
|
|
16
|
+
}
|
|
17
|
+
export interface TeeSignatureVerificationResult {
|
|
18
|
+
isValid: boolean;
|
|
19
|
+
errors: string[];
|
|
20
|
+
address?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Verifies a complete TEE verification bundle
|
|
24
|
+
* @param bundleBytes - Raw protobuf-encoded verification bundle
|
|
25
|
+
* @param logger - Logger instance
|
|
26
|
+
* @returns Validated TEE bundle data
|
|
27
|
+
*/
|
|
28
|
+
export declare function verifyTeeBundle(bundleBytes: Uint8Array, logger: Logger): Promise<TeeBundleData>;
|