feat: Add ere-zisk with only compile and execute utility. (#27)

* feat: add `ere-zisk` and `compile` functionality

* fix: use `FixintEncoding` for `Input::as_bytes` to make it deterministic

* feat: implement `zkVM::execute`

* fix: make `install_zisk_sdk.sh` work with docker

* chore: add comment why use `#[should_panic]`

* feat: use command `cargo-zisk ...` for `compile`, `execute`, `prove` and `verify`

* ci

* fix: invalid proof
This commit is contained in:
Han
2025-05-28 15:49:04 +01:00
committed by GitHub
parent d106f8d65c
commit 5b5a012e26
16 changed files with 777 additions and 68 deletions

View File

@@ -1,36 +1,36 @@
name: Check ZisK Docker Image
# on:
# push:
# branches:
# - master
# pull_request:
# branches:
# - master
# workflow_dispatch:
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
# jobs:
# build_zisk_image:
# name: Build ZisK Docker Image
# runs-on: ubuntu-latest
jobs:
build_zisk_image:
name: Build ZisK Docker Image
runs-on: ubuntu-latest
# steps:
# - name: Checkout repository
# uses: actions/checkout@v4
steps:
- name: Checkout repository
uses: actions/checkout@v4
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# - name: Build dependent Docker base image
# run: |
# docker build \
# --file docker/base/Dockerfile.base \
# --tag ere-base:latest \
# .
- name: Build dependent Docker base image
run: |
docker build \
--file docker/base/Dockerfile.base \
--tag ere-base:latest \
.
# - name: Build ZisK Docker image
# run: |
# docker build \
# --file docker/zisk/Dockerfile \
# --tag ere-builder-zisk-check:latest \
# .
- name: Build ZisK Docker image
run: |
docker build \
--file docker/zisk/Dockerfile \
--tag ere-builder-zisk-check:latest \
.

21
Cargo.lock generated
View File

@@ -1193,7 +1193,7 @@ dependencies = [
"bitflags 2.9.0",
"cexpr",
"clang-sys",
"itertools 0.10.5",
"itertools 0.11.0",
"log",
"prettyplease",
"proc-macro2",
@@ -2630,6 +2630,19 @@ dependencies = [
"zkvm-interface",
]
[[package]]
name = "ere-zisk"
version = "0.1.0"
dependencies = [
"bincode",
"serde",
"tempfile",
"thiserror 2.0.12",
"toml",
"tracing",
"zkvm-interface",
]
[[package]]
name = "errno"
version = "0.3.11"
@@ -2637,7 +2650,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -7142,7 +7155,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
dependencies = [
"anyhow",
"itertools 0.10.5",
"itertools 0.11.0",
"proc-macro2",
"quote",
"syn 2.0.101",
@@ -7235,7 +7248,7 @@ dependencies = [
"once_cell",
"socket2",
"tracing",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]

View File

@@ -8,6 +8,7 @@ members = [
"crates/ere-openvm",
"crates/ere-pico",
"crates/ere-jolt",
"crates/ere-zisk",
]
resolver = "2"

View File

@@ -0,0 +1,19 @@
[package]
name = "ere-zisk"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
[dependencies]
zkvm-interface = { workspace = true }
thiserror = "2"
toml = "0.8"
tracing = "0.1"
tempfile = "3.3"
serde = { version = "1.0", features = ["derive"] }
bincode = "1.3"
[lib]
name = "ere_zisk"
path = "src/lib.rs"

View File

@@ -0,0 +1,158 @@
use crate::error::CompileError;
use std::{
fs,
path::{Path, PathBuf},
process::Command,
};
use toml::Value as TomlValue;
use tracing::info;
/// Compile the guest crate and return raw ELF bytes.
pub fn compile_zisk_program(program_crate_path: &Path) -> Result<PathBuf, CompileError> {
info!("Compiling ZisK program at {}", program_crate_path.display());
if !program_crate_path.exists() || !program_crate_path.is_dir() {
return Err(CompileError::InvalidProgramPath(
program_crate_path.to_path_buf(),
));
}
let guest_manifest_path = program_crate_path.join("Cargo.toml");
if !guest_manifest_path.exists() {
return Err(CompileError::CargoTomlMissing {
program_dir: program_crate_path.to_path_buf(),
manifest_path: guest_manifest_path.clone(),
});
}
// ── read + parse Cargo.toml ───────────────────────────────────────────
let manifest_content =
fs::read_to_string(&guest_manifest_path).map_err(|e| CompileError::ReadFile {
path: guest_manifest_path.clone(),
source: e,
})?;
let manifest_toml: TomlValue =
manifest_content
.parse::<TomlValue>()
.map_err(|e| CompileError::ParseCargoToml {
path: guest_manifest_path.clone(),
source: e,
})?;
let program_name = manifest_toml
.get("package")
.and_then(|p| p.get("name"))
.and_then(|n| n.as_str())
.ok_or_else(|| CompileError::MissingPackageName {
path: guest_manifest_path.clone(),
})?;
info!("Parsed program name: {program_name}");
// ── build ─────────────────────────────────────────────────────────────
let status = Command::new("cargo-zisk")
.current_dir(program_crate_path)
.args(["build", "--release"])
.status()
.map_err(|e| CompileError::CargoZiskBuild {
cwd: program_crate_path.to_path_buf(),
source: e,
})?;
if !status.success() {
return Err(CompileError::CargoZiskBuildFailed {
status,
path: program_crate_path.to_path_buf(),
});
}
let elf_path = program_crate_path
.join("target")
.join("riscv64ima-zisk-zkvm-elf")
.join("release")
.join(program_name);
let elf_path = elf_path
.canonicalize()
.map_err(|e| CompileError::ElfNotFound {
path: elf_path,
source: e,
})?;
// FIXME: This currently uses global build directory `${HOME}/.zisk/zisk/emulator-asm`
// which causes `compile_zisk_program` to panic if ran in parallel.
// We should create a temporary directory and copy only necessary
// data to setup each ELF.
let status = Command::new("cargo-zisk")
.current_dir(program_crate_path)
.arg("rom-setup")
.arg("-e")
.arg(&elf_path)
.status()
.map_err(|e| CompileError::CargoZiskRomSetup { source: e })?;
if !status.success() {
return Err(CompileError::CargoZiskRomSetupFailed {
status,
path: program_crate_path.to_path_buf(),
});
}
Ok(elf_path)
}
#[cfg(test)]
mod tests {
use zkvm_interface::Compiler;
use crate::RV64_IMA_ZISK_ZKVM_ELF;
use super::*;
use std::path::PathBuf;
// TODO: for now, we just get one test file
// TODO: but this should get the whole directory and compile each test
fn get_compile_test_guest_program_path() -> PathBuf {
let workspace_dir = env!("CARGO_WORKSPACE_DIR");
PathBuf::from(workspace_dir)
.join("tests")
.join("zisk")
.join("compile")
.join("basic")
.canonicalize()
.expect("Failed to find or canonicalize test guest program at <CARGO_WORKSPACE_DIR>/tests/compile/zisk")
}
#[test]
fn test_compile_zisk_program() {
let test_guest_path = get_compile_test_guest_program_path();
match compile_zisk_program(&test_guest_path) {
Ok(elf_path) => {
assert!(
fs::metadata(elf_path).unwrap().len() != 0,
"ELF bytes should not be empty."
);
}
Err(e) => {
panic!("compile failed for dedicated guest: {e:?}");
}
}
}
#[test]
fn test_compile_trait() {
let test_guest_path = get_compile_test_guest_program_path();
match RV64_IMA_ZISK_ZKVM_ELF::compile(&test_guest_path) {
Ok(elf_path) => {
assert!(
fs::metadata(elf_path).unwrap().len() != 0,
"ELF bytes should not be empty."
);
}
Err(e) => {
panic!("compile_zisk_program direct call failed for dedicated guest: {e:?}");
}
}
}
}

View File

@@ -0,0 +1,121 @@
use std::{io, path::PathBuf, process::ExitStatus};
use thiserror::Error;
use zkvm_interface::zkVMError;
impl From<ZiskError> for zkVMError {
fn from(value: ZiskError) -> Self {
zkVMError::Other(Box::new(value))
}
}
#[derive(Debug, Error)]
pub enum ZiskError {
#[error(transparent)]
Compile(#[from] CompileError),
#[error(transparent)]
Execute(#[from] ExecuteError),
#[error(transparent)]
Prove(#[from] ProveError),
#[error(transparent)]
Verify(#[from] VerifyError),
}
#[derive(Debug, Error)]
pub enum CompileError {
#[error("Program path does not exist or is not a directory: {0}")]
InvalidProgramPath(PathBuf),
#[error(
"Cargo.toml not found in program directory: {program_dir}. Expected at: {manifest_path}"
)]
CargoTomlMissing {
program_dir: PathBuf,
manifest_path: PathBuf,
},
#[error("Could not find `[package].name` in guest Cargo.toml at {path}")]
MissingPackageName { path: PathBuf },
#[error("Compiled ELF not found at expected path: {path}")]
ElfNotFound {
path: PathBuf,
#[source]
source: io::Error,
},
#[error("Failed to read file at {path}: {source}")]
ReadFile {
path: PathBuf,
#[source]
source: io::Error,
},
#[error("Failed to parse guest Cargo.toml at {path}: {source}")]
ParseCargoToml {
path: PathBuf,
#[source]
source: toml::de::Error,
},
#[error("Failed to execute `cargo-zisk build --release` in {cwd}: {source}")]
CargoZiskBuild {
cwd: PathBuf,
#[source]
source: io::Error,
},
#[error("`cargo-zisk build --release` failed with status: {status} for program at {path}")]
CargoZiskBuildFailed { status: ExitStatus, path: PathBuf },
#[error("Failed to execute `cargo-zisk rom-setup`: {source}")]
CargoZiskRomSetup {
#[source]
source: io::Error,
},
#[error("`cargo-zisk rom-setup` failed with status: {status} for program at {path}")]
CargoZiskRomSetupFailed { status: ExitStatus, path: PathBuf },
}
#[derive(Debug, Error)]
pub enum ExecuteError {
#[error("IO failure: {0}")]
Io(io::Error),
#[error("Failed to serialize input: {0}")]
SerializeInput(Box<dyn std::error::Error + Send + Sync>),
#[error("Failed to execute `ziskemu`: {source}")]
Ziskemu {
#[source]
source: io::Error,
},
#[error("`ziskemu` failed with status: {status}")]
ZiskemuFailed { status: ExitStatus },
#[error("Total steps not found in report")]
TotalStepsNotFound,
}
#[derive(Debug, Error)]
pub enum ProveError {
#[error("IO failure: {0}")]
Io(io::Error),
#[error("Failed to serialize input: {0}")]
SerializeInput(Box<dyn std::error::Error + Send + Sync>),
#[error("Failed to execute `cargo prove`: {source}")]
CargoZiskProve {
#[source]
source: io::Error,
},
#[error("`cargo prove` failed with status: {status}")]
CargoZiskProveFailed { status: ExitStatus },
#[error("Serialising proof with `bincode` failed: {0}")]
Bincode(#[from] bincode::Error),
}
#[derive(Debug, Error)]
pub enum VerifyError {
#[error("IO failure: {0}")]
Io(io::Error),
#[error("Deserialising proof with `bincode` failed: {0}")]
Bincode(#[from] bincode::Error),
#[error("Failed to execute `cargo-zisk verify`: {source}")]
CargoZiskVerify {
#[source]
source: io::Error,
},
#[error("Invalid proof: {0}")]
InvalidProof(String),
}

339
crates/ere-zisk/src/lib.rs Normal file
View File

@@ -0,0 +1,339 @@
use crate::{
compile::compile_zisk_program,
error::{ExecuteError, ProveError, VerifyError, ZiskError},
};
use serde::{Deserialize, Serialize};
use std::{
fs,
io::Write,
path::{Path, PathBuf},
process::{Command, Stdio},
time,
};
use tempfile::tempdir;
use zkvm_interface::{
Compiler, Input, ProgramExecutionReport, ProgramProvingReport, ProverResourceType, zkVM,
zkVMError,
};
mod compile;
mod error;
#[allow(non_camel_case_types)]
pub struct RV64_IMA_ZISK_ZKVM_ELF;
impl Compiler for RV64_IMA_ZISK_ZKVM_ELF {
type Error = ZiskError;
/// Path to compiled ELF.
type Program = PathBuf;
fn compile(path_to_program: &Path) -> Result<Self::Program, Self::Error> {
compile_zisk_program(path_to_program).map_err(ZiskError::Compile)
}
}
#[derive(Serialize, Deserialize)]
pub struct ZiskProofWithPublicValues {
/// The raw aggregated proof generated by the ZisK zkVM.
pub proof: Vec<u8>,
/// The public values generated by the ZisK zkVM.
pub public_values: Vec<u8>,
}
pub struct EreZisk {
elf_path: PathBuf,
resource: ProverResourceType,
}
impl EreZisk {
pub fn new(elf_path: PathBuf, resource: ProverResourceType) -> Self {
Self { elf_path, resource }
}
}
impl EreZisk {}
impl zkVM for EreZisk {
fn execute(&self, input: &Input) -> Result<ProgramExecutionReport, zkVMError> {
let input_bytes = input
.iter()
.try_fold(Vec::new(), |mut acc, item| {
acc.extend(item.as_bytes().map_err(ExecuteError::SerializeInput)?);
Ok(acc)
})
.map_err(ZiskError::Execute)?;
let output_dir = tempdir().map_err(|e| ZiskError::Execute(ExecuteError::Io(e)))?;
let input_path = input_path(output_dir.path());
fs::File::create(&input_path)
.and_then(|mut file| file.write_all(&input_bytes))
.map_err(|e| ZiskError::Execute(ExecuteError::Io(e)))?;
let output = Command::new("ziskemu")
.arg("-e")
.arg(&self.elf_path)
.arg("-i")
.arg(&input_path)
.arg("-x")
.stderr(Stdio::inherit())
.output()
.map_err(|e| ZiskError::Execute(ExecuteError::Ziskemu { source: e }))?;
if !output.status.success() {
return Err(ZiskError::Execute(ExecuteError::ZiskemuFailed {
status: output.status,
})
.into());
}
let total_num_cycles = String::from_utf8_lossy(&output.stdout)
.split_once("total steps = ")
.and_then(|(_, stats)| {
stats
.split_whitespace()
.next()
.and_then(|steps| steps.parse::<u64>().ok())
})
.ok_or(ZiskError::Execute(ExecuteError::TotalStepsNotFound))?;
Ok(ProgramExecutionReport::new(total_num_cycles))
}
fn prove(&self, input: &Input) -> Result<(Vec<u8>, ProgramProvingReport), zkVMError> {
let input_bytes = input
.iter()
.try_fold(Vec::new(), |mut acc, item| {
acc.extend(item.as_bytes().map_err(ProveError::SerializeInput)?);
Ok(acc)
})
.map_err(ZiskError::Prove)?;
let output_dir = tempdir().map_err(|e| ZiskError::Prove(ProveError::Io(e)))?;
let input_path = input_path(output_dir.path());
let proof_path = proof_path(output_dir.path());
let public_values_path = public_values_path(output_dir.path());
fs::File::create(&input_path)
.and_then(|mut file| file.write_all(&input_bytes))
.map_err(|e| ZiskError::Prove(ProveError::Io(e)))?;
let start = time::Instant::now();
match self.resource {
ProverResourceType::Cpu => {
let status = Command::new("cargo-zisk")
.arg("prove")
.arg("-e")
.arg(&self.elf_path)
.arg("-i")
.arg(&input_path)
.arg("-o")
.arg(output_dir.path())
// FIXME: Not sure why if we don't set the flag `aggregation`
// there will be no proof, but ideally we should
// only generate the core proof as other zkVMs.
.arg("-a")
.status()
.map_err(|e| ZiskError::Prove(ProveError::CargoZiskProve { source: e }))?;
if !status.success() {
return Err(
ZiskError::Prove(ProveError::CargoZiskProveFailed { status }).into(),
);
}
}
ProverResourceType::Gpu => {
// TODO: Need to install another version of `cargo-zisk` with
// `features = gpu` and call it here.
unimplemented!()
}
}
let proving_time = start.elapsed();
let proof_with_public_values = ZiskProofWithPublicValues {
proof: fs::read(proof_path).map_err(|e| ZiskError::Prove(ProveError::Io(e)))?,
public_values: fs::read(public_values_path)
.map_err(|e| ZiskError::Prove(ProveError::Io(e)))?,
};
let bytes = bincode::serialize(&proof_with_public_values)
.map_err(|err| ZiskError::Prove(ProveError::Bincode(err)))?;
Ok((bytes, ProgramProvingReport::new(proving_time)))
}
fn verify(&self, bytes: &[u8]) -> Result<(), zkVMError> {
let proof_with_public_values: ZiskProofWithPublicValues = bincode::deserialize(bytes)
.map_err(|err| ZiskError::Verify(VerifyError::Bincode(err)))?;
let output_dir = tempdir().map_err(|e| ZiskError::Verify(VerifyError::Io(e)))?;
let proof_path = proof_path(output_dir.path());
let public_values_path = public_values_path(output_dir.path());
fs::create_dir_all(proof_dir(output_dir.path()))
.map_err(|e| ZiskError::Verify(VerifyError::Io(e)))?;
fs::File::create(&proof_path)
.and_then(|mut file| file.write_all(&proof_with_public_values.proof))
.map_err(|e| ZiskError::Verify(VerifyError::Io(e)))?;
fs::File::create(&public_values_path)
.and_then(|mut file| file.write_all(&proof_with_public_values.public_values))
.map_err(|e| ZiskError::Verify(VerifyError::Io(e)))?;
let output = Command::new("cargo-zisk")
.arg("verify")
.arg("-p")
.arg(&proof_path)
.arg("-u")
.arg(&public_values_path)
.output()
.map_err(|e| ZiskError::Verify(VerifyError::CargoZiskVerify { source: e }))?;
if !output.status.success() {
return Err(ZiskError::Verify(VerifyError::InvalidProof(
String::from_utf8_lossy(&output.stderr).to_string(),
))
.into());
}
Ok(())
}
}
fn input_path(dir: impl AsRef<Path>) -> PathBuf {
dir.as_ref().join("input.bin")
}
fn proof_dir(dir: impl AsRef<Path>) -> PathBuf {
dir.as_ref().join("proofs")
}
fn proof_path(dir: impl AsRef<Path>) -> PathBuf {
proof_dir(dir).join("vadcop_final_proof.json")
}
fn public_values_path(dir: impl AsRef<Path>) -> PathBuf {
dir.as_ref().join("publics.json")
}
#[cfg(test)]
mod execute_tests {
use super::*;
fn get_compiled_test_zisk_elf() -> Result<PathBuf, ZiskError> {
let test_guest_path = get_execute_test_guest_program_path();
RV64_IMA_ZISK_ZKVM_ELF::compile(&test_guest_path)
}
fn get_execute_test_guest_program_path() -> PathBuf {
let workspace_dir = env!("CARGO_WORKSPACE_DIR");
PathBuf::from(workspace_dir)
.join("tests")
.join("zisk")
.join("execute")
.join("basic")
.canonicalize()
.expect("Failed to find or canonicalize test guest program at <CARGO_WORKSPACE_DIR>/tests/execute/zisk")
}
#[test]
fn test_execute_zisk_dummy_input() {
let elf_path = get_compiled_test_zisk_elf()
.expect("Failed to compile test ZisK guest for execution test");
let mut input_builder = Input::new();
let n: u32 = 42;
let a: u16 = 42;
input_builder.write(n);
input_builder.write(a);
let zkvm = EreZisk::new(elf_path, ProverResourceType::Cpu);
let result = zkvm.execute(&input_builder);
if let Err(e) = &result {
panic!("Execution error: {e:?}");
}
}
#[test]
fn test_execute_zisk_no_input_for_guest_expecting_input() {
let elf_path = get_compiled_test_zisk_elf()
.expect("Failed to compile test ZisK guest for execution test");
let empty_input = Input::new();
let zkvm = EreZisk::new(elf_path, ProverResourceType::Cpu);
assert!(zkvm.execute(&empty_input).is_err());
}
}
#[cfg(test)]
mod prove_tests {
use std::path::PathBuf;
use super::*;
use zkvm_interface::Input;
fn get_prove_test_guest_program_path() -> PathBuf {
let workspace_dir = env!("CARGO_WORKSPACE_DIR");
PathBuf::from(workspace_dir)
.join("tests")
.join("zisk")
.join("prove")
.join("basic")
.canonicalize()
.expect("Failed to find or canonicalize test guest program at <CARGO_WORKSPACE_DIR>/tests/execute/zisk")
}
fn get_compiled_test_zisk_elf_for_prove() -> Result<PathBuf, ZiskError> {
let test_guest_path = get_prove_test_guest_program_path();
RV64_IMA_ZISK_ZKVM_ELF::compile(&test_guest_path)
}
#[test]
fn test_prove_zisk_dummy_input() {
let elf_path = get_compiled_test_zisk_elf_for_prove()
.expect("Failed to compile test ZisK guest for proving test");
let mut input_builder = Input::new();
let n: u32 = 42;
let a: u16 = 42;
input_builder.write(n);
input_builder.write(a);
let zkvm = EreZisk::new(elf_path, ProverResourceType::Cpu);
let proof_bytes = match zkvm.prove(&input_builder) {
Ok((prove_result, _)) => prove_result,
Err(err) => {
panic!("Proving error in test: {err:?}");
}
};
assert!(!proof_bytes.is_empty(), "Proof bytes should not be empty.");
assert!(zkvm.verify(&proof_bytes).is_ok());
let invalid_proof_bytes = {
let mut invalid_proof: ZiskProofWithPublicValues =
bincode::deserialize(&proof_bytes).unwrap();
// alter the first digit of `evals[0][0]`
invalid_proof.proof[40] = invalid_proof.proof[40].overflowing_add(1).0;
bincode::serialize(&invalid_proof).unwrap()
};
assert!(zkvm.verify(&invalid_proof_bytes).is_err());
// TODO: Check public inputs
}
#[test]
fn test_prove_zisk_fails_on_bad_input_causing_execution_failure() {
let elf_path = get_compiled_test_zisk_elf_for_prove()
.expect("Failed to compile test ZisK guest for proving test");
let empty_input = Input::new();
let zkvm = EreZisk::new(elf_path, ProverResourceType::Cpu);
assert!(zkvm.prove(&empty_input).is_err());
}
}

View File

@@ -1,3 +1,4 @@
use bincode::Options;
use erased_serde::Serialize as ErasedSerialize;
use serde::Serialize;
@@ -69,12 +70,14 @@ impl InputItem {
}
/// Get the item as bytes (serialize objects, return bytes directly)
pub fn as_bytes(&self) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
pub fn as_bytes(&self) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
match self {
InputItem::Object(obj) => {
let mut buf = Vec::new();
let mut serializer =
bincode::Serializer::new(&mut buf, bincode::DefaultOptions::new());
let mut serializer = bincode::Serializer::new(
&mut buf,
bincode::DefaultOptions::new().with_fixint_encoding(),
);
erased_serde::serialize(obj.as_ref(), &mut serializer)?;
Ok(buf)
}

View File

@@ -40,13 +40,13 @@ RUN chmod +x /tmp/install_zisk_sdk.sh
RUN /tmp/install_zisk_sdk.sh && rm /tmp/install_zisk_sdk.sh # Clean up the script
# The 'zisk' Rust toolchain is now installed.
# cargo-zisk is installed in $HOME/.zisk/bin.
# The install_zisk_sdk.sh script adds $HOME/.zisk/bin to PATH for its session.
# For the image environment, we need to ensure $HOME/.zisk/bin is persistently in PATH.
ENV ZISK_TOOLS_BIN_DIR="${HOME}/.zisk/bin"
ENV PATH="${ZISK_TOOLS_BIN_DIR}:${PATH}"
# cargo-zisk is installed in /root/.zisk/bin.
# The ziskup script adds /root/.zisk/bin to PATH for its session.
# For the image environment, we need to ensure /root/.zisk/bin is persistently in PATH.
ENV ZISK_BIN_DIR="/root/.zisk/bin"
ENV PATH="${PATH}:${ZISK_BIN_DIR}"
# Verify cargo-zisk is accessible
RUN echo "Verifying Zisk installation in Dockerfile ..." && cargo +zisk zisk --version
RUN echo "Verifying Zisk installation in Dockerfile ..." && cargo-zisk --version
CMD ["/bin/bash"]

View File

@@ -31,32 +31,14 @@ ensure_tool_installed "rustup" "for managing Rust toolchains (ZisK installs its
ensure_tool_installed "cargo" "as cargo-zisk is a cargo subcommand"
# Step 1: Download and run the script that installs the ziskup binary itself.
ZISKUP_INSTALLER_DOWNLOAD_PATH="/tmp/ziskup_install.sh"
echo "Downloading the script that installs the 'ziskup' binary to ${ZISKUP_INSTALLER_DOWNLOAD_PATH}..."
curl -L https://raw.githubusercontent.com/0xPolygonHermez/zisk/main/ziskup/install.sh -o "${ZISKUP_INSTALLER_DOWNLOAD_PATH}"
chmod +x "${ZISKUP_INSTALLER_DOWNLOAD_PATH}"
echo "Running the 'ziskup' binary installer script..."
"${ZISKUP_INSTALLER_DOWNLOAD_PATH}" # This script installs $HOME/.zisk/bin/ziskup
rm "${ZISKUP_INSTALLER_DOWNLOAD_PATH}" # Clean up the downloaded installer script
# Step 2: Ensure the installed ziskup binary is in PATH for this script session.
ZISK_BIN_DIR="${HOME}/.zisk/bin"
if [ -d "${ZISK_BIN_DIR}" ] && [[ ":$PATH:" != *":${ZISK_BIN_DIR}:"* ]]; then
echo "Adding ${ZISK_BIN_DIR} to PATH for current script session."
export PATH="${ZISK_BIN_DIR}:$PATH"
fi
# Ensure the ziskup binary itself is now installed and executable
ensure_tool_installed "ziskup" "ZisK SDK manager tool"
# Step 3: Now run the installed ziskup binary with non-interactive flags.
echo "Running 'ziskup --provingkey' to install ZisK components..."
# Export GH_RUNNER=true to ensure ziskup uses default non-interactive options.
export GH_RUNNER=true
ziskup --provingkey # This is the actual ziskup tool that processes --provingkey
curl https://raw.githubusercontent.com/0xPolygonHermez/zisk/main/ziskup/install.sh | bash
unset GH_RUNNER
# Step 2: Ensure the installed cargo-zisk binary is in PATH for this script session.
export PATH="${PATH}:${HOME}/.zisk/bin"
# Verify ZisK installation
echo "Verifying ZisK installation..."
@@ -76,16 +58,16 @@ else
fi
echo "Checking for cargo-zisk CLI tool (using +zisk toolchain)..."
# cargo-zisk should be callable via `cargo +zisk zisk ...`
if cargo +zisk zisk --version; then
# cargo-zisk should be callable via `cargo-zisk ...`
if cargo-zisk --version; then
echo "cargo-zisk CLI tool verified successfully."
else
echo "Error: 'cargo +zisk zisk --version' failed." >&2
echo "Error: 'cargo-zisk --version' failed." >&2
echo " Attempting verification with cargo-zisk directly (if in PATH from ${ZISK_BIN_DIR})..."
if command -v cargo-zisk &> /dev/null && cargo-zisk --version; then
echo "cargo-zisk found directly in PATH and verified."
else
echo "Error: cargo-zisk also not found directly or 'cargo +zisk zisk --version' failed." >&2
echo "Error: cargo-zisk also not found directly or 'cargo-zisk --version' failed." >&2
echo " Ensure ${ZISK_BIN_DIR} is effectively in PATH for new shells and check ziskup output." >&2
exit 1
fi

View File

@@ -0,0 +1,9 @@
[package]
name = "ere-test-zisk-guest"
version = "0.1.0"
edition = "2021"
[workspace]
[dependencies]
ziskos = { git = "https://github.com/0xPolygonHermez/zisk.git", rev = "f9a3655" }

View File

@@ -0,0 +1,14 @@
#![no_main]
ziskos::entrypoint!(main);
fn main() {
// Read an input
let n = u32::from_le_bytes(
ziskos::read_input()
.try_into()
.expect("input to be 4 bytes"),
);
// Write n*2 to output
ziskos::set_output(0, n * 2);
}

View File

@@ -0,0 +1,9 @@
[package]
name = "ere-test-zisk-guest"
version = "0.1.0"
edition = "2021"
[workspace]
[dependencies]
ziskos = { git = "https://github.com/0xPolygonHermez/zisk.git", rev = "f9a3655" }

View File

@@ -0,0 +1,16 @@
#![no_main]
ziskos::entrypoint!(main);
fn main() {
let input = ziskos::read_input();
if input.len() != 6 {
std::process::exit(1);
}
// Read an input
let n = u32::from_le_bytes(input[..4].try_into().unwrap());
let a = u16::from_le_bytes(input[4..6].try_into().unwrap()) as u32;
ziskos::set_output(0, (n + a) * 2);
}

View File

@@ -0,0 +1,9 @@
[package]
name = "ere-test-zisk-guest"
version = "0.1.0"
edition = "2021"
[workspace]
[dependencies]
ziskos = { git = "https://github.com/0xPolygonHermez/zisk.git", rev = "f9a3655" }

View File

@@ -0,0 +1,16 @@
#![no_main]
ziskos::entrypoint!(main);
fn main() {
let input = ziskos::read_input();
if input.len() != 6 {
std::process::exit(1);
}
// Read an input
let n = u32::from_le_bytes(input[..4].try_into().unwrap());
let a = u16::from_le_bytes(input[4..6].try_into().unwrap()) as u32;
ziskos::set_output(0, (n + a) * 2);
}