#hash #zero-knowledge #plonk #zero-knowledge-proofs

plonky2_monolith

使用 Monolith 哈希函数生成 Plonky2 证明,并编写 Plonky2 电路

1 个不稳定版本

0.1.0 2023 年 10 月 2 日

#2192 in 密码学

自定义许可证

97KB
2K SLoC

Monolith Plonky2

此 crate 提供了 Monolith 哈希函数的实现,该函数可用于 Monolith 哈希函数,该函数可以用于 Plonky2 证明系统。Monolith 哈希函数是一种新的 zk-友好哈希函数,比现有的 zk-友好哈希函数快得多,其性能与 Keccak 哈希函数相似。特别是,根据我们的初步基准测试,Monolith 比 Plonky2 证明系统中当前使用的 Poseidon 哈希函数快 2 到 3 倍。

此 crate 可用于

  • 使用 Monolith 哈希函数生成 Plonky2 证明
  • 使用 Monolith 闸门构建电路,以计算 Monolith 哈希,这对于递归验证使用 Monolith 生成的 Plonky2 证明也非常有用。为此,此 crate 提供了 Monolith 排列的 Plonky2 闸门。

该 crate 还提供了基准测试,比较了 Monolith 实现和 Monolith 闸门与 Plonky2 中当前使用的相应 Poseidon 组件。

用法

使用 Monolith 哈希函数生成证明

use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::iop::witness::PartialWitness;
use plonky2::field::goldilocks_field::GoldilocksField;
use plonky2::plonk::circuit_data::CircuitConfig;
use plonky2::field::types::Sample;
use plonky2::iop::witness::WitnessWrite;
use plonky2_monolith::monolith_hash::monolith_goldilocks::MonolithGoldilocksConfig;
use std::error::Error;

const D: usize = 2;
type F = GoldilocksField;
fn main() -> Result<(), Box<dyn Error>> {
    let config = CircuitConfig::standard_recursion_config();
    let mut builder = CircuitBuilder::<F, D>::new(config);
    let init_t = builder.add_virtual_public_input();
    let mut res_t = builder.add_virtual_target();
    builder.connect(init_t, res_t);
    for _ in 0..100 {
        res_t = builder.mul(res_t, init_t);
    }
    builder.register_public_input(res_t);
    let data = builder.build::<MonolithGoldilocksConfig>();

    let mut pw = PartialWitness::<F>::new();
    let input = F::rand();
    pw.set_target(init_t, input);


    let proof = data.prove(pw)?;

    Ok(data.verify(proof)?)
}

使用 Monolith 闸门构建电路

use std::cmp;
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::iop::witness::PartialWitness;
use plonky2::field::goldilocks_field::GoldilocksField;
use plonky2::plonk::circuit_data::CircuitConfig;
use plonky2::field::types::Sample;
use plonky2::iop::witness::WitnessWrite;
use plonky2::gates::gate::Gate;
use plonky2::hash::hash_types::NUM_HASH_OUT_ELTS;
use plonky2_monolith::monolith_hash::monolith_goldilocks::MonolithGoldilocksConfig;
use plonky2_monolith::gates::monolith::MonolithGate;
use plonky2_monolith::monolith_hash::MonolithHash;
use std::error::Error;

const D: usize = 2;
type F = GoldilocksField;

fn generate_config_for_monolith() -> CircuitConfig {
        let needed_wires = cmp::max(MonolithGate::<F,D>::new().num_wires(), CircuitConfig::standard_recursion_config().num_wires);
        CircuitConfig {
            num_wires: needed_wires,
            num_routed_wires: needed_wires,
            ..CircuitConfig::standard_recursion_config()
        }
    }

fn main() -> Result<(), Box<dyn Error>> {
    let config = generate_config_for_monolith();
    let mut builder = CircuitBuilder::<F, D>::new(config);
    let inp_targets_array = builder.add_virtual_target_arr::<{NUM_HASH_OUT_ELTS}>();
    let mut res_targets_array = inp_targets_array.clone();
    for _ in 0..100 {
        res_targets_array = builder.hash_or_noop::<MonolithHash>(res_targets_array.to_vec()).elements;
    }
    builder.register_public_inputs(&res_targets_array);
    let data = builder.build::<MonolithGoldilocksConfig>();
    
    
    let mut pw = PartialWitness::<F>::new();
    inp_targets_array.into_iter().for_each(|t| {
        let input = F::rand();
        pw.set_target(t, input); 
    });
    
    let proof = data.prove(pw)?;
    
    Ok(data.verify(proof)?)
}

依赖项

~7.5MB
~147K SLoC