Skip to content

Chapter 39: Consensus and staking signatures

A consensus signature authenticates a validator’s vote on a block at the chain’s heartbeat: every slot, every epoch. Ethereum’s beacon chain runs BLS signatures on the BLS12-381 pairing-friendly curve (Boneh et al., 2022; Ethereum Foundation, 2024). The construction has one architectural property the post-quantum candidates do not match: pairing-based aggregation collapses NN partial signatures from NN validators to one 96-byte aggregate that any verifier can check against the aggregated public key. The post-quantum lattice and hash-based candidates produce NN independent signatures per attestation set. The per-set byte budget scales linearly in NN rather than sitting flat.

Covered in Ch 37 and Ch 38: the per-spend transaction surface (BIP-360 P2MR on Bitcoin, ERC-4337 on Ethereum) and the wallet-and-derivation surface (BIP-32 redesign under post-quantum primitives). The consensus surface from the Ch 36 surface taxonomy is this chapter’s target. The wallet-vendor migration timeline from Ch 38 is independent of the chain-level consensus migration here. The wallet migrates on its custody-vendor cadence and the chain protocol migrates on a hard-fork cadence.

A Strand consensus surface migrating from BLS-BLS12-381 to ML-DSA-65

Section titled “A Strand consensus surface migrating from BLS-BLS12-381 to ML-DSA-65”

The Strand consensus surface from the Ch 36 fixture deploys BLS-BLS12-381 per-slot at X=2X = 2 years (validator-key reuse window) and Y=1Y = 1 year (consensus-signature rollout window). Ethereum processes validator activations, exits, and committee reshuffling at epoch boundaries: 32 slots of 12 seconds gives a 6.4-minute epoch. Committees reshuffle every epoch, but validator registry membership changes only through the activation and exit queues, which Ethereum has metered in ETH rather than in validators since the Electra fork. The per-epoch activation and exit churn is min(MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT, get_balance_churn_limit(state)), floored at 128 ETH and capped at 256 ETH. Mainnet has sat at the 256 ETH cap since Electra activated, because roughly 42.4 million ETH of total stake (per the beaconcha.in-fed dashboard at validatorqueue.com, read 25 August 2026) puts the balance-derived term far above the ceiling (validatorqueue.com, 2026). At Strand’s scale of 100 thousand validators holding 32 ETH each, the 128 ETH floor binds instead, which is 4 validators per epoch. Strand parameterizes its churn limit at 8 validators per epoch, a chain-specific ceiling at twice that floor.

A migration of the consensus signature requires a hard fork because the BeaconBlock and Attestation data structures, the SimpleSerialize (SSZ) encoding those structures use, the verifier-set logic, and the slashing conditions all change.

The byte-budget framing throughout this chapter is a normalized per-validator-set comparison, not a literal Ethereum per-block estimate. Assume NN validators sign one consensus message and the protocol must represent all NN contributions in one payload. Ethereum’s actual beacon-chain attestations are split by slot, committee, subnet, and aggregation structure. The current Electra Attestation carries aggregation_bits, data, signature, and committee_bits, so the per-slot block payload at any moment is a fraction of the per-validator-set total. The normalized model isolates the cryptographic aggregation effect. The architectural property at issue (aggregation collapses NN to one signature vs post-quantum produces NN signatures) holds at any subset. For the non-aggregating candidates the normalized figure is also the deployment total, because splitting the set across committees leaves the same NN signatures in smaller parcels. For the aggregating candidates it is a single-payload floor rather than a total, and how many payloads a deployment pays is a protocol choice. At one million validators Ethereum’s committee formula caps at 64 committees per slot across 32 slots, 2,048 per epoch, and since Electra (7 May 2025) EIP-7549 keeps the committee index out of the signed AttestationData, so equal votes across committees aggregate into one signature and BLS does not pay one per committee (dapplion & Kalinin, 2023; Ethereum Foundation, 2024). A comparison imposed at one signature per committee puts threshold ML-DSA at roughly 2048×33092048 \times 3309 signature bytes plus the bitmap, near 6.9 MB per epoch, beside roughly 322 KB for BLS priced the same way: a factor of about 21 rather than the normalized 1.03, for that imposed shape and not for Ethereum’s current aggregation, whose real payloads depend on how many distinct attestation data are cast and included. Where a figure below is this floor rather than a deployment price, the surrounding text says so.

The motivating example: 100 validators sign an attestation under both BLS-BLS12-381 and ML-DSA-65, and the per-validator-set byte budget compares as follows. Under BLS, the 100 partial signatures aggregate to one 96-byte signature plus a 13-byte participation bitmap (one bit per validator, rounded up to the byte), totaling 109 bytes. Under ML-DSA-65 the 100 partial signatures ship independently at 3309 bytes each, totaling 330 900 bytes. The byte-budget factor against the BLS aggregate is 3036 to one. At the Ethereum mainnet round-figure anchor of one million active validators, the same factor sits at 26 452 to one. The consensus-signature migration imposes a per-validator-set byte tax that has no on-chain mitigation short of a SNARK-based aggregation wrapper (an open-research direction at chain-tip 2026).

The four-part operator playbook translates this byte-budget figure into four decisions: pick the candidate per the byte budget, decide between threshold and per-validator signing, plan the validator-key rotation cadence, and choreograph the hard-fork rollout.

BLS signatures, aggregation, and the discrete-log reduction

Section titled “BLS signatures, aggregation, and the discrete-log reduction”

BLS signatures on a pairing-friendly curve implement the Boneh-Lynn-Shacham construction (Boneh et al., 2004). The signing key is a scalar xZqx \in \mathbb{Z}_q; the public key is the point g1xG1g_1^x \in G_1 on the curve E1E_1 where g1g_1 is a fixed generator and qq is the curve order. The signature on a message mm is the point σ=H(m)xG2\sigma = H(m)^x \in G_2 where HH is a hash-to-curve function targeting G2G_2 (the order-qq subgroup of E2E_2). Verification computes the pairing e(g1,σ)e(g_1, \sigma) on one side and e(g1x,H(m))e(g_1^x, H(m)) on the other. The signature verifies if and only if the two pairings are equal.

