12 KiB
TRUSTED-COMPUTING-BASE — luxfi/teleport
Inventory of every component whose correct operation is required for the Teleport bridge to provide its security guarantees. Reading this file should give an auditor / operator a complete picture of what must be trusted, and what is verified.
The TCB is split into three layers:
- Hardware / OS: standard for a Solidity bridge — what runs the EVM, what runs the Node.js services.
- Cryptographic primitives: the schemes whose security assumptions Teleport inherits.
- Quorum operators: the human + multi-sig parties whose honesty is required for liveness and (in some cases) safety.
1. Hardware / OS layer
| Component | Trust model | What's verified |
|---|---|---|
| Source-chain client (geth, Bitcoin Core, etc.) | Trusted (operator-run; relay reads from it) | None — Teleport reads logs at face value, mitigated by waiting for min_confirmations per asset |
| Destination-chain EVM | Trusted to execute Solidity correctly | Implicit in EVM consensus; Lux quasar consensus on Lux-side, Ethereum consensus on Ethereum-side, etc. |
mpcd host OS (linux) |
Trusted | Secrets in memory, zeroized on exit per signer's contract |
| API / MPC service OS | Trusted | TLS termination at ingress; rate limits + helmet + cors on the express layer |
| MongoDB | Trusted for liveness only (signatures persisted are bound to chain by claimId = keccak256(...)) |
Replay protection lives on-chain in usedMessages; MongoDB loss does not enable replay |
2. Cryptographic primitives
Teleport composes the following primitives. Each carries its own security proof in its own repository; this table catalogues the assumption Teleport inherits.
2.1 Solidity-side primitives
| Primitive | Where used | Assumption | Profile |
|---|---|---|---|
keccak256 |
Envelope binding, claimId, EIP-712 digest, allow-list keying | Collision resistance + indifferentiability from RO | both |
| ECDSA on secp256k1 | Bridge.sol oracle signature |
EUF-CMA under DLP on secp256k1 | classical-compat only |
| BLS12-381 pairing | Beam lane (envelope BLS aggregate) | co-DDH on G1×G2, ROM | classical-compat only (refused in strict-PQ Z-Chain slot) |
BN254 pairing (0x06 0x07 0x08) |
Groth16 / PLONK / KZG verifier slot | DDH on BN254, ROM | classical-compat only (refused in strict-PQ slot) |
| ML-DSA-65 (FIPS 204) on-chain verifier | Optional cert-set lane | M-LWE + M-SIS + ROM | strict-PQ allowed |
| STARK / FRI verifier over SHA-3 | P3Q proof slot | SHA-3 modeled as RO + FRI soundness | strict-PQ allowed |
The strict-PQ allow-list is exactly {POLICY_STARK_FRI_SHA3_PQ, POLICY_MLDSA65_FIPS204} — every other proof backend is refused at
install time under PROFILE_QUASAR_STRICT_PQ. The constants live in
@luxfi/pq-profile-ids (single source of truth).
2.2 Off-chain (MPC bus) primitives
| Primitive | Repo | File | Assumption |
|---|---|---|---|
| GG18 ECDSA threshold | luxfi/multi-party-ecdsa (legacy) |
mpc/src/signers/ecdsa.ts (spawn) |
EUF-CMA secp256k1 + simulation security for the threshold |
| CGGMP21 ECDSA threshold | luxfi/threshold/protocols/cmp |
mpc/src/signers/cggmp21.ts (JSON-RPC) |
UC-secure under DLP + Paillier + RO |
| FROST Schnorr (RFC 9591) | @noble/curves@^2.2 (default) or luxfi/threshold/protocols/frost (daemon) |
mpc/src/signers/frost.ts |
EUF-CMA under DLP secp256k1 + ROM |
| Pulsar M-LWE threshold | luxfi/pulsar |
mpc/src/signers/pulsar.ts (JSON-RPC) |
M-LWE + M-SIS + ROM (FIPS 204 ML-DSA-65 byte-equivalent output) |
| Corona R-LWE threshold | luxfi/corona |
mpc/src/signers/corona.ts (JSON-RPC) |
R-LWE + ROM (built on the two-round Corona construction, eprint 2024/1113, with DKG2 + Pulsar-SHA3) |
| Double-lattice (Pulsar ⊕ Corona) | composition | mpc/src/signers/doubleLattice.ts |
M-LWE ⊕ R-LWE — breakage of either alone does not forge |
Default scheme under strict-PQ is double-lattice (belt-and-braces). A break of M-LWE alone does not forge if R-LWE holds, and vice versa. This is the conservative posture appropriate for a bridge that authorises cross-chain value transfer.
2.3 Wire-level primitives
| Primitive | Where | Assumption |
|---|---|---|
| cSHAKE256 (digest of envelope bytes) | api/src/pq/pqSigner.ts |
SHA-3 modeled as RO + customisation strings act as domain separator |
keccak256 (every messageHash, claimId, EIP-712 digest) |
Solidity contracts + Express layer | Collision resistance |
| TLS 1.3 (ingress) | API / MPC service ingress | Standard TLS assumptions (BoringSSL / OpenSSL); not bridge-specific |
| ML-KEM-768 (FIPS 203) for transport | mpcd <-> mpcd peer transport |
M-LWE for ML-KEM |
3. Quorum operators
Teleport delegates trust to two quorum sets. These are the human- operated components whose collusion can break the bridge.
3.1 Lux validator set
The Lux validator set signs the Warp 2.0 envelope. Their honesty is required for safety (no unauthorised mint). The residual:
- Beam lane: BLS quorum (>= 2/3 by stake) signs the BLS aggregate.
- ML-DSA cert set: each validator signs with its FIPS 204 ML-DSA-65 key.
- Pulse: t-of-n Pulsar threshold over the M-LWE kernel.
Adversary model: Byzantine minority (up to n/3 - 1 validators
may be malicious without breaking safety; 2n/3 are required for
liveness). Same residual as Lux quasar consensus (LP-110); Teleport
does not weaken or strengthen this residual.
Quorum takeover (>= 2n/3 malicious by stake) lets the attacker
forge an envelope. This is the same residual as the underlying
consensus; mitigations are stake distribution, slashing, validator
diversity — out of Teleport's scope.
3.2 M-Chain custody quorum
The M-Chain ThresholdVM (LP-7330) holds the external-asset MPC key shares. Their honesty is required for safety of custodied funds. Residual:
- Per-asset MPC key set (CGGMP21 for ECDSA chains, FROST for Ed25519 chains).
- Threshold
tconfigurable per asset; default(2/3)n + 1. - LSS (Live Secret Sharing) refresh on a schedule.
Adversary model: Threshold minority. Up to t-1 shareholders can
be compromised without producing an unauthorised signature; t
collusion forges a release.
Mitigation: M-Chain validator set is selected as a subset of Lux validators with custody-specific staking and is on a separate slashing schedule (LP-7330 §"Custody Staking").
3.3 Bridge admin keys
The on-chain BridgeV2 contract has two distinct admin roles:
| Role | Capabilities | Suggested holder |
|---|---|---|
DEFAULT_ADMIN_ROLE |
Extend allowedVerifierCodeHashes allow-list |
Multi-sig + timelock (e.g. 4-of-7 with 48h timelock) |
ADMIN_ROLE |
Swap verifier among allow-listed code hashes; configure profile / token / fee / pause | Operations multi-sig (e.g. 3-of-5, no timelock) |
PAUSER_ROLE |
Emergency pause | On-call rotation (single-key allowed under tight monitoring) |
The split is the load-bearing defence against ADMIN_ROLE
compromise. A compromised operations multi-sig can swap among
already-vetted verifiers but cannot install a new "true-returning"
verifier — that requires DEFAULT_ADMIN_ROLE (timelocked
governance).
See DEPLOYMENT-RUNBOOK.md §"Role assignments" for the recommended
multi-sig configuration.
4. Inheritance chain
The bridge endpoint's security claim is:
Teleport bridge security
⇐ (composition)
∧ Strict-PQ gate refusal (P1–P6, proved here)
∧ Envelope verifier soundness (Warp 2.0)
⇐ ∧ BLS12-381 unforgeability + ML-DSA-65 unforgeability + Pulsar M-LWE
⇐ Beam BLS impl + ML-DSA impl + luxfi/pulsar
∧ Validator-set quorum honesty (LP-075, LP-110)
∧ M-Chain custody quorum honesty (LP-7330)
∧ Source-chain finality (per-asset min_confirmations)
∧ Destination-chain finality (per-deployment policy)
Each ∧ is an independent assumption. A break of any single line
narrows but does not collapse the overall security:
- Strict-PQ gate break: bridge accepts a classical verifier under strict-PQ. Mitigated by P5 (EXTCODEHASH allow-list + multi-sig).
- BLS break: Beam lane fails. ML-DSA + Pulse still require a quorum break to forge.
- ML-DSA break: cert-set lane fails. Beam + Pulse still required.
- Pulsar break: Pulse lane fails. Beam + ML-DSA still required.
- Validator quorum takeover: same residual as Lux consensus.
- M-Chain quorum takeover: custodied assets stolen — same residual as any threshold-custody bridge.
The composition is post-quantum agile: a quantum advance against BLS / ECDSA does not forge a bridge claim if ML-DSA + Pulse still hold, and the strict-PQ profile gate forces both PQ lanes to be present for high-value assets.
5. What is NOT in the TCB
Explicit non-TCB:
- JS code in
app/(frontend). The frontend constructs unsigned burn transactions and submits them to the user's wallet for signing. A malicious frontend can produce a tx the user signs by mistake, but cannot bypass the bridge's on-chain validation. - MongoDB persistence in
api/andmpc/. The on-chainusedMessagesmap is the source of truth for replay; MongoDB is a cache. Loss of MongoDB causes a service outage but not a safety break. - Express middleware (helmet, cors, rateLimit). These are
defence-in-depth; their failure does not bypass the cryptographic
validation in
bridgeBurn/bridgeMint.
6. Threat-model summary
| Threat | Mitigation | Residual |
|---|---|---|
| Quantum break of BLS12-381 | Multi-lane envelope (ML-DSA + Pulse) | Mitigated until all PQ lanes also break |
| Quantum break of secp256k1 (v1 oracle) | Migrate to v2 (BridgeV2 + Warp 2.0); v1 is deprecated post-Phase 5 | Until Phase 5 complete, v1 retains classical risk |
Compromised ADMIN_ROLE |
EXTCODEHASH allow-list + DEFAULT_ADMIN_ROLE timelock |
Attacker swaps among allow-listed verifiers — no novel verifier install |
Compromised DEFAULT_ADMIN_ROLE |
Multi-sig + timelock | Threshold-of-signers compromise; same as governance breach |
| Compromised M-Chain custody quorum | Threshold + LSS refresh + watchdogs | Threshold-of-shareholders compromise; out of scope |
| Source-chain reorg | min_confirmations per asset |
Reorg longer than configured threshold |
| Destination-chain reorg | Standard "wait for finality" UX | Reorg longer than user's wait |
| Replay across chains | (sourceChainId, destChainId) in messageHash |
None — covered by P4 |
| Replay within a chain | usedMessages[messageHash] |
None — covered by P4 |
| Cross-version v1 ↔ v2 reuse | messageHash identical across v1 / v2 → same usedMessages map |
None — covered by luxfi/warp/envelope.go line 207-212 |
Spoofed verifier (policyId returns whitelist but verify returns true) |
EXTCODEHASH allow-list (P5) | None — covered by P5 |
| Frontend MITM | User-signed tx on the wallet side | Out of scope — frontend is non-TCB |
| MPC daemon DoS | Rate limit + retries with backoff | Liveness only — bridge stops minting until MPC recovers |
7. Audit / review history
| Round | Reviewer | Date | Finding | Status |
|---|---|---|---|---|
| Red round 1 | internal | 2024 | EIP-712 typed signing missing | Closed in v1.0 (commit 8acf621) |
| Red round 2 | internal | 2024 | Token whitelist missing | Closed in v1.0 (commit 8acf621) |
| Red round 3 | internal | 2024 | Adversarial test gaps | Closed in v1.0 (commit fa742a9) |
| Red round 4 | internal | 2026-Q1 | Privacy contracts deprecated (FHE / Bulletproofs no longer load-bearing) | Closed by removal in commit 49522d3 |
| Red round 5 (Section C residual) | internal | 2026-Q1 | Spoofed verifier with allow-listed policyId could pass policy-id check + return true from verify | Closed by EXTCODEHASH allow-list in commit 3098d07 |
| Red HIGH #4 | internal | 2026-Q1 | Missing env config silently meant classical signing on strict-PQ deployment | Closed by fail-closed resolver in mpc/src/signers/index.ts |
Closed-out residual: every finding in Red rounds 1-5 + Red HIGH #4 has a code-level fix and a test in this repository. There is no known residual finding at the time of this Tier A pass.