Security boundaries
This page explains what the ML-DSA signature authorizes inside the PQ smart-account stack, and what it explicitly does not. The product-level threat model lives in Threat model.
What the ML-DSA signature protects
The signature is over userOpHash, the EIP-4337 hash of a UserOperation. A valid signature proves the holder of the ML-DSA private key authorized exactly this UserOp:
- This
sender(smart account address). - This
nonce(which encodes the PQ validator and prevents replay). - This
callData(the calldata to execute — transfer, swap, governance vote, etc.). - This
factory/factoryData(if the account is being deployed). - This
paymasterAndData,callGasLimit,verificationGasLimit, and related fields. - On this
chainIdand via thisEntryPoint.
An attacker cannot replay the UserOp to a different account, change the calldata, point it at a different EntryPoint, or replay it on a different chain.
What the signature does not protect
Mempool inclusion is not authorization
A signed UserOp is permission to be executed if a bundler accepts it. It does not guarantee that a bundler will accept it, that it will be included in a block, or that it will succeed. The ERC-4337 bundler can drop, censor, or front-run UserOps within the rules of its mempool.
Target-contract behavior is opaque to the validator
The validator approves the calldata that the EntryPoint will execute. The smart account then executes that calldata against whatever target contract was specified. If the target contract has a bug, a centralized admin key, a malicious upgrade path, or unexpected reentrancy, the PQ signature does not help. The signature authorizes the call; it does not bless the callee.
Paymaster behavior is out of scope
If a paymaster is used, the paymaster's own logic — solvency, signature validation, abuse prevention — is independent of the PQ validator.
ECDSA root validator still exists
The standard Kernel v3 setup retains an ECDSA root validator for setup, recovery, and selectors not yet moved under PQ. If that root key is compromised, an attacker can uninstall the PQ module — a privileged operation, but one gated by the root key, not the PQ key. Accounts wanting strict PQ-only security must constrain or remove the root validator after setup. Kernel supports this, but it is a sharp-edge operation.
Off-chain key custody is its own concern
The smart-account stack assumes you have an ML-DSA private key and can sign with it. How that key is stored, encrypted, and protected is outside this stack.
What the verifier promises
The Stylus MLDSAVerifier is a stateless function. Given (public_key, message_hash, signature):
- Returns
trueif and only if the signature is a valid ML-DSA-65 signature ofmessage_hashunderpublic_keyper FIPS 204. - Returns
falseotherwise, including on malformed signatures. - Reverts before reaching Stylus if the public key has the wrong length.
- Has no storage, no admin, no upgrade, no callbacks — it is a pure function.
Auditable failure modes are limited to: (a) a bug in the underlying ml-dsa crate, (b) a Stylus SDK issue affecting argument decoding or return encoding, and (c) a deployment error pointing the validator module at the wrong verifier address.
Related
- Threat model — product-level boundaries
- Production limitations — outstanding risks before mainnet
- Stylus maturity assessment — Stylus SDK known issues