The Ethereum consensus-specs fix the canonical signature form at 96 bytes (the compressed G2G_2 point) and the canonical public-key form at 48 bytes (the compressed G1G_1 point) (Boneh et al., 2022; Ethereum Foundation, 2024). These sizes record as named constants in the package. A future revision can update one number rather than recompute every figure.

The aggregation property is structural to the pairing. Given NN signatures σ1,,σN\sigma_1, \ldots, \sigma_N on the same message mm from public keys pk1,,pkN\mathsf{pk}_1, \ldots, \mathsf{pk}_N, the aggregate signature is the group product σagg=i=1Nσi\sigma_\text{agg} = \prod_{i=1}^{N} \sigma_i on G2G_2 (Boneh et al., 2003). Verification of the aggregate against the aggregated public key pkagg=i=1Npki\mathsf{pk}_\text{agg} = \prod_{i=1}^{N} \mathsf{pk}_i on G1G_1 requires one pairing on each side, regardless of NN (same-message fast aggregate verification). Multi-message aggregates require one pairing per distinct message. The same-message aggregate-verification path is safe only under a rogue-key mitigation: Ethereum’s validator registration includes a BLS proof-of-possession verified by is_valid_deposit_signature before the public key is added to the validator registry by add_validator_to_registry (Ethereum Foundation, 2024).

What aggregation buys is therefore narrower than it first looks. BLS makes the cryptographic signature component constant in NN: NN same-message signatures collapse to one 96-byte aggregate. The full on-chain payload is not constant, because the chain still carries one participation bit per validator. In the normalized all-validator-set model the total is 96+N/896 + \lceil N / 8 \rceil bytes, with the bitmap growing linearly in NN. That second term is the one the rest of this chapter keeps running into: it survives every candidate swap, and at one million validators it is three orders of magnitude larger than the signature it accompanies.

The security of BLS reduces to the computational co-Diffie-Hellman assumption on the pairing-friendly curve (Boneh et al., 2004). The discrete-log problem on E1E_1 (or E2E_2) is the underlying hard problem. An algorithm that solves discrete logs on either curve breaks BLS. Shor’s algorithm (Shor, 1994) solves discrete logs in polynomial time on a sufficiently large quantum computer, breaking BLS at every active validator’s public key once a CRQC arrives (Aggarwal et al., 2018; Babbush et al., 2026). The first-wave exposure for the consensus surface is the validator-set registry: every registered validator’s public key sits in BeaconState.validators[].pubkey from deposit processing onward (Ethereum Foundation, 2024), regardless of whether the validator has been activated or has signed any specific slot. A CRQC running Shor against any registered pki=g1xi\mathsf{pk}_i = g_1^{x_i} recovers the signing scalar xix_i in polynomial time.

The post-quantum candidates do not aggregate trivially. ML-DSA-65 (National Institute of Standards and Technology, 2024) is a Fiat-Shamir lattice signature with no group homomorphism on signatures. The verification equation checks a norm bound on the response vector and a hash equality against the commitment, neither of which is preserved under addition of signatures, and the signer’s rejection-sampling loop (Ch 12) leaves no algebraic structure for a combiner to exploit. SLH-DSA-128s (National Institute of Standards and Technology, 2024b) signs the message digest with a few-time FORS key and authenticates that key with a hypertree of XMSS signatures, each a WOTS+ signature plus a Merkle authentication path (Ch 17). A signature therefore carries signer-specific signature material as well as authentication nodes, and neither part combines across signers, so aggregation reduces no bytes. FN-DSA-512 (Perlner, 2025) is a NTRU-based Gaussian-sampling signature whose signature carries a short vector that does not concatenate. Its 666-byte signature and 897-byte public key are Falcon-512’s figures from the round-3 submission (Fouque et al., 2020). FIPS 206 has published no document to take them from.

Threshold constructions are the one direction that would restore something like aggregation, and they are not evenly developed across the candidate set. ML-DSA is an active research and standardization area for threshold variants in which TT cosigners produce one verifier-compatible ML-DSA-65 signature via a multi-round combine protocol off-chain. NIST’s 2026 Multi-Party Threshold Schemes workshop tracks proposals along these lines. Quorus is the model this chapter prices (Bienstock et al., 2025). Its distributed key generation jointly produces one fixed ML-DSA public key plus secret shares, and any authorized subset then produces one standard FIPS 204 signature under that joint key. An SLH-DSA threshold combiner remains an open research problem at chain-tip 2026, because the hypertree authentication path resists the standard threshold-protocol techniques. FALCON’s Gaussian-sampling step resisted them too until Garg, Escudero, Polychroniadou, Takahashi and Wang (June 2026, revised July) ran the sampler inside a multi-party computation and presented what they call the first threshold protocol whose signatures verify under the unmodified FALCON verification algorithm, implemented and benchmarked in an N-party and a three-party setting (Garg et al., 2026). Whether it aligns with the final FN-DSA standard and whether it suits a consensus deployment are questions the paper does not settle. A deployable threshold-PQ protocol on the consensus surface still ships a per-validator participation bitmap on-chain alongside the combined signature, analogous in format to the BLS bitmap, to record which validators earn attestation rewards. Unlike the BLS bitmap, it is not an input to verification: one standard verification against the joint key proves that an authorized threshold signed and identifies no cosigner. Rewards and slashing therefore need a separate accountability mechanism (attributable partial signatures in the combine transcript, or an accountable-threshold extension), and this chapter’s byte figures do not price it.

The four-part consensus migration playbook

Section titled “The four-part consensus migration playbook”

Pick the candidate per validator-set byte budget

Section titled “Pick the candidate per validator-set byte budget”

The Strand operator picks one primitive based on the per-validator-set byte budget against the five-candidate set. The first inline block walks the byte arithmetic. The function below is a pedagogical slice of consensus_staking.aggregation_overhead.evaluate over the five primitives at one million validators.

# Block 1: pedagogical slice of consensus_staking.aggregation_overhead
# (stdlib only).
N = 1_000_000 # Ethereum mainnet round-figure anchor.
BLS_AGG_BYTES = 96 # canonical G2 aggregate signature size.
CANDIDATES = {
"BLS-BLS12-381": {"sig_bytes": 96, "aggregates": True},
"ML-DSA-65": {"sig_bytes": 3309, "aggregates": False},
"SLH-DSA-128s": {"sig_bytes": 7856, "aggregates": False},
"FN-DSA-512": {"sig_bytes": 666, "aggregates": False},
"threshold-ML-DSA": {"sig_bytes": 3309, "aggregates": True},
}
def per_set_bytes(primitive, N):
spec = CANDIDATES[primitive]
bitmap_bytes = (N + 7) // 8 # one bit per validator, byte-aligned.
if primitive == "BLS-BLS12-381":
return BLS_AGG_BYTES + bitmap_bytes
if primitive == "threshold-ML-DSA":
# One combined ML-DSA-65 signature plus the per-validator
# participation bitmap the chain records for rewards. Unlike
# BLS's bitmap it is not an input to verification.
return spec["sig_bytes"] + bitmap_bytes
return N * spec["sig_bytes"]
baseline = per_set_bytes("BLS-BLS12-381", N)
print(f"{'primitive':<19} {'per-set bytes':>15} {'factor vs BLS':>15}")
for primitive in CANDIDATES:
total = per_set_bytes(primitive, N)
factor = total / baseline
print(f"{primitive:<19} {total:>15,} {factor:>15.2f}")
# ==> primitive per-set bytes factor vs BLS
# ==> BLS-BLS12-381 125,096 1.00
# ==> ML-DSA-65 3,309,000,000 26451.69
# ==> SLH-DSA-128s 7,856,000,000 62799.77
# ==> FN-DSA-512 666,000,000 5323.91
# ==> threshold-ML-DSA 128,309 1.03

Every Python block this chapter prints is also a standalone file in the companion repository, under chapter-code/ch39/, one file per block. Appendix C covers the clone and the environment they run on.

The BLS aggregate at one million validators carries 96 bytes of signature plus 125 000 bytes of participation bitmap, totaling 125 096 bytes. The participation bitmap dominates the BLS payload; the 96-byte aggregate signature is a rounding error against the bitmap at this scale. ML-DSA-65 produces 3.3 GB of signature per attestation set, a factor of 26 452 against the BLS baseline. SLH-DSA-128s produces 7.86 GB, a factor of 62 800. FN-DSA-512 produces 666 MB, a factor of 5324 (the smallest of the three plain post-quantum candidates because the NTRU-based signature is the most compact). Threshold ML-DSA carries 3 309 bytes of combined signature plus the same 125 000-byte participation bitmap that BLS ships, totaling 128 309 bytes per attestation set. The factor against the BLS aggregate is 1.03. The threshold-PQ payload is approximately the same size as the BLS aggregate at one million validators because the bitmap dominates both. The parity is a payload-size parity only: the BLS bitmap selects the public keys the aggregate verifies against, while the threshold bitmap rides beside a signature that verifies without it. It is also a normalized floor rather than a deployment price: a per-committee deployment pays one 3 309-byte combined signature per committee against 96 bytes for BLS. At Ethereum’s 2 048 committees per epoch the two totals (signatures plus the participation bitmap) sit near 6.9 MB and 322 KB, a factor of about 21.

Figure 39.1 below compares BLS aggregation against post-quantum non-aggregation under NN validators.

BLS aggregation versus post-quantum non-aggregation at one million validators Two columns side by side, each a vertical stack of labeled boxes joined by a downward arrow. The left column, titled BLS-BLS12-381 (aggregating), starts at N partial signatures of 96 bytes each (N times 96 equals 96,000,000 bytes at one million validators), passes through a solid green arrow labeled G2 group product, and reaches a 96-byte aggregate box followed by a 125,000-byte participation bitmap box, with an on-chain per-set total of 125,096 bytes. The right column, titled post-quantum candidates (non-aggregating), starts at the same N partial signatures, passes through a dashed red arrow labeled no group homomorphism, and reaches a dashed box listing ML-DSA-65 at 3.3 GB, SLH-DSA-128s at 7.86 GB and FN-DSA-512 at 666 MB, annotated N times sig_bytes per primitive, with an on-chain per-set total reading linear in N. The two columns are drawn at the same size: the contrast is carried by the box contents, the arrow style and the color, not by the shape of the pipeline. BLS-BLS12-381 (aggregating) post-quantum candidates (non-aggregating) N partial signatures (96 bytes each) N x 96 = 96000000 bytes G2 group product 96-byte aggregate + ceil(N / 8) bitmap 125000 bytes on-chain per-set total 125096 bytes N partial signatures N independent signatures no group homomorphism ML-DSA-65: 3.3 GB SLH-DSA-128s: 7.86 GB FN-DSA-512: 666 MB (N x sig_bytes per primitive) on-chain per-set total linear in N aggregating: signature constant in N; bitmap linear in N non-aggregating: per-set bytes scale linearly in N
Figure 39.1. BLS aggregation versus post-quantum non-aggregation at one million validators. Left: BLS collapses N partial signatures to one 96-byte aggregate (constant in N) plus a 125000-byte participation bitmap (linear in N at one bit per validator), totaling 125096 bytes. Right: each of the three plain post-quantum candidates produces N independent signatures whose per-set total scales linearly in N, ranging from 666 MB (FN-DSA-512) to 7.86 GB (SLH-DSA-128s). Aggregation is the operator's binding byte-budget constraint at the consensus surface.

