Skip to content

izzetemredemir/zkRust

 
 

Repository files navigation

zkRust

zkRust is a CLI tool to simplify the developing applications in Rust using zkVM's such as SP1 or Risc0.

zkRust seeks to simplify the development experience of developing using zkVM's and enable developers by providing the choice of which zkVM they would like to develop with and eliminating redundancy in the Zk Application development process.

Installation:

First make sure Rust is installed on your machine. Then install the zkVM toolchains from risc0 and sp1 by running:

make install

zkRust can then be installed directly by downloading the latest release binaries.

curl -L https://raw.githubusercontent.com/yetanotherco/zkRust/main/install_zkrust.sh | bash

Quickstart

To get started you can create a workspace for your project in zkRust by running:

cargo new <PROGRAM_DIRECTORY>

It's that simple.

You can test zkRust for any of the examples in the examples folder. This include programs for:

  • Computing and reading the results of computing Fibonacci numbers.
  • Performing RSA key verification.
  • Performing ECDSA program.
  • a blockchain state diff program verification.
  • Computing the Sha256 hash of a value.
  • Verifying a tendermint block.
  • Interacting with a user to answer a quiz.

Run one of the following commands to test zkRust. You can choose either Risc0 or SP1:

Fibonacci:

make prove_risc0_fibonacci
make prove_sp1_fibonacci

RSA:

make prove_risc0_rsa
make prove_sp1_rsa

ECDSA:

make prove_risc0_ecdsa
make prove_sp1_ecdsa

Blockchain state diff:

make prove_risc0_json
make prove_sp1_json

Blockchain state diff:

make prove_risc0_json
make prove_sp1_json

Regex:

make prove_risc0_regex
make prove_sp1_regex

Sha:

make prove_risc0_sha
make prove_sp1_sha

Tendermint:

make prove_risc0_tendermint
make prove_sp1_tendermint

Zk Quiz:

make prove_risc0_zkquiz
make prove_sp1_zkquiz

Usage:

To use zkRust, To use zkRust users specify a fn main() whose execution is proven within the zkVM. This function must be defined within a main.rs file in a directory with the following structure:

.
└── <PROGRAM_DIRECTORY>
    ├── Cargo.toml
    └── src
        └── main.rs

For more complex projects can define a separate library folder for your use.

.
└── <PROGRAM_DIRECTORY>
    ├── Cargo.toml
    ├── lib/
    └── src
        └── main.rs

The user may also define a input(), output(), in addition to the main(). The fn input() and fn output() function which defines code that runs outside of the zkVM before and after the VM executes. The input() function executes before the zkVM code is executed and allows the user to define inputs passed to the vm such as a deserialized Tx or data fetched from an external source at runtime. Within the main() (guest) function the user may write information from the computation performed in the zkVM to an output buffer to be used after proof generation. The output() defines code that allows the user to read the information written to that buffer of the and perform post-processing of that data.

The user may specify inputs into the VM (guest) code using zk_rust_io::write() as long on the type of rust object they are writing implements Serializable. Within there main() function (guest) the user may read in the inputs by specifying zk_rust_io::read() and output data computed during the execution phase of the code within the VM (guest) program by specifying zk_rust_io::commit(). To read the output of the output of the VM (guest) program you declare zk_rust_io::out(). The zk_rust_io crate defines function headers that are not inlined and are purely used as compile time symbols to ensure a user can compile there rust code before running it within one of the zkVM available in zkRust.

To use the I/O imports import the zk_rust_io crate by adding the following to the Cargo.toml in your project directory.

zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git", version = "v0.1.0" }

input.rs

use zk_rust_io;

pub fn input() {
    let pattern = "a+".to_string();
    let target_string = "an era of truth, not trust".to_string();

    // Write in a simple regex pattern.
    zk_rust_io::write(&pattern);
    zk_rust_io::write(&target_string);
}

main.rs

use regex::Regex;
use zk_rust_io;

pub fn main() {
    // Read two inputs from the prover: a regex pattern and a target string.
    let pattern: String = zk_rust_io::read();
    let target_string: String = zk_rust_io::read();

    // Try to compile the regex pattern. If it fails, write `false` as output and return.
    let regex = match Regex::new(&pattern) {
        Ok(regex) => regex,
        Err(_) => {
            panic!("Invalid regex pattern");
        }
    };

    // Perform the regex search on the target string.
    let result = regex.is_match(&target_string);

    // Write the result (true or false) to the output.
    zk_rust_io::commit(&result);
}

output.rs

use zk_rust_io;

pub fn output() {
    // Read the output.
    let res: bool = zk_rust_io::out();
    println!("res: {}", res);
}

//NOTE ADD ANNOTATION ABOUT WRITTEN AND READING FROM BUFFER IN ONE call -> Otherwise issues.

To generate a proof of the execution of your code run the following:

  • SP1:
    cargo run --release -- prove-sp1 <PROGRAM_DIRECTORY_PATH> .
  • Risc0:
    cargo run --release -- prove-risc0  <PROGRAM_DIRECTORY_PATH> .
    Make sure to have Risc0 installed with version v1.0.1

To generate your proof and send it to Aligned. First generate a local wallet keystore using `cast.

cast wallet new-mnemonic

Then you can import your created keystore using:

cast wallet import --interactive <PATH_TO_KEYSTORE.json>

Finally, to generate and send your proof of your programs execution to aligned use the zkRust CLI with the --submit-to-aligned-with-keystore flag.

cargo run --release -- prove-sp1 --submit-to-aligned-with-keystore <PATH_TO_KEYSTORE> <PROGRAM_DIRECTORY_PATH .

Flags

  • --submit_to_aligned: Sends the proof to be verified on Aligned after proof generation. Requires an rpc url and keystore for a funded wallet specified via the --rpc-url and --key_store flags.

  • --keystore_path: Path to the keystore of the users wallet. Defaults to ~/keystore.

  • --rpc-url: Specify the rpc-url used for the user eth rpc-url. Defaults to https://ethereum-holesky-rpc.publicnode.com.

  • --chain_id: Chain ID number of the ethereum chain Aligned is deployed on. Defaults to 1700.

  • --precompiles: Enables in acceleration via precompiles for supported zkVM's. Specifying this flag allows for VM specific speedups for specific expensive operations such as SHA256, SHA3, bigint multiplication, and ed25519 signature verification. By specifying this flag proving operations for specific operations within the following rust crates are accelerated:

    • SP1:

      • sha2 v0.10.6
      • sha3 v0.10.8
      • crypto-bigint v0.5.5
      • tiny-keccak v2.0.2
      • ed25519-consensus v2.1.0
      • ecdsa-core v0.16.9
    • Risc0:

      • sha2 v0.10.6
      • k256 v0.13.1
      • crypto-bigint v0.5.5

NOTE: for the precompiles to be included within the compilation step the crate version you are using must match the crate version above.

Acknowledgments:

ZK Rust was intended and designed as a tool to make development on programs that use zkVM's easier and reduce deduplication of code for developers that want to experiment with zk on aligned layer. We want the work and contributions of the SP1 and Risc0 teams to the field of Zero Knowledge Cryptography.

SP1

Risc0

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 90.6%
  • Shell 5.6%
  • Makefile 3.8%