Deploy KeY to Europe โ Reiner Hรคhnle ๐ฉ๐ช๐ธ๐ช + KIT ๐ฉ๐ช + TU Darmstadt ๐ฉ๐ช (2001), the EU-Native Java Formal Verifier for JavaCard Payment Systems and Design by Contract, on EU Infrastructure in 2026
Every time you tap a contactless bank card at a point-of-sale terminal, the JavaCard applet executing on the card's microcontroller processes an ISO 7816 command sequence in a few milliseconds. The card has no operating system pager, no memory management unit, no exception recovery that would survive a power glitch mid-transaction. The correctness of the applet โ that it correctly validates PINs, maintains card balances, cannot be driven into an undefined state by a malformed APDU โ must be established before manufacture. After the ROM mask is committed, no patch is possible.
This is the problem domain that motivated KeY: a deductive Java verifier that proves functional correctness of Java and JavaCard programs using Java Dynamic Logic โ a formal logic in which programs appear as first-class syntactic objects inside logical formulas. KeY was developed starting in 2001 as a joint project of Chalmers University of Technology ๐ธ๐ช (Gรถteborg), Universitรคt Karlsruhe ๐ฉ๐ช (now Karlsruhe Institute of Technology, KIT), and later TU Darmstadt ๐ฉ๐ช โ three EU universities forming the backbone of the KeY consortium.
The principal architects are Reiner Hรคhnle ๐ฉ๐ช๐ธ๐ช (Professor at Chalmers 1996โ2006, then TU Darmstadt 2006โpresent), Bernhard Beckert ๐ฉ๐ช (KIT Karlsruhe, Professor since 2008), and Peter H. Schmitt ๐ฉ๐ช (Universitรคt Karlsruhe / KIT). The KeY Book โ Deductive Software Verification: The KeY Book (Springer LNCS 10001, 2016), edited by Hรคhnle and Schmitt โ is the definitive reference and one of the most comprehensive texts on deductive program verification in the literature.
Java Dynamic Logic โ Programs Inside Logic
KeY's formal foundation is Java Dynamic Logic (JavaDL): an extension of first-order logic in which programs appear as modal operators applied to formulas. Two modalities express the two standard correctness properties:
- Box modality
[prog]ฯโ partial correctness: ifprogterminates, thenฯholds in the resulting state - Diamond modality
<prog>ฯโ total correctness:progterminates, andฯholds in the resulting state
Where prog is a fragment of Java source code. JavaDL extends this with Java-specific theories: heap model (object creation, field access, arrays, aliasing), exception semantics (try/catch/finally), object initialisation order, integer overflow (modular arithmetic on int/long), and the JavaCard transaction protocol.
A JavaDL sequent โ KeY's basic proof obligation unit โ looks like:
ฮ โข {h := h[obj.balance := obj.balance - amount]}
[if (amount > 0 && amount <= obj.balance)
{ obj.balance = obj.balance - amount; }]
(obj.balance >= 0), ฮ
This encodes: given the preconditions in ฮ, after executing the Java debit operation, the balance postcondition obj.balance >= 0 holds. The {h := ...} syntax is a state update โ KeY's representation of a heap mutation before symbolic execution begins.
JML โ The Specification Language
KeY reads contracts written in JML (Java Modeling Language), developed by Gary Leavens (Iowa State University, US) as a specification language for Java in the tradition of Eiffel's Design by Contract. JML contracts are embedded in Java source files as structured comments, preserving Java toolchain compatibility:
public class BankCard {
private /*@ spec_public @*/ int balance;
private /*@ spec_public @*/ int limit;
/*@ public normal_behavior
@ requires amount > 0 && amount <= balance;
@ ensures balance == \old(balance) - amount;
@ assignable balance;
@*/
public void debit(int amount) {
balance = balance - amount;
}
/*@ public normal_behavior
@ requires amount > 0;
@ ensures balance == \old(balance) + amount;
@ ensures balance <= limit;
@ assignable balance;
@ also
@ public exceptional_behavior
@ requires amount > 0 && \old(balance) + amount > limit;
@ signals (OverLimitException e) true;
@ assignable \nothing;
@*/
public void credit(int amount) throws OverLimitException {
if (balance + amount > limit) throw new OverLimitException();
balance = balance + amount;
}
}
JML specification constructs:
requiresโ precondition: what must hold when the method is calledensuresโ postcondition: what must hold when the method returns normallysignalsโ exception postcondition: what holds when the method throwsassignableโ frame condition: which heap locations the method may modify\old(expr)โ value ofexprin the pre-state (before the method executed)\resultโ return value of the methodnormal_behavior/exceptional_behaviorโ split specification for normal vs. exceptional termination
KeY translates JML contracts into JavaDL proof obligations, then applies its sequent calculus to discharge them.
Symbolic Execution via Sequent Calculus
KeY's proof engine is a sequent calculus โ a formal proof system where each rule corresponds to one Java language construct. Rather than executing the program concretely, KeY performs symbolic execution: program statements are reduced step by step according to calculus rules, accumulating symbolic constraints on the heap and local variables.
The calculus rule for if (cond) { stmt_then } else { stmt_else } splits into two branches:
ฮ โข cond = true, [{stmt_then; rest}] ฯ, ฮ
ฮ โข cond = false, [{stmt_else; rest}] ฯ, ฮ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ (if-rule)
ฮ โข [{if (cond) {stmt_then} else {stmt_else}; rest}] ฯ, ฮ
Each branch constrains the symbolic state: in the left branch, cond is assumed true; in the right branch, false. Loops are handled via loop invariants (explicit in JML or interactively supplied). Method calls are handled by their JML contracts โ the callee's precondition becomes a proof obligation, and the postcondition is assumed in the caller's continuation.
The result is a proof tree: a hierarchical structure where each leaf is either a trivially true formula (closed by a first-order prover) or a remaining open goal. KeY interfaces with SMT solvers โ Z3, CVC5, Simplify โ for closing arithmetic and pure first-order leaves, and retains the ability to close complex goals with the interactive KeY IDE.
JavaCard โ EU Payment Infrastructure Verification
The most significant application domain for KeY is JavaCard: the Java platform for smart cards, defined in ISO/IEC 7816 and implemented on constrained microcontrollers (16โ32 KB RAM, 256โ512 KB EEPROM, 8/32-bit CPU). JavaCard powers the EU's payment infrastructure:
- EMV payment cards (Mastercard, Visa, American Express) โ the payment applets on Visa credit cards and Girocard (EC-Karte) are JavaCard programs
- German Gesundheitskarte (eGK) โ the German statutory health insurance card carries a JavaCard applet managing insurance data, electronic prescriptions (eRezept)
- German Personalausweis โ the German national ID card's ePA function uses JavaCard for the cryptographic authentication applet
- SIM/eSIM cards โ JavaCard runtime on UICC (Universal Integrated Circuit Card) per ETSI TS 102 221
The EU companies manufacturing these systems are KeY's primary industrial users:
Infineon Technologies ๐ฉ๐ช (Munich): The dominant European smart card chip manufacturer. Infineon's SLM/SLE series microcontrollers power hundreds of millions of bank cards, ID documents, and health cards. Infineon uses formal verification for JavaCard applets submitted for Common Criteria evaluation.
Giesecke+Devrient (G+D) ๐ฉ๐ช (Munich): Smart card OS developer (StarSign, Convego). G+D produces 4+ billion smart cards per year โ bank cards, SIM cards, government documents. JavaCard applets undergo formal security evaluation at EAL 4โ6 under Common Criteria.
Idemia ๐ซ๐ท (Courbevoie, formerly Oberthur Technologies): The French counterpart โ Europe's second smart card giant, producing bank cards, passports, national ID cards, and SIM cards for Vodafone, Orange, Deutsche Telekom. JavaCard formal verification for Common Criteria EAL 5+.
NXP Semiconductors ๐ณ๐ฑ (Eindhoven): MIFARE and SmartMX smart card controllers. NXP's P60 family โ used in German national ID cards, EU passports, transit cards โ carries JavaCard runtime. NXP holds Common Criteria EAL 6+ certifications.
Bundesdruckerei ๐ฉ๐ช (Berlin): Germany's federal printing office. Bundesdruckerei personalises and issues German passports, ID cards, and health insurance cards. The eGK (Gesundheitskarte) JavaCard applets are formally evaluated.
Common Criteria โ The EU Formal Verification Mandate
Common Criteria (CC, ISO/IEC 15408) is the international standard for IT security evaluation. Smart cards with financial or governmental functions in the EU must be evaluated at:
- EAL 4+ (Augmented Level 4): Bank cards, SIM cards โ requires Semiformal Design Description, informal operation model, independent penetration testing
- EAL 5+ (Augmented Level 5): High-security cards (EU passports, national ID, health cards) โ requires Semiformal Functional Specification, Formal Security Policy Model, formal correspondence between model and implementation
- EAL 6+ (Augmented Level 6): Cryptographic hardware, military ID โ full formal verification of implementation
At EAL 5 and above, Common Criteria explicitly requires formal verification evidence: a mathematical proof that the implementation satisfies the security policy model. KeY is the EU academic tool of choice for generating such evidence for JavaCard applets. A KeY proof of a JavaCard payment applet method constitutes machine-checked evidence of absence of buffer overflows, integer arithmetic errors, null pointer dereferences, and violations of the card balance invariant โ directly mappable to the CC threat model.
KeY for EU AI Act Art. 9 โ Java AI Inference Components
The EU AI Act Article 9 requires high-risk AI systems (Annex III: biometric identification, critical infrastructure control, employment decisions, credit scoring) to implement a risk management system with testing and validation of AI components. For Java-based AI inference systems:
/*@ public normal_behavior
@ requires input != null && input.length == MODEL_INPUT_DIM;
@ requires (\forall int i; 0 <= i && i < input.length;
@ input[i] >= 0.0f && input[i] <= 1.0f);
@ ensures \result >= 0 && \result < NUM_CLASSES;
@ ensures confidenceScore >= 0.0f && confidenceScore <= 1.0f;
@ assignable confidenceScore;
@*/
public int classify(float[] input) {
// ... inference logic
}
KeY can prove: (1) that the classifier always returns a valid class index in [0, NUM_CLASSES), (2) that the confidence score remains in [0.0, 1.0], (3) that the method does not modify heap locations beyond confidenceScore. This constitutes formal verification evidence for EU AI Act Annex IV technical documentation requirements.
Deploy KeY on sota.io
KeY is distributed as a standalone JAR (key.jar) requiring Java 11+. The KeY IDE and batch prover run on standard JVM infrastructure:
# Install KeY (download from key-project.org)
wget https://www.key-project.org/dist/2.12.3/key-2.12.3-exe.jar
# Run KeY prover in batch mode (non-interactive)
java -jar key-2.12.3-exe.jar \
--auto \
--jmlspecs \
BankCard.java
# Run with SMT backend (Z3 for arithmetic obligations)
java -jar key-2.12.3-exe.jar \
--auto \
--smt Z3 \
--jmlspecs \
BankCard.java
sota.io deployment โ Dockerfile for a KeY formal verification service:
FROM sotaio/builder:ubuntu-24.04
# Install Java runtime + Z3 SMT solver
RUN apt-get update && apt-get install -y \
openjdk-21-jre-headless \
z3 \
&& rm -rf /var/lib/apt/lists/*
# Download KeY batch prover
ARG KEY_VERSION=2.12.3
RUN wget -q \
https://www.key-project.org/dist/${KEY_VERSION}/key-${KEY_VERSION}-exe.jar \
-O /opt/key.jar
WORKDIR /verification
# Copy Java sources with JML contracts
COPY src/ ./src/
# Run KeY batch verification
RUN java -jar /opt/key.jar \
--auto \
--jmlspecs \
--timeout 60000 \
src/BankCard.java \
&& echo "KeY verification: ALL GOALS CLOSED"
CMD ["java", "-jar", "/opt/key.jar", "--auto", "--jmlspecs", \
"${TARGET:-src/Main.java}"]
# Combined workflow: compile โ verify โ test
# Step 1: Compile with JML annotations (OpenJML for type checking)
openjml -check src/BankCard.java
# Step 2: KeY deductive verification (prove JML postconditions)
java -jar /opt/key.jar \
--auto \
--smt Z3 \
--jmlspecs \
--timeout 120000 \
src/BankCard.java
# Step 3: JUnit tests as specification-based test oracle
mvn test -Dtest=BankCardTest
sota.io free tier (512 MB RAM, 0.5 vCPU) handles KeY verification of small JavaCard applet methods (2โ10 JML-annotated methods, arithmetic-heavy contracts closed by Z3) within standard timeout. JavaCard applets for Common Criteria EAL 5+ evaluation require Standard tier (โฌ9/month, 2 GB RAM) โ KeY proof trees for payment applets with 20โ50 methods and loop invariants require 1โ4 GB heap for the JVM. Persistent proof sessions (.proof files) across deployments are supported via sota.io volume mounts.
See Also
- Deploy Why3 to Europe โ โ EU-native multi-prover deductive verification platform (LRI/INRIA Saclay ๐ซ๐ท, 2010) โ IVL for Frama-C WP and SPARK Ada GNATprove
- Deploy Frama-C to Europe โ โ EU-native C code formal verifier (CEA LIST ๐ซ๐ท + INRIA ๐ซ๐ท, 2008) โ WP + Eva plugins + ACSL
- Deploy SPARK Ada to Europe โ โ Formally verifiable Ada subset (AdaCore ๐ซ๐ท, 1988) โ GNATprove proves Ada contracts via Why3
- Deploy Dafny to Europe โ โ Verification-aware language (Microsoft Research, 2009)
- Deploy Isabelle to Europe โ โ Generic theorem prover (Cambridge ๐ฌ๐ง + TU Munich ๐ฉ๐ช, 1988) โ higher-order logic
- Deploy NuSMV to Europe โ โ EU-native symbolic model checker (FBK Trento ๐ฎ๐น, 2002)
- All 145 languages on sota.io โ