The threshold-ML-DSA byte budget covers the on-chain payload (combined signature plus participation bitmap); it excludes whatever accountability evidence a real protocol would add to make the bitmap enforceable for rewards and slashing. The combine protocol that produces the single signature runs off-chain across a participating subset of validators. The combine round carries multi-round message-passing overhead that scales in the number of cosigners. The package records the off-chain combine overhead as a flag rather than as a byte count, since the off-chain bytes do not ship in the BeaconBlock.

The conservative-assumption preference moves SLH-DSA-128s to the top of any long-lived validator-set key. The hash-only security argument depends on the pseudorandomness of the underlying PRF and on preimage resistance and related properties of the underlying hash function, SHA-2 or SHAKE (National Institute of Standards and Technology, 2024b). Chapter 18 names the hypothesis set the current tight proof rests on. It does not depend on a structured-lattice assumption. The byte-budget preference moves FN-DSA-512 to the top among plain, non-aggregating post-quantum signatures if FIPS 206 lands as a final standard before the consensus-migration hard fork. The aggregation-density preference moves threshold-ML-DSA to the top if the threshold construction reaches a deployable status, which it has not at chain-tip 2026.

Decide between threshold and per-validator signing

Section titled “Decide between threshold and per-validator signing”

The threshold-versus-per-validator decision sits orthogonal to the candidate decision. The second inline block walks the threshold-scheme by candidate support matrix. The function below is a pedagogical slice of consensus_staking.threshold_compare.lookup over the five primitives and the three threshold-protocol roles.

# Block 2: pedagogical slice of consensus_staking.threshold_compare
# (stdlib only).
PRIMITIVES = (
"BLS-BLS12-381",
"ML-DSA-65",
"SLH-DSA-128s",
"FN-DSA-512",
"threshold-ML-DSA",
)
# Each cell records the deployment status at chain-tip 2026 across
# three threshold-protocol roles. ``--`` means the cell is not a
# candidate for the operator (incompatible primitive plus role).
MATRIX = {
"BLS-BLS12-381": ("production", "classical-only", "--"),
"ML-DSA-65": ("fips-final", "--", "research"),
"SLH-DSA-128s": ("fips-final", "--", "research-early"),
"FN-DSA-512": ("pre-draft", "--", "research-early"),
"threshold-ML-DSA": ("research", "--", "research"),
}
ROLES = ("no-threshold", "classical-FROST", "threshold-PQ")
print(f"{'primitive':<19} {'no-thr':<14} {'FROST':<16} threshold-PQ")
for primitive in PRIMITIVES:
a, b, c = MATRIX[primitive]
print(f"{primitive:<19} {a:<14} {b:<16} {c}")
# ==> primitive no-thr FROST threshold-PQ
# ==> BLS-BLS12-381 production classical-only --
# ==> ML-DSA-65 fips-final -- research
# ==> SLH-DSA-128s fips-final -- research-early
# ==> FN-DSA-512 pre-draft -- research-early
# ==> threshold-ML-DSA research -- research

Only one cell records a deployed primitive on a live chain: BLS at no-threshold. Of the four post-quantum rows in that column, the three plain signature candidates sit at a NIST-finalized standard or in the NIST standardization pipeline. The fourth, threshold-ML-DSA, reads research in that column too. An operator can deploy ML-DSA-65 or SLH-DSA-128s today, and FN-DSA-512 once FIPS 206 reaches a final standard. FIPS 206 is under development, with no Initial Public Draft yet released for public comment (Perlner, 2025). Every post-quantum threshold cell sits at a research stage. An operator who wants threshold post-quantum signatures has no chain-deployable option at chain-tip 2026.

The classical-FROST cell is included to be excluded. FROST, Flexible Round-Optimized Schnorr Threshold signatures (Komlo & Goldberg, 2020), is a threshold-Schnorr scheme over a discrete-log-based curve. It is Shor-vulnerable and not a post-quantum migration target. The matrix records FROST to make explicit the distinction between threshold-on-classical (FROST is implemented in some Bitcoin custody products, but Shor-vulnerable) and threshold-on-post-quantum (every variant remains a research direction).

The operator’s decision under a Mosca breach: deploy a no-threshold post-quantum candidate today, accept the per-validator-set byte tax, and revisit threshold-PQ once a candidate reaches a chain-deployable status. The validator-set rotation cadence against the Mosca window (next subsection) determines how aggressive the no-threshold deployment must be.

The validator-key rotation cadence is the operator’s response to the Mosca window for the consensus surface. The Strand consensus surface from Ch 36 sits at X=2X = 2 and Y=1Y = 1. The cadence functions below work with the signed margin X+YZX + Y - Z. Ch 36’s exposure window is its positive part, so a negative margin is years of clearance, not a breach. All three of Ch 36’s planning scenarios clear the Mosca window for this surface. The two 2035 policy dates (NCSC and NSM-10) both sit at Z=9Z = 9, giving a margin of 6-6 years (cleared by six) with a safe window of 8. The hypothetical mid-arrival scenario at Z=14Z = 14 gives 11-11. This chapter therefore adds a Z=2Z = 2 scenario of its own, an aggressive arrival forecast included for pedagogical purposes, because none of Ch 36’s three puts the consensus surface under any pressure at all. It breaches by 1 year with a safe window of 1 year, which is the only setting in which the fixed-interval cadence below has anything to decide.

The third inline block runs the recommendation function over four scenarios spanning the three cadence regimes.

# Block 3: pedagogical slice of consensus_staking.consensus_mosca
# (stdlib only).
def breach_years(X, Y, Z):
return X + Y - Z
def recommend(X, Y, Z):
breach = breach_years(X, Y, Z)
safe_window = max(0, Z - Y)
if breach <= 0:
return ("per-epoch", 0)
if safe_window >= 1:
return ("every-N-epochs", safe_window)
return ("hard-fork-trigger", 0)
# Strand consensus surface from Ch 36: X=2, Y=1.
X, Y = 2, 1
SCENARIOS = (
("aggressive Z=0", 0),
("narrow Z=2", 2),
("ncsc-2035 Z=9", 9),
("mid-2040 Z=14", 14),
)
for label, Z in SCENARIOS:
cadence, N = recommend(X, Y, Z)
breach = breach_years(X, Y, Z)
print(f"{label}: breach={breach:>4}y -> {cadence}, N={N}y")
# ==> aggressive Z=0: breach= 3y -> hard-fork-trigger, N=0y
# ==> narrow Z=2: breach= 1y -> every-N-epochs, N=1y
# ==> ncsc-2035 Z=9: breach= -6y -> per-epoch, N=0y
# ==> mid-2040 Z=14: breach= -11y -> per-epoch, N=0y

