Tutorial: Rust via Docker
Last updated
Last updated
This is a tutorial on setting up and using the Dockerized Valida zk-VM stack to write a Rust program, compile it to Valida, and provide its execution. The Valida Compiler Toolchain and Valida zk-VM pages provide the same information about the stack, in a more concise and complete reference-style format. You can safely skip this tutorial if you prefer that style of presentation, since there is no information about the stack which is contained in this tutorial and nowhere else.
This section covers the following steps:
Install the toolchain via Docker.
Clone the Rust project template.
Validate that the installation is working correctly.
You can see all of the steps in this section performed in this video demo:
First make sure that your system meets the requirements for following this tutorial. You will need a system which can run Docker containers. Your user will need to be part of the docker
group. You will need at least 10 GB of free space on your filesystem.
To install the toolchain as a Docker image, run:
To clone the Rust project template, run:
Follow the steps in this section to ensure that the toolchain is working correctly on your machine. After performing the above steps, cd
into the template project:
Next, enter the Docker container:
From within the Docker container, build the template project:
Next, run the template project:
You should see a prompt that looks like this:
Enter a number between 0 and 46, and press enter. At this point, the program should print the answer and exit. For example:
At this point, you have validated that the toolchain is working on your system. You have also demonstrated how to compile a Rust program to a Valida executable, and run it on the zk-VM.
In the previous steps, you cloned the fibonacci
template project. This contains a single Rust source file, src/main.rs
. This is roughly what it should look like if you open it up in a text editor:
This program computes an element of the Fibonacci sequence based on user input. Here are some to observe about this program:
This program begins with #![no_main]
. This is a pragma indicating to the Rust compiler that this program has a non-standard entry point. It prevents the Rust compiler from emitting the standard boilerplate entry point which calls the standard main
function. This is required because Valida does not currently support a main
function which takes arguments. Every Valida Rust program must contain this #![no_main]
pragma in its entry point (main.rs
) file.
The #[no_mangle]
pragma on the main
function turns off name mangling for this function, allowing it to be linked properly with the program entry point.
The main
function uses valida_rs::io::read_line::<u8>
to read a number from standard in, in lieu of Rust standard library I/O functions.
Let's delete the application-specific logic from this file, in order to come up with a generic starting point for the project:
Let's create a program which proves knowledge of the prime factorization of a 32-bit unsigned integer.
This tutorial demonstrates that multi-file Rust projects are supported by the Valida toolchain. We create a new file, call it src/lib.rs
, which we fill with the following contents:
This module defines three functions: read_number
, check_prime_factorization
, and is_prime
. Here is what each of these functions does:
The read_number
function attempts to read an unsigned 32-bit integer from the input tape. If it fails to do so, it outputs an error message and again attempts to read an unsigned integer, continuing until it succeeds.
The check_prime_factorization
function checks that ys
is a prime factorization of x
, outputting true
if this is the case and false
otherwise.
The is_prime
function outputs true
if x
is a prime number, and false
otherwise.
Next, we'll edit the src/main.rs
file so that it looks like this:
This modifies the template src/main.rs
file by adding imports from src/lib.rs
and populating the main
function. The new main
function reads a 32-bit number x
, followed by its number of prime factors, and then each of its prime factors. It then checks whether the claimed prime factors are in fact the prime factors of x
, providing output which indicates whether or not this is the case.
Let's rename the project so that it is no longer called fibonacci
. First open the Cargo.toml
file in the root folder of the project. You should see something like this:
Edit the line name = "fibonacci"
to read instead name = "prime_factorization"
.
To build the program to run on Valida, simply run:
To run the program:
You will get a series of prompts. Here is an example interaction with this program:
At this point, the output of the program will have been written to log
. To prove an execution of the program, run:
You will again get a series of prompts, which you should respond to in the same way. The result should be that a proof of that execution is written to proof
. You can verify this proof as follows: