RISC Zero各功能模块代码解析

1. 引言

开源代码见:

  • https://github.com/risc0/risc0(C++ 和 Rust)

2. risc0-build-kernel模块

risc0-build-kernel模块:

  • 用于构建kernels的工具。所谓kernels,包括CPU、CUDA、Metal。
  • 代码见:risc0/build_kernel。

依赖库有:

  • cc:用于将 C/C++/汇编代码,编译进Rust库或Rust应用中。
  • directories:为一个小的中间层库,用于为Linux/Windows/macOS等操作系统上的config、cache或其它数据,提供平台指定的标准路径位置。
  • hex:以十六进制对数据进行编解码。
  • sha2:SHA2哈希函数,包括:SHA-224、SHA-256、SHA-384 和 SHA-512。
  • tempfile:管理临时文件和路径。

risc0-build-kernel模块,提供了接口函数:

	pub fn compile(&mut self, output: &str) {
        for src in self.files.iter() {
            println!("cargo:rerun-if-changed={}", src.display());
        }
        for dep in self.deps.iter() {
            println!("cargo:rerun-if-changed={}", dep.display());
        }
        match &self.kernel_type {
            KernelType::Cpp => self.compile_cpp(output), //直接使用cc::Build
            KernelType::Cuda => self.compile_cuda(output), //使用nvcc
            KernelType::Metal => self.compile_metal(output), //使用xcrun
        }
    }

3. risc0-core模块

risc0-core模块:

  • RISC Zero的核心类型
  • 主要定义了Babybear域和Goldilocks域。
  • 代码见:risc0/core。

依赖库有:

  • bytemuck:在数据类型之间安全地执行“位转换(bit cast)”操作。
  • rand_core:Core 随机数生成器。
  • rand:随机数生成器,以及其他随机值功能。

4. risc0-circuit-rv32im-sys模块

risc0-circuit-rv32im-sys模块:

  • 为rv32im电路,生成HAL(Hardware Abstraction Layer)代码。
  • 代码见:risc0/circuit/rv32im-sys。

针对不同的模式,会编译生成不同的库文件:

  • CPU模式:生成libcircuit.a库文件。
  • Metal模式:生成libmetal_kernel.a库文件。
  • CUDA模式:生成libcuda_kernel.a库文件。

依赖库有:

  • risc0-build-kernel模块
  • risc0-core模块
  • glob:支持根据Unix shell样式模式匹配文件路径。

risc0-circuit-rv32im-sys模块内的cxx目录、kernels/cuda、kernels/metal目录下的rv32im ZK电路文件,均由Zirgen编译生成。目前Zirgen未开源。

5. risc0-circuit-recursion-sys模块

risc0-circuit-recursion-sys模块:

  • 为递归电路生成HAL(Hardware Abstraction Layer)代码。
  • 代码见:risc0/circuit/recursion-sys。

针对不同的模式,会编译生成不同的库文件:

  • CPU模式:生成libcircuit.a库文件。
  • Metal模式:生成libmetal_kernel.a库文件。
  • CUDA模式:生成libcuda_kernel.a库文件。

依赖库有:

  • risc0-build-kernel模块
  • risc0-core模块
  • glob:支持根据Unix shell样式模式匹配文件路径。

risc0-circuit-recursion-sys模块内的cxx目录、kernels/cuda、kernels/metal目录下的ZK递归电路文件,均由Zirgen编译生成。目前Zirgen未开源。

6. risc0-sys模块

risc0-sys模块:

  • 为RISC Zero生成原生/HAL(Hardware Abstraction Layer)代码。
  • 代码见:rics0/sys。
  • 主要用于生成:
    • CUDA库:libcuda_kernels_zkp.a 和 libsupra_ntt.a。
    • Metal库:libmetal_kernels_zkp.a。

依赖库有:

  • risc0-build-kernel模块
  • cc:用于将 C/C++/汇编代码,编译进Rust库或Rust应用中。
  • cust:对 CUDA Driver API的高层bindings。
  • risc0-sppark:该库专注于加速ZKP中计算昂贵的部分,如multi-scalar multiplication(MSM)、number theoretic transform(NTT)、arithmetic hashes等。该库是CUDA/C++模板的集合,可以为一系列有限域和椭圆曲线实例化。