Under the aggressive scenario, Z=0Z = 0 leaves no safe window for a fixed-interval rotation. The recommendation falls back to hard-fork-trigger. The operator coordinates a rotation at a named hard-fork event (CRQC arrival rumor, jurisdictional mandate, post-quantum activation fork). Under the narrow scenario, Z=2Z = 2 admits a one-year rotation interval, which brings effective key reuse to 1 and closes the arithmetic, on three conditions the arithmetic does not state. The interval counts down to the absolute arrival date, so it shrinks as ZZ does rather than resetting at each rotation. The post-quantum consensus-signature rollout completes inside YY, before that date, and every key issued after it is a post-quantum key. And every classical key retires within one year of issue, so that none is still trusted when the CRQC arrives. Rotating one classical key for another does nothing against Shor once the machine exists, because the newly active public key is as recoverable as the old one. What a shorter interval buys is a shorter tail of legacy keys still valid past the cutover, and that is the whole of its benefit.

Under both of the distinct Z values Ch 36’s planning scenarios use, no breach exists, so no emergency validator signing-key rotation is required. The operator continues normal validator lifecycle management (activations and exits through the chain’s churn-limited queues) and prepares for the post-quantum registration window introduced by the migration fork. Under today’s Ethereum protocol, a forced signing-key rotation in place requires exit and re-entry rather than a single in-protocol key-change call. A future hard fork could add an explicit validator key-change mechanism, after which the cadence would be bounded by the Mosca window.

The every-N-validator-rotations cadence is the operator’s contingency for a protocol that does add explicit key-change. Ethereum’s churn limit caps activations and exits per epoch in ETH terms, at most 256 ETH per epoch under Electra, and it is a ceiling on turnover rather than a source of it: a validator may stay active indefinitely, committee reshuffling does not rotate its BLS key, and no half-life follows from the cap (Ethereum Foundation, 2024). A saturated exit queue would need at least 21.2×106/(256×225)21.2 \times 10^6 / (256 \times 225) epochs’ worth of days, about 368 days, to move half of the 42.4 million ETH staked at the 25 August 2026 snapshot, and that is a throughput floor on a stated assumption rather than an observed turnover rate. An operator who wants to align an explicit key-change cadence with validator-set attrition rather than calendar time picks every-N-validator-rotations. The package returns it as a runner-up rather than as the recommendation because the calendar-time framing is sharper for the Mosca arithmetic.

The hard-fork choreography for the consensus signature touches many more parts of the protocol than the signature field alone. The migration is not a field-size replacement; it is a packing, verification, gossip, and slashing-format redesign, and the table below is the change list an implementer works from.

The Attestation container changes in two different ways depending on the migration design, and it is the entry the rest of the list hangs off. In a threshold-PQ design the existing aggregate-attestation shape mostly survives (the Electra Attestation with its committee_bits, while the hypothetical design in D39 prices one per committee), and the single signature field changes from a 96-byte BLSSignature to a 3,309-byte combined ML-DSA-65 signature. In a no-threshold design the protocol must represent one signature per participating validator. The container becomes closer to a list of SingleAttestation-style records (with committee_index, attester_index, data, and per-validator signature), or a packed vector of validator-index plus signature pairs (Ethereum Foundation, 2024). The signature size class widens with the candidate: 666 bytes (FN-DSA-512), 3,309 bytes (ML-DSA-65 or threshold-ML-DSA), or 7,856 bytes (SLH-DSA-128s) per signature, multiplied by the validator count in the no-threshold case.

Protocol areaWhat the fork changesWhy it cannot be deferred
BeaconBlock and Attestation SSZsignature field size, and the container shape itself under no-thresholdthe wire format is consensus-critical
Validator registryadds a post-quantum public key or credential alongside the legacy BLS keythe verifier needs both during the transition
Domain separationa post-quantum domain tag on the signing rootBLS and post-quantum signatures over the same AttestationData must not be interchangeable
Verifier-set logicpairing verification replaced by the candidate’s verification routineper-slot verification is the feasibility bound
Gossip validationsubnets accept the new attestation type, reject mismatched primitive and domain pairspropagation rules gate what reaches a proposer
Aggregation and packingunder no-threshold, a list of per-validator signatures rather than one aggregateblock-body packing efficiency changes with it
Slashing evidencethe two-conflicting-attestation intersection rule survives per-validator signing; a joint-key threshold design needs attributable partials or an accountable-threshold extensionequivocation detection may need different logic
Fork choiceupdates if the candidate changes the per-slot verification budgetverification times differ by orders of magnitude across the set
Light client and sync committeeproof size grows in committee size without BLS aggregationboth rely on aggregation for compact proofs
Validator client and remote signerAPIs expose the post-quantum signing callthe operator cannot sign otherwise
Builder, relay, and the MEV-boost block-building middlewarecompatibility follows the attestation formatbuilders consume and republish attestations
Rollback semanticsstates whether registered post-quantum key material is retained or zeroeda second fork back to BLS leaves it exposed but no longer relied on

The cutover-and-rollback procedure runs as a coordinated activation block. Before the activation block, validators register a post-quantum public key alongside their existing BLS public key during a registration window. The protocol enforces the registration window’s end as a hard deadline. Validators that have not registered a post-quantum public key by the end of the window are treated as inactive at activation. At the activation block, the consensus rule changes from BLS verification to post-quantum verification. BLS attestations after the activation block are invalid. The rollback path is a second hard fork that returns to BLS verification if the post-quantum implementation produces a runtime failure across a critical mass of validator clients.

