Use Case: Program Execution
Introduction
As this walkthrough describes a more advanced use case for the zkVM, we recommend reviewing both the SDK Quick Start and the simpler Stable Matching walkthrough first.
By design, a zkVM proves the correctness of a program’s execution. However, a more advanced use case arises when the program to be proven is not the code running directly in the zkVM, but is instead provided as input to the zkVM. In this case, the zkVM executes an interpreter as its guest program, which then reads, interprets, and runs the input program inside the zkVM. This effectively allows the zkVM to generate a proof for the execution of arbitrary, dynamically supplied programs.
Consider the following guest program in which program_to_be_proven
is nested inside as input to the zkVM
At first glance, this pattern may seem redundant—why not just run program_to_be_proven
directly as the guest program? However, this level of indirection unlocks powerful capabilities that significantly expand the utility of the zkVM.
Enabling Private Program Execution
The first benefit, illustrated by the example above, is the ability to treat the program to be proven as a private input. This allows the zkVM to prove the execution of programs without revealing their source, making it possible to build private smart contracts on-chain.
By comparing the program’s digest to a public input, verifiers can still check meaningful properties — such as:
- Consistency of the private program across multiple invocations
- Conformance to a known, audited version without exposing implementation details
This digest check enables trust minimization while preserving privacy.
Generalization Across Programs with a Single zkVM Binary
A second, more technical benefit is that this structure enables the zkVM to handle a wide range of programs through a single, fixed guest binary — the interpreter.
With careful planning around memory constraints (e.g. stack, heap, and output size bounds), this pattern allows:
- Shared proving key / public parameter reuse across many programs, which can simplify definitions for non-transparent provers which may require per-program setup
- Simplified deployment pipelines for applications/smart contracts verifying zkVM proofs on-chain
- Easier management of systems using non-transparent proving systems, which often require per-program setup (though note: the
Stwo
prover used here is transparent)_
This approach decouples the proving circuit from individual guest programs, significantly improving composability and maintainability.
The Lambda Calculus Model
Instead of working through this design at the full complexity of the RISC-V32i instruction set, we will work through a simpler example of the core concept using a much more fundamental computational model: the lambda calculus.
Implementation
To start, we will follow along with the SDK Quick Start. After installing the zkVM, we run:
to initialize the host and guest programs. We begin by creating a shared library for the guest and host program, which we’ll locate within the guest program crate.
Shared Library
The first part of the library will define terms in the calculus:
This code block defines an Enum
of the possible Term
s available: an indexed Var
, a Lambda
function definition, and an Apply
function application, as well as some useful trait implementations for constructing and debugging. In the rest of the library, we’ll define full expressions in the calculus, which amount to programs that are “executed” via reduction.
The implementation also includes various trait implementations as well as both individual step
and iterative eval
routines that reduce the statement into a stable form.
In order to make our common library work across both the host and guest, we have a few quick steps we need to handle. First, we need to update the guest crate to depend on serde
, which the library uses for serializing and deserializing the Expr
structs to and from the zkVM:
Next, we need to export the common code as a Rust library.
And lastly we need to make this library visible to the host program.
Guest Program
Returning to the guest program, as an Expr
is a program in the lambda calculus, we can now implement our (dead simple) interpreter — for simplicity, we omit any hash-based consistency checking:
Host Program
Here we create a suitable host program that invokes the guest using the private program:
Verification
Meanwhile, as desired verification does not require any access to the private program:
In this way, we are able to use the zkVM to prove the correctness of executing a private program.
Conclusion
Through this walkthrough, we have successfully demonstrated how the Nexus zkVM can be applied to fundamental computational models, showcasing its versatility beyond practical applications. We accomplished our goal of proving the correct execution of lambda calculus programs while keeping the program logic completely private.
The key achievements of this implementation include: (1) a shared library architecture that enables code reuse between guest and host programs, (2) a clean abstraction for lambda calculus expressions with evaluation semantics, (3) a zkVM-based interpreter that generates proofs for program execution, and (4) a verification system that confirms correctness without exposing the original program.
This lambda calculus example illustrates several important principles about zkVM applications.
First, it demonstrates that zkVMs can handle abstract computational models, not just concrete algorithms. The ability to prove correct evaluation of lambda expressions opens possibilities for verifying functional programming languages, theorem provers, and symbolic computation systems.
Second, this walkthrough shows how the same privacy-preserving verification principles from our stable matching example apply to entirely different domains. Whether proving the correctness of medical residency assignments or lambda calculus reductions, the zkVM provides the same fundamental guarantee: mathematical proof of correct execution without revealing sensitive inputs.
Finally, the simplicity of this implementation—requiring just a few dozen lines of code—highlights how accessible zkVM technology has become for researchers and developers. Complex theoretical concepts like lambda calculus evaluation can be made verifiable with minimal overhead, enabling new possibilities for transparent yet private computation in academic research, compiler verification, and programming language development.
This approach transforms program execution from a “trust the interpreter” model to a “verify the computation” model, providing mathematical assurance that programs are evaluated correctly according to their formal semantics. The same principles demonstrated here extend to any computational model where execution correctness matters but program privacy must be preserved.