The Birth of a Zero-Knowledge Programming Language
ZKCC: zero-knowledge circuit language and compiler for practical deployment in Identity Wallets.
Longfellow-ZK is, in my view, a rare example of serious engineering work applied to zero-knowledge proofs. It is not a new cryptographic construction. It is a carefully selected combination of known primitives that produces efficient, practical proofs for real-world identity documents based on ECDSA P-256 and SHA-256, and will support additional cryptographic algorithms in the future.

Since I discovered this remarkable achievement by Frigo and Shelat in late 2024, I have become passionate about establishing and maintaining a European distribution for this system and facilitating contributions to it. Additionally, I aim to develop a circuit programming language that makes the technology accessible, auditable, and reusable within the EU Digital Identity Wallet (EUDI). This involves more than simply recompiling someone else’s code. It is about:
- Removing unnecessary dependencies, particularly on Google Play and OpenSSL.
- Making the system portable to WebAssembly and other constrained environments.
- Maintaining control over how and where zero-knowledge runs, ensuring the privacy it promises is not compromised by the surrounding platform.
And, last not least...
A language to create and maintain Longfellow-ZK circuits

Why a New ZK Circuit Language? The question is pertinent: there are already several ZK circuit languages: Circom, Noir, Ligetron, etc. Many are general-purpose, equipped with their own compilers and proving systems. By contrast, Longfellow-ZK is crafted manually using C++ by one of the best coders I know. This has several consequences:
- It is fast and close to the metal.
- It is difficult to read and understand for anyone who is not comfortable with template-heavy C++ and low-level cryptographic engineering.
- It is not ideal as an educational tool or as a medium for documenting architecture and design choices.
My plan is to leverage 1. and mitigate 2. and 3.
The language and compiler I am building, which I currently refer to as ZKCC, is a domain-specific language implemented on top of the original C++ code, using Lua as a direct syntax parser. Lua acts as a syntax layer and control structure, while all cryptographic and low-level primitives are provided by Longfellow-ZK’s C++ library.
ZKCC's objectives are:
- Demystify production ZK systems by exposing real circuits, not toy examples, in a language that people can easily read and understand.
- Enable education by allowing students and practitioners to learn how a functioning, deployed ZK system appears internally, rather than solely reading papers or high-level diagrams.
- Document architecture by making circuits first-class artefacts that can be versioned, commented on, and audited, instead of being hidden within C++ code paths.
- Bridge languages by mapping C++ primitives to Lua constructs, enabling experts familiar with the C++ implementation to extend it while providing a more accessible layer for application developers.
A DSL on top of Longfellow-ZK
Technically, ZKCC is a compiler for a Domain-Specific Language that directly binds to the C++ primitives used in Longfellow-ZK to build circuits and witness proofs. It offers a higher-level API that recognises:
- Circuits and sub-circuits.
- Wires, including named wires rather than only positional indices.
- Inputs and outputs, with metadata and types.
- Phases of execution: circuit generation, witness generation, proof creation, and verification.
The design principle is conservative. Every operation available in the C++ library should be accessible in ZKCC while preserving both semantics and performance. Additionally, the DSL introduces only those abstractions that simplify writing, maintaining, and auditing circuits.
An important point is that ZKCC is not a new proof system. It is a compiler and orchestration layer for an existing system with robust cryptographic foundations and published benchmarks.
Three examples as a teaser
To give a concrete sense of how this language looks, I will present three simple circuit examples: the point in showing them is not what the circuit does, but how it is written.
1: A minimal addition circuit (z = x + y)
The first example is deliberately modest: a circuit with three values, where z is public and x and y are private, and the constraint is simply z = x + y.
zkcc_small.lua
This example mirrors the structure of the original C++ Longfellow circuit-building code closely:


Here, there aren't many syntax shortcuts or fancy abstractions. The idea is to expose the underlying style: imperative, verbose, and somehow prone to the same maintenance problems as C++ when the circuit grows larger. This provides readers with an intuitive baseline for why the language requires syntactic improvements without obscuring the original model.
2: Horner’s method for polynomial evaluation
The second example moves to a slightly more complex setting: a circuit implementing Horner’s algorithm to evaluate a polynomial at a given point. This is still a simple algebraic computation, but it introduces repetition, structure and the need for a compact representation of a pattern.
zkcc_horner_expr.lua
Here, the language starts to show its added value, even beyond the simplification of C++ syntax:


Here we can see clear separation between the mathematical expression of the polynomial and the details of wire allocation. The corresponding C++ code would require repetitive and error-prone expansions of the circuit-building pattern. In Lua, the same pattern can be expressed as a reusable function, allowing:
- Easier auditing of the circuit structure.
- Parametric generation of circuits for polynomials of different degrees.
- Clearer documentation of what the circuit is supposed to compute.
This example presents ZKCC as a compiler that preserves the performance characteristics of the original system but makes repetitive circuit patterns tractable at scale.
3: Arithmetic progression sum check with named inputs
The third example presents what I currently consider the state-of-the-art design for this language: a circuit that checks the sum of an arithmetic progression with multiple inputs, using named inputs and explicit input schemas.
Conceptually, the circuit verifies that a claimed sum S corresponds to an arithmetic progression defined by the parameters a, d, and n. The constraints ensure that S matches the closed-form formula for the sum of an arithmetic progression or an equivalent iterative construction.


The example demonstrates several features that I consider crucial for production use: the circuit carries information about the inputs it accepts: names, types, perhaps ranges or other validation hints. Applications that use the circuit do not need to reverse-engineer the encoding. They can generate witnesses and encode data safely by referring to the schema.
In practice, this design facilitates long-term maintainability and reproducibility.
The language encourages a model in which the circuit knows its inputs and constraints, while the application layer decides how these inputs are serialised, transmitted, and stored. This reduces the risk of off-by-one errors and other typical mistakes when working with large arrays of anonymous wires.
Future directions
ZKCC is not meant to compete with other proof systems. It is a practical effort to create a high-performance, production-ready ZK system that is readable, auditable, and accessible to a broader community of developers and researchers, with a focus on European digital identity use cases.
If upstream Longfellow-ZK develops in a way that stays compatible with these objectives, the European build will follow and contribute. If not, the work may diverge and follow an independent path. In both cases, having a clear, expressive circuit language will help retain knowledge about how these systems function and reduce the barriers for others to scrutinise, extend, and deploy them.
The code examples provided here are merely a starting point. Once ZKCC stabilises, then more complex circuits, including the full SD-JWT flow needed in Europe, can be expressed in the same manner. The aim is to ensure that zero-knowledge in EUDI is not a black box supplied by an opaque platform, but a transparent component controlled by those who develop and maintain public digital identity infrastructures.

Right now this is a voluntary effort, encouraged by many kind and knowledgeable people including the very creators of Longfellow-ZK. My gratituge goes to Matteo Frigo and abhi shelat for the creation of this wonderful system and to Roberto Ierusalimschy and all the team of Lua developers.
In case you are at the EUDI wallet launchpad event these days, don't miss to say hello to my Forkbomb.solutions colleagues Andrea and Puria!