The work-stream owner per the Ch 30 framework is the consensus-client team for each major Ethereum consensus client (Lighthouse, Prysm, Teku, Nimbus, Lodestar). The validator-coordinator owner per the same framework is the validator-set operator (staking pool, solo validator, custody platform) running the candidate-key registration. The chain governance owner per Ch 41 is the All Core Devs forum coordinating the hard-fork activation block. The Ch 30 four-phase program runs the migration through discovery (validator-key registration window), first-wave (early-adopter clients deploy the post-quantum verifier), broad-rollout (mainnet activation block), and end-of-migration (BLS-key registration window closes for any new validators).

Cryptanalysis: three consensus-surface attack categories

Section titled “Cryptanalysis: three consensus-surface attack categories”

Three attack categories specific to the consensus surface beyond the generic Shor break covered in Ch 04 and the per-output-type framing covered in Ch 37.

The first is aggregator equivocation and invalid aggregate construction under BLS. In Ethereum’s BLS attestation flow, an aggregator is a validator selected by the protocol’s BLS selection-proof mechanism (the is_aggregator() check and the SignedAggregateAndProof broadcast with a selection proof) to collect committee signatures from a subnet and broadcast a single aggregate (Ethereum Foundation, 2024). There is no separate long-lived aggregator key. The aggregator role attaches to the validator’s ordinary BLS signing key for the slot it is selected. A malicious aggregator can omit contributions, delay propagation, or publish an invalid aggregate. What it cannot do under honest BLS is cryptographically claim participation from validators whose signatures it does not possess: the aggregate verification fails against the claimed participant set unless the aggregator actually holds the matching partial signatures.

Under a Shor-capable adversary, the threat changes qualitatively. Registered BLS public keys become sufficient targets for discrete-log recovery, so an adversary that recovers any subset of validator signing keys can forge signatures for those validators and assemble aggregates whose participation bitmap matches the forged subset. The mitigation is the primitive swap (BLS to a post-quantum candidate) rather than rotating a notional aggregator key. The post-quantum candidates eliminate the aggregator role entirely at the no-threshold candidates because every validator’s signature ships independently; threshold-ML-DSA reintroduces a combine-round coordinator analogous to the aggregator role, with the partial-leakage exposure documented in the third attack category below. The coordinator’s bitmap is also weaker evidence than the BLS aggregator’s: the combined signature verifies against the fixed joint key whatever the bitmap claims. A threshold-sized coalition can therefore sign an attribution the named validators never made, and per-validator rewards and slashing need accountability evidence beyond the signature itself.

The second is registered-validator Shor against on-chain pubkeys. Every registered validator’s public key sits in BeaconState.validators[].pubkey from deposit processing onward (Ethereum Foundation, 2024), regardless of whether the validator has been activated or has signed any specific slot. The verifier needs every registered validator’s pk\mathsf{pk} to compute aggregated pkagg\mathsf{pk}_\text{agg} during attestation verification. A CRQC running Shor against any registered pki=g1xi\mathsf{pk}_i = g_1^{x_i} recovers the signing scalar xix_i in polynomial time (Shor, 1994). The exposure horizon is from-deposit-to-rotation: every validator whose public key has been registered on chain since chain-tip 2026 has its key recoverable once the CRQC arrives. The mitigation is the primitive swap (BLS to a post-quantum candidate). The rotation cadence and the protocol’s key-change mechanism determine how stale the legacy keys can be without breaching the Mosca window.

The third is threshold-signature attack surfaces absent from the single-signer setting. A threshold-PQ scheme that allows TT cosigners out of NN to produce one verifier-compatible signature introduces attack surfaces a single-signer scheme does not face. These include nonce-generation failures across the cosigner set, abort-round leakage from aborted protocol executions, coordinator trust assumptions, transcript leakage from the multi-round combine protocol, side channels in partial-signature generation, key-share compromise, and threshold-specific cryptanalysis. These are protocol-specific risk classes rather than a generic break of every threshold-PQ proposal. Individual schemes will have different exposure profiles depending on their construction.

At chain-tip 2026, threshold ML-DSA is an active research and standardization area (NIST’s 2026 Multi-Party Threshold Schemes workshop tracks proposals along these lines (Bienstock et al., 2025)) rather than a NIST-final, multi-client, consensus-deployed primitive. The conservative operator defers threshold-PQ deployment until a candidate has public specifications, security proofs, interoperable implementations, and several years of cryptanalysis. The conservative-assumption preference for the consensus surface therefore moves to a no-threshold post-quantum candidate during the cutover and revisits threshold-PQ once a candidate reaches a chain-deployable status.

The five candidates trade off on five axes. The security-category column distinguishes assumption class and NIST category so the byte and timing numbers are not read as an equal-security comparison.

CandidateCategory / assumptionAggregationPer-set byte cost (1M validators)Signing time classDeployment status (chain-tip 2026)
BLS-BLS12-381classical pairing (Shor-vulnerable)yes (G2 product)125 KBfastdeployed on Ethereum mainnet
ML-DSA-65lattice, NIST category 3none3.3 GBfastFIPS 204 final
SLH-DSA-128shash-based, NIST category 1none7.86 GBslowFIPS 205 final
FN-DSA-512NTRU lattice, NIST category 1none666 MBmoderateFIPS 206 under development
threshold-ML-DSAlattice threshold, researchT-of-N combine128 KB on-chainmoderate (combine round)research

The two aggregation rows are normalized single-payload figures. Priced at one signature per committee, BLS’s 125 KB grows to roughly 322 KB and threshold-ML-DSA’s 128 KB to roughly 6.9 MB per epoch. Ethereum’s own BLS payload since Electra aggregates equal votes across committees and is smaller than that imposed figure.

