mirror of
https://github.com/caulk-crypto/caulk.git
synced 2026-01-09 13:27:56 -05:00
refactoring multiple_open
This commit is contained in:
@@ -6,7 +6,6 @@ use ark_poly_commit::kzg10::KZG10;
|
||||
use ark_std::test_rng;
|
||||
use ark_std::UniformRand;
|
||||
use caulk_single_opening::caulk_single_setup;
|
||||
use caulk_single_opening::multiple_open;
|
||||
use caulk_single_opening::CaulkTranscript;
|
||||
use caulk_single_opening::KZGCommit;
|
||||
use caulk_single_opening::{caulk_single_prove, caulk_single_verify};
|
||||
@@ -95,7 +94,7 @@ fn main() {
|
||||
|
||||
//compute all openings
|
||||
let now = Instant::now();
|
||||
let g1_qs = multiple_open(&c_poly, &pp.poly_ck, p);
|
||||
let g1_qs = KZGCommit::multiple_open(&c_poly, &pp.poly_ck, p);
|
||||
g1_q = g1_qs[position];
|
||||
println!("Time to compute all KZG openings {:?}", now.elapsed());
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use ark_poly::{EvaluationDomain, GeneralEvaluationDomain};
|
||||
use ark_std::rand::RngCore;
|
||||
use ark_std::UniformRand;
|
||||
use ark_std::{One, Zero};
|
||||
use std::ops::Neg;
|
||||
|
||||
// Structure of opening proofs output by prove.
|
||||
#[allow(non_snake_case)]
|
||||
@@ -131,12 +132,7 @@ pub fn caulk_single_verify<E: PairingEngine>(
|
||||
|
||||
// check that e( - C + cm, [1]_2) + e( [T]_1, [z]_2 ) + e( [h]_1, [S]_2 ) = 1
|
||||
let eq1: Vec<(E::G1Prepared, E::G2Prepared)> = vec![
|
||||
(
|
||||
(g1_C.mul(-E::Fr::one()) + cm.into_projective())
|
||||
.into_affine()
|
||||
.into(),
|
||||
vk.poly_vk.prepared_h.clone(),
|
||||
),
|
||||
((g1_C.neg() + *cm).into(), vk.poly_vk.prepared_h.clone()),
|
||||
((proof.g1_T).into(), proof.g2_z.into()),
|
||||
(vk.pedersen_param.h.into(), proof.g2_S.into()),
|
||||
];
|
||||
@@ -165,17 +161,7 @@ pub fn caulk_single_verify<E: PairingEngine>(
|
||||
transcript.append_element(b"t1", &proof.pi_ped.t1);
|
||||
transcript.append_element(b"t2", &proof.pi_ped.t2);
|
||||
|
||||
let vk_unity = VerifierPublicParametersUnity {
|
||||
poly_vk: vk.poly_vk.clone(),
|
||||
gxpen: vk.poly_ck_pen,
|
||||
g1: vk.pedersen_param.g,
|
||||
g1_x: vk.g1_x,
|
||||
lagrange_scalars_Vn: vk.lagrange_scalars_Vn.clone(),
|
||||
poly_prod: vk.poly_prod.clone(),
|
||||
logN: vk.logN,
|
||||
domain_Vn: vk.domain_Vn,
|
||||
powers_of_g2: vk.powers_of_g2.clone(),
|
||||
};
|
||||
let vk_unity = VerifierPublicParametersUnity::from(vk);
|
||||
|
||||
// Verify that g2_z = [ ax - b ]_1 for (a/b)**N = 1
|
||||
let check3 = caulk_single_unity_verify(&vk_unity, transcript, &proof.g2_z, &proof.pi_unity);
|
||||
|
||||
@@ -50,10 +50,10 @@ fn trim<E: PairingEngine, P: UVPolynomial<E::Fr>>(
|
||||
if supported_degree == 1 {
|
||||
supported_degree += 1;
|
||||
}
|
||||
let pp = srs.clone();
|
||||
let powers_of_g = pp.powers_of_g[..=supported_degree].to_vec();
|
||||
|
||||
let powers_of_g = srs.powers_of_g[..=supported_degree].to_vec();
|
||||
let powers_of_gamma_g = (0..=supported_degree)
|
||||
.map(|i| pp.powers_of_gamma_g[&i])
|
||||
.map(|i| srs.powers_of_gamma_g[&i])
|
||||
.collect();
|
||||
|
||||
let powers = Powers {
|
||||
@@ -61,12 +61,12 @@ fn trim<E: PairingEngine, P: UVPolynomial<E::Fr>>(
|
||||
powers_of_gamma_g: ark_std::borrow::Cow::Owned(powers_of_gamma_g),
|
||||
};
|
||||
let vk = VerifierKey {
|
||||
g: pp.powers_of_g[0],
|
||||
gamma_g: pp.powers_of_gamma_g[&0],
|
||||
h: pp.h,
|
||||
beta_h: pp.beta_h,
|
||||
prepared_h: pp.prepared_h.clone(),
|
||||
prepared_beta_h: pp.prepared_beta_h.clone(),
|
||||
g: srs.powers_of_g[0],
|
||||
gamma_g: srs.powers_of_gamma_g[&0],
|
||||
h: srs.h,
|
||||
beta_h: srs.beta_h,
|
||||
prepared_h: srs.prepared_h.clone(),
|
||||
prepared_beta_h: srs.prepared_beta_h.clone(),
|
||||
};
|
||||
(powers, vk)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ This file includes the Caulk's unity prover and verifier for single openings.
|
||||
The protocol is described in Figure 2.
|
||||
*/
|
||||
|
||||
use crate::caulk_single_setup::PublicParameters;
|
||||
use crate::caulk_single_setup::{PublicParameters, VerifierPublicParameters};
|
||||
use crate::kzg::KZGCommit;
|
||||
use crate::CaulkTranscript;
|
||||
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
@@ -69,6 +69,22 @@ impl<E: PairingEngine> From<&PublicParameters<E>> for PublicParametersUnity<E> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: PairingEngine> From<&VerifierPublicParameters<E>> for VerifierPublicParametersUnity<E> {
|
||||
fn from(vk: &VerifierPublicParameters<E>) -> Self {
|
||||
Self {
|
||||
poly_vk: vk.poly_vk.clone(),
|
||||
gxpen: vk.poly_ck_pen,
|
||||
g1: vk.pedersen_param.g,
|
||||
g1_x: vk.g1_x,
|
||||
lagrange_scalars_Vn: vk.lagrange_scalars_Vn.clone(),
|
||||
poly_prod: vk.poly_prod.clone(),
|
||||
logN: vk.logN,
|
||||
domain_Vn: vk.domain_Vn,
|
||||
powers_of_g2: vk.powers_of_g2.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prove knowledge of a, b such that g2_z = [ax - b]_2 and a^n = b^n
|
||||
#[allow(non_snake_case)]
|
||||
pub fn caulk_single_unity_prove<E: PairingEngine, R: RngCore>(
|
||||
@@ -185,12 +201,11 @@ pub fn caulk_single_unity_prove<E: PairingEngine, R: RngCore>(
|
||||
////////////////////////////
|
||||
// Commit to f(X) and h(X)
|
||||
////////////////////////////
|
||||
let (g1_F, _) = KZG10::commit(&pp.poly_ck, &f_poly, None, None).unwrap();
|
||||
let g1_F: E::G1Affine = g1_F.0;
|
||||
let (h_hat_com, _) = KZG10::commit(&pp.poly_ck, &h_hat_poly, None, None).unwrap();
|
||||
let g1_F = KZGCommit::<E>::commit(&pp.poly_ck, &f_poly);
|
||||
let h_hat_com = KZGCommit::<E>::commit(&pp.poly_ck, &h_hat_poly);
|
||||
|
||||
// g1_H is a commitment to h_hat_poly + X^(d-1) z(X)
|
||||
let g1_H = h_hat_com.0 + (pp.gxd.mul(-*a) + pp.gxpen.mul(*b)).into_affine();
|
||||
let g1_H = (h_hat_com.into_projective() + pp.gxd.mul(-*a) + pp.gxpen.mul(*b)).into_affine();
|
||||
|
||||
////////////////////////////
|
||||
// alpha = Hash([z]_2, [F]_1, [H]_1)
|
||||
@@ -392,7 +407,7 @@ pub fn caulk_single_unity_verify<E: PairingEngine>(
|
||||
),
|
||||
(
|
||||
((vk.g1.mul(-rho0 - rho1) + vk.gxpen.mul(-zalpha)).into_affine()).into(),
|
||||
g2_z.into_projective().into_affine().into(),
|
||||
(*g2_z).into(),
|
||||
),
|
||||
((-g1_q).into(), vk.poly_vk.prepared_beta_h.clone()),
|
||||
];
|
||||
|
||||
@@ -5,16 +5,15 @@ It is useful for preprocessing.
|
||||
The full algorithm is described here https://github.com/khovratovich/Kate/blob/master/Kate_amortized.pdf
|
||||
*/
|
||||
|
||||
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{Field, PrimeField};
|
||||
use ark_poly::univariate::DensePolynomial;
|
||||
use ark_poly::{EvaluationDomain, GeneralEvaluationDomain, UVPolynomial};
|
||||
use ark_poly_commit::kzg10::*;
|
||||
use ark_std::One;
|
||||
use ark_std::Zero;
|
||||
use std::vec::Vec;
|
||||
|
||||
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use ark_poly::{EvaluationDomain, GeneralEvaluationDomain, UVPolynomial};
|
||||
use ark_poly_commit::kzg10::*;
|
||||
|
||||
//compute all pre-proofs using DFT
|
||||
// h_i= c_d[x^{d-i-1}]+c_{d-1}[x^{d-i-2}]+c_{d-2}[x^{d-i-3}]+\cdots + c_{i+2}[x]+c_{i+1}[1]
|
||||
pub fn compute_h<E: PairingEngine>(
|
||||
@@ -29,12 +28,14 @@ pub fn compute_h<E: PairingEngine>(
|
||||
|
||||
//let now = Instant::now();
|
||||
//1. x_ext = [[x^(d-1)], [x^{d-2},...,[x],[1], d+2 [0]'s]
|
||||
let mut x_ext = vec![];
|
||||
for i in 0..=dom_size - 2 {
|
||||
x_ext.push(poly_ck.powers_of_g[dom_size - 2 - i].into_projective());
|
||||
}
|
||||
let g1inf = poly_ck.powers_of_g[0].mul(fpzero);
|
||||
x_ext.resize(2 * dom_size, g1inf); //filling 2d+2 neutral elements
|
||||
let mut x_ext: Vec<E::G1Projective> = poly_ck
|
||||
.powers_of_g
|
||||
.iter()
|
||||
.take(dom_size - 1)
|
||||
.rev()
|
||||
.map(|x| x.into_projective())
|
||||
.collect();
|
||||
x_ext.resize(2 * dom_size, E::G1Projective::zero()); //filling 2d+2 neutral elements
|
||||
|
||||
let y = dft_g1::<E>(&x_ext, p + 1);
|
||||
//println!("Step 1 computed in {:?}", now.elapsed());
|
||||
@@ -125,39 +126,6 @@ pub fn dft_opt<E: PairingEngine>(h: &[E::Fr], p: usize) -> Vec<E::Fr> {
|
||||
xvec
|
||||
}
|
||||
|
||||
//compute all openings to c_poly using a smart formula
|
||||
pub fn multiple_open<E: PairingEngine>(
|
||||
c_poly: &DensePolynomial<E::Fr>, //c(X)
|
||||
poly_ck: &Powers<E>, //SRS
|
||||
p: usize,
|
||||
) -> Vec<E::G1Affine> {
|
||||
let degree = c_poly.coeffs.len() - 1;
|
||||
let input_domain: GeneralEvaluationDomain<E::Fr> = EvaluationDomain::new(degree).unwrap();
|
||||
|
||||
//let now = Instant::now();
|
||||
let h2 = compute_h(c_poly, poly_ck, p);
|
||||
//println!("H2 computed in {:?}", now.elapsed());
|
||||
//assert_eq!(h,h2);
|
||||
|
||||
let dom_size = input_domain.size();
|
||||
assert_eq!(1 << p, dom_size);
|
||||
assert_eq!(degree + 1, dom_size);
|
||||
/*let now = Instant::now();
|
||||
let q = DFTG1(&h,p);
|
||||
println!("Q computed in {:?}", now.elapsed());*/
|
||||
|
||||
//let now = Instant::now();
|
||||
let q2 = dft_g1::<E>(&h2, p);
|
||||
//println!("Q2 computed in {:?}", now.elapsed());
|
||||
//assert_eq!(q,q2);
|
||||
|
||||
let mut res: Vec<E::G1Affine> = vec![];
|
||||
for e in q2.iter() {
|
||||
res.push(e.into_affine());
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
//compute idft of size @dom_size over vector of G1 elements
|
||||
//q_i = (h_0 + h_1w^-i + h_2w^{-2i}+\cdots + h_{dom_size-1}w^{-(dom_size-1)i})/dom_size for 0<= i< dom_size=2^p
|
||||
pub fn idft_g1<E: PairingEngine>(h: &[E::G1Projective], p: usize) -> Vec<E::G1Projective> {
|
||||
@@ -194,8 +162,9 @@ pub fn idft_g1<E: PairingEngine>(h: &[E::G1Projective], p: usize) -> Vec<E::G1Pr
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use super::*;
|
||||
use crate::caulk_single_setup::caulk_single_setup;
|
||||
use crate::multiopen::*;
|
||||
use crate::KZGCommit;
|
||||
use ark_bls12_377::Bls12_377;
|
||||
use ark_bls12_381::Bls12_381;
|
||||
use ark_ec::PairingEngine;
|
||||
@@ -395,7 +364,7 @@ pub mod tests {
|
||||
println!("Multi naive computed in {:?}", now.elapsed());
|
||||
|
||||
let now = Instant::now();
|
||||
let q2 = multiple_open(&c_poly, &pp.poly_ck, p);
|
||||
let q2 = KZGCommit::multiple_open(&c_poly, &pp.poly_ck, p);
|
||||
println!("Multi advanced computed in {:?}", now.elapsed());
|
||||
assert_eq!(q, q2);
|
||||
}
|
||||
@@ -7,11 +7,13 @@ This file includes backend tools:
|
||||
(5) random_field is for generating random field elements
|
||||
*/
|
||||
|
||||
use crate::{compute_h, dft_g1};
|
||||
use ark_ec::{msm::VariableBaseMSM, AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{Field, PrimeField};
|
||||
use ark_poly::{univariate::DensePolynomial, Polynomial, UVPolynomial};
|
||||
use ark_poly::{EvaluationDomain, GeneralEvaluationDomain};
|
||||
use ark_poly_commit::kzg10::*;
|
||||
use ark_std::rand::RngCore;
|
||||
use ark_std::{end_timer, start_timer};
|
||||
use ark_std::{One, Zero};
|
||||
#[cfg(feature = "parallel")]
|
||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||
@@ -36,14 +38,44 @@ pub struct KZGCommit<E: PairingEngine> {
|
||||
}
|
||||
|
||||
impl<E: PairingEngine> KZGCommit<E> {
|
||||
pub fn commit<R: RngCore>(
|
||||
powers: &Powers<E>,
|
||||
polynomial: &DensePolynomial<E::Fr>,
|
||||
) -> E::G1Affine {
|
||||
pub fn commit(powers: &Powers<E>, polynomial: &DensePolynomial<E::Fr>) -> E::G1Affine {
|
||||
let (com, _randomness) = KZG10::<E, _>::commit(powers, polynomial, None, None).unwrap();
|
||||
com.0
|
||||
}
|
||||
|
||||
// compute all openings to c_poly using a smart formula
|
||||
// This Code implements an algorithm for calculating n openings of a KZG vector commitment of size n in n log(n) time.
|
||||
// The algorithm is by Feist and Khovratovich.
|
||||
// It is useful for preprocessing.
|
||||
// The full algorithm is described here https://github.com/khovratovich/Kate/blob/master/Kate_amortized.pdf
|
||||
pub fn multiple_open(
|
||||
c_poly: &DensePolynomial<E::Fr>, //c(X)
|
||||
poly_ck: &Powers<E>, //SRS
|
||||
p: usize,
|
||||
) -> Vec<E::G1Affine> {
|
||||
let timer = start_timer!(|| "multiple open");
|
||||
|
||||
let degree = c_poly.coeffs.len() - 1;
|
||||
let input_domain: GeneralEvaluationDomain<E::Fr> = EvaluationDomain::new(degree).unwrap();
|
||||
|
||||
let h_timer = start_timer!(|| "compute h");
|
||||
let h2 = compute_h(c_poly, poly_ck, p);
|
||||
end_timer!(h_timer);
|
||||
|
||||
let dom_size = input_domain.size();
|
||||
assert_eq!(1 << p, dom_size);
|
||||
assert_eq!(degree + 1, dom_size);
|
||||
|
||||
let dft_timer = start_timer!(|| "G1 dft");
|
||||
let q2 = dft_g1::<E>(&h2, p);
|
||||
end_timer!(dft_timer);
|
||||
|
||||
let res = E::G1Projective::batch_normalization_into_affine(q2.as_ref());
|
||||
|
||||
end_timer!(timer);
|
||||
res
|
||||
}
|
||||
|
||||
/*
|
||||
KZG.Open( srs_KZG, f(X), deg, (alpha1, alpha2, ..., alphan) )
|
||||
returns ([f(alpha1), ..., f(alphan)], pi)
|
||||
@@ -63,7 +95,7 @@ impl<E: PairingEngine> KZGCommit<E> {
|
||||
proofs.push(pi);
|
||||
}
|
||||
|
||||
let mut res: E::G1Projective = E::G1Projective::zero(); //default value
|
||||
let mut res = E::G1Projective::zero(); //default value
|
||||
|
||||
for j in 0..points.len() {
|
||||
let w_j = points[j];
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
mod caulk_single;
|
||||
mod caulk_single_setup;
|
||||
mod caulk_single_unity;
|
||||
mod dft;
|
||||
mod kzg;
|
||||
mod multiopen;
|
||||
mod pedersen;
|
||||
mod transcript;
|
||||
|
||||
pub use caulk_single::{caulk_single_prove, caulk_single_verify};
|
||||
pub use caulk_single_setup::caulk_single_setup;
|
||||
pub use dft::*;
|
||||
pub use kzg::KZGCommit;
|
||||
pub use multiopen::multiple_open;
|
||||
pub use pedersen::PedersenParam;
|
||||
pub use transcript::CaulkTranscript;
|
||||
|
||||
@@ -17,7 +17,6 @@ pub use transcript::CaulkTranscript;
|
||||
mod tests {
|
||||
|
||||
use crate::caulk_single_setup;
|
||||
use crate::multiple_open;
|
||||
use crate::CaulkTranscript;
|
||||
use crate::KZGCommit;
|
||||
use crate::{caulk_single_prove, caulk_single_verify};
|
||||
@@ -97,7 +96,7 @@ mod tests {
|
||||
}
|
||||
// compute all openings
|
||||
{
|
||||
let g1_qs = multiple_open(&c_poly, &pp.poly_ck, p);
|
||||
let g1_qs = KZGCommit::multiple_open(&c_poly, &pp.poly_ck, p);
|
||||
let g1_q = g1_qs[position];
|
||||
|
||||
// run the prover
|
||||
|
||||
@@ -6,7 +6,6 @@ The protocol is informally described in Appendix A.2, Proof of Opening of a Pede
|
||||
use crate::CaulkTranscript;
|
||||
use ark_ec::{AffineCurve, ProjectiveCurve};
|
||||
use ark_ff::PrimeField;
|
||||
use ark_std::Zero;
|
||||
use ark_std::{rand::RngCore, UniformRand};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
@@ -67,11 +66,6 @@ impl<C: AffineCurve> PedersenCommit<C> {
|
||||
let c = transcript.get_and_append_challenge(b"get c");
|
||||
|
||||
// check that R g^(-t1) h^(-t2) cm^(c) = 1
|
||||
let check = proof.g1_r.into_projective()
|
||||
+ param.g.mul(-proof.t1)
|
||||
+ param.h.mul(-proof.t2)
|
||||
+ cm.mul(c);
|
||||
|
||||
check.is_zero()
|
||||
proof.g1_r.into_projective() + cm.mul(c) == param.g.mul(proof.t1) + param.h.mul(proof.t2)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user