7. risc0-zkvm-platform模块

risc0-zkvm-platform模块:

  • 为RISC Zero zkVM
  • 对RISC Zero zkVM的平台定义,包括:
    • IO端口地址:见lib.rs。
    • 内存区域:见memory.rs。zkVM单个内存page size为1024字节;单个word size为32字节。
    • 底层运行时函数:见syscall.rs。定义了reg_abi(包括REG_ZERO、REG_RA、REG_SP等),以及ecall类型(包括HALT、INPUT、SOFTWARE、SHA、BIGINT)等等。
/// Size of a zkVM machine word in bytes.
/// 4 bytes (i.e. 32 bits) as the zkVM is an implementation of the rv32im ISA.
pub const WORD_SIZE: usize = core::mem::size_of::<u32>();

/// Size of a zkVM memory page.
pub const PAGE_SIZE: usize = 1024;

/// Standard IO file descriptors for use with sys_read and sys_write.
pub mod fileno {
    pub const STDIN: u32 = 0;
    pub const STDOUT: u32 = 1;
    pub const STDERR: u32 = 2;
    pub const JOURNAL: u32 = 3;
}

依赖的库有:

  • bytemuck:在数据类型之间安全地执行“位转换(bit cast)”操作。
  • getrandom:一个用于从系统源检索随机数据的小型跨平台库
  • libm:为wasm32-unknown-unknown target提供数学支持,如sin、atan2等。

8. risc0-zkvm-receipts模块

risc0-zkvm-receipts模块:

  • 读取receipts.rs内容,写入到lib.rs中。
  • 代码见:risc0/zkvm/receipts

9. risc0-zkp模块

risc0-zkp模块:

  • 为RISC Zero ZKP证明系统核心库
  • 详情参看:
    • RISC Zero zk-STARK证明系统代码解析

10. risc0-zkvm-methods模块

risc0-zkvm-methods模块:

  • 用于测试和benchmark的RISC Zero zkVM guest code。
  • 代码见:risc0/zkvm/methods。

有2大类methods:【未包含risc0-zkvm-methods-rand?】

  • risc0-zkvm-methods-guest:见risc0/zkvm/methods/guest。
  • risc0-zkvm-methods-std:见risc0/zkvm/methods/std。

均会调用risc0-build模块的embed_methods_with_options函数,来生成methods.rs文件——嵌入为RISC-V构建的methods,供host端依赖项使用。

	let map = HashMap::from([
        (
            "risc0-zkvm-methods-guest",
            GuestOptions {
                features: vec![],
                use_docker,
            },
        ),
        (
            "risc0-zkvm-methods-std",
            GuestOptions {
                features: vec!["test_feature1".to_string(), "test_feature2".to_string()],
                use_docker: None,
            },
        ),
    ]);

    embed_methods_with_options(map);

依赖库有:

  • risc0-build 模块,使用其embed_methods_with_options函数。
  • risc0-zkvm模块
  • risc0-zkevm-platform模块
  • tracing-subscriber:用于实现和组成“tracing”订阅者的实用程序。
  • serde:序列化、反序列化库。

11. risc0-binfmt模块

risc0-binfmt模块:

  • RISC Zero二进制格式库
  • 代码见:risc0/binfmt
  • 有:
    • elf.rs:加载ELF文件来初始化RISC Zero program。
    • hash.rs:采用Sha256哈希函数。
    • image.rs:对应某zkVM guest程序的memory image。
    • sys_state.rs:表示某segment的public state:
      /// Represents the public state of a segment, needed for continuations and
      /// receipt verification.
      #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
      pub struct SystemState {
          /// The program counter.
          pub pc: u32,
      
          /// The root hash of a merkle tree which confirms the
          /// integrity of the memory image.
          pub merkle_root: Digest,
      }
      

依赖库有:

  • risc0-zkvm-methods模块
  • risc0-zkevm-platform模块
  • risc0-zkp模块
  • tracing-subscriber:用于实现和组成“tracing”订阅者的实用程序。
  • serde:序列化、反序列化库。
  • test-log:替代#[test]属性,支持在运行tests之前,对logging和(或)tracing框架进行初始化。
  • anyhow:基于std::error::Error构建的灵活具体错误类型库。
  • elf:解析ELF文件的库。
  • tracing:应用层的tracing。

