Rust多项式承诺库ark-poly-commit的使用:支持高效零知识证明和密码学原语的多项式承诺方案

Rust多项式承诺库ark-poly-commit的使用

ark-poly-commit是一个实现多项式承诺方案的Rust库,最初作为Marlin论文的一部分开发,采用MIT许可证和Apache v2许可证双重授权。

警告:这是一个学术原型,尚未经过严格的代码审查,不适用于生产环境。

概述

多项式承诺方案是一种密码学原语,允许一方对有限域上的多项式进行承诺,随后可以揭示所需的多项式评估值并提供证明其正确性的密码学证据。

该库提供多种多项式承诺方案构造,支持:

  • 同时承诺多个不同度数限制的多项式
  • 将同一评估点的多个证明批量处理为单个证明
  • 批量验证证明

主要特性包括简洁性可提取性隐藏性

使用示例

以下是使用Marlin变体的KZG10多项式承诺方案的完整示例:

// 在这个例子中,我们将对一个多项式进行承诺,首先在一个点打开它,然后在两个点批量打开,最后验证证明。
// 我们将使用KZG10多项式承诺方案,遵循Marlin的方法。

use ark_poly_commit::{Polynomial, marlin_pc::MarlinKZG10, LabeledPolynomial, PolynomialCommitment, QuerySet, Evaluations};
use ark_bls12_377::Bls12_377;
use ark_crypto_primitives::sponge::poseidon::{PoseidonSponge, PoseidonConfig};
use ark_crypto_primitives::sponge::CryptographicSponge;
use ark_ec::pairing::Pairing;
use ark_ff::UniformRand;
use ark_std::test_rng;
use ark_poly::{univariate::DensePolynomial, DenseUVPolynomial};
use rand_chacha::ChaCha20Rng;
use ark_ff::PrimeField;

type UniPoly_377 = DensePolynomial<<Bls12_377 as Pairing>::ScalarField>;
type PCS = MarlinKZG10<Bls12_377, UniPoly_377>;

let rng = &mut test_rng();

let max_degree = 16; // 方案支持的最大度数,由设置的公共参数决定

// 1. 设置阶段
let pp = PCS::setup(max_degree, None, rng).unwrap();

let degree = 10; // 我们的多项式度数
let secret_poly = UniPoly_377::rand(degree, rng);

let point_1 = <Bls12_377 as Pairing>::ScalarField::rand(rng);
let point_2 = <Bls12_377 as Pairing>::ScalarField::rand(rng);

let label = String::from("secret_poly");
let labeled_poly = LabeledPolynomial::new(
   label.clone(),
   secret_poly.clone(),
   Some(degree),
   Some(2), // 我们将在两个点打开一元多项式
);

// 测试用海绵函数
fn test_sponge<F: PrimeField>() -> PoseidonSponge<F> {
   let full_rounds = 8;
   let partial_rounds = 31;
   let alpha = 17;

   let mds = vec![
      vec![F::one(), F::zero(), F::one()],
      vec![F::one(), F::one(), F::zero()],
      vec![F::zero(), F::one(), F::one()],
   ];

   let mut v = Vec::new();
   let mut ark_rng = test_rng();

   for _ in 0..(full_rounds + partial_rounds) {
      let mut res = Vec::new();

      for _ in 0..3 {
         res.push(F::rand(&mut ark_rng));
      }
      v.push(res);
   }
   let config = PoseidonConfig::new(full_rounds, partial_rounds, alpha, mds, v, 2, 1);
   PoseidonSponge::new(&config)
}
let mut test_sponge = test_sponge::<<Bls12_377 as Pairing>::ScalarField>();

// 2. 修剪SRS
let (ck, vk) = PCS::trim(&pp, degree, 2, Some(&[degree])).unwrap(); 

// 3. 承诺阶段
let (comms, states) = PCS::commit(&ck, [&labeled_poly], Some(rng).unwrap()); 

// 4a. 单点打开
let proof_single = PCS::open(&ck, [&labeled_poly], &comms, &point_1, &mut (test_sponge.clone()), &states, None).unwrap(); 

// 5a. 单点验证
assert!(PCS::check(&vk, &comms, &point_1, [secret_poly.evaluate(&point_1)], &proof_single, &mut (test_sponge.clone()), Some(rng)).unwrap()); 

let mut query_set = QuerySet::new();
let mut values = Evaluations::new();
for (i, point) in [point_1, point_2].iter().enumerate() {
   query_set.insert((label.clone(), (format!("{}", i), point.clone())));
   let value = secret_poly.evaluate(&point);
   values.insert((label.clone(), point.clone()), value);
}

