Most signature schemes are designed so that nothing bad ever happens. Jevil is designed so that something catastrophic happens exactly once, at a moment you choose in advance.
It is a few-time signature scheme. You pick a budget (say, a thousand signatures) at key generation. The first thousand signatures are ordinary, unforgeable, post-quantum signatures. The thousand-and-first publishes your secret key to the entire world. Not “weakens.” Not “degrades.” Publishes. Anyone watching can sit down with a piece of paper and reconstruct it.
That is the whole idea, and the rest of this post is about why anyone would want such a thing, and how the machinery underneath actually works. The best way to start is to break it yourself. Go ahead: sign a few messages, then push it over the edge.
Enable JavaScript to explore this figure.
If you cranked the budget up and signed past it, you saw the fog of possibilities collapse onto a single curve. Hold that picture; everything below is an unpacking of it.
Why would you want a cliff?
A few-time signature caps how many signatures you can safely issue. That sounds like a limitation, and it is, but plenty of things in the real world are intrinsically finite and would rather be finite: a firmware vendor that will sign a bounded number of releases and then go quiet for a decade; an operator binding themselves to a fixed per-tenure attestation budget; an audit-budgeted credential that issues its allowance and then has no further business existing. In all of these, “you may sign at most $n^\star$ times” is not a nuisance. It is the actual security goal.
The obvious way to enforce a count is with state: a counter, a synced database, a hardware register that ticks up and refuses to go past the budget. This is how stateful hash-based schemes like XMSS and LMS work, and it is notoriously fragile in deployment. Restore a backup, clone a VM, fork a container, and the counter silently rolls back, so the signer happily re-uses key material it already spent and security quietly collapses with no alarm. That fragility is exactly what motivated the move to stateless schemes in the first place.
Stateless schemes route around the counter by making the cap a property of the cryptographic object itself. The dominant family, HORS and its descendants (which sit at the leaves of SPHINCS⁺ and the standardized SLH-DSA), does this, but its failure is soft. After $n$ signatures, a forger’s success probability rises gradually, roughly as $\left(\tfrac{nK}{T}\right)^{K}$. There is no single moment where anything breaks; “how many signatures is safe” is a slider on a continuum, and you pick a point on the slope and hope.
Jevil’s degradation is the opposite of soft. It is a wall.
Enable JavaScript to explore this figure.
To the best of my knowledge, Jevil is the first few-time signature scheme that is simultaneously post-quantum, transparent (no trusted setup), and cliff-shaped: its key-recovery threshold is a single sharp edge rather than a probabilistic ramp. Cliff-like behavior has shown up before, but always in a corner that fails one of those three tests. Nonce reuse in Schnorr or ECDSA recovers the key from two signatures, but it is classical and an accident, not a designed feature. Chaum-style offline e-cash extracts a double-spender’s identity, but it is classical and interactive. Polynomial-witness constructions over KZG or IPA commitments have exactly this geometry, but KZG needs a trusted setup and both are broken by Shor. Jevil’s one technical move is to bring that geometry into the post-quantum, transparent world. We will get to how.
The secret is a polynomial
Here is the entire trick, with no cryptography in it yet, just a fact about polynomials you already half-remember.
Two points determine a line. Three points determine a parabola. In general, $D+1$ distinct points determine a unique polynomial of degree $D$, and fewer than that determine nothing: through any $D$ points there run infinitely many degree-$D$ curves. This is the seesaw the whole scheme balances on. Give an observer $D$ evaluations of a secret degree-$D$ polynomial and they have learned, in a precise sense, nothing about which polynomial it is. Give them one more, the $(D{+}1)$-th, and it is pinned forever; they can recover every coefficient in $O(D^2)$ arithmetic by Lagrange interpolation.
That is the snap you saw in the sandbox. Below the threshold, a fog of curves all fit the revealed points equally well. At the threshold, the fog has exactly one member.
So here is the plan. The secret key is the coefficient vector of a degree-$D$ polynomial $f$. Signing a message will reveal a few evaluations of $f$. If we arrange for each signature to reveal exactly enough, and for the budget $n^\star$ to be the number of signatures that just barely keeps the total below $D+1$, then signatures $1$ through $n^\star$ leave $f$ undetermined, and signature $n^\star{+}1$ tips it over. The cliff is not bolted on. It is the same Lagrange fact that powers Shamir secret sharing and threshold signatures, simply inverted: where those schemes hand out evaluations on purpose so that enough parties can reconstruct, Jevil accumulates them as the penalty for over-use.
There is one detail worth flagging now because it reappears everywhere: the public key carries a single free evaluation of $f$, a point $(z, w=f(z))$ I will call the out-of-domain point. Think of it as one of the $D+1$ pins handed out for free at key generation. It is the purple point in the sandbox, and it earns its keep later.
A polynomial becomes a signature
If the secret is a polynomial, signing a message has to mean revealing some evaluations of it, and the choice of where to evaluate has to come from the message, deterministically, so that the verifier can re-derive the same points.
That is exactly what happens. The message is hashed to produce $K$ positions (Jevil fixes $K=16$), and the signature reveals $f$ at those $K$ points. “Hashed” means the positions are unpredictable and effectively random, but not fresh on every call: the same message always yields the same positions, so re-signing a message you already signed is free and tells the world nothing new. Type the same string into the figure below twice and watch the second one change nothing.
Enable JavaScript to explore this figure.
Now, “reveal $f$ at a point” needs to be something a verifier can check against the public key without holding $f$, and ideally something expressible in the narrow language that our commitment scheme will speak. The bridge is almost embarrassingly simple. Write $f(X)=\sum_{k} c_k X^k$ with coefficient vector $c$. Then evaluating $f$ at a point $x$ is just a dot product of $c$ against the powers of $x$:
$$ f(x) \;=\; \langle\, c,\; (1, x, x^2, \dots, x^{M-1}) \,\rangle. $$This is the lift: it turns “evaluate the secret polynomial” into “take a linear form of the secret vector.” Drag $x$ below and watch the powers vector fill in and the dot product compute to $f(x)$.
Enable JavaScript to explore this figure.
Two things fall out of this little identity, and both matter later. First, whatever vector the signer is committed to lives in $M$ coordinates, so $\langle c, (1,x,\dots)\rangle$ is always a polynomial of degree at most $D=M-1$. There is no room to cheat the degree. Second, the claim “this is $f(x)$” is purely a statement about $c$, which is what lets us hide everything except the evaluations we meant to reveal.
The catch, and the fix
If signing just meant publishing the pairs $(x_t, f(x_t))$ in the clear, we would be done, and also broken in three different ways.
- A dishonest signer could lie, publishing a $y_t$ that is not actually $f(x_t)$, to dodge the consequences of an honest reveal.
- A dishonest signer could cheat the degree: secretly use a higher-degree polynomial so that the “$D+1$ points pin it” accounting never catches up, and keep signing forever past the budget.
- And even an honest reveal might leak more than the $K$ points if the verification machinery exposed side information about $f$.
The fix for all three is a polynomial commitment. At key generation the signer commits to the coefficient vector $c$, producing a short public digest, a 32-byte root. From then on, the signer can open evaluations: prove “the polynomial behind root takes value $y$ at point $x$” without revealing anything else about it. Jevil uses zk-WHIR, a hash-based commitment I will treat here as a sealed box with three buttons.
Enable JavaScript to explore this figure.
The box gives us exactly the two guarantees we need. It is hiding: an opening reveals the asked-for evaluation and nothing more. Formally, it is zero-knowledge, so the proof could have been simulated from the evaluation alone. And it is binding to the degree: the thing inside is a vector of $M$ coordinates, so every value it ever opens is consistent with one fixed polynomial of degree at most $D$. The signer cannot lie (an inconsistent opening fails to verify) and cannot smuggle in a higher-degree secret. The “lie” attack and the “leak” attack both die here.
The “cheat the degree” attack is worth lingering on, because it is what makes the cliff unavoidable rather than merely default. You might worry that a malicious signer could pick a weird public key, not the honest output of key generation, engineered so the cliff never fires. It cannot. zk-WHIR’s knowledge soundness means that behind any root the verifier ever accepts, there provably exists a degree-$\le D$ polynomial that every accepted opening agrees with. The degree cap is a property of the public key itself, not of honest behavior. So the cliff binds even an adversary who chose their key in bad faith.
Enable JavaScript to explore this figure.
Why zk-WHIR specifically? Because it is the commitment that satisfies all of Jevil’s constraints at once. It is post-quantum (its security rests on hash functions and Reed–Solomon proximity, not on discrete logs, so Shor does not touch it), it is transparent (no trusted setup, so nobody has to generate and then destroy a secret), it supports the linear-form openings our lift produces, and it is zero-knowledge. It sits at the end of a lineage of Reed–Solomon proximity tests (FRI, then DEEP-FRI, then STIR, then WHIR) with the zero-knowledge layer added on top. For this post it stays a black box; if you want the inside of the box, the paper and the zk-WHIR paper it builds on are the places to go.
One proof, not seventeen
Each signature reveals $K=16$ evaluations, plus we want to fold in that free out-of-domain point, so naively that is $K+1 = 17$ openings per signature, each with its own proof. That would be bulky. Instead Jevil batches them into a single opening.
The trick is a random linear combination. Squeeze $K+1$ random coefficients $\beta_t$ out of the transcript (Fiat–Shamir: hash everything so far), and combine the $K+1$ separate claims “$f(x_t)=y_t$” into one claim about a single linear form. Because the lift already turned each evaluation into a linear form of $c$, a combination of them is again a linear form of $c$, so the whole bundle becomes one zk-WHIR opening.
Enable JavaScript to explore this figure.
What stops a signer from sneaking one false value into the bundle, hoping it averages out? Schwartz–Zippel. If even a single one of the $K+1$ claimed values is wrong, the combined claim is wrong for all but a $1/|\mathbb{F}|$ fraction of the random $\beta$’s, and $|\mathbb{F}|\approx 2^{256}$, so the signer is caught with overwhelming probability. Lie once, get caught. One proof now stands in for seventeen, at no security cost.
Why you can’t forge below the cliff
The cliff is the dramatic part, but a few-time signature is worthless if the signatures before the cliff are forgeable. They are not. Below the budget, Jevil is unforgeable at roughly $124$-bit classical security against an adversary making up to $2^{128}$ hash queries.
A forger trying to sign a fresh message has only three moves, and each is a wall. They can lie about an evaluation, but we just closed that door with the commitment and Schwartz–Zippel. They can try to guess the value of $f$ at a genuinely new position, but below the cliff $f$ is information-theoretically undetermined, so any unseen evaluation is uniform over a $2^{256}$-element field, and guessing it is hopeless. Or they can hope that the fresh message’s positions happen to land entirely inside the set of positions already revealed by past signatures, the only case where they could quote honest values without ever signing.
That last move is the classic HORS coverage attack, and it is the one the parameters are tuned against. The “seen pool” grows by $K$ positions per signature; a fresh message’s $K$ positions are an independent random subset of the whole space $\{0,\dots,T-1\}$; the forger wins only if all $K$ land in the pool, which happens with probability at most $\left(\tfrac{n^\star K}{T}\right)^{K}$ per attempt. Make the position space $T$ big enough and that probability stays negligible even after grinding $2^{128}$ messages. Throw some forgeries below and watch the odds.
Enable JavaScript to explore this figure.
Add the three bounds together (the commitment’s soundness, the Schwartz–Zippel term, and the coverage term) and the total forgery advantage comes in under $2^{-124}$. Signatures below the budget are real signatures.
Tuning it, and when to reach for it
Everything is driven by one knob: the budget $n^\star$, chosen from $\{1, 3, 7, 15, \dots, 2^{14}-1\}$, the values where $n^\star+1$ is a power of two, so the cliff lands exactly at signature $n^\star+1$. From $n^\star$ and the fixed $K=16$, the rest falls out: the polynomial has $M=(n^\star{+}1)K$ coefficients, degree $D=M-1$, and the cliff sits at $n^\star+1$. Slide the budget below and watch the sizes move.
Enable JavaScript to explore this figure.
The numbers are friendly. Public keys are 68 bytes flat: a 32-byte commitment root, the 32-byte out-of-domain value, and 4 bytes naming the budget. Secret keys are 32 bytes, a single seed everything else is derived from. Signatures run from about 40 KB at the smallest budget to a few hundred KB at the large end, growing only logarithmically in the polynomial size, so a thousand-fold increase in budget costs only a handful of times more bytes. Key generation, signing, and verification are all comfortably sub-second across the deployable range. The ceiling on the budget, $n^\star = 2^{14}-1$, comes from an arithmetic property of the working field: a degree-4 extension of the 64-bit Goldilocks prime, with about $2^{256}$ elements and just enough power-of-two structure to index the positions.
So when is the cliff the right tool? When over-signing should be self-punishing rather than merely forbidden. A stateful scheme says “don’t sign past the budget” and trusts your storage to enforce it; lose that bet to a rolled-back counter and you are silently insecure. Jevil moves the cap into the math: oversign and the polynomial becomes public, in $O(D^2)$, for everyone, immediately. There is no silent failure mode because there is no quiet way to fail. The failure is the loudest possible event. That is a strictly stronger promise than discipline, and it does not depend on durable state, on operator vigilance, or on anyone trusting anything operational.
The paper and the code
If you want the formal version, with the security proofs, the exact parameters, and the cap-binding theorem stated properly, it is all in the paper. The reference implementation in Rust tracks the construction module for module.
- Paper: eprint 2026/1103
- Reference implementation: github.com/symbolicsoft/jevil
Go on, then: spend a thousand signatures on a thousand different messages. Just don’t reach for the thousand-and-first. (Signing the same message again is free; it is the next new one that sets the key free, free.)