Skip to content

Commit

Permalink
Merge branch 'master' into feature/opt-serde
Browse files Browse the repository at this point in the history
  • Loading branch information
Velnbur committed Apr 1, 2024
2 parents 7e5fdd7 + c649684 commit d31860a
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 264 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ and `Deserialize` was implemented.
Use [tests](./src/tests.rs) to run the provided example:

```rust
pub fn main() {
use k256::elliptic_curve::{Group, rand_core::OsRng};
use k256::ProjectivePoint;

use bp_pp::range_proof;
use bp_pp::range_proof::u64_proof::G_VEC_FULL_SZ;
use bp_pp::range_proof::u64_proof::H_VEC_FULL_SZ;
use bp_pp::range_proof::reciprocal::{SerializableProof, self};

fn main() {
let mut rand = OsRng::default();

let x = 123456u64; // private value to create proof for.
Expand Down Expand Up @@ -63,4 +71,4 @@ pub fn main() {
let mut vt = merlin::Transcript::new(b"u64 range proof");
assert!(public.verify(&commitment, proof, &mut vt));
}
```
```
98 changes: 49 additions & 49 deletions src/circuit.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(non_snake_case)]
///! Definition and implementation of the Bulletproofs++ arithmetic circuit protocol.
//! Definition and implementation of the Bulletproofs++ arithmetic circuit protocol.

use std::ops::{Add, Mul, Sub};
use k256::{ProjectivePoint, Scalar};
Expand Down Expand Up @@ -105,15 +105,15 @@ impl<P> ArithmeticCircuit<P>
P: Fn(PartitionType, usize) -> Option<usize>
{
/// Creates commitment to the arithmetic circuit witness.
pub fn commit(&self, v: &Vec<Scalar>, s: &Scalar) -> ProjectivePoint {
pub fn commit(&self, v: &[Scalar], s: &Scalar) -> ProjectivePoint {
self.
g.mul(&v[0]).
add(&self.h_vec[0].mul(s)).
add(&vector_mul(&self.h_vec[9..].to_vec(), &v[1..].to_vec()))
add(&vector_mul(&self.h_vec[9..], &v[1..]))
}

/// Verifies arithmetic circuit proof with respect to the `v` commitments vector.
pub fn verify(&self, v: &Vec<ProjectivePoint>, t: &mut Transcript, proof: Proof) -> bool {
pub fn verify(&self, v: &[ProjectivePoint], t: &mut Transcript, proof: Proof) -> bool {
transcript::app_point(b"commitment_cl", &proof.c_l, t);
transcript::app_point(b"commitment_cr", &proof.c_r, t);
transcript::app_point(b"commitment_co", &proof.c_o, t);
Expand Down Expand Up @@ -185,7 +185,7 @@ impl<P> ArithmeticCircuit<P>
cl_tau = vector_mul_on_scalar(&cl_tau, &Scalar::from(2u32));
cl_tau = vector_sub(&cl_tau, &c_l0);

let mut c = Vec::from([&cr_tau[..], &cl_tau[..]].concat());
let mut c = [&cr_tau[..], &cl_tau[..]].concat();

let commitment = pt.
add(&proof.c_s.mul(&tau_inv)).
Expand All @@ -199,25 +199,25 @@ impl<P> ArithmeticCircuit<P>
}

let wnla = WeightNormLinearArgument {
g: ProjectivePoint::from(self.g),
g_vec: Vec::from([&self.g_vec[..], &self.g_vec_[..]].concat()),
h_vec: Vec::from([&self.h_vec[..], &self.h_vec_[..]].concat()),
g: self.g,
g_vec: [&self.g_vec[..], &self.g_vec_[..]].concat(),
h_vec: [&self.h_vec[..], &self.h_vec_[..]].concat(),
c,
rho,
mu,
};

return wnla.verify(&commitment, t, wnla::Proof {
wnla.verify(&commitment, t, wnla::Proof {
r: proof.r,
x: proof.x,
l: proof.l,
n: proof.n,
});
})
}

/// Creates arithmetic circuit proof for the corresponding witness. Also, `v` commitments vector
/// should correspond input witness in `witness` argument.
pub fn prove<R>(&self, v: &Vec<ProjectivePoint>, witness: Witness, t: &mut Transcript, rng: &mut R) -> Proof
pub fn prove<R>(&self, v: &[ProjectivePoint], witness: Witness, t: &mut Transcript, rng: &mut R) -> Proof
where
R: RngCore + CryptoRng
{
Expand Down Expand Up @@ -262,46 +262,46 @@ impl<P> ArithmeticCircuit<P>

let no = (0..self.dim_nm).map(|j|
if let Some(i) = (self.partition)(PartitionType::NO, j) {
Scalar::from(witness.w_o[i])
witness.w_o[i]
} else {
Scalar::ZERO
}
).collect::<Vec<Scalar>>();

let lo = (0..self.dim_nv).map(|j|
if let Some(i) = (self.partition)(PartitionType::LO, j) {
Scalar::from(witness.w_o[i])
witness.w_o[i]
} else {
Scalar::ZERO
}
).collect::<Vec<Scalar>>();

let ll = (0..self.dim_nv).map(|j|
if let Some(i) = (self.partition)(PartitionType::LL, j) {
Scalar::from(witness.w_o[i])
witness.w_o[i]
} else {
Scalar::ZERO
}
).collect::<Vec<Scalar>>();

let lr = (0..self.dim_nv).map(|j|
if let Some(i) = (self.partition)(PartitionType::LR, j) {
Scalar::from(witness.w_o[i])
witness.w_o[i]
} else {
Scalar::ZERO
}
).collect::<Vec<Scalar>>();

let co =
vector_mul(&self.h_vec, &Vec::from([&ro[..], &lo[..]].concat())).
vector_mul(&self.h_vec, &[&ro[..], &lo[..]].concat()).
add(vector_mul(&self.g_vec, &no));

let cl =
vector_mul(&self.h_vec, &Vec::from([&rl[..], &ll[..]].concat())).
vector_mul(&self.h_vec, &[&rl[..], &ll[..]].concat()).
add(vector_mul(&self.g_vec, &nl));

let cr =
vector_mul(&self.h_vec, &Vec::from([&rr[..], &lr[..]].concat())).
vector_mul(&self.h_vec, &[&rr[..], &lr[..]].concat()).
add(vector_mul(&self.g_vec, &nr));

transcript::app_point(b"commitment_cl", &cl, t);
Expand All @@ -328,8 +328,8 @@ impl<P> ArithmeticCircuit<P>
c_lO
) = self.collect_c(&lambda_vec, &mu_vec, &mu);

let ls = (0..self.dim_nv).map(|_| Scalar::generate_biased(rng)).collect();
let ns = (0..self.dim_nm).map(|_| Scalar::generate_biased(rng)).collect();
let ls = (0..self.dim_nv).map(|_| Scalar::generate_biased(rng)).collect::<Vec<Scalar>>();
let ns = (0..self.dim_nm).map(|_| Scalar::generate_biased(rng)).collect::<Vec<Scalar>>();

let mut v_0 = Scalar::ZERO;
(0..self.k).
Expand All @@ -348,7 +348,7 @@ impl<P> ArithmeticCircuit<P>
let mut v_1 = vec![Scalar::ZERO; self.dim_nv - 1];
(0..self.k).
for_each(|i|
v_1 = vector_add(&v_1, &vector_mul_on_scalar(&witness.v[i][1..].to_vec(), &self.linear_comb_coef(i, &lambda, &mu)))
v_1 = vector_add(&v_1, &vector_mul_on_scalar(&witness.v[i][1..], &self.linear_comb_coef(i, &lambda, &mu)))
);
v_1 = vector_mul_on_scalar(&v_1, &Scalar::from(2u32));

Expand Down Expand Up @@ -424,7 +424,7 @@ impl<P> ArithmeticCircuit<P>
f_[7].mul(&beta_inv).add(&ro[7].mul(&delta)).sub(&rl[6]).add(&rr[5]),
];

let cs = vector_mul(&self.h_vec, &Vec::from([&rs[..], &ls[..]].concat())).
let cs = vector_mul(&self.h_vec, &[&rs[..], &ls[..]].concat()).
add(vector_mul(&self.g_vec, &ns));

transcript::app_point(b"commitment_cs", &cs, t);
Expand All @@ -434,11 +434,11 @@ impl<P> ArithmeticCircuit<P>
let tau2 = tau.mul(&tau);
let tau3 = tau2.mul(&tau);

let mut l = vector_mul_on_scalar(&Vec::from([&rs[..], &ls[..]].concat()), &tau_inv);
l = vector_sub(&l, &vector_mul_on_scalar(&Vec::from([&ro[..], &lo[..]].concat()), &delta));
l = vector_add(&l, &vector_mul_on_scalar(&Vec::from([&rl[..], &ll[..]].concat()), &tau));
l = vector_sub(&l, &vector_mul_on_scalar(&Vec::from([&rr[..], &lr[..]].concat()), &tau2));
l = vector_add(&l, &vector_mul_on_scalar(&Vec::from([&rv[..], &v_1[..]].concat()), &tau3));
let mut l = vector_mul_on_scalar(&[&rs[..], &ls[..]].concat(), &tau_inv);
l = vector_sub(&l, &vector_mul_on_scalar(&[&ro[..], &lo[..]].concat(), &delta));
l = vector_add(&l, &vector_mul_on_scalar(&[&rl[..], &ll[..]].concat(), &tau));
l = vector_sub(&l, &vector_mul_on_scalar(&[&rr[..], &lr[..]].concat(), &tau2));
l = vector_add(&l, &vector_mul_on_scalar(&[&rv[..], &v_1[..]].concat(), &tau3));

let mut pn_tau = vector_mul_on_scalar(&c_nO, &tau3.mul(&delta_inv));
pn_tau = vector_sub(&pn_tau, &vector_mul_on_scalar(&c_nL, &tau2));
Expand Down Expand Up @@ -473,7 +473,7 @@ impl<P> ArithmeticCircuit<P>
cl_tau = vector_mul_on_scalar(&cl_tau, &Scalar::from(2u32));
cl_tau = vector_sub(&cl_tau, &c_l0);

let mut c = Vec::from([&cr_tau[..], &cl_tau[..]].concat());
let mut c = [&cr_tau[..], &cl_tau[..]].concat();

let v = ps_tau.add(&tau3.mul(&v_0));

Expand All @@ -491,17 +491,17 @@ impl<P> ArithmeticCircuit<P>
}

let wnla = WeightNormLinearArgument {
g: ProjectivePoint::from(self.g),
g_vec: Vec::from([&self.g_vec[..], &self.g_vec_[..]].concat()),
h_vec: Vec::from([&self.h_vec[..], &self.h_vec_[..]].concat()),
g: self.g,
g_vec: [&self.g_vec[..], &self.g_vec_[..]].concat(),
h_vec: [&self.h_vec[..], &self.h_vec_[..]].concat(),
c,
rho,
mu,
};

let proof_wnla = wnla.prove(&commitment, t, l, n);

return Proof {
Proof {
c_l: cl,
c_r: cr,
c_o: co,
Expand All @@ -510,18 +510,18 @@ impl<P> ArithmeticCircuit<P>
x: proof_wnla.x,
l: proof_wnla.l,
n: proof_wnla.n,
};
}
}


fn linear_comb_coef(&self, i: usize, lambda: &Scalar, mu: &Scalar) -> Scalar {
let mut coef = Scalar::ZERO;
if self.f_l {
coef = coef.add(pow(&lambda, self.dim_nv * i))
coef = coef.add(pow(lambda, self.dim_nv * i))
}

if self.f_m {
coef = coef.add(pow(&mu, self.dim_nv * i + 1))
coef = coef.add(pow(mu, self.dim_nv * i + 1))
}

coef
Expand All @@ -530,30 +530,30 @@ impl<P> ArithmeticCircuit<P>
fn collect_cl0(&self, lambda: &Scalar, mu: &Scalar) -> Vec<Scalar> {
let mut c_l0 = vec![Scalar::ZERO; self.dim_nv - 1];
if self.f_l {
c_l0 = e(&lambda, self.dim_nv)[1..].to_vec();
c_l0 = e(lambda, self.dim_nv)[1..].to_vec();
}
if self.f_m {
c_l0 = vector_sub(&c_l0, &vector_mul_on_scalar(&e(&mu, self.dim_nv)[1..].to_vec(), &mu));
c_l0 = vector_sub(&c_l0, &vector_mul_on_scalar(&e(mu, self.dim_nv)[1..], mu));
}

c_l0
}

fn collect_c(&self, lambda_vec: &Vec<Scalar>, mu_vec: &Vec<Scalar>, mu: &Scalar) -> (Vec<Scalar>, Vec<Scalar>, Vec<Scalar>, Vec<Scalar>, Vec<Scalar>, Vec<Scalar>) {
fn collect_c(&self, lambda_vec: &[Scalar], mu_vec: &[Scalar], mu: &Scalar) -> (Vec<Scalar>, Vec<Scalar>, Vec<Scalar>, Vec<Scalar>, Vec<Scalar>, Vec<Scalar>) {
let (M_lnL, M_mnL, M_lnR, M_mnR) = self.collect_m_rl();
let (M_lnO, M_mnO, M_llL, M_mlL, M_llR, M_mlR, M_llO, M_mlO) = self.collect_m_o();

let mu_diag_inv = diag_inv(&mu, self.dim_nm);
let mu_diag_inv = diag_inv(mu, self.dim_nm);

let c_nL = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_lnL), &vector_mul_on_matrix(&mu_vec, &M_mnL)), &mu_diag_inv);
let c_nR = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_lnR), &vector_mul_on_matrix(&mu_vec, &M_mnR)), &mu_diag_inv);
let c_nO = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_lnO), &vector_mul_on_matrix(&mu_vec, &M_mnO)), &mu_diag_inv);
let c_nL = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(lambda_vec, &M_lnL), &vector_mul_on_matrix(mu_vec, &M_mnL)), &mu_diag_inv);
let c_nR = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(lambda_vec, &M_lnR), &vector_mul_on_matrix(mu_vec, &M_mnR)), &mu_diag_inv);
let c_nO = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(lambda_vec, &M_lnO), &vector_mul_on_matrix(mu_vec, &M_mnO)), &mu_diag_inv);

let c_lL = vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_llL), &vector_mul_on_matrix(&mu_vec, &M_mlL));
let c_lR = vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_llR), &vector_mul_on_matrix(&mu_vec, &M_mlR));
let c_lO = vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_llO), &vector_mul_on_matrix(&mu_vec, &M_mlO));
let c_lL = vector_sub(&vector_mul_on_matrix(lambda_vec, &M_llL), &vector_mul_on_matrix(mu_vec, &M_mlL));
let c_lR = vector_sub(&vector_mul_on_matrix(lambda_vec, &M_llR), &vector_mul_on_matrix(mu_vec, &M_mlR));
let c_lO = vector_sub(&vector_mul_on_matrix(lambda_vec, &M_llO), &vector_mul_on_matrix(mu_vec, &M_mlO));

return (c_nL, c_nR, c_nO, c_lL, c_lR, c_lO);
(c_nL, c_nR, c_nO, c_lL, c_lR, c_lO)
}

fn collect_lambda(&self, lambda: &Scalar, mu: &Scalar) -> Vec<Scalar> {
Expand All @@ -568,15 +568,15 @@ impl<P> ArithmeticCircuit<P>
);
}

return lambda_vec;
lambda_vec
}

fn collect_m_rl(&self) -> (Vec<Vec<Scalar>>, Vec<Vec<Scalar>>, Vec<Vec<Scalar>>, Vec<Vec<Scalar>>) {
let M_lnL = (0..self.dim_nl).map(|i| Vec::from(&self.W_l[i][..self.dim_nm])).collect::<Vec<Vec<Scalar>>>();
let M_mnL = (0..self.dim_nm).map(|i| Vec::from(&self.W_m[i][..self.dim_nm])).collect::<Vec<Vec<Scalar>>>();
let M_lnR = (0..self.dim_nl).map(|i| Vec::from(&self.W_l[i][self.dim_nm..self.dim_nm * 2])).collect::<Vec<Vec<Scalar>>>();
let M_mnR = (0..self.dim_nm).map(|i| Vec::from(&self.W_m[i][self.dim_nm..self.dim_nm * 2])).collect::<Vec<Vec<Scalar>>>();
return (M_lnL, M_mnL, M_lnR, M_mnR);
(M_lnL, M_mnL, M_lnR, M_mnR)
}

fn collect_m_o(&self) -> (Vec<Vec<Scalar>>, Vec<Vec<Scalar>>, Vec<Vec<Scalar>>, Vec<Vec<Scalar>>, Vec<Vec<Scalar>>, Vec<Vec<Scalar>>, Vec<Vec<Scalar>>, Vec<Vec<Scalar>>) {
Expand All @@ -587,7 +587,7 @@ impl<P> ArithmeticCircuit<P>
(0..isz).map(|i|
(0..jsz).map(|j|
if let Some(j_) = (self.partition)(typ, j) {
Scalar::from(W_x[i][j_])
W_x[i][j_]
} else {
Scalar::ZERO
}
Expand Down
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]

pub mod wnla;
pub mod circuit;
pub(crate) mod transcript;
pub mod range_proof;

mod util;
mod tests;
#[cfg(test)]
mod tests;
21 changes: 12 additions & 9 deletions src/range_proof/reciprocal.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(non_snake_case)]

///! Definition and implementation of the reciprocal range-proof protocol based on arithmetic circuits protocol.
//! Definition and implementation of the reciprocal range-proof protocol based on arithmetic circuits protocol.

use std::ops::{Add, Mul};
use k256::{ProjectivePoint, Scalar};
Expand All @@ -10,6 +10,9 @@ use crate::util::*;
use crate::{circuit, transcript};
use crate::circuit::{ArithmeticCircuit, PartitionType};

#[cfg(feature = "serde")]
pub use super::serializable::SerializableProof;

/// Represents reciprocal range-proof protocol witness.
#[derive(Clone, Debug)]
pub struct Witness {
Expand Down Expand Up @@ -62,8 +65,8 @@ impl ReciprocalRangeProofProtocol {
}

/// Creates commitment for the reciprocals and blinding: `commitment = s*h_vec[0] + <r, h_vec[9:]>`
pub fn commit_poles(&self, r: &Vec<Scalar>, s: &Scalar) -> ProjectivePoint {
self.h_vec[0].mul(s).add(&vector_mul(&self.h_vec[9..].to_vec(), &r))
pub fn commit_poles(&self, r: &[Scalar], s: &Scalar) -> ProjectivePoint {
self.h_vec[0].mul(s).add(&vector_mul(&self.h_vec[9..], r))
}

/// Verifies zk-proof that committed value lies in [0..dim_np^dim_nd) range.
Expand All @@ -75,7 +78,7 @@ impl ReciprocalRangeProofProtocol {

let circuit_commitment = commitment.add(&proof.r);

return circuit.verify(&vec![circuit_commitment], t, proof.circuit_proof);
circuit.verify(&[circuit_commitment], t, proof.circuit_proof)
}

/// Creates zk-proof that committed value lies in [0..dim_np^dim_nd) range.
Expand Down Expand Up @@ -111,14 +114,14 @@ impl ReciprocalRangeProofProtocol {
};

let circuit_commitment = circuit.commit(&circuit_witness.v[0], &circuit_witness.s_v[0]);
return Proof {
circuit_proof: circuit.prove::<R>(&vec![circuit_commitment], circuit_witness, t, rng),
Proof {
circuit_proof: circuit.prove::<R>(&[circuit_commitment], circuit_witness, t, rng),
r: r_com,
};
}
}

/// Creates circuit parameters based on provided challenge. For the same challenge will generate same parameters.
fn make_circuit<'a>(&'a self, e: Scalar) -> ArithmeticCircuit<impl Fn(PartitionType, usize) -> Option<usize> + 'a>
fn make_circuit(&self, e: Scalar) -> ArithmeticCircuit<impl Fn(PartitionType, usize) -> Option<usize> + '_>
{
let dim_nm = self.dim_nd;
let dim_no = self.dim_np;
Expand Down Expand Up @@ -169,7 +172,7 @@ impl ReciprocalRangeProofProtocol {
dim_nl,
dim_nv,
dim_nw,
g: self.g.clone(),
g: self.g,
g_vec: self.g_vec.clone(),
h_vec: self.h_vec.clone(),
W_m,
Expand Down

0 comments on commit d31860a

Please sign in to comment.