// 4b. 批量打开
let proof_batched = PCS::batch_open(
   &ck,
   [&labeled_poly],
   &comms,
   &query_set,
   &mut (test_sponge.clone()),
   &states,
   Some(rng),
).unwrap();

// 5b. 批量验证
assert!(PCS::batch_check(
   &vk,
   &comms,
   &query_set,
   &values,
   &proof_batched,
   &mut (test_sponge.clone()),
   rng,
).unwrap());

支持的方案

该库支持以下多项式承诺方案:

  1. 基于离散对数问题的内积论证PC
  2. Marlin变体的KZG10 PC
  3. Sonic/AuroraLight变体的KZG10 PC
  4. Hyrax多线性PC
  5. Ligero和Brakedown
  6. Marlin变体的PST多变量PC

构建指南

使用Rust稳定版工具链构建:

rustup install stable
git clone https://github.com/scipr-lab/poly-commit.git
cd poly-commit
cargo build --release

运行测试:

cargo test

运行基准测试:

cargo bench

许可证

该库采用以下双重许可证:

  • Apache License Version 2.0
  • MIT License

1 回复

Rust多项式承诺库ark-poly-commit使用指南

简介

ark-poly-commit是Rust中一个强大的多项式承诺库,属于arkworks生态系统的一部分。它提供了高效的多项式承诺方案,特别适用于零知识证明系统和密码学原语的构建。该库支持多种多项式承诺方案,包括KZG承诺等,能够满足现代密码学应用的需求。

主要特性

  • 支持多种多项式承诺方案
  • 高效的多项式承诺和验证操作
  • 适用于零知识证明系统
  • 提供批量验证功能
  • 与arkworks生态系统的其他组件良好集成

基本使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
ark-poly-commit = "0.3"
ark-bls12-381 = "0.3"  # 示例中使用BLS12-381曲线

基本示例

use ark_bls12_381::{Bls12_381, Fr};
use ark_poly::{univariate::DensePolynomial, UVPolynomial};
use ark_poly_commit::{kzg10::KZG10, PolynomialCommitment};
use ark_std::{rand::thread_rng, UniformRand};

fn main() {
    // 设置参数
    let rng = &mut thread_rng();
    let max_degree = 10;
    
    // 生成随机多项式
    let poly = DensePolynomial::<Fr>::rand(max_degree, rng);
    
    // 初始化KZG10承诺方案
    let pp = KZG10::<Bls12_381>::setup(max_degree, rng).unwrap();
    let (ck, vk) = KZG10::<Bls12_381>::trim(&pp, max_degree, 0).unwrap();
    
    // 创建承诺
    let (commitment, rand) = KZG10::commit(&ck, &poly, None, None).unwrap();
    
    // 选择一个随机点进行验证
    let point = Fr::rand(rng);
    let value = poly.evaluate(&point);
    
    // 创建见证
    let proof = KZG10::open(&ck, &poly, point, &rand).unwrap();
    
    // 验证承诺
    let valid = KZG10::check(&vk, &commitment, point, value, &proof).unwrap();
    assert!(valid, "验证失败");
}

高级用法

批量验证

use ark_poly_commit::kzg10::BatchCheck;

// ...前面的设置代码...

// 创建多个承诺和验证点
let poly1 = DensePolynomial::<Fr>::rand(max_degree, rng);
let poly2 = DensePolynomial::<Fr>::rand(max_degree, rng);

let (commitment1, rand1) = KZG10::commit(&ck, &poly1, None, None).unwrap();
let (commitment2, rand2) = KZG10::commit(&ck, &poly2, None, None).unwrap();

let point = Fr::rand(rng);
let value1 = poly1.evaluate(&point);
let value2 = poly2.evaluate(&point);

let proof1 = KZG10::open(&ck, &poly1, point, &rand1).unwrap();
let proof2 = KZG10::open(&ck, &poly2, point, &rand2).unwrap();

// 批量验证
let commitments = vec![commitment1, commitment2];
let values = vec![value1, value2];
let proofs = vec![proof1, proof2];
let points = vec![point, point];  // 相同点

let valid = KZG10::batch_check(
    &vk,
    &commitments,
    &points,
    &values,
    &proofs,
    rng,
).unwrap();
assert!(valid, "批量验证失败");

与零知识证明系统集成

ark-poly-commit可以与ark-groth16等零知识证明系统集成:

use ark_groth16::{Groth16, Proof, ProvingKey, VerifyingKey};
use ark_snark::SNARK;

// ...前面的设置代码...

// 假设我们有一个电路需要使用多项式承诺
// 这里简化示例,实际使用时需要定义完整的电路

// 创建证明
let circuit = MyCircuit { /* 电路参数 */ };
let pk = ProvingKey::from(...);  // 从某种方式获取证明密钥
let proof = Groth16::<Bls12_381>::prove(&pk, circuit, rng).unwrap();

// 验证证明
let vk = VerifyingKey::from(...);  // 验证密钥
let public_inputs = vec![/* 公共输入 */];
let valid = Groth16::<Bls12_381>::verify(&vk, &public_inputs, &proof).unwrap();
assert!(valid, "零知识证明验证失败");

性能优化建议

  1. 选择合适的曲线:根据安全需求选择适当的椭圆曲线(如BLS12-381或BN254)

  2. 批量操作:尽可能使用批量验证而不是单个验证

  3. 预处理:对于固定多项式,可以预处理某些计算

  4. 并行化:利用Rust的并行特性加速计算密集型操作

注意事项

  1. 确保理解所选多项式承诺方案的安全假设
  2. 在实际应用中妥善处理随机数生成
  3. 注意内存管理,特别是处理大多项式时
  4. 定期检查库的更新和安全公告

ark-poly-commit库为构建复杂的密码学协议提供了坚实的基础,特别是在需要多项式承诺的零知识证明系统中表现优异。

完整示例代码

以下是一个完整的示例,展示了如何使用ark-poly-commit库进行多项式承诺的基本操作:

use ark_bls12_381::{Bls12_381, Fr};
use ark_poly::{univariate::DensePolynomial, UVPolynomial};
use ark_poly_commit::{kzg10::KZG10, PolynomialCommitment};
use ark_std::{rand::thread_rng, UniformRand};

fn main() {
    // 初始化随机数生成器
    let rng = &mut thread_rng();
    
    // 设置多项式最大次数
    let max_degree = 15;
    
    // 生成一个随机多项式: f(x) = 3x^3 + 2x^2 + x + 5
    let coefficients = vec![
        Fr::from(5),  // 常数项
        Fr::from(1),  // x项
        Fr::from(2),  // x^2项
        Fr::from(3),  // x^3项
    ];
    let poly = DensePolynomial::from_coefficients_vec(coefficients);
    
    println!("多项式: {:?}", poly);
    
    // 初始化KZG10承诺方案
    let pp = KZG10::<Bls12_381>::setup(max_degree, rng).unwrap();
    let (ck, vk) = KZG10::<Bls12_381>::trim(&pp, max_degree, 0).unwrap();
    
    // 创建多项式承诺
    let (commitment, rand) = KZG10::commit(&ck, &poly, None, None).unwrap();
    println!("承诺值: {:?}", commitment);
    
    // 选择一个验证点
    let point = Fr::from(2);  // 在x=2处验证
    let value = poly.evaluate(&point);
    println!("在x={}处的值为: {}", point, value);
    
    // 创建见证
    let proof = KZG10::open(&ck, &poly, point, &rand).unwrap();
    
    // 验证承诺
    let valid = KZG10::check(&vk, &commitment, point, value, &proof).unwrap();
    assert!(valid, "多项式承诺验证失败");
    println!("验证成功!");
    
    // 批量验证示例
    let poly2 = DensePolynomial::<Fr>::rand(max_degree, rng);
    let (commitment2, rand2) = KZG10::commit(&ck, &poly2, None, None).unwrap();
    let value2 = poly2.evaluate(&point);
    let proof2 = KZG10::open(&ck, &poly2, point, &rand2).unwrap();
    
    let commitments = vec![commitment, commitment2];
    let values = vec![value, value2];
    let proofs = vec![proof, proof2];
    
    let batch_valid = KZG10::batch_check(
        &vk,
        &commitments,
        &vec![point, point],  // 相同点验证
        &values,
        &proofs,
        rng,
    ).unwrap();
    assert!(batch_valid, "批量验证失败");
    println!("批量验证成功!");
}

这个完整示例展示了:

  1. 如何创建多项式
  2. 初始化KZG10承诺方案
  3. 生成承诺
  4. 在特定点验证多项式
  5. 执行批量验证

要运行此示例,请确保Cargo.toml中包含正确的依赖项,如前面所述。

回到顶部