Protocol verification tools have grown more expressive with every paper, and harder to pick up with every release. Most end up used by the group that built them and almost nobody else. Verifpal goes the other way: a small language you can read out loud, an active attacker, and output that names the attack instead of leaving you to reconstruct it.
×confidentiality? m1Contradiction foundThe attacker substitutes its own identity key and a prekey signed by that key. Alice accepts the signature, so the four X3DH secrets are derived using keys controlled by the attacker.
✓authentication? Alice → Bob: e1HoldsBob’s checked decryption fails because Alice encrypted the message with a key derived from the attacker’s input. Bob therefore accepts no message.
Attack trace
|▸ 1.Attacker constructs PUBKEY(nil).
|▸ 2.Attacker constructs SIGN(nil, PUBKEY(nil)).
|▸ 3.Attacker replaces gblongterm, gbs, gbo, gbssig (sent by Bob to Alice) with PUBKEY(nil), PUBKEY(nil), PUBKEY(nil), SIGN(nil, PUBKEY(nil)). (gblongterm was PUBKEY(blongterm); gbs was PUBKEY(bs); gbo was PUBKEY(bo); gbssig was SIGN(blongterm, gbs))
|▸ 4.Alice's SIGNVERIF(PUBKEY(nil), PUBKEY(nil), SIGN(nil, PUBKEY(nil)))? passes — the attacker controls one of its inputs.
|▸ 5.Attacker observes e1 on the wire.
|▸ 6.Attacker observes galongterm on the wire.
|▸ 7.Attacker constructs DH_KEX(galongterm, nil).
|▸ 8.Attacker observes gae1 on the wire.
|▸ 9.Attacker constructs DH_KEX(gae1, nil).
|▸ 10.Attacker constructs amaster.
|▸ 11.Attacker observes gae2 on the wire.
|▸ 12.Attacker constructs DH_KEX(gae2, nil).
|▸ 13.Attacker constructs ack.
|▸ 14.Attacker constructs MAC(ack, nil).
|▸ 15.Attacker constructs akenc.
|▸ 16.Attacker observes n_e1 on the wire.
|▸ 17.Attacker opens e1 with akenc and n_e1, obtaining m1.
Verifpal 1.4.4 models threshold cryptography directly. THRESHOLD_SPLIT[n] replaces the fixed SHAMIR_SPLIT and produces up to sixteen shares for any threshold, THRESHOLD_SIGN produces a partial signature from one share, and THRESHOLD_JOIN reconstructs by symbolic Lagrange interpolation once enough distinct partials agree on their commitments and message. Reusing a nonce with the same share hands that share to the attacker, which is how the worked model forges a signature across a 3-of-5 boundary from one leaked share and two partials from an oracle.
Verifpal 1.4 closes four sources of false positives, including deliveries that no honest sender could have produced and attacks assembled from incompatible execution paths, and finds two classes of attack it previously missed: values forwarded unguarded across a guarded hop, and the 2007 Pi_Toy attack, which needs nested encryptions deeper than the honest protocol goes. AEAD_ENC and AEAD_DEC now take a nonce; knows password and PW_HASH are gone. Verdicts carry labels such as [attacker-supplied value] and [search exhausted at 2 sessions], and precondition now restricts a query to the executions in which the named message is sent.
Verifpal 1.3 adds a scenarios[] block for assigning different peers to concurrent instances of a principal. This allows models to reproduce Lowe’s 1995 attack on Needham-Schroeder and distinguish the original protocol from Lowe’s correction. Query results now show session and term-depth limits. --saturate increases the session count until verdicts stabilize, and --auto-queries generates confidentiality, authentication and freshness queries.
Verifpal 1.0 removes the beta warning introduced in 2020. It adds post-quantum key exchange, declared weakening assumptions and witness-based unlinkability. The accompanying paper presents a soundness theorem and a termination proof, and compares the readability of Verifpal attack traces with ProVerif and Tamarin.
The language reads close to how you would describe a protocol out loud to a colleague, while staying precise enough to analyze. Principals know things, generate things and send them to each other.
Alice->Bob: e
Modeling that avoids user error
You cannot define your own cryptographic primitives. Verifpal ships the functions instead, which takes an entire class of modeling mistakes off the table before analysis starts.
e = AEAD_ENC(k, n, m, ad)
Analysis output you can act on
When a query fails, Verifpal describes the attack in the protocol’s own terms: who sent what, what the attacker put in its place, and why nobody noticed the swap.
×authentication?Alice->Bob: e
Analysis inside your editor
The Visual Studio Code extension highlights syntax, runs the queries as you type and draws the protocol as a diagram, so the analysis keeps up with the model while you are still writing it.
code --install-extension symbolicsoft.verifpal
What Verifpal covers
Verifpal models protocols against an active network attacker. It checks confidentiality, authentication, freshness, equivalence and unlinkability. Models can express forward secrecy, key-compromise impersonation, declared primitive failures and classical, post-quantum or hybrid key exchange.
Verifpal has been used to model Signal, Scuttlebutt, TLS 1.3 and Telegram. The version 1.0 paper formalizes its syntax, semantics and analysis, proves soundness independently of solver behavior, and proves unconditional termination. The software is free and open source under the GPLv3.