15个版本 (8个破坏性更新)
0.11.0 | 2020年11月1日 |
---|---|
0.9.0 | 2020年10月1日 |
0.7.0 | 2020年6月29日 |
0.4.0 | 2020年3月23日 |
0.3.0 | 2019年5月20日 |
#34 in #mpc
每月38次下载
91KB
1.5K SLoC
phase21 ![Crates.io](https://img.shields.io/crates/v/phase21.svg)
这是对优秀的phase2库的分支。
此库仍在开发中。
文档
安全警告
此库不保证常量时间操作、内存访问模式或抵抗侧信道攻击。
许可
许可协议为以下之一
- Apache许可证2.0版,(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非你明确表示,否则任何提交以包含在作品中的贡献,如Apache-2.0许可证中定义的,均将双许可如上,没有任何附加条款或条件。
lib.rs
:
zk-SNARK MPC,简单易用。
创建你的电路
获取bellperson
包。Bellman提供了一个名为Circuit
的trait,你必须实现它来处理你的计算。
这里有一个愚蠢的例子:证明你知道一个域元素的立方根。
use ff::Field;
use bellperson::{
Circuit,
ConstraintSystem,
SynthesisError,
bls::Engine,
};
struct CubeRoot<E: Engine> {
cube_root: Option<E::Fr>
}
impl<E: Engine> Circuit<E> for CubeRoot<E> {
fn synthesize<CS: ConstraintSystem<E>>(
self,
cs: &mut CS
) -> Result<(), SynthesisError>
{
// Witness the cube root
let root = cs.alloc(|| "root", || {
self.cube_root.ok_or(SynthesisError::AssignmentMissing)
})?;
// Witness the square of the cube root
let square = cs.alloc(|| "square", || {
self.cube_root
.ok_or(SynthesisError::AssignmentMissing)
.map(|mut root| {root.square(); root })
})?;
// Enforce that `square` is root^2
cs.enforce(
|| "squaring",
|lc| lc + root,
|lc| lc + root,
|lc| lc + square
);
// Witness the cube, as a public input
let cube = cs.alloc_input(|| "cube", || {
self.cube_root
.ok_or(SynthesisError::AssignmentMissing)
.map(|root| {
let mut tmp = root;
tmp.square();
tmp.mul_assign(&root);
tmp
})
})?;
// Enforce that `cube` is root^3
// i.e. that `cube` is `root` * `square`
cs.enforce(
|| "cubing",
|lc| lc + root,
|lc| lc + square,
|lc| lc + cube
);
Ok(())
}
}
创建一些证明
现在我们已经有了实现Circuit
的CubeRoot<E>
,让我们创建一些参数并生成一些证明。
use bellperson::bls::{Bls12, Fr};
use bellperson::groth16::{
generate_random_parameters,
create_random_proof,
prepare_verifying_key,
verify_proof
};
use rand::{OsRng, Rand};
let rng = &mut OsRng::new();
// Create public parameters for our circuit
let params = {
let circuit = CubeRoot::<Bls12> {
cube_root: None
};
generate_random_parameters::<Bls12, _, _>(
circuit,
rng
).unwrap()
};
// Prepare the verifying key for verification
let pvk = prepare_verifying_key(¶ms.vk);
// Let's start making proofs!
for _ in 0..50 {
// Verifier picks a cube in the field.
// Let's just make a random one.
let root = Fr::rand(rng);
let mut cube = root;
cube.square();
cube.mul_assign(&root);
// Prover gets the cube, figures out the cube
// root, and makes the proof:
let proof = create_random_proof(
CubeRoot::<Bls12> {
cube_root: Some(root)
}, ¶ms, rng
).unwrap();
// Verifier checks the proof against the cube
assert!(verify_proof(&pvk, &proof, &[cube]).unwrap());
}
创建参数
在之前的例子中注意到,我们通过调用generate_random_parameters
创建了我们的zk-SNARK参数。然而,如果你想的话,你可以用你选择的某些秘密数字调用generate_parameters
,并保留它们。有了这些数字,你可以创建虚假的证明。
为了说服别人你没有,可以使用多方计算(MPC)。MPC具有这样的性质:只有一位参与者需要诚实,参数才能安全。这个crate(phase21
)就是关于使用这样的MPC安全地创建参数。
让我们首先使用phase21
为我们电路创建一些基本参数
let mut params = phase21::MPCParameters::new(CubeRoot {
cube_root: None
}).unwrap();
第一次尝试这样做时,它将尝试从当前目录读取一个像phase1radix2m2
的文件。您需要从Powers of Tau获取该文件。
这些参数不安全使用;可以为他们创建错误的证明。让我们向这些参数添加一些随机性。
// Contribute randomness to the parameters. Remember this hash,
// it's how we know our contribution is in the parameters!
let hash = params.contribute(rng);
这些参数现在可以安全使用,只要你不是恶意的。这可能不足以说服别人,所以也让他们添加随机性!params
可以被序列化并发送到其他地方,他们可以执行相同的事情,并将新的参数发送回您。只有一个人需要诚实,最终参数才能安全。
一旦你设置好参数,你就可以验证参数
let contributions = params.verify(CubeRoot {
cube_root: None
}).expect("parameters should be valid!");
// We need to check the `contributions` to see if our `hash`
// is in it (see above, when we first contributed)
assert!(phase21::contains_contribution(&contributions, &hash));
太好了,现在如果你满意,可以使用params
的params.params()
获取Groth16 Parameters
,这样你就可以像以前一样与bellman API交互。
依赖关系
~3.5–6MB
~121K SLoC