The signing-time tiers in the table are qualitative. The fast cells correspond to microsecond-scale signing on a server-class CPU (BLS and ML-DSA-65). The moderate cells correspond to low-millisecond signing (FN-DSA-512 carries a Gaussian-sampling step; threshold-ML-DSA adds the combine round). The slow cells correspond to signing in the range of hundreds of milliseconds or longer (SLH-DSA-128s pays for the hypertree authentication path). A primary-source benchmark is the operator’s responsibility before locking the candidate.

An operator who weighs the prospect of a structural attack on the lattice problems takes the conservative-assumption preference: deploy SLH-DSA-128s for the long-lived validator-set key, accept the longer signing time per attestation, and pay the 7.86 GB per-validator-set byte budget. The byte-budget preference favors FN-DSA-512 once FIPS 206 reaches a final standard. FN-DSA-512 produces the smallest plain post-quantum signature at 666 bytes. The aggregation-density preference favors threshold-ML-DSA once the construction reaches a chain-deployable status.

The deployment-status axis is the binding constraint for any candidate selected at chain-tip 2026. Threshold-ML-DSA and threshold-SLH-DSA sit at the research stage with no NIST standard and no multi-year cryptanalysis history. An operator who deploys either accepts the protocol-specific risk classes documented in the threshold partial-leakage section above. FN-DSA-512 sits at FIPS 206 under development, with no Initial Public Draft yet released for public comment (Perlner, 2025). An operator who deploys it before FIPS 206 reaches a final standard accepts that the parameter set may change at finalization. ML-DSA-65 and SLH-DSA-128s are both NIST-finalized. An operator who deploys either has the strongest standards footing among the post-quantum options.

Figure 39.2 below is the five-by-four candidate-axis matrix. Rows are the five candidates; columns are aggregation property, per-set byte cost class, signing-time class, and deployment status. Cells encode the decision with a label plus a redundant non-color marker, mirroring the Ch 38 Figure 38.2 convention.

Candidate-axis matrix for the consensus signature A five by four matrix, twenty cells, each carrying a label plus a redundant non-color corner marker. Rows: BLS-BLS12-381, ML-DSA-65, SLH-DSA-128s, FN-DSA-512, threshold-ML-DSA. Columns: aggregation, per-set byte cost class, signing-time class, deployment status at chain-tip 2026. The legend marks four marker categories in left-to-right order: circle for the deployed-legacy baseline, square for favorable, triangle for moderate, X for unfavorable. The BLS row is square on aggregation, byte cost and signing time, and circle on deployment, which reads deployed with a Shor-vulnerable annotation. The ML-DSA-65 row is X on aggregation, triangle on its 3.3 GB byte cost, and square on both fast signing and FIPS final. The SLH-DSA-128s row is X on aggregation, on its 7.86 GB byte cost and on slow signing, and square on FIPS final. The FN-DSA-512 row is X on aggregation and triangle on all three of its 666 MB byte cost, moderate signing and FIPS 206 under development. The threshold-ML-DSA row is square on its T-of-N combine and its 128 KB normalized-floor byte cost, triangle on moderate signing, and X on research. Candidate-axis matrix for the consensus signature aggregation byte cost signing time deployment BLS-BLS12-381 yes 96B sig + linear bitmap fast deployed (Shor-vulnerable) ML-DSA-65 none 3.3 GB fast FIPS final SLH-DSA-128s none 7.86 GB slow FIPS final FN-DSA-512 none 666 MB moderate FIPS 206 (under dev) threshold-ML-DSA T-of-N combine 128 KB floor moderate research deployed / legacy favorable moderate unfavorable
Figure 39.2. Candidate-axis matrix for the consensus signature. BLS is the deployed-legacy baseline with a constant 96-byte aggregate signature plus a linear participation bitmap, fast signing, and Shor-vulnerable status. ML-DSA-65 carries 3.3 GB byte cost and fast signing at FIPS 204 final. FN-DSA-512 carries 666 MB byte cost and moderate signing while FIPS 206 is under development. SLH-DSA-128s pays the largest byte cost (7.86 GB) and runs at slow signing. Threshold-ML-DSA carries the 128 KB normalized on-chain floor (one signature plus the participation bitmap, though a per-committee deployment pays one combined signature per committee) via the combine round but sits at the research stage at chain-tip 2026.

The per-validator-set byte tax against the BLS aggregate is the constraint the consensus migration is planned around. BLS at one million validators carries 125 096 bytes of aggregate-plus-bitmap; ML-DSA-65 at the same validator count carries 3.3 billion bytes of independent signatures, a factor of 26 452. No SNARK-based aggregation wrapper is chain-deployed at chain-tip 2026. The per-validator-set byte tax is the binding constraint until either a SNARK aggregator reaches a deployable stage or threshold-PQ does.

  1. Normalized per-validator-set byte budget at one million validators. Compute the normalized per-attestation-set byte budget under each of the five candidates (BLS-BLS12-381, ML-DSA-65, SLH-DSA-128s, FN-DSA-512, threshold-ML-DSA) at N=1000000N = 1\,000\,000 active validators, where the protocol must represent all NN contributions in one payload. Report the multiplicative factor against the BLS aggregate baseline. State which candidate carries the smallest per-set byte budget and which carries the largest. Note that this is not a literal Ethereum per-block estimate: Ethereum splits the validator set across slots, committees, and subnets.

  2. BeaconBlock SSZ change for post-quantum attestations. Ethereum’s Attestation SSZ container currently carries aggregation_bits, data, signature (a 96-byte BLSSignature), and committee_bits. Sketch two SSZ designs for switching the consensus signature off BLS:

    1. A naive per-validator ML-DSA-65 attestation design: one Attestation per signing validator, no committee-level aggregate. Identify which fields collapse, what new fields appear (validator index, signature), and what the new per-attestation byte count is.
    2. A hypothetical threshold-ML-DSA design assuming a deployable combine protocol: one combined ML-DSA-65 signature per committee plus a participation bitmap that keeps the aggregation_bits format. Identify which fields change size, which retain their BLS-era shape, and which lose their role in verification. For each design, state the new verification rule the verifier-set must implement.
  3. Open-ended: surface taxonomy on a proof-of-authority chain. Apply the Ch 36 surface taxonomy to a proof-of-authority chain with a fixed validator set of 21 validators. State which surfaces are present (transaction, consensus, wallet, on-chain-verifier, governance) and which differ from the Ethereum proof-of-stake setting. For the consensus surface, pick a candidate from the chapter’s matrix and justify the decision against the chain’s constraints (small fixed validator set, no churn, governance via off-chain coordination).

  4. Strand validator-key rotation cadence under Z=9Z = 9. Strand has 100 thousand active validators. Each validator-key rotation costs the operator 5 minutes of operational work (stop signing under the old key, register the new key, resume signing). Assume Strand parameterizes its churn limit at 8 validators per epoch (a Strand-specific ceiling at twice the 4 validators per epoch that Ethereum’s 128 ETH Electra churn floor permits at this validator count and balance). Justify a validator-key rotation cadence under Z=9Z = 9. Compute the wall-clock time to rotate the full validator set once at the chain’s churn limit. Compare against the chapter’s framing that no emergency signing-key rotation is required under Z=9Z = 9.

  5. Open-ended: map to the Ch 30 four-phase program. Map the consensus migration to the Ch 30 four-phase program (discovery, first-wave, broad-rollout, end-of-migration). For each phase, name the validator-coordinator work-stream owner per the same Ch 30 framework (consensus-client team, validator-set operator, chain governance forum, slashing-monitor service). Justify each mapping in one sentence.

