2 个稳定版本
1.0.1 | 2020年12月9日 |
---|---|
1.0.0 | 2020年12月1日 |
#33 in #mpc
1MB
10K SLoC
Filecoin Phase2
用于运行电路信任设置的第二个阶段的库和二进制文件。
许可协议
MIT 或 Apache 2.0
lib.rs
:
zk-SNARK MPC,简单易用。
构建您的电路
获取 bellperson
仓库。Bellman 提供了一个名为 Circuit
的 trait,您必须为您的计算实现它。
以下是一个愚蠢的例子:证明您知道一个域元素的立方根。
use fff::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::rngs::OsRng;
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 的属性是,只有一位参与者必须诚实,参数才能安全。这个仓库 (filecoin-phase2
) 主要是关于使用这样的 MPC 安全地创建参数。
让我们先使用 filecoin-phase2
为我们的电路创建一些基本参数
let mut params = crate::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!(crate::contains_contribution(&contributions, &hash));
太好了,现在如果您感到满意,请获取 Groth16 的 Parameters
,使用 params.params()
,这样您就可以像以前一样与 bellman API 进行交互。
依赖项
~21–37MB
~455K SLoC