Post-quantum and AI security
What is post-quantum, hybrid and classical on Tenzro Network and why, how an AI agent is bounded by its owner's terms, how releases are verified, and the residuals that are not yet closed.
This page states what Tenzro guarantees against a break of classical cryptography, what it does not, and how an AI agent acting on the network is bounded. Every statement is taken from the node source and its documentation, and the code that enforces it is named. It makes no claim of an external audit, a compliance certification or an unbreakable system. The Security page is the short version.
The guarantee
A break of classical cryptography alone (ECDSA over secp256k1 or P-256, Ed25519, X25519) cannot forge a validator vote or certificate, move funds from a Tenzro account, forge a bridge committee attestation, or read a protected secret that Tenzro wraps.
The word alone matters. The guarantee holds while the post-quantum primitive of each path holds, and breaking both legs of a path breaks the path. The exceptions are places where the verifier belongs to someone else: an external chain, a hardware vendor or a standard. They are listed under What stays classical.
Primitives
| Purpose | Primitive | Parameter set | Code |
|---|---|---|---|
| Signatures | ML-DSA (FIPS 204) | ML-DSA-65 by default, ML-DSA-87 for the optional validator scheme | tenzro-types/src/signature_scheme.rs, tenzro-crypto/src/pq.rs |
| Key encapsulation | ML-KEM (FIPS 203) | ML-KEM-768 | tenzro-crypto/src/ml_kem768.rs |
| Hashes and MACs | SHA-256, SHA-512, Keccak-256, BLAKE3 | 256 bits and above | tenzro-crypto/src/hash.rs |
| Symmetric encryption | AES-256-GCM | 256-bit keys | tenzro-crypto/src/encryption.rs |
| Finality proofs | STARK (RISC Zero) | the receipt's succinct form | tenzro-zk/src/finality_proof.rs |
| One-time signatures | WOTS+ over SHA-256 | Winternitz 16 | channel vouchers |
ML-DSA verification runs two independent implementations, RustCrypto ml-dsa and the formally verified libcrux-ml-dsa. A signature is accepted only if both accept it, and a disagreement is an error (tenzro-crypto/src/pq.rs). ML-KEM likewise runs two implementations and refuses the exchange when they differ (tenzro-crypto/src/ml_kem768.rs).
Grover's algorithm leaves about 128-bit security against preimages for the 256-bit hashes. The documentation gives no key-size or speed comparison for these parameter sets, and this page makes none.
Composition: both legs are mandatory
Where a classical primitive remains, it is paired with a post-quantum one. A signature verifies only if every leg verifies, and a shared secret is derived from every exchange.
- Signatures. Validators sign the composite
COMPSIG-MLDSA65-ECDSA-P256-SHA512, or the ML-DSA-87 and P-384 variant (tenzro-crypto/src/composite.rs,tenzro-finality/src/key.rs). Accounts sign P-256 plus ML-DSA-65 over the transaction hash. Bridge committee members sign secp256k1 plus ML-DSA-65 over the attestation digest. - Key agreement and wrapping. The secret is derived with HKDF-SHA256 from the X25519 secret and the ML-KEM-768 secret together, salted with a hash over the domain, the recipient key fingerprint, the sender share, the ciphertext and the context (
tenzro-crypto/src/hybrid_seal.rs). Peer transport and the consensus channels use the same shape. - Proof systems. The canonical finality proof is the STARK. The Groth16 wrap over BN254 is optional, is labelled classical-assumption, and is not the default form (
ProofForm,tenzro-zk/src/finality_proof.rs).
Where each path is enforced
| Path | Guarantee | Code |
|---|---|---|
| Validator votes, certificates, registration | Composite signature, both legs mandatory | tenzro-finality/src/key.rs, tenzro-consensus/src/validator_key.rs |
| Consensus channels | X25519 and ML-KEM-768 into HKDF, handshake signed by composite session keys | tenzro-consensus/src/channel.rs |
| Account transactions and every other account-signed message | P-256 and ML-DSA-65 both required under PqPolicy::Required, which is the default policy | tenzro-crypto/src/composite.rs, tenzro-vm/src/account_keys.rs, tenzro-node/src/event_loop.rs |
| Inbound bridge deliveries | A committee member counts only with both legs; a member without an ML-DSA-65 key cannot be seated | tenzro-bridge/src/route/attestation.rs |
| Bridge equivocation evidence | Needs both legs of the member on both deliveries | tenzro-vm/src/native/bridge_committee.rs |
| Node RPC authentication (A2A, MCP, MoE) | Both hardware keys sign the TLS exporter of every connection | tenzro-iroh/src/pq_endpoint.rs |
| Peer transport key exchange | Only X25519MLKEM768 is offered and accepted between nodes | tenzro-iroh/src/identity_transport.rs |
| Key wraps, TEE key release | Envelope version 2, hybrid X25519 and ML-KEM-768 | tenzro-crypto/src/encryption.rs, tenzro-tee/src/key_release.rs |
| Identity | Registration is refused for hardware with no ML-DSA-65 key; DID documents list an ML-DSA-65 method first | tenzro-identity/src/document.rs, tenzro-identity/src/w3c.rs |
| Finality proofs | STARK is the default form | tenzro-zk/src/finality_proof.rs |
An account with no ML-DSA-65 key enrolled signs nothing until it enrols one. The first transaction of a new sender is its enrolment (tenzro pq-hybrid enroll). Where the hardware implements ML-DSA the key is created and used inside it. On every other machine, including a TPM-less machine that delegates to a TPM machine, the key is derived from the machine's hardware-held derivation root for each operation and wiped afterwards, so nothing is stored and without the hardware there is no key (tenzro-device-key/src/derive.rs).
What stays classical
- Hardware attestation roots. TPM endorsement certificates, Secure Enclave attestations and TEE quotes are signed by the vendor with RSA or ECDSA. Tenzro verifies them (
tenzro-tee/src/tpm_attest.rs) and cannot change the vendor's algorithm. They bind a machine to a key, and the key's use on Tenzro is hybrid. A party that forges a vendor chain can claim a machine is genuine hardware. It still cannot sign for that machine's ML-DSA key. - The P-256 leg of hardware keys. TPM 2.0 and the Secure Enclave sign P-256 natively. The composite pairing is what makes the pair safe: breaking P-256 yields half a signature.
- External chains' own signatures. Acceptance of a bridge delivery is hybrid. The external chain's finality (ECDSA, Ed25519, BLS12-381) is not Tenzro's to change. A classical ceiling on each mint bounds what a forged source chain can mint, and outbound records are verified by contracts on those chains with secp256k1.
- EVM-standard transactions. A transaction type defined by an external standard is verified by that standard and carries no ML-DSA-65 leg. Funds at an address controlled only by a secp256k1 key are protected by secp256k1. A holder who wants the guarantee uses a native account.
- Web certificates. RPC and MCP endpoints presented to browsers use classical certificates, and relay connections accept X25519 alone for a terminator that cannot do the hybrid, although the hybrid exchange is offered first.
- Release signing and published checksums. Signing uses a hardware key through the cosign toolchain.
Harvest now, decrypt later
Recorded traffic that stays readable to a future quantum computer is the exposure. Between Tenzro nodes it is closed: the peer provider offers only X25519MLKEM768, and a peer that offers X25519 alone has no group in common and fails the handshake (tenzro-iroh/src/identity_transport.rs). Key wraps and TEE key releases are hybrid. The exposure that remains is the relay and web-certificate path in item 5 above, and any traffic to and from systems that Tenzro does not control.
Algorithm agility
What can change through governance: the validator signature schemes a node may register under, as a bitmask (staking.validator_signature_schemes, genesis value 3, so ML-DSA-65 with P-256 and ML-DSA-87 with P-256 are both allowed); the date from which machine records must carry the ML-DSA leg (records.pq_leg_required_from_ms); and the date from which stored session records are hybrid (session.hybrid_records_from_ms). An identity can rotate its governing key to ML-DSA-65 (tenzro-identity/src/pq_rotation.rs).
What cannot: the set of known algorithms is part of the binary. Adding another signature scheme or a new KEM needs a protocol upgrade, which enacts only after validators holding a governed share of stake (67 percent by default) have quoted the new binary from their TPMs. See Governed parameters.
AI agents are bounded by their owner
An agent on Tenzro is a delegate, not a principal. Every agent has an owner: a human with a passkey or an autonomous machine with a TPM or Secure Enclave key (RootKind, tenzro-types/src/agent_terms.rs). The properties below are enforced by chain state and by validators, not by the agent's prompt.
- Terms.
SetAgentTermsrecords the owner's approval, and every validator re-verifies the root's signature over exactly those terms (tenzro-vm/src/native/agent_terms.rs). Terms carry capabilities, per-payment and daily spend caps, allowed counterparties, remote limits per external chain, a delegation scope and an expiry. - Every action is checked.
AgentActexecutes only when the signing node is assigned in the current terms andcheck_actionpasses: capability present, amount within the per-action and daily limits, terms unexpired, and the agent neither revoked nor quarantined. The running daily total is chain state, so every node sees the same spend. - Step-up. An action to a new counterparty or above a limit needs the owner's passkey again. An action marked as derived from untrusted input is held to a value limit that is zero when unset. A change to the terms moves only the limits the owner's pre-approved bounds name.
- The lethal trifecta is refused. Terms cannot grant private-data access, untrusted input and external egress together without an explicit exception the root approved (
check_trifecta). - No raw keys. The agent's signing key is a P-256 key held in the TPM of each serving machine and approved by the owner in the terms. It never leaves the chip (
tenzro-node/src/agent_delegation.rs). Third-party credentials are sealed to the serving node and attached by its egress guard to requests for the host the terms name (tenzro-node/src/egress_guard.rs). - Tool output is data. Content from outside labels the agent on the node for one hour, and its actions count as untrusted-input actions (
tenzro-node/src/agent_guardrails.rs). Nothing in consensus or the virtual machine consumes model text. - Owner levers. The owner can pause, quarantine or terminate an agent and can reclaim its unspent funds (
PauseAgent,QuarantineAgent,TerminateAgent,ReclaimAgentFundsintenzro-types/src/transaction.rs). A revocation or a validator quarantine makes every node refuse the agent. Per-epoch commitments over each node's agent audit trail let an evidence pack prove entries (tenzro-vm/src/native/agent_audit.rs). - Receipts. An inference result is paid on a receipt signed with a hybrid session key that the provider's hardware identity certified. A disputed result is settled by re-execution on independent providers and validator attestation (
tenzro-vm/src/native/inference_fault.rs). - Attested hardware and signed liveness. Attestation from TPMs, Intel TDX, AMD SEV-SNP, AWS Nitro and NVIDIA GPUs is verified against vendor chains (
tenzro-tee). Provider heartbeats are signed as the provider's machine identity and accepted only as the identity pinned by its announcement (tenzro-node/src/provider_heartbeat.rs).
See Agents, TEE and Hardware-rooted keys.
Supply chain
A release is a set of archives with a SHA256SUMS manifest, a cosign signature over the manifest and over each archive, a software bill of materials in SPDX form and an in-toto SLSA v1 provenance statement, also signed. Release signing uses a hardware-held key, and the release script refuses a key file and refuses a commit with no two-host reproducibility match (scripts/supply-chain/release.sh). Steps to check a download are in Verify your download.
Builds use one pinned Rust toolchain and a locked dependency set. cargo deny and cargo vet run on every push and weekly, a daily advisory gate covers every lockfile, and a check refuses new places in non-test code that create or store a private key in software (docs/SUPPLY-CHAIN.md).
Adversarial testing
Every decoder a peer can reach has a coverage-guided fuzz target, run nightly, including a differential check of two ML-DSA-65 verifiers. Kani proofs cover fee, supply, slashing, ledger, bridge-limit, governance and insurance arithmetic. Launch gates include seeded simulations of packet loss, partition and heal, parameter activation under partition, and removal of a slashed validator under partition. See Security for the programme as the repository describes it.
Pause and guardian levers
Protocol guardians pause the enactment of governance proposals and governance guardians veto a queued proposal. A pause needs two distinct seated guardians by default and lifts by itself after three days by default. Every guardian power stops things and originates nothing: no guardian action moves funds, sets a parameter or enacts a proposal (tenzro-vm/src/governance.rs). Individual features carry governed status levers, where 0 is enabled, 1 is paused and 2 is retired. Validators holding two thirds of stake can pause a bridge route on a finding (tenzro-vm/src/native/bridge_circuit.rs).
What this page does not claim
- No external security audit has been performed. The threat model scopes that engagement.
- No claim that the system is unbreakable.
- No compliance certification is claimed.
- A scan by an AI vulnerability tool that returns no findings is not evidence of absence and is not cited as assurance.
Not yet done
- Machine records.
records.pq_leg_required_from_msdefaults to never, and the launch genesis in the current source does not set it. Until it is set, usage records, meter bond consent, reserve attestations, sensor readings, batch roots, session keys, trust policy attestors and TEE identity evidence verify the ML-DSA-65 leg only when the key has one. - Other verifiers that check the ML-DSA-65 leg only when the key has one: sealed-model manifests, identity envelopes, session certificates, the operator binding in the trust policy, the admin audit log and the read-only signature check.
- Authentication on block sync, state sync, gossip, blobs and inference requests uses the node's Ed25519 key under the hybrid key exchange. A versioned protocol that carries the ML-DSA proof is not built yet.
- Duty handover proofs and TEE finality attestation bind a Groth16 seal. A STARK-verified duty needs a consensus rule and a change to the finality program.
- Wrong-handover evidence for bridge committees checks only the secp256k1 signature, so a party that forges secp256k1 signatures could frame a committee member until the handover format carries both legs.
- The node's own DID document carries a P-256 proof. The ML-DSA-65 method is listed in the document it covers, but the document has no ML-DSA-65 signature of its own.
- The release signing key's fingerprint is not yet published independently of the release page, signatures are not in a transparency log, and Windows archives are not Authenticode-signed unless the build host had a certificate.
- The participation roster at epoch close must be redesigned before mainnet: a node that lacks the closing epoch's validator set skips a write the others make, and its state root differs.
- The record age rule has no activation gate, so a later upgrade of a running network must take effect from a chain height.
- A restarted validator can stay outside the mesh for minutes under packet loss. A repeated sealed endpoint set shortens it, and a four-validator run that stopped finalizing for 246 seconds is unexplained because its logs were not kept.
- The signing health flag is not a reliable alarm for a missing ML-DSA leg. Operators should watch for the refusal line the node logs.
- Bridge routes without a light client rest on their committee, bounded by the caps, the breaker and the supply invariant.
- No independent audit of the cryptography or the protocol has been performed.
Report a vulnerability
Email eng@tenzro.com or use GitHub private vulnerability reporting on the affected repository in the tenzro organisation. Do not open a public issue for an unpatched vulnerability.