#plonk #zero-knowledge #zk-snarks #cryptography #crypto

已撤销 parity-plonk

PLONK ZK-Proof算法的纯Rust实现

0.2.0 2021年12月12日
0.1.0 2021年11月28日
0.0.2 2021年11月28日
0.0.1 2021年11月28日

#plonk 排名 51


2 crates 中使用

MPL-2.0 许可证

605KB
14K SLoC

PLONK

Build Status Repository Documentation

这是BLS12-381上的PLONK证明系统的纯Rust实现

此库包含了一个模块化的KZG10实现,作为默认的多项式承诺方案。

使用方法

use parity_plonk::prelude::*;
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use rand_core::RngCore;

// Implement a circuit that checks:
// 1) a + b = c where C is a PI
// 2) a <= 2^6
// 3) b <= 2^5
// 4) a * b = d where D is a PI
// 5) JubJub::GENERATOR * e(JubJubScalar) = f where F is a Public Input
#[derive(Debug, Default)]
pub struct TestCircuit {
    a: BlsScalar,
    b: BlsScalar,
    c: BlsScalar,
    d: BlsScalar,
    e: JubJubScalar,
    f: JubJubAffine,
}

impl Circuit for TestCircuit {
    const CIRCUIT_ID: [u8; 32] = [0xff; 32];
    fn gadget(
        &mut self,
        composer: &mut TurboComposer,
    ) -> Result<(), Error> {
        let a = composer.append_witness(self.a);
        let b = composer.append_witness(self.b);

        // Make first constraint a + b = c
        let constraint = Constraint::new()
            .left(1)
            .right(1)
            .public(-self.c)
            .a(a)
            .b(b);

        composer.append_gate(constraint);

        // Check that a and b are in range
        composer.component_range(a, 1 << 6);
        composer.component_range(b, 1 << 5);

        // Make second constraint a * b = d
        let constraint = Constraint::new()
            .mult(1)
            .output(1)
            .public(-self.d)
            .a(a)
            .b(b);

        composer.append_gate(constraint);

        let e = composer.append_witness(self.e);
        let scalar_mul_result = composer
            .component_mul_generator(e, dusk_jubjub::GENERATOR_EXTENDED);
        // Apply the constrain
        composer.assert_equal_public_point(scalar_mul_result, self.f);
        Ok(())
    }

    fn public_inputs(&self) -> Vec<PublicInputValue> {
        vec![self.c.into(), self.d.into(), self.f.into()]
    }

    fn padded_gates(&self) -> usize {
        1 << 11
    }
}

// Now let's use the Circuit we've just implemented!

let rng = XorShiftRng::from_seed([
    0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37,
    0x32, 0x54, 0x06, 0xbc, 0xe5,
]);
let pp = PublicParameters::setup(1 << 12, rng).unwrap();
// Initialize the circuit
let mut circuit = TestCircuit::default();
// Compile the circuit
let (pk, vd) = circuit.compile(&pp).unwrap();
// Prover POV
let proof = {
    let mut circuit = TestCircuit {
        a: BlsScalar::from(20u64),
        b: BlsScalar::from(5u64),
        c: BlsScalar::from(25u64),
        d: BlsScalar::from(100u64),
        e: JubJubScalar::from(2u64),
        f: JubJubAffine::from(
            dusk_jubjub::GENERATOR_EXTENDED * JubJubScalar::from(2u64),
        ),
    };
    circuit.prove(&pp, &pk, b"Test").unwrap()
};
// Verifier POV
let public_inputs: Vec<PublicInputValue> = vec![
    BlsScalar::from(25u64).into(),
    BlsScalar::from(100u64).into(),
    JubJubAffine::from(
        dusk_jubjub::GENERATOR_EXTENDED * JubJubScalar::from(2u64),
    )
    .into(),
];
TestCircuit::verify(
    &pp,
    &vd,
    &proof,
    &public_inputs,
    b"Test",
).unwrap();

功能

此crate包含了许多功能,以下将简要介绍

  • alloc: 启用分配器的使用,并因此能够执行Proof构造和验证。没有此功能,**无法**进行证明或验证。其缺失仅使dusk-plonk导出某些固定大小的数据结构,如Proof,这在没有分配器也没有的no_std环境中可能有用。
  • std: 启用std使用以及某些证明和验证操作中的rayon并行化。它还使用椭圆曲线依赖项的std版本,利用了dusk-bls12-381parallel功能。默认情况下,这是crate中启用功能。
  • trace: 启用电路调试工具。这基本上是使用StandardComposer::check_circuit_satisfied函数的能力。函数将输出有关每个电路门的信息,直到其中一个门不满足方程或没有更多门。如果有不满足的门方程,函数将panic并返回门号。
  • trace-print: 比trace更进一步,打印每个gate组件数据,清晰地概述构成我们正在构建的电路的所有值。建议的方法是导出std输出和std错误,然后将它们放置在文本文件中,以便有效地分析门。
  • canon: 启用特定数据结构的canonical序列化,这在将此库集成到Dusk堆栈的其余部分中非常有用,特别是对于存储目的。

文档

在此存储库中有两种主要类型的文档

  • 容器文档。这提供了关于库提供的所有函数以及它导出的数据结构文档的信息。要检查这些信息,请随意访问文档页面或运行make docmake doc-internal

  • 备注。这是一组特定的文档,解释了PLONK的关键数学概念以及它们是如何通过数学证明来工作的。要检查它,请运行make doc并打开生成的文档,这些文档位于/target下,您可以使用浏览器打开。

性能

Intel(R) Core(TM) i9-9900X CPU @ 3.50GHz上进行的基准测试。对于大小为2^16的约束/门

  • 证明时间:5.46s
  • 验证时间:9.34ms(这个时间不会因电路大小而变化。)

要获取更多结果,请运行cargo bench以获取关于约束数基准测试的完整报告。

致谢

  • AztecProtocol/Barretenberg的参考实现
  • FFT模块和KZG10模块分别从zexe/zcash和scipr-lab获取并修改。

许可

此代码根据Mozilla Public License Version 2.0 (MPL-2.0)许可。有关更多信息,请参阅LICENSE

关于

dusk团队设计的实现。

贡献

  • 如果您想为此存储库/项目做出贡献,请参阅CONTRIBUTING.md
  • 如果您想报告错误或请求添加新功能,请在此存储库上打开一个问题。

依赖项

~5–11MB
~116K SLoC