RISC Zero program结构为:【对应load_elf函数为:从ELF文件加载初始化RISC Zero program。】

/// A RISC Zero program
pub struct Program {
    /// The entrypoint of the program
    pub entry: u32,

    /// The initial memory image
    pub image: BTreeMap<u32, u32>,
}

zkVM guest程序的memory image定义为:

/// An image of a zkVM guest's memory
///
/// This is an image of the full memory state of the zkVM, including the data,
/// text, inputs, page table, and system memory. In addition to the memory image
/// proper, this includes some metadata about the page table.
#[derive(Clone, Serialize, Deserialize)]
pub struct MemoryImage {
    /// Sparse memory memory image as a map from page index to page.
    pub pages: BTreeMap<u32, Vec<u8>>,

    /// Metadata about the structure of the page table
    pub info: PageTableInfo,

    /// Program Counter from [Program] entry point
    pub pc: u32,
}

相应的ImageID计算方式为:

/// Compute and return the ImageID of the specified ELF binary.
#[cfg(not(target_os = "zkvm"))]
pub fn compute_image_id(elf: &[u8]) -> anyhow::Result<risc0_zkp::core::digest::Digest> {
    use risc0_zkvm_platform::{memory::GUEST_MAX_MEM, PAGE_SIZE};

    let program = Program::load_elf(elf, GUEST_MAX_MEM as u32)?;
    let image = MemoryImage::new(&program, PAGE_SIZE as u32)?;
    image.compute_id()
}
	/// Compute and return the root merkle entry of this image.
    pub fn compute_root_hash(&self) -> Result<Digest> {
        let root_page = self
            .pages
            .get(&self.info.root_idx)
            .expect("Missing root page?");
        hash_page_bytes(&root_page[..(self.info.root_addr - self.info.root_page_addr) as usize])
    }

    /// Compute and return the ImageID of this image.
    pub fn compute_id(&self) -> Result<Digest> {
        Ok(compute_image_id(&self.compute_root_hash()?, self.pc))
    }

/// Compute and return the ImageID of the given `(merkle_root, pc)` pair.
fn compute_image_id(merkle_root: &Digest, pc: u32) -> Digest {
    SystemState {
        merkle_root: *merkle_root,
        pc,
    }
    .digest::<Impl>()
}

12. risc0-build模块

risc0-build模块:

  • 为RISC Zero zkVM build工具
  • 代码见:risc0/build
const RUSTUP_TOOLCHAIN_NAME: &str = "risc0";

#[derive(Debug, Deserialize)]
struct Risc0Metadata {
    methods: Vec<String>,
}
struct Risc0Method {
    name: String,
    elf_path: PathBuf,
}

依赖库有:

  • risc0-binfmt模块
  • risc0-zkevm-platform模块
  • risc0-zkp模块
  • serde:序列化、反序列化库。
  • serde_json:json序列化。
  • anyhow:基于std::error::Error构建的灵活具体错误类型库。
  • cargo_metadata:结构化访问cargo metadata的输出。cargo metadata:以 JSON 格式输出包结构和依赖关系信息。
  • docker-generate:docker文件读写。
  • tempfile:管理临时文件和路径。

13. risc0-circuit-rv32im模块

risc0-circuit-rv32im模块:

  • 为rv32im的RISC Zero电路
  • 代码见:risc0/circuit/rv32im。
  • 有:
    • cpu.rs/cuda.rs/metal.rs:实现了eval_check函数。
    • cpp.rs:实现了step_compute_accum、step_verify_accum、step_exec、step_verify_bytes、step_verify_mem等函数。
    • layout.rs 和 layout.rs.inc :定义了code、data和out的layout buffer信息。
    • taps.rs、info.rs、poly_ext.rs:为自动生成的代码。

