#proofs #commitment #membership #zero-knowledge #set #scalar #generator

nightly no-std one-of-many-proofs

实现一种“众多证明之一”的无知识成员证明

1个不稳定版本

0.1.0 2020年8月12日

#30 in #membership

自定义许可

56KB
897 代码行

众多证明之一

基于Groth和Kohlweiss的One-out-of-Many证明的纯Rust实现。

⚠️ 安全警告

此crate正在开发中,尚未经过独立审计!

自行承担风险!

文档

详细文档可在此处找到。


lib.rs:

基于One-out-of-Many证明方案的零知识成员证明。

这种成员证明允许您在不透露关于承诺或其在集合中的位置的情况下,证明您知道pedersen承诺的开启。

示例

证明您知道一组承诺中的零承诺 C_l

#
// Set up proof generators
let gens = ProofGens::new(5).unwrap();

// Create the prover's commitment to zero
let l: usize = 3; // The prover's commitment will be third in the set
let v = Scalar::zero();
let r = Scalar::random(&mut OsRng); // You should use a more secure RNG
let C_l = gens.commit(&v, &r).unwrap();

// Build a random set containing the prover's commitment at index `l`
let mut set = (1..gens.max_set_size())
    .map(|_| RistrettoPoint::random(&mut OsRng))
    .collect::<Vec<RistrettoPoint>>();
set.insert(l, C_l);

// Compute a `OneOfMany` membership proof for this commitment
let mut t = Transcript::new(b"OneOfMany-Test");
let proof = set.iter().prove(&gens, &mut t.clone(), l, &r).unwrap();

// Verify this membership proof, without any knowledge of `l` or `r`.
assert!(set
    .iter()
    .verify(&gens, &mut t.clone(), &proof)
    .is_ok());

证明您知道一组承诺中任何值的承诺(可能非零)

#
// Set up proof generators
let gens = ProofGens::new(5).unwrap();

// Create the prover's commitment to zero
let l: usize = 3; // The prover's commitment will be third in the set
let v = Scalar::random(&mut OsRng); // Commit to any random value
let r = Scalar::random(&mut OsRng); // You should use a more secure RNG
let C_l = gens.commit(&v, &r).unwrap();

// Build a random set containing the prover's commitment at index `l`
let mut set = (1..gens.max_set_size())
    .map(|_| RistrettoPoint::random(&mut OsRng))
    .collect::<Vec<RistrettoPoint>>();
set.insert(l, C_l);

// Create a new commitment to the same value as `C_l`
let r_new = Scalar::random(&mut OsRng); // You should use a more secure RNG
let C_new = gens.commit(&v, &r_new).unwrap();

// Compute a `OneOfMany` membership proof for this commitment
let mut t = Transcript::new(b"OneOfMany-Test");
let proof = set.iter().prove_with_offset(&gens, &mut t.clone(), l, &(r - r_new), Some(&C_new)).unwrap();

// Verify this membership proof, without any knowledge of `l` or `r`.
assert!(set
    .iter()
    .verify_with_offset(&gens, &mut t.clone(), &proof, Some(&C_new))
    .is_ok());

环签名

成员证明的一个特别有用的应用是环签名。这可以通过在计算或验证证明之前对某些消息进行提交来轻松实现。以下是一个示例,它签署并验证来自匿名成员的消息

#
// Set up proof generators
let gens = ProofGens::new(5).unwrap();

// Create the prover's commitment to zero
let l: usize = 3; // The signer's commitment will be third in the set
let v = Scalar::random(&mut OsRng); // Commit to any random value
let r = Scalar::random(&mut OsRng); // You should use a more secure RNG
let C_l = gens.commit(&v, &r).unwrap();

// Build a random set containing the prover's commitment at index `l`
let mut set = (1..gens.max_set_size())
    .map(|_| RistrettoPoint::random(&mut OsRng))
    .collect::<Vec<RistrettoPoint>>();
set.insert(l, C_l);

// Create a new commitment to the same value as `C_l`
let r_new = Scalar::random(&mut OsRng); // You should use a more secure RNG
let C_new = gens.commit(&v, &r_new).unwrap();

// Compute a `OneOfMany` membership proof for this commitment
let mut t = Transcript::new(b"OneOfMany-Test");

// Commit to a message to be signed
t.append_message(b"msg", b"Hello, World!");

// Sign the message anonymously
let proof = set.iter().prove_with_offset(&gens, &mut t.clone(), l, &(r - r_new), Some(&C_new)).unwrap();

// Compute a `OneOfMany` membership proof for this commitment
let mut t = Transcript::new(b"OneOfMany-Test");

// Verification will fail, because this transcript doesn't commit to the same message
assert!(set
    .iter()
    .verify_with_offset(&gens, &mut t.clone(), &proof, Some(&C_new))
    .is_err());

// Commit to a message to be signed
t.append_message(b"msg", b"Hello, World!");

 // Verification will now succeed, because this transcript commits to the signed message
assert!(set
    .iter()
    .verify_with_offset(&gens, &mut t.clone(), &proof, Some(&C_new))
    .is_ok());

性能

此crate提供的证明依赖于curve25519-dalek在ristretto255曲线群上的椭圆曲线操作。这些操作可以通过编译到使用SIMD后端进行优化。为此,请设置以下环境变量

export RUSTFLAGS="-C target_cpu=native"

基准测试使用criterion.rs运行

cargo bench

参考文献

依赖项

~5.5MB
~97K SLoC