0.2.0 |
|
---|---|
0.1.0 |
|
0.0.2 |
|
0.0.1 |
|
在 #plonk 排名 51
在 2 crates 中使用
605KB
14K SLoC
PLONK
这是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-381
的parallel
功能。默认情况下,这是crate中启用功能。trace
: 启用电路调试工具。这基本上是使用StandardComposer::check_circuit_satisfied
函数的能力。函数将输出有关每个电路门的信息,直到其中一个门不满足方程或没有更多门。如果有不满足的门方程,函数将panic并返回门号。trace-print
: 比trace更进一步,打印每个gate
组件数据,清晰地概述构成我们正在构建的电路的所有值。建议的方法是导出std输出和std错误,然后将它们放置在文本文件中,以便有效地分析门。canon
: 启用特定数据结构的canonical
序列化,这在将此库集成到Dusk堆栈的其余部分中非常有用,特别是对于存储目的。
文档
在此存储库中有两种主要类型的文档
-
容器文档。这提供了关于库提供的所有函数以及它导出的数据结构文档的信息。要检查这些信息,请随意访问文档页面或运行
make doc
或make 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