Solutions to Exercises 1, 2, and 4 are in Appendix D, Chapter 39; Exercises 3 and 5 are open-ended and have editorial-note treatments rather than worked answers. A separate track, for rebuilding rather than reading: the package exercises/ch39-consensus-staking has every function the chapter teaches replaced by a stub. Run PQC_IMPL=exercises pytest tests/ch39 to grade your version against the suite that proves the reference one.

Aggarwal, D., Brennen, G. K., Lee, T., Santha, M., & Tomamichel, M. (2018). Quantum Attacks on Bitcoin, and How to Protect Against Them. Ledger, 3, 68–90. https://doi.org/10.5195/ledger.2018.127
Babbush, R., Zalcman, A., Gidney, C., Broughton, M., Khattar, T., Neven, H., Bergamaschi, T., Drake, J., & Boneh, D. (2026). Securing Elliptic Curve Cryptocurrencies against Quantum Vulnerabilities: Resource Estimates and Mitigations. PRX Quantum, 7(3), 031001. https://doi.org/10.1103/j3xf-bw18
Bienstock, A., de Castro, L., Escudero, D., Polychroniadou, A., & Takahashi, A. (2025). Quorus: Efficient, Scalable Threshold ML-DSA Signatures from MPC. IACR Cryptology ePrint Archive, Paper 2025/1163. https://eprint.iacr.org/2025/1163
Boneh, D., Gentry, C., Lynn, B., & Shacham, H. (2003). Aggregate and Verifiably Encrypted Signatures from Bilinear Maps. Advances in Cryptology - EUROCRYPT 2003, 2656, 416–432. https://doi.org/10.1007/3-540-39200-9_26
Boneh, D., Gorbunov, S., Wahby, R. S., Wee, H., Wood, C. A., & Zhang, Z. (2022). BLS Signatures. IRTF CFRG Internet-Draft draft-irtf-cfrg-bls-signature. https://datatracker.ietf.org/doc/draft-irtf-cfrg-bls-signature/
Boneh, D., Lynn, B., & Shacham, H. (2004). Short Signatures from the Weil Pairing. Journal of Cryptology, 17(4), 297–319. https://doi.org/10.1007/s00145-004-0314-9
dapplion, & Kalinin, M. (2023). EIP-7549: Move committee index outside Attestation. Ethereum Improvement Proposals. https://eips.ethereum.org/EIPS/eip-7549
Ethereum Foundation. (2024). Ethereum Consensus Specifications. GitHub repository at ethereum/consensus-specs. https://github.com/ethereum/consensus-specs
Fouque, P.-A., Hoffstein, J., Kirchner, P., Lyubashevsky, V., Pornin, T., Prest, T., Ricosset, T., Seiler, G., Whyte, W., & Zhang, Z. (2020). FALCON: Fast-Fourier Lattice-based Compact Signatures over NTRU. Specification v1.2, NIST post-quantum cryptography standardization round-3 submission. https://falcon-sign.info/falcon.pdf
Garg, R., Escudero, D., Polychroniadou, A., Takahashi, A., & Wang, X. (2026). Thresholdizing Standardized FALCON Signatures. IACR ePrint 2026/1300. https://eprint.iacr.org/2026/1300
Komlo, C., & Goldberg, I. (2020). FROST: Flexible Round-Optimized Schnorr Threshold Signatures. Selected Areas in Cryptography - SAC 2020, 12804, 34–65. https://doi.org/10.1007/978-3-030-81652-0_2
National Institute of Standards and Technology. (2024a). FIPS 204: Module-Lattice-Based Digital Signature Standard. Federal Information Processing Standards Publication. https://doi.org/10.6028/NIST.FIPS.204
National Institute of Standards and Technology. (2024b). FIPS 205: Stateless Hash-Based Digital Signature Standard. Federal Information Processing Standards Publication. https://doi.org/10.6028/NIST.FIPS.205
Perlner, R. (2025). FIPS 206 Status Update: Fast-Fourier Lattice-Based Digital Signature Standard (FN-DSA, Falcon). NIST Computer Security Resource Center status presentation. https://csrc.nist.gov/presentations/2025/fips-206-fn-dsa-falcon
Shor, P. W. (1994). Algorithms for quantum computation: discrete logarithms and factoring. Proceedings of the 35th Annual Symposium on Foundations of Computer Science (FOCS), 124–134. https://doi.org/10.1109/SFCS.1994.365700
validatorqueue.com. (2026). Ethereum validator queue dashboard. Analytics page, data provided by beaconcha.in. https://www.validatorqueue.com/

Last updated: