5个不稳定版本
使用旧的Rust 2015
0.2.2 | 2018年4月13日 |
---|---|
0.2.1 | 2018年4月8日 |
0.2.0 | 2018年4月8日 |
0.1.0 | 2018年4月6日 |
0.0.1 | 2018年4月4日 |
#32 in #mpc
45KB
877 行
阶段2
这个库仍在开发中。
文档
安全警告
此库不对常量时间操作、内存访问模式或抵抗侧信道攻击做出任何保证。
许可协议
许可协议为以下之一
- Apache许可证第2版,(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非你明确表示,否则根据Apache-2.0许可证定义,你有意提交的任何贡献都将按上述方式双重许可,不附加任何额外条款或条件。
lib.rs
:
zk-SNARK MPC,变得简单。
创建你的电路
获取 bellman
和 pairing
包。Bellman提供了一个名为 Circuit
的特质,你必须实现它以进行计算。
以下是一个愚蠢的示例:证明你知道一个域元素的立方根。
extern crate pairing;
extern crate bellman;
use pairing::{Engine, Field};
use bellman::{
Circuit,
ConstraintSystem,
SynthesisError,
};
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(())
}
}
创建一些证明
现在我们已经有了 CubeRoot<E>
实现 Circuit
,让我们创建一些参数并生成一些证明。
extern crate rand;
use pairing::bls12_381::{Bls12, Fr};
use bellman::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具有这样一个特性,即只有一名参与者诚实,参数才能保证安全。这个包(phase2
)就是关于使用这样的MPC安全地创建参数。
让我们首先使用 phase2
为我们的电路创建一些基本参数。
extern crate phase2;
let mut params = phase2::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!(phase2::contains_contribution(&contributions, &hash));
太好了,现在如果您满意,使用 params.params()
获取 Groth16 Parameters
,这样您就可以像以前一样与 bellman APIs 交互。
依赖项
~1.5MB
~22K SLoC