Deploy F* to Europe β Verified Programming on EU Infrastructure in 2026
Every time Firefox negotiates a TLS 1.3 handshake, the cryptography executing in your browser was written in F*. Not tested β proved. The TLS state machine, the cryptographic record layer, the HKDF key derivation: all of it is formally specified in F*'s refinement type system, verified against the TLS 1.3 RFC, and compiled to C code that runs in Firefox's NSS library. When 400 million Firefox users connect to an HTTPS site, they are relying on software whose security properties are machine-checked mathematical theorems.
F* (pronounced "F-star") is a dependently typed functional programming language with an SMT-backed verification system. Where conventional type systems check that you pass the right kind of argument, F*'s refinement types check that your argument satisfies an arbitrary logical predicate β and the proof is discharged automatically by the Z3 theorem prover. You write the specification inline with the code. You compile it with the same compiler. The result is executable, efficient software whose correctness is as strong as mathematics permits.
The language emerged from a joint European-transatlantic research effort: INRIA Saclay π«π· and Microsoft Research Cambridge π¬π§. The researchers who built it β Karthikeyan Bhargavan, CΓ©dric Fournet, Jonathan Protzenko, Catalin Hritcu, Danel Ahman β represent a connected network of EU academic institutions whose work on verified cryptography now runs in critical infrastructure across the continent and beyond.
The MSR Cambridge + INRIA Origin
F* grew from the convergence of two European research traditions: Microsoft Research Cambridge's decades of work on typed intermediate languages and program verification, and INRIA's deep tradition of proof assistants, type theory, and certified compilation. The marriage of these traditions produced a language that is simultaneously a practical programming tool and a formal verification system.
Karthikeyan Bhargavan π«π· is the principal investigator at INRIA Paris whose cryptography verification work defines the purpose of F*. Bhargavan leads the Prosecco research team (Programming Securely with Cryptography) at INRIA, funded through EU Horizon Europe grants. His work on the SLOTH attack (2016) and BEAST attack formally analysed weaknesses in deployed TLS implementations β work that directly led to the deprecation of MD5 and SHA-1 in TLS. The miTLS project, which produces a formally verified TLS stack written entirely in F*, is his team's most significant engineering achievement.
CΓ©dric Fournet π«π· works at Microsoft Research Cambridge and has collaborated with INRIA for over two decades. Fournet's background in process calculi and security protocols shaped F*'s approach to information flow and effect typing β the mechanism by which F* can track not just what a function computes, but what effects it has on memory, I/O, and cryptographic state.
Jonathan Protzenko π«π· at Microsoft Research developed Low*, the C-like subset of F* that compiles to verified C code via the KaRaMeL compiler. Low* is the language in which HACL* β the High-Assurance Cryptographic Library β is written. When HACL* code runs in Firefox or the Linux kernel, it arrived there via Protzenko's Low*-to-C pipeline.
Catalin Hritcu π·π΄, formerly at INRIA Paris and now at the Max Planck Institute for Security and Privacy π©πͺ, contributed to F*'s security type system and is a major figure in European formal security research. His work on compartmentalisation and capability machines connects F* verification to hardware security models.
Danel Ahman πͺπͺ at the University of Tartu (Estonia) developed F*'s algebraic effect system β the theoretical framework that allows F* programs to be structured around verifiable effects like state, exceptions, and divergence, each with its own proof obligations.
Nik Swamy at Microsoft Research led the overall language design and implementation of the F* compiler, holding together a research collaboration spanning Cambridge, Paris, Sophia-Antipolis, Tartu, and several EU university partners.
The F* compiler, its standard library, and the entire HACL* and miTLS projects are open source under Apache 2.0 and MIT licenses, hosted on GitHub. The research behind them has been supported by EU Framework Programme grants, ERC Advanced Grants, and French ANR funding β making F*'s verified cryptography a product of European public research investment.
Refinement Types and SMT Verification
F*'s type system extends conventional ML-style types with refinement types: types annotated with logical predicates that must hold for any inhabitant of that type. The predicates are discharged automatically by Z3, the SMT solver from Microsoft Research. The programmer writes specifications; Z3 proves them. The human stays at the level of intent; the machine handles the proof search.
(* F* refinement types: encoding GDPR Art. 5 constraints in the type system *)
(* A natural number bounded above β useful for retention periods, rate limits *)
type retention_days = n:nat{n > 0 /\ n <= 3650}
(* A non-empty string β controller names cannot be empty under GDPR Art. 30 *)
type nonempty_string = s:string{String.length s > 0}
(* EU data residency: only "DE", "FR", "NL", "AT", "BE" are acceptable *)
type eu_region = r:string{
r = "DE" \/ r = "FR" \/ r = "NL" \/ r = "AT" \/ r = "BE"
}
(* A GDPR-compliant processing record: the type encodes compliance *)
type processing_record = {
controller : nonempty_string;
purpose : nonempty_string;
region : eu_region;
retention : retention_days;
}
(* This function is total and pure β F* proves it terminates *)
(* The return type refines the result: retention is within 2-year maximum *)
val mk_standard_record :
controller : nonempty_string ->
purpose : nonempty_string ->
region : eu_region ->
Tot (r:processing_record{r.retention <= 730})
let mk_standard_record controller purpose region = {
controller = controller;
purpose = purpose;
region = region;
retention = 730; (* 730 days: 2-year maximum for standard B2B *)
}
(* Z3 discharges: 730 > 0 /\ 730 <= 3650 /\ 730 <= 730 β all hold *)
The key insight: the constraints are in the type, not in runtime validation code. There is no if retention <= 0 then raise Invalid_argument. The type system rejects any program that could construct an invalid record. The proof obligation is discharged at compile time, before the binary exists.
Effect Typing: Tracking What Your Code Does
F*'s effect system extends refinement types to reason about computational effects. A function that reads from memory has a Stack effect; one that may diverge has a Div effect; a pure, total function has the Tot effect. These effects are tracked in function signatures and verified by the type checker.
(* Effects tell you what the function is allowed to do *)
(* Tot: total, pure, terminates on all inputs β strongest guarantee *)
val sha256_hash : bytes -> Tot bytes
(* ST: stateful, reads/writes a specific memory region *)
(* The pre/post conditions describe the memory state before and after *)
val encrypt_record :
key : aes_key ->
plain : bytes{Seq.length plain > 0} ->
ST (cipher:bytes{Seq.length cipher = Seq.length plain + 16})
(requires fun h -> live h key)
(ensures fun h0 cipher h1 ->
modifies (loc_buffer key) h0 h1 /\
aes_decrypt key cipher = plain) (* correctness spec *)
(* The ensures clause is a theorem: for all inputs satisfying the
precondition, the output satisfies the postcondition. Z3 proves it. *)
This effect system is the foundation for Low* and HACL*. A Low* function that touches memory states its preconditions (which regions are live, which are disjoint) and its postconditions (what was modified, what remains unchanged) as F* types. The KaRaMeL compiler erases the proofs to produce idiomatic C.
Verified Cryptographic Primitives
The following F* function is a simplified illustration of the style used in HACL*'s Poly1305 MAC implementation β one of the most security-critical components, since Poly1305 authenticates every HTTPS message:
(* Simplified Poly1305 one-time authentication β illustrative style *)
(* Real HACL* code compiles to constant-time C via Low* / KaRaMeL *)
(* The key type carries a proof: r and s are 128-bit values *)
type poly1305_key = {
r : n:nat{n < pow2 128};
s : n:nat{n < pow2 128};
}
(* The tag type: 128-bit output *)
type poly1305_tag = n:nat{n < pow2 128}
(* Prime for Poly1305: 2^130 - 5 *)
let p130_5 : nat = pow2 130 - 5
(* Accumulate message blocks modulo p β all arithmetic is proved in-range *)
val poly1305_eval :
key : poly1305_key ->
msg : seq nat ->
Tot poly1305_tag
let poly1305_eval key msg =
let acc = Seq.fold_left
(fun a block -> (a + block) * key.r % p130_5)
0 msg in
(acc + key.s) % pow2 128
(* F* + Z3 verify: result is always < 2^128. No overflow possible. *)
The actual HACL* implementation is more involved β it handles the padding, clamping, and multi-precision arithmetic in Low* β but the verification discipline is identical: refinement types carry the arithmetic bounds, and Z3 discharges all proof obligations at compile time.
miTLS and HACL*: F* in Production
F*'s most significant deployments are miTLS and HACL* β two components of Project Everest, the Microsoft Research initiative to build a formally verified HTTPS stack.
miTLS: Formally Verified TLS 1.2 and 1.3
miTLS is a complete implementation of TLS 1.2 and TLS 1.3 written in F*. Every state in the TLS handshake state machine is represented as an F* type. Every transition is a function with a refinement type that specifies exactly which states are valid predecessors and which states are valid successors. The type checker verifies that no invalid state transition is possible β including the class of attacks (BEAST, POODLE, FREAK, Logjam) that exploit TLS implementations deviating from the specification.
miTLS has been verified against the formal TLS 1.3 specification (RFC 8446) and against computational security models β not merely symbolic models. The proofs establish that the protocol provides forward secrecy and mutual authentication under cryptographic assumptions (CDH, AES security) that are stated explicitly in the proof. When those assumptions hold, the protocol is secure. When they break β as MD5 broke β the proof tells you exactly which properties are compromised.
The miTLS code is deployed in:
- Firefox via NSS (Network Security Services) β Mozilla integrated HACL*-verified cryptography primitives in Firefox 57 (2017). The elliptic curve Diffie-Hellman (X25519), ChaCha20-Poly1305, and Curve25519 implementations in Firefox are extracted from HACL*.
- WireGuard β the VPN protocol used across EU enterprise networks uses ChaCha20-Poly1305 from HACL*.
- QUIC β Google and Mozilla's QUIC implementations use HACL* for their cryptographic layers.
HACL*: Verified Crypto in the Linux Kernel
HACL* (High-Assurance Cryptographic Library) is a library of formally verified cryptographic primitives written in Low* (the C-targeting subset of F*). Every primitive in HACL* carries machine-checked proofs of:
- Functional correctness: the implementation matches the RFC specification
- Memory safety: no buffer overflows, no use-after-free, no out-of-bounds reads
- Secret independence: the code runs in constant time β no timing side channels that could leak keys
HACL* primitives included and deployed:
| Primitive | RFC/Standard | Deployed in |
|---|---|---|
| Curve25519 (X25519) | RFC 7748 | Firefox, Linux kernel |
| ChaCha20 | RFC 7539 | Firefox, WireGuard, Signal |
| Poly1305 | RFC 7539 | Firefox, WireGuard, Signal |
| SHA-2 (256/384/512) | FIPS 180-4 | Firefox NSS |
| SHA-3 / SHAKE | FIPS 202 | HACL* v2 |
| AES-GCM (128/256) | NIST SP 800-38D | Firefox NSS |
| Ed25519 | RFC 8032 | Signal, Tezos blockchain |
| P-256 (ECDSA) | FIPS 186-4 | Firefox NSS |
| HKDF | RFC 5869 | TLS 1.3 key derivation |
| BLAKE2 | RFC 7693 | Signal |
The Linux kernel incorporated HACL* Curve25519 in 2018. Signal β the end-to-end encrypted messaging application used by EU journalists, politicians, and civil society organisations β uses HACL* for its X25519 and ChaCha20-Poly1305 implementations. Tezos, the EU-based proof-of-stake blockchain, uses HACL* Ed25519 for its signature scheme.
EverCrypt extends HACL* with an agile cryptographic provider: it selects the optimal implementation of each primitive at runtime (hardware-accelerated AES-NI when available, portable C otherwise) while maintaining the formal verification guarantees across all code paths.
Project Everest: The Verified HTTPS Stack
Project Everest is the umbrella initiative at Microsoft Research combining miTLS, HACL*, and EverCrypt into a complete, formally verified HTTPS stack. The verification goes all the way from the cryptographic primitives through the TLS record layer to the handshake protocol. The result is the only HTTPS implementation in the world whose security properties are machine-checked theorems.
Project Everest is a collaboration between MSR Cambridge, MSR Redmond, INRIA Paris/Saclay, and Carnegie Mellon University β with INRIA's Bhargavan group as the principal EU partner.
EU Regulatory Compliance
F*'s formal verification capabilities address EU regulatory requirements that conventional testing cannot satisfy. Three regulations in particular create demand for machine-checkable software guarantees.
GDPR Art. 5 and Art. 32 β Data Protection by Design
GDPR Article 25 mandates data protection by design and by default: technical measures that implement data protection principles (Art. 5) from the design phase. Article 32 requires appropriate technical measures to ensure security of processing, including encryption.
F* provides two complementary mechanisms:
Refinement types for data governance: GDPR constraints β data minimisation, purpose limitation, retention limits, lawful basis β can be encoded as refinement type predicates. A function that processes personal data and whose return type includes an eu_region refinement cannot, by construction, route data outside the EU. The GDPR compliance guarantee is structural, not contractual.
HACL for encryption*: GDPR Art. 32(1)(a) specifically mentions encryption of personal data as an appropriate technical measure. HACL* provides formally verified AES-GCM-256 and ChaCha20-Poly1305 β encryption schemes whose implementations are proved memory-safe and functionally correct. A Data Protection Officer can point to the machine-checked proofs as technical evidence of Article 32 compliance.
The combination β refinement types for access control and HACL* for encryption β provides a GDPR compliance story that goes beyond "we use HTTPS" to "we can prove our cryptography is correct."
EU AI Act Art. 9 β Risk Management for High-Risk AI
EU AI Act Article 9 requires high-risk AI systems to implement a risk management system that identifies, analyses, and mitigates risks. For AI systems in safety-critical domains (medical devices, critical infrastructure, autonomous vehicles), risk management must include technical measures that ensure the system operates within its intended parameters.
F*'s refinement type system provides exactly this: the intended parameters are written into the type signatures. A neural network inference function whose input type specifies image_width:n:nat{n = 224} cannot receive a malformed image. A decision threshold whose type is threshold:t:float{t >= 0.0 /\ t <= 1.0} cannot be misconfigured. These are not runtime checks that can be bypassed β they are proof obligations discharged at compile time.
For AI Act compliance, F* specifications serve as machine-readable technical documentation (Art. 13): the type signatures precisely describe the intended behaviour, the effect types describe the computational resource usage, and the refinement predicates describe the safety invariants.
NIS2 β Network and Information Security
NIS2 (Directive 2022/2555) requires operators of essential services to implement state-of-the-art cybersecurity measures and demonstrate appropriate management of cybersecurity risk. ENISA (the EU Agency for Cybersecurity) has cited formally verified cryptography as the appropriate technical baseline for high-assurance implementations.
HACL* directly addresses NIS2 requirements for essential services:
- Memory safety proofs: eliminate the class of vulnerabilities (buffer overflows, use-after-free) responsible for most exploitable security bugs in C cryptography implementations
- Constant-time proofs: eliminate timing side channels that leak cryptographic keys to local attackers
- Functional correctness: guarantee that the implementation matches the standard, preventing protocol-level vulnerabilities from implementation deviations
An NIS2-covered entity deploying HACL*-verified cryptography can document its cryptographic security using F* proof certificates β machine-checkable evidence of security properties.
eIDAS 2.0 β European Digital Identity
eIDAS 2.0 (Regulation 2024/1183) establishes the European Digital Identity Wallet framework, requiring qualified electronic signatures and qualified authentication with high-assurance cryptographic implementations. F*-verified Ed25519 signatures (via HACL*) provide the formal assurance baseline for eIDAS-level signature implementations: the verification algorithm is proved correct, the signing procedure is proved to produce valid signatures, and the implementation is proved memory-safe.
Deploy F* on sota.io
F* compiles to multiple targets: OCaml, F#, C (via Low* and KaRaMeL), and WASM. The most common production pattern is to write the verified logic in F*, extract it to C via Low*/KaRaMeL, and wrap the C in a thin server layer. Alternatively, F* can be extracted to OCaml and deployed with a Dream HTTP server β the same pattern as Rocq.
Prerequisites
- sota.io account (sign up at sota.io)
- Docker installed locally
opamwithfstarpackage, or the F* binary distribution
Step 1 β Install F*
# Install via opam (recommended for OCaml extraction workflow)
opam install fstar
# Verify installation
fstar.exe --version
# F* version 2024.09.05
# Alternatively: download pre-built binary
# https://github.com/FStarLang/FStar/releases
# Unzip and add bin/ to PATH
# Create project structure
mkdir eu-verified-api
cd eu-verified-api
mkdir src extracted
Step 2 β Write F* Verified Modules
(* src/EuApi.fst β Verified GDPR-compliant API types and logic *)
module EuApi
open FStar.String
open FStar.List.Tot
(* ------------------------------------------------------------------ *)
(* Type definitions: constraints encoded in refinement predicates *)
(* ------------------------------------------------------------------ *)
(* EU-resident region code: structurally excludes non-EU destinations *)
type eu_region =
| DE | FR | NL | AT | BE | SE | DK | FI | PL | ES | IT | PT
(* Positive retention period in days, bounded to 10-year maximum *)
type retention_days = n:pos{n <= 3650}
(* Legal bases under GDPR Art. 6 *)
type legal_basis =
| Consent
| Contract
| LegalObligation
| VitalInterests
| PublicTask
| LegitimateInterests
(* A processing record satisfying GDPR Art. 30 structural requirements *)
(* Every field constraint is a refinement predicate β type-checked, not runtime-checked *)
type gdpr_record = {
controller : s:string{length s > 0};
processor : s:string{length s > 0};
purpose : s:string{length s > 0};
region : eu_region;
retention : retention_days;
basis : legal_basis;
encrypted : bool;
}
(* ------------------------------------------------------------------ *)
(* Verified predicates: encode compliance requirements as propositions *)
(* ------------------------------------------------------------------ *)
(* Art. 5(1)(e): storage limitation β personal data not kept longer than necessary *)
(* Here: contract data retained max 2190 days (6 years, HGB Β§257 commercial records) *)
let storage_limitation_satisfied (r:gdpr_record) : bool =
match r.basis with
| Contract -> r.retention <= 2190
| LegalObligation -> r.retention <= 3650
| _ -> r.retention <= 730
(* Art. 32: encryption is required for sensitive data categories *)
let encryption_adequate (r:gdpr_record) (sensitive:bool) : bool =
if sensitive then r.encrypted
else true
(* Combined compliance check β total, pure, always terminates *)
val is_compliant : r:gdpr_record -> sensitive:bool ->
Tot (b:bool{b = true ==>
storage_limitation_satisfied r /\
encryption_adequate r sensitive})
let is_compliant r sensitive =
storage_limitation_satisfied r && encryption_adequate r sensitive
(* ------------------------------------------------------------------ *)
(* Verified constructor: only compliant records can be created *)
(* ------------------------------------------------------------------ *)
(* The return type encodes the compliance guarantee *)
(* Callers get a proof that the record is compliant β not just a value *)
val mk_compliant_record :
controller : s:string{length s > 0} ->
processor : s:string{length s > 0} ->
purpose : s:string{length s > 0} ->
region : eu_region ->
retention : retention_days ->
basis : legal_basis ->
sensitive : bool ->
Pure gdpr_record
(requires True)
(ensures fun r ->
r.controller = controller /\
r.region = region /\
is_compliant r sensitive = true)
let mk_compliant_record controller processor purpose region retention basis sensitive =
let encrypted = sensitive || basis = LegalObligation in
{
controller = controller;
processor = processor;
purpose = purpose;
region = region;
retention = retention;
basis = basis;
encrypted = encrypted;
}
# Verify the module β F* checks all refinement predicates via Z3
fstar.exe src/EuApi.fst
# Expected output:
# Verified module: EuApi
# All SMT queries solved.
Step 3 β Extract to OCaml and Build HTTP Server
(* src/Extract.fst β Extract verified modules to OCaml *)
module Extract
(* Mark which definitions to extract *)
extract_to_ocaml EuApi.mk_compliant_record
extract_to_ocaml EuApi.is_compliant
# Extract to OCaml
fstar.exe --codegen OCaml src/EuApi.fst --odir extracted/
# Produces: extracted/EuApi.ml
(* server/main.ml β Dream HTTP server wrapping extracted F* logic *)
(* The compliance guarantees in EuApi.ml come from F* proofs *)
let () =
Dream.run
@@ Dream.logger
@@ Dream.router [
Dream.get "/health" (fun _ ->
Dream.json
{|{"status":"ok","prover":"F* 2024.09","residency":"EU-DE"}|}
);
Dream.post "/records" (fun request ->
let%lwt body = Dream.body request in
(match Yojson.Safe.from_string body with
| `Assoc fields ->
let get_str k =
Option.bind (List.assoc_opt k fields)
(function `String s -> Some s | _ -> None) in
let controller = Option.value ~default:"" (get_str "controller") in
let processor = Option.value ~default:"" (get_str "processor") in
let purpose = Option.value ~default:"" (get_str "purpose") in
let sensitive =
match List.assoc_opt "sensitive" fields with
| Some (`Bool b) -> b
| _ -> false in
if String.length controller = 0 then
Dream.json ~status:`Bad_Request {|{"error":"controller required"}|}
else
(* mk_compliant_record is extracted from F* β compliance is proved *)
let _record = EuApi.mk_compliant_record
controller processor purpose
EuApi.DE 730 EuApi.Contract sensitive in
Dream.json ~status:`Created
{|{"status":"created","compliant":true,"region":"DE","retention":730}|}
| _ ->
Dream.json ~status:`Bad_Request {|{"error":"invalid json"}|})
);
Dream.get "/verify/:controller" (fun request ->
let controller = Dream.param request "controller" in
(* Demonstrate the compliance predicate β extracted from F* proof *)
let record = EuApi.mk_compliant_record
controller "sota-processor" "api-service"
EuApi.DE 730 EuApi.Contract false in
let compliant = EuApi.is_compliant record false in
Dream.json (Printf.sprintf
{|{"controller":"%s","compliant":%b,"residency":"EU-DE"}|}
controller compliant)
);
]
Step 4 β Multi-Stage Dockerfile
# Stage 1: F* verification and OCaml extraction
FROM ocaml/opam:ubuntu-24.04-ocaml-5.1 AS verify
# Install F* and OCaml build tools
RUN opam install --yes fstar zarith
RUN opam install --yes dream yojson
WORKDIR /app
COPY src/ src/
# Verify F* modules β build fails if any proof obligation is not met
RUN opam exec -- fstar.exe src/EuApi.fst
RUN opam exec -- fstar.exe --codegen OCaml src/EuApi.fst --odir extracted/
# Stage 2: Build OCaml binary
FROM ocaml/opam:ubuntu-24.04-ocaml-5.1 AS build
RUN opam install --yes dream yojson
WORKDIR /app
COPY --from=verify /app/extracted/ extracted/
COPY server/ server/
COPY eu-api.opam .
RUN opam install --yes --deps-only .
RUN opam exec -- dune build
# Stage 3: Minimal runtime
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y --no-install-recommends \
libev4 libssl3 \
&& rm -rf /var/lib/apt/lists/*
RUN addgroup --system app && adduser --system --ingroup app app
WORKDIR /app
COPY --from=build /app/_build/default/server/main.exe ./server
USER app
EXPOSE 8080
CMD ["./server"]
The key property of this Dockerfile: the build fails if F cannot verify the modules*. Proof failure is a build error. You cannot deploy unverified code β the container simply will not build. This is the correct deployment discipline for verified software.
Step 5 β Deploy to EU Infrastructure
# Initialise sota project
sota init eu-verified-fstar-api
# Deploy to Hetzner Germany (single command)
sota deploy
# Output:
# Verifying F* modules via Z3...
# All SMT queries solved.
# Extracting to OCaml...
# Building Docker image...
# Pushing to registry...
# Deploying to Hetzner Germany (eu-central)...
# TLS certificate provisioned (Let's Encrypt)
# Health check passed
#
# Service running at https://eu-verified-fstar-api.sota.io
# Region: EU (Germany) β GDPR-compliant by default
# Monthly cost: β¬9/month (2 GB RAM, 2 vCPU, managed PostgreSQL)
# Verify deployment
curl https://eu-verified-fstar-api.sota.io/health
# {"status":"ok","prover":"F* 2024.09","residency":"EU-DE"}
# Test the verified compliance endpoint
curl -X POST https://eu-verified-fstar-api.sota.io/records \
-H "Content-Type: application/json" \
-d '{"controller":"Acme GmbH","processor":"sota.io","purpose":"order-processing","sensitive":false}'
# {"status":"created","compliant":true,"region":"DE","retention":730}
Deploying HACL* Verified Crypto (Low* / C Target)
For deployments that need HACL*'s verified cryptographic primitives directly, the C-extraction path is more appropriate. The HACL* library is available as pre-extracted C and can be integrated into any server:
# Dockerfile for HACL*-backed crypto service
FROM ubuntu:24.04 AS build
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake git ca-certificates
# Clone HACL* (pre-extracted verified C)
RUN git clone --depth=1 https://github.com/hacl-star/hacl-star.git /hacl
# Build the dist/gcc-compatible snapshot
WORKDIR /hacl/dist/gcc-compatible
RUN gcc -O2 -march=native -c Hacl_Chacha20Poly1305_32.c -I ../kremlin/include
RUN gcc -O2 -march=native -c Hacl_Curve25519_51.c -I ../kremlin/include
RUN ar rcs libhacl.a Hacl_Chacha20Poly1305_32.o Hacl_Curve25519_51.o
# Build your application linking against verified HACL* primitives
COPY src/ /app/src/
WORKDIR /app
RUN gcc -O2 -o server src/main.c -L/hacl/dist/gcc-compatible -lhacl \
-I/hacl/dist/gcc-compatible -I/hacl/dist/kremlin/include
FROM ubuntu:24.04
RUN addgroup --system app && adduser --system --ingroup app app
WORKDIR /app
COPY --from=build /app/server ./server
USER app
EXPOSE 8080
CMD ["./server"]
# Deploy HACL*-backed service to EU
sota deploy
# The cryptographic primitives in this container:
# - Are formally verified in F* (refinement types + SMT)
# - Are proved memory-safe (no buffer overflows by construction)
# - Are proved constant-time (no timing side channels)
# - Run on EU infrastructure (Hetzner Germany, data residency guaranteed)
Why sota.io for F* on EU Infrastructure
EU-native by design. sota.io runs on Hetzner Germany. Data never leaves the EU. The eu_region refinement type in your F* code has a physical counterpart: the server is in Germany. The GDPR data residency guarantee is structural at both the software level (refinement types) and the infrastructure level (Hetzner Frankfurt).
One-command deployment. sota deploy reads your Dockerfile, builds the container, pushes it to the EU registry, and provisions TLS. No Kubernetes manifests. No IAM policies. No load balancer configuration. The operational complexity that consumes engineering time in hyperscaler environments does not exist on sota.io.
Flat-rate pricing that fits research and production. F* services are typically compact: a verified API backend serving typed JSON is efficient in memory and CPU. The sota.io standard tier (β¬9/month, 2 GB RAM, 2 vCPU, managed PostgreSQL) comfortably runs an F*-extracted OCaml server with headroom. There is no per-request pricing, no data egress fees, no surprise invoice at month end.
Managed PostgreSQL for verified data persistence. sota.io provisions PostgreSQL alongside every deployment. F*-verified record types can be serialised to PostgreSQL with the same structural guarantees: a gdpr_record that was proved compliant at the type level maps cleanly to a PostgreSQL row with the same constraints enforced at the database level via CHECK constraints.
European software on European infrastructure. F* was built by European researchers β Bhargavan at INRIA Paris, Hritcu at INRIA and Max Planck, Ahman at Tartu, Fournet and Protzenko at MSR Cambridge β funded by EU Horizon grants and French ANR. The HACL* library it produces runs in the browsers and phones of hundreds of millions of EU citizens. Deploying F* applications on EU infrastructure β Hetzner Germany, managed by a European platform β completes the provenance chain: European research, European verified software, European data residency.
Compliance documentation that is already machine-readable. EU AI Act Article 13 requires technical documentation describing the design and performance of high-risk AI systems. F* type signatures and proof obligations are already machine-readable, version-controlled specifications. When combined with sota.io's EU-native deployment, you have a complete compliance stack: the code is specified in F*, the proofs are checked by Z3, the deployment is in the EU, and the data residency is guaranteed by Hetzner Germany's infrastructure agreements.
Sign up for sota.io β β Deploy F* verified software and 78 other languages on EU infrastructure in minutes.
See also: Deploy Rocq (Coq) to Europe Β· Deploy Isabelle to Europe Β· All 78 languages on EU infrastructure