#circuit #parameters #filecoin #mpc #proofs #setup #phase2

bin+lib filecoin-phase2

Filecoin 电路的第二阶段

2 个稳定版本

1.0.1 2020年12月9日
1.0.0 2020年12月1日

#33 in #mpc

MIT/Apache

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(())
    }
}

创建一些证明

现在我们已经有了实现 CircuitCubeRoot<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(&params.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)
        }, &params, 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