Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support precompile #53

Merged
merged 5 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
/target
/verifier/data/test_circuit
/test-vectors/mips
target
verifier/data/test_circuit
test-vectors/mips
push.sh
mips-zkm-zkvm-elf
libsnark.h
libsnark.so
*.log
Cargo.lock
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"host-program/sha2-rust",
"host-program/revme",
"host-program/mem-alloc-vec",
"host-program/sha2-precompile",
"sdk"
]
resolver = "2"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Please refer to [this](guest-program/README.md) guide.
```sh
cd zkm-project-template
sh sdk/src/local/libsnark/compile.sh # compile snark library
cargo build --release # build host programs
cargo build --release # build host programs
```

If successfully, it will generate the binary files in `target/release`/{`sha2-rust` ,`sha2-go` ,`revme`, `mem-alloc-vec`}
Expand Down Expand Up @@ -114,7 +114,7 @@ The result proof and contract file will be in the contracts/verifier and contrac

> The proving task requires several stages: queuing, splitting, proving, aggregating and finalizing. Each stage involves a varying duration.

Must set the `PRIVATE_KEY` and `ZKM_PROVER=network` in [`run-proving.sh`](host-program/run-proving.sh) and run the program:
Must set the `PROOF_NETWORK_PRVKEY` and `ZKM_PROVER=network` in [`run-proving.sh`](host-program/run-proving.sh) and run the program:

```sh
./run-proving.sh sha2-rust
Expand Down
9 changes: 9 additions & 0 deletions guest-program/sha2-precompile/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[workspace]
[package]
version = "0.1.0"
name = "sha2-precompile"
edition = "2021"

[dependencies]
zkm-runtime = { git = "https://github.com/zkMIPS/zkm.git"}
sha2 = { version = "0.10.8", default-features = false }
24 changes: 24 additions & 0 deletions guest-program/sha2-precompile/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![no_std]
#![no_main]

use sha2::{Digest, Sha256};
extern crate alloc;
use alloc::vec::Vec;

zkm_runtime::entrypoint!(main);

pub fn main() {
let public_input: Vec<u8> = zkm_runtime::io::read();
let input: [u8; 32] = zkm_runtime::io::read();
let elf_id: Vec<u8> = zkm_runtime::io::read();

zkm_runtime::io::verify(elf_id, &input);
let mut hasher = Sha256::new();
hasher.update(input.to_vec());
let result = hasher.finalize();

let output: [u8; 32] = result.into();
assert_eq!(output.to_vec(), public_input);

zkm_runtime::io::commit::<[u8; 32]>(&output);
}
53 changes: 26 additions & 27 deletions host-program/mem-alloc-vec/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ use anyhow::Result;
use std::env;
use std::fs::read;
use std::time::Instant;
use zkm_sdk::{prover::ClientCfg, prover::ProverInput, ProverClient};

pub const DEFAULT_PROVER_NETWORK_RPC: &str = "https://152.32.186.45:20002";
pub const DEFALUT_PROVER_NETWORK_DOMAIN: &str = "stage";
use zkm_sdk::{is_local_prover, prover::ClientCfg, prover::ProverInput, ProverClient};

#[tokio::main]
async fn main() -> Result<()> {
Expand All @@ -29,42 +26,44 @@ async fn main() -> Result<()> {
let elf_path = env::var("ELF_PATH").unwrap_or(env!("GUEST_TARGET_PATH").to_string());
let proof_results_path = env::var("PROOF_RESULTS_PATH").unwrap_or("../contracts".to_string());
let vk_path = env::var("VERIFYING_KEY_PATH").unwrap_or("/tmp/input".to_string());
let zkm_prover_type = env::var("ZKM_PROVER").expect("ZKM PROVER is missing");

//network proving
let endpoint = env::var("ENDPOINT").unwrap_or(DEFAULT_PROVER_NETWORK_RPC.to_string());
// network proving
let endpoint = env::var("ENDPOINT").unwrap_or("".to_string());
let ca_cert_path = env::var("CA_CERT_PATH").unwrap_or("".to_string());
let cert_path = env::var("CERT_PATH").unwrap_or("".to_string());
let key_path = env::var("KEY_PATH").unwrap_or("".to_string());
let domain_name = env::var("DOMAIN_NAME").unwrap_or(DEFALUT_PROVER_NETWORK_DOMAIN.to_string());
let private_key = env::var("PRIVATE_KEY").unwrap_or("".to_string());
let zkm_prover_type = env::var("ZKM_PROVER").expect("ZKM PROVER is missing");
let domain_name = env::var("DOMAIN_NAME").unwrap_or("".to_string());
let private_key = env::var("PROOF_NETWORK_PRVKEY").unwrap_or("".to_string());

let client_config: ClientCfg = ClientCfg {
zkm_prover: zkm_prover_type.to_owned(),
endpoint: Some(endpoint),
ca_cert_path: Some(ca_cert_path),
cert_path: Some(cert_path),
key_path: Some(key_path),
domain_name: Some(domain_name),
private_key: Some(private_key),
vk_path: vk_path.to_owned(),
};
let mut client_config: ClientCfg =
ClientCfg::new(zkm_prover_type.to_owned(), vk_path.to_owned());

if !is_local_prover(&zkm_prover_type) {
client_config.set_network(
endpoint,
ca_cert_path,
cert_path,
key_path,
domain_name,
private_key,
);
}

let prover_client = ProverClient::new(&client_config).await;
log::info!("new prover client,ok.");

let prover_input = ProverInput {
elf: read(elf_path).unwrap(),
public_inputstream: vec![],
private_inputstream: vec![],
seg_size,
execute_only,
..Default::default()
};

//If the guest program does't have inputs, it does't need the set_guest_input().
//set_guest_input(&mut prover_input, None);
// If the guest program does't have inputs, it does't need the set_guest_input().
// set_guest_input(&mut prover_input, None);

//excuting the setup_and_generate_sol_verifier
// excuting the setup_and_generate_sol_verifier
if setup_flag {
match prover_client
.setup_and_generate_sol_verifier(&zkm_prover_type, &vk_path, &prover_input)
Expand All @@ -83,7 +82,7 @@ async fn main() -> Result<()> {
match proving_result {
Ok(Some(prover_result)) => {
if !execute_only {
//excute the guest program and generate the proof
// excute the guest program and generate the proof
prover_client
.process_proof_results(
&prover_result,
Expand All @@ -93,8 +92,8 @@ async fn main() -> Result<()> {
)
.expect("Process proof results false");
} else {
//only excute the guest program without generating the proof.
//the mem-alloc-vec guest program doesn't have output messages.
// only excute the guest program without generating the proof.
// the mem-alloc-vec guest program doesn't have output messages.
prover_client
.print_guest_execution_output(false, &prover_result)
.expect("Print guest program excution's output false.");
Expand Down
51 changes: 25 additions & 26 deletions host-program/revme/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ use anyhow::Result;
use std::env;
use std::fs::read;
use std::time::Instant;
use zkm_sdk::{prover::ClientCfg, prover::ProverInput, ProverClient};

pub const DEFAULT_PROVER_NETWORK_RPC: &str = "https://152.32.186.45:20002";
pub const DEFALUT_PROVER_NETWORK_DOMAIN: &str = "stage";
use zkm_sdk::{is_local_prover, prover::ClientCfg, prover::ProverInput, ProverClient};

#[tokio::main]
async fn main() -> Result<()> {
Expand All @@ -30,42 +27,44 @@ async fn main() -> Result<()> {
let json_path = env::var("JSON_PATH").expect("JSON PATH is missing");
let proof_results_path = env::var("PROOF_RESULTS_PATH").unwrap_or("../contracts".to_string());
let vk_path = env::var("VERIFYING_KEY_PATH").unwrap_or("/tmp/input".to_string());
let zkm_prover_type = env::var("ZKM_PROVER").expect("ZKM PROVER is missing");

//network proving
let endpoint = env::var("ENDPOINT").unwrap_or(DEFAULT_PROVER_NETWORK_RPC.to_string());
// network proving
let endpoint = env::var("ENDPOINT").unwrap_or("".to_string());
let ca_cert_path = env::var("CA_CERT_PATH").unwrap_or("".to_string());
let cert_path = env::var("CERT_PATH").unwrap_or("".to_string());
let key_path = env::var("KEY_PATH").unwrap_or("".to_string());
let domain_name = env::var("DOMAIN_NAME").unwrap_or(DEFALUT_PROVER_NETWORK_DOMAIN.to_string());
let private_key = env::var("PRIVATE_KEY").unwrap_or("".to_string());
let zkm_prover_type = env::var("ZKM_PROVER").expect("ZKM PROVER is missing");
let domain_name = env::var("DOMAIN_NAME").unwrap_or("".to_string());
let private_key = env::var("PROOF_NETWORK_PRVKEY").unwrap_or("".to_string());

let client_config: ClientCfg = ClientCfg {
zkm_prover: zkm_prover_type.to_owned(),
endpoint: Some(endpoint),
ca_cert_path: Some(ca_cert_path),
cert_path: Some(cert_path),
key_path: Some(key_path),
domain_name: Some(domain_name),
private_key: Some(private_key),
vk_path: vk_path.to_owned(),
};
let mut client_config: ClientCfg =
ClientCfg::new(zkm_prover_type.to_owned(), vk_path.to_owned());

if !is_local_prover(&zkm_prover_type) {
client_config.set_network(
endpoint,
ca_cert_path,
cert_path,
key_path,
domain_name,
private_key,
);
}

let prover_client = ProverClient::new(&client_config).await;
log::info!("new prover client,ok.");

let mut prover_input = ProverInput {
elf: read(elf_path).unwrap(),
public_inputstream: vec![],
private_inputstream: vec![],
seg_size,
execute_only,
..Default::default()
};

//If the guest program does't have inputs, it does't need the setting.
// If the guest program does't have inputs, it does't need the setting.
set_guest_input(&mut prover_input, Some(&json_path));

//excuting the setup_and_generate_sol_verifier
// excuting the setup_and_generate_sol_verifier
if setup_flag {
match prover_client
.setup_and_generate_sol_verifier(&zkm_prover_type, &vk_path, &prover_input)
Expand All @@ -84,7 +83,7 @@ async fn main() -> Result<()> {
match proving_result {
Ok(Some(prover_result)) => {
if !execute_only {
//excute the guest program and generate the proof
// excute the guest program and generate the proof
prover_client
.process_proof_results(
&prover_result,
Expand All @@ -94,8 +93,8 @@ async fn main() -> Result<()> {
)
.expect("process proof results error");
} else {
//only excute the guest program without generating the proof.
//the revme guest program doesn't have outputs messages.
// only excute the guest program without generating the proof.
// the revme guest program doesn't have outputs messages.
prover_client
.print_guest_execution_output(false, &prover_result)
.expect("print guest program excution's output false.");
Expand Down
7 changes: 5 additions & 2 deletions host-program/run-proving.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ export SETUP_FLAG=false

##network proving
export CA_CERT_PATH=${BASEDIR}/tool/ca.pem
export PRIVATE_KEY= ##The private key corresponding to the public key when registering in the https://www.zkm.io/apply
export PROOF_NETWORK_PRVKEY= ##The private key corresponding to the public key when registering in the https://www.zkm.io/apply
export ENDPOINT=https://152.32.186.45:20002 ##the test entry of zkm proof network
export DOMAIN_NAME=stage

echo "Compile guest-program ${program}"
if [[ "$program" =~ .*go$ ]];then
Expand All @@ -33,7 +34,9 @@ fi
if [ "$program" == "sha2-rust" ];then
export SEG_SIZE=65536
elif [ "$program" == "mem-alloc-vec" ];then
export SEG_SIZE=65536
export SEG_SIZE=65536
elif [ "$program" == "sha2-precompile" ];then
export SEG_SIZE=16384
fi

echo "SEG_SIZE:$SEG_SIZE"
Expand Down
44 changes: 21 additions & 23 deletions host-program/sha2-go/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ use serde::{Deserialize, Serialize};
use std::env;
use std::fs::read;
use std::time::Instant;
use zkm_sdk::{prover::ClientCfg, prover::ProverInput, ProverClient};

pub const DEFAULT_PROVER_NETWORK_RPC: &str = "https://152.32.186.45:20002";
pub const DEFALUT_PROVER_NETWORK_DOMAIN: &str = "stage";
use zkm_sdk::{is_local_prover, prover::ClientCfg, prover::ProverInput, ProverClient};

const GUEST_TARGET_PATH: &str = concat!(
env!("CARGO_MANIFEST_DIR"),
Expand All @@ -33,45 +30,46 @@ async fn main() -> Result<()> {

let elf_path = env::var("ELF_PATH").unwrap_or(GUEST_TARGET_PATH.to_string());
let args_parameter = env::var("ARGS").unwrap_or("data-to-hash".to_string());
//let json_path = env::var("JSON_PATH").expect("JSON PATH is missing");
let proof_results_path = env::var("PROOF_RESULTS_PATH").unwrap_or("../contracts".to_string());
let vk_path = env::var("VERIFYING_KEY_PATH").unwrap_or("/tmp/input".to_string());

//network proving
let endpoint = env::var("ENDPOINT").unwrap_or(DEFAULT_PROVER_NETWORK_RPC.to_string());
// network proving
let endpoint = env::var("ENDPOINT").unwrap_or("".to_string());
let ca_cert_path = env::var("CA_CERT_PATH").unwrap_or("".to_string());
let cert_path = env::var("CERT_PATH").unwrap_or("".to_string());
let key_path = env::var("KEY_PATH").unwrap_or("".to_string());
let domain_name = env::var("DOMAIN_NAME").unwrap_or(DEFALUT_PROVER_NETWORK_DOMAIN.to_string());
let private_key = env::var("PRIVATE_KEY").unwrap_or("".to_string());
let domain_name = env::var("DOMAIN_NAME").unwrap_or("".to_string());
let private_key = env::var("PROOF_NETWORK_PRVKEY").unwrap_or("".to_string());
let zkm_prover_type = env::var("ZKM_PROVER").expect("ZKM PROVER is missing");

let client_config: ClientCfg = ClientCfg {
zkm_prover: zkm_prover_type.to_owned(),
endpoint: Some(endpoint),
ca_cert_path: Some(ca_cert_path),
cert_path: Some(cert_path),
key_path: Some(key_path),
domain_name: Some(domain_name),
private_key: Some(private_key),
vk_path: vk_path.to_owned(),
};
let mut client_config: ClientCfg =
ClientCfg::new(zkm_prover_type.to_owned(), vk_path.to_owned());

if !is_local_prover(&zkm_prover_type) {
client_config.set_network(
endpoint,
ca_cert_path,
cert_path,
key_path,
domain_name,
private_key,
);
}

let prover_client = ProverClient::new(&client_config).await;
log::info!("new prover client,ok.");

let mut prover_input = ProverInput {
elf: read(elf_path).unwrap(),
public_inputstream: vec![],
private_inputstream: vec![],
seg_size,
execute_only,
..Default::default()
};

//If the guest program does't have inputs, it does't need the setting.
// If the guest program does't have inputs, it does't need the setting.
set_guest_input(&mut prover_input, Some(&args_parameter));

//excuting the setup_and_generate_sol_verifier
// excuting the setup_and_generate_sol_verifier
if setup_flag {
match prover_client
.setup_and_generate_sol_verifier(&zkm_prover_type, &vk_path, &prover_input)
Expand Down
24 changes: 24 additions & 0 deletions host-program/sha2-precompile/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "sha2-precompile"
version = "0.1.0"
edition = "2021"


[dependencies]
zkm-sdk = { path = "../../sdk", features = ["snark"] }
bincode = "1.3.3"
sha2 = { version = "0.10.8", default-features = false }

tokio = { version = "1.21.0", features = ["macros", "rt-multi-thread", "signal"] }
#ethers = "2.0.14"

log = { version = "0.4.14", default-features = false }
anyhow = "1.0.75"
env_logger = "0.10.0"

[build-dependencies]
tonic-build = "0.8.0"
zkm-build = { git = "https://github.com/zkMIPS/zkm", branch = "main", default-features = false }

[features]
test = []
Loading
Loading