Skip to content

Pricing the verifiers

A precompile’s gas price is a claim about how much real work it does relative to everything else in the EVM. Price it too low and it becomes a denial-of-service vector; price it too high and nobody can afford the feature the chain exists to provide.

Frost prices its ML-DSA verifiers at ecrecover throughput parity.

ecrecover is the natural yardstick: it is the EVM’s existing signature verification, it has been priced at 3,000 gas since Frontier, and the network has years of evidence that this price is survivable.

So the rule is simply that a verifier should cost the same per unit of real work as ecrecover does:

gas = t_verify × (EcrecoverGas / t_ecrecover)

Measure both operations on the same machine, take the ratio, round up for margin.

Measured on validator-class hardware — AMD EPYC Milan, with ecrecover using the optimised C library implementation:

Operation Time Implied gas
ecrecover (reference) 33.7 µs 3,000 → 89 Mgas/s
ML-DSA-44 verify 116.3 µs 10,400
ML-DSA-65 verify 177.7 µs 15,900

Rounded up for margin against slower verification paths:

Precompile Address Price
VERIFY_MLDSA44 0x15 10,500
VERIFY_MLDSA65 0x14 16,000

The ratio these prices depend on is not constant across architectures, which makes where you measure a substantive decision rather than an incidental one.

ecrecover has a heavily optimised C implementation that ports to x86 at full speed. The ML-DSA verifier is written in Go and does not. So moving from ARM to x86 makes ecrecover relatively faster while ML-DSA gains much less — and since the price is a ratio, prices derived on ARM come out roughly 20% too low on the x86 machines validators actually run.

Hence the rule: price on the hardware the validators run, not on the hardware the developer has. A price derived on a laptop understates the cost on the machine that has to sustain it under load, and understating it is the direction that hurts.

Both verifiers charge a flat price regardless of input. This is not an approximation — the inputs are fixed length. An ML-DSA-65 call is exactly 5,293 bytes and an ML-DSA-44 call exactly 3,764, and anything else is rejected outright rather than padded. There is no variable-size work to price.

Gas is charged in full whether or not the signature verifies, so a caller cannot probe cheaply with malformed input.

Worth distinguishing, because the two look similar and are governed differently.

The verifier prices and the frame-transaction validity caps are enforced on the block-processing path, so they are consensus rules and follow the fresh-chain discipline above.

The admission budgets — such as the 100,000 gas ceiling on VERIFY-frame simulation at the submission gate — are not. They bound work a node is willing to do before accepting something into a mempool. Two nodes running different values disagree about what to accept, never about what a block means, so these can be tuned in place.

At 16,000 gas, an ML-DSA-65 verification costs a little over five ecrecover calls. That is the number that makes post-quantum accounts practical: a Solidity implementation of the same verification would cost millions of gas, which is not a fee, it is a prohibition.

It is also, deliberately, not cheap. The price reflects genuine work, so an attacker filling blocks with signature verifications pays the same rate per unit of validator CPU as they would filling them with ecrecover calls — which is exactly the property that makes the existing price defensible.

Note where the cost actually falls: calldata gas on a 3,309-byte witness exceeds the verification price. Reducing signature size buys more than reducing verification cost.