依赖库有:

  • risc0-core模块
  • risc0-zkp模块
  • risc0-zkvm-platform模块
  • risc0-circuit-rv32im-sys模块
  • anyhow:基于std::error::Error构建的灵活具体错误类型库。
  • tracing:应用层的tracing。
  • rand:随机数生成器,以及其他随机值功能。
  • cust:对 CUDA Driver API的高层bindings。
  • metal:Unsafe Rust bindings for the Metal 3D Graphics API。针对Macos的Metal GPU。
  • rayon:并行库。
  • criterion:统计驱动的微benchmark库。
  • test-log:替代#[test]属性,支持在运行tests之前,对logging和(或)tracing框架进行初始化。
  • tracing-subscriber:用于实现和组成“tracing”订阅者的实用程序。

14. risc0-circuit-recursion模块

risc0-circuit-recursion模块:

  • 为递归的RISC Zero电路
  • 代码见:risc0/circuit/recursion
  • 会下载recursion_zkr.zip文件。配置RECURSION_SRC_PATH环境变量,下载链接为“https://risc0-artifacts.s3.us-west-2.amazonaws.com/zkr/{SHA256_HASH}.zip”。

依赖库有:

  • risc0-core模块
  • risc0-zkp模块
  • risc0-circuit-recursion-sys模块
  • anyhow:基于std::error::Error构建的灵活具体错误类型库。
  • tracing:应用层的tracing。
  • rand:随机数生成器,以及其他随机值功能。
  • cust:对 CUDA Driver API的高层bindings。
  • metal:Unsafe Rust bindings for the Metal 3D Graphics API。针对Macos的Metal GPU。
  • rayon:并行库。
  • criterion:统计驱动的微benchmark库。
  • test-log:替代#[test]属性,支持在运行tests之前,对logging和(或)tracing框架进行初始化。
  • tracing-subscriber:用于实现和组成“tracing”订阅者的实用程序。
  • bytemuck:在数据类型之间安全地执行“位转换(bit cast)”操作。
  • zip:支持对zip文件读写。
  • tracing-forest:保持来自并发任务的跟踪数据之间的上下文一致性
  • downloader:通过HTTP/HTTPS下载。
  • sha2:SHA2哈希函数,包括:SHA-224、SHA-256、SHA-384 和 SHA-512。

15. risc0-zkvm模块

risc0-zkvm模块:

  • 为RISC Zero zkVM
  • 代码见:risc0/zkvm。
  • 有:
    • benches:benchmark
    • examples:包含fib、loop和recursion例子。运行cargo run --example fib --features="prove" -- --iterations 10
    • methods:见risc0-zkvm-methods模块。用于测试和benchmark的RISC Zero zkVM guest code。
    • platform:见risc0-zkvm-platform模块。定义了IO端口地址、内存区域和底层runtime函数。
    • receipts:见risc0-zkvm-receipts模块。读取receipts.rs内容,写入到lib.rs中。
    • src:定义了guest和host以及序列化相关接口。

risc0-zkvm支持如下features:【注意,若想在guest中使用risc0-zkvm,需通过设置default-features = false来禁用"prove" feature。】

Feature Target(s) Implies Description
client all except rv32im std Enables the client API.
cuda prove, std Enables CUDA GPU acceleration for the prover. Requires CUDA toolkit to be installed.
disable-dev-mode all except rv32im Disables dev mode so that proving and verifying may not be faked. Used to prevent a misplaced RISC0_DEV_MODE from breaking security in production systems.
metal macos prove, std Enables Metal GPU acceleration for the prover.
prove all except rv32im std Enables the prover, incompatible within the zkvm guest.
std all Support for the Rust stdlib.

依赖库有:

  • prost-build:使用protoc来解析 .proto 文件。
  • protobuf-src:集成了C++版本的libprotobuf。
  • anyhow:基于std::error::Error构建的灵活具体错误类型库。
  • bytemuck:在数据类型之间安全地执行“位转换(bit cast)”操作。
  • cfg-if:一个宏,用于根据大量#[cfg]参数以符合人体工程学的方式定义items。结构类似于if-else链,第一个匹配的分支是发出的项。
  • getrandom:一个用于从系统源检索随机数据的小型跨平台库。
  • hex:以十六进制对数据进行编解码。
  • risc0-binfmt模块
  • risc0-core模块
  • risc0-zkp模块
  • risc0-zkvm-platform模块
  • rrs-lib:构建RISC-V指令集模拟器的库。
  • semver:解析Cargo风格的语义版本控制。
  • serde:序列化库。
  • addr2line:使用gimli用Rust编写的跨平台符号库。
  • ark-bn254:BN254 pairing-friendly elliptic curve
  • ark-groth16:Groth16 ZKP系统。
  • ark-serialize:arkworks生态序列化库。
  • bincode:结构体与字节码之间的相互二进制转换。
  • bonsai-sdk模块
  • bytes:字节码操作相关库。
  • crypto-bigint:大整数库。
  • elf:解析ELF文件的库。
  • lazy-regex:编译时检查的惰性静态正则表达式
  • num-bigint:大整数库。
  • num-derive:数字语法扩展
  • num-traits:通用数学数字traits
  • prost:对proto2和proto3文件解析库。
  • rayon:并行库。
  • risc0-circuit-recursion模块
  • risc0-circuit-rv32im模块
  • rustc-demangle:Rust编译器符号解映射。
  • sha2:SHA2哈希函数,包括:SHA-224、SHA-256、SHA-384 和 SHA-512。
  • tempfile:管理临时文件和路径。
  • tracing:应用层的tracing。
  • typetag:trait对象的序列化和反序列化。
  • clap:命令行参数解析器。
  • criterion:统计驱动的微benchmark库。
  • human-repr:Generate beautiful human representations of bytes, durations, and even throughputs! 即让表示更人性化。
  • lazy_static:A macro for declaring lazily evaluated statics in Rust.
  • rand:随机数生成器,以及其他随机值功能。
  • tracing-forest:保持来自并发任务的跟踪数据之间的上下文一致性。
  • tracing-subscriber:用于实现和组成“tracing”订阅者的实用程序。
  • flate2:DEFLATE压缩和解压缩暴露为Read/BufRead/Write流。支持miniz_oxide和多个zlib实现。支持zlib、gzip和原始deflate流。
  • risc0-zkvm-methods模块。
  • serde_json:json序列化。
  • serial_test:支持创建序列化Rust测试。
  • tar:tar文件读写库
  • tempfile:管理临时文件和路径。
  • test-log:替代#[test]属性,支持在运行tests之前,对logging和(或)tracing框架进行初始化。

RISC Zero系列博客

  • RISC0:Towards a Unified Compilation Framework for Zero Knowledge
  • Risc Zero ZKVM:zk-STARKs + RISC-V
  • 2023年 ZK Hack以及ZK Summit 9 亮点记
  • RISC Zero zkVM 白皮书
  • Risc0:使用Continunations来证明任意EVM交易
  • Zeth:首个Type 0 zkEVM
  • RISC Zero项目简介
  • RISC Zero zkVM性能指标
  • Continuations:扩展RISC Zero zkVM支持(无限)大计算
  • A summary on the FRI low degree test前2页导读
  • Reed-Solomon Codes及其与RISC Zero zkVM的关系
  • RISC Zero zkVM架构
  • RISC-V与RISC Zero zkVM的关系
  • 有限域的Fast Multiplication和Modular Reduction算法实现
  • RISC Zero的Bonsai证明服务
  • RISC Zero ZKP协议中的商多项式
  • FRI的Commit、Query以及FRI Batching内部机制
  • RISC Zero的手撕STARK
  • RISC Zero zkVM guest程序优化技巧 及其 与物理CPU的关键差异
  • ZK*FM:RISC Zero zkVM的形式化验证
  • Zirgen MLIR:RISC-Zero的ZK-circuits形式化验证
  • 以RISC Zero ZK Fraud Proof赋能Optimistic Rollups
  • zkSummit10 亮点记
  • 技术探秘:在RISC Zero中验证FHE——由隐藏到证明:FHE验证的ZK路径(1)
  • 技术探秘:在RISC Zero中验证FHE——RISC Zero应用的DevOps(2)
  • RISC Zero STARK证明系统时序图及规范
  • RISC Zero zkVM Host & Guest 101
  • RISC Zero zk-STARK证明系统代码解析
  • RISC Zero的Babybear域 及其 扩域

你可能感兴趣的:(zkVM,zkVM)