Skip to content

Commit

Permalink
Fix/refactors (#104)
Browse files Browse the repository at this point in the history
* Rename UVPolynomial to DenseUVPolynomial

needed due to arkworks-rs/algebra#412

* Fix formatting

* Fix `msm` usage after `ark-ec` breaking change

Use `<E::G{1,2}Projective as VariableBaseMSM>::msm_bigint` instead of `VariableBase::msm`

* Removed ToBytes implementations and replaced uses of the tobytes! macro.

* Update Cargo.toml

* Update src/ipa_pc/mod.rs

* Apply suggestions from code review

* apply fmt

* small change to ipa_pc open

Co-authored-by: Marcin Górny <[email protected]>
Co-authored-by: Weikeng Chen <[email protected]>
  • Loading branch information
3 people authored Aug 26, 2022
1 parent a6def66 commit 88c97d2
Show file tree
Hide file tree
Showing 18 changed files with 227 additions and 280 deletions.
4 changes: 2 additions & 2 deletions src/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ pub trait PCCheckVar<
>: Clone
{
/// An allocated version of `PC::VerifierKey`.
type VerifierKeyVar: AllocVar<PC::VerifierKey, ConstraintF> + Clone + ToBytesGadget<ConstraintF>;
type VerifierKeyVar: AllocVar<PC::VerifierKey, ConstraintF> + Clone;
/// An allocated version of `PC::PreparedVerifierKey`.
type PreparedVerifierKeyVar: AllocVar<PC::PreparedVerifierKey, ConstraintF>
+ Clone
+ PrepareGadget<Self::VerifierKeyVar, ConstraintF>;
/// An allocated version of `PC::Commitment`.
type CommitmentVar: AllocVar<PC::Commitment, ConstraintF> + Clone + ToBytesGadget<ConstraintF>;
type CommitmentVar: AllocVar<PC::Commitment, ConstraintF> + Clone;
/// An allocated version of `PC::PreparedCommitment`.
type PreparedCommitmentVar: AllocVar<PC::PreparedCommitment, ConstraintF>
+ PrepareGadget<Self::CommitmentVar, ConstraintF>
Expand Down
13 changes: 2 additions & 11 deletions src/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ pub trait PCPreparedVerifierKey<Unprepared: PCVerifierKey> {

/// Defines the minimal interface of commitments for any polynomial
/// commitment scheme.
pub trait PCCommitment:
Clone + ark_ff::ToBytes + CanonicalSerialize + CanonicalDeserialize
{
pub trait PCCommitment: Clone + CanonicalSerialize + CanonicalDeserialize {
/// Outputs a non-hiding commitment to the zero polynomial.
fn empty() -> Self;

Expand Down Expand Up @@ -100,7 +98,7 @@ pub trait PCRandomness: Clone + CanonicalSerialize + CanonicalDeserialize {

/// Defines the minimal interface of evaluation proofs for any polynomial
/// commitment scheme.
pub trait PCProof: Clone + ark_ff::ToBytes + CanonicalSerialize + CanonicalDeserialize {
pub trait PCProof: Clone + CanonicalSerialize + CanonicalDeserialize {
/// Size in bytes
#[deprecated(since = "0.4.0", note = "Please use `.serialized_size()` instead.")]
fn size_in_bytes(&self) -> usize {
Expand Down Expand Up @@ -232,13 +230,6 @@ impl<C: PCCommitment> LabeledCommitment<C> {
}
}

impl<C: PCCommitment> ark_ff::ToBytes for LabeledCommitment<C> {
#[inline]
fn write<W: Write>(&self, writer: W) -> ark_std::io::Result<()> {
self.commitment.write(writer)
}
}

/// A term in a linear combination.
#[derive(Hash, Ord, PartialOrd, Clone, Eq, PartialEq, Debug)]
pub enum LCTerm {
Expand Down
33 changes: 1 addition & 32 deletions src/ipa_pc/data_structures.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::*;
use crate::{PCCommitterKey, PCVerifierKey, Vec};
use ark_ec::AffineCurve;
use ark_ff::{Field, ToBytes, UniformRand, Zero};
use ark_ff::{Field, UniformRand, Zero};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError};
use ark_std::rand::RngCore;
use ark_std::{
Expand Down Expand Up @@ -121,19 +121,6 @@ impl<G: AffineCurve> PCCommitment for Commitment<G> {
}
}

impl<G: AffineCurve> ToBytes for Commitment<G> {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> ark_std::io::Result<()> {
self.comm.write(&mut writer)?;
let shifted_exists = self.shifted_comm.is_some();
shifted_exists.write(&mut writer)?;
self.shifted_comm
.as_ref()
.unwrap_or(&G::zero())
.write(&mut writer)
}
}

/// Nothing to do to prepare this commitment (for now).
pub type PreparedCommitment<E> = Commitment<E>;

Expand Down Expand Up @@ -214,24 +201,6 @@ pub struct Proof<G: AffineCurve> {

impl<G: AffineCurve> PCProof for Proof<G> {}

impl<G: AffineCurve> ToBytes for Proof<G> {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> ark_std::io::Result<()> {
self.l_vec.write(&mut writer)?;
self.r_vec.write(&mut writer)?;
self.final_comm_key.write(&mut writer)?;
self.c.write(&mut writer)?;
self.hiding_comm
.as_ref()
.unwrap_or(&G::zero())
.write(&mut writer)?;
self.rand
.as_ref()
.unwrap_or(&G::ScalarField::zero())
.write(&mut writer)
}
}

/// `SuccinctCheckPolynomial` is a succinctly-representated polynomial
/// generated from the `log_d` random oracle challenges generated in `open`.
/// It has the special property that can be evaluated in `O(log_d)` time.
Expand Down
120 changes: 78 additions & 42 deletions src/ipa_pc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::{BTreeMap, BTreeSet, String, ToString, Vec, CHALLENGE_SIZE};
use crate::{BatchLCProof, Error, Evaluations, QuerySet, UVPolynomial};
use crate::{BatchLCProof, DenseUVPolynomial, Error, Evaluations, QuerySet};
use crate::{LabeledCommitment, LabeledPolynomial, LinearCombination};
use crate::{PCCommitterKey, PCRandomness, PCUniversalParams, PolynomialCommitment};

use ark_ec::{msm::VariableBase, AffineCurve, ProjectiveCurve};
use ark_ff::{to_bytes, Field, One, PrimeField, UniformRand, Zero};
use ark_ec::{msm::VariableBaseMSM, AffineCurve, ProjectiveCurve};
use ark_ff::{Field, One, PrimeField, UniformRand, Zero};
use ark_serialize::CanonicalSerialize;
use ark_std::rand::RngCore;
use ark_std::{convert::TryInto, format, marker::PhantomData, vec};
use ark_std::{convert::TryInto, format, marker::PhantomData, ops::Mul, vec};

mod data_structures;
pub use data_structures::*;
Expand Down Expand Up @@ -34,7 +35,7 @@ use digest::Digest;
pub struct InnerProductArgPC<
G: AffineCurve,
D: Digest,
P: UVPolynomial<G::ScalarField>,
P: DenseUVPolynomial<G::ScalarField>,
S: CryptographicSponge,
> {
_projective: PhantomData<G>,
Expand All @@ -46,8 +47,9 @@ pub struct InnerProductArgPC<
impl<G, D, P, S> InnerProductArgPC<G, D, P, S>
where
G: AffineCurve,
G::Projective: VariableBaseMSM<MSMBase = G, Scalar = G::ScalarField>,
D: Digest,
P: UVPolynomial<G::ScalarField>,
P: DenseUVPolynomial<G::ScalarField>,
S: CryptographicSponge,
{
/// `PROTOCOL_NAME` is used as a seed for the setup function.
Expand All @@ -65,7 +67,7 @@ where
.map(|s| s.into_bigint())
.collect::<Vec<_>>();

let mut comm = VariableBase::msm(comm_key, &scalars_bigint);
let mut comm = <G::Projective as VariableBaseMSM>::msm_bigint(comm_key, &scalars_bigint);

if randomizer.is_some() {
assert!(hiding_generator.is_some());
Expand All @@ -79,8 +81,9 @@ where
let mut i = 0u64;
let mut challenge = None;
while challenge.is_none() {
let hash_input = ark_ff::to_bytes![bytes, i].unwrap();
let hash = D::digest(&hash_input);
let mut hash_input = bytes.to_vec();
hash_input.extend(i.to_le_bytes());
let hash = D::digest(&hash_input.as_slice());
challenge = <G::ScalarField as Field>::from_random_bytes(&hash);

i += 1;
Expand Down Expand Up @@ -143,32 +146,47 @@ where
if proof.hiding_comm.is_some() {
let hiding_comm = proof.hiding_comm.unwrap();
let rand = proof.rand.unwrap();

let hiding_challenge = Self::compute_random_oracle_challenge(
&ark_ff::to_bytes![combined_commitment, point, combined_v, hiding_comm].unwrap(),
);
let mut byte_vec = Vec::new();
combined_commitment
.serialize_uncompressed(&mut byte_vec)
.unwrap();
point.serialize_uncompressed(&mut byte_vec).unwrap();
combined_v.serialize_uncompressed(&mut byte_vec).unwrap();
hiding_comm.serialize_uncompressed(&mut byte_vec).unwrap();
let bytes = byte_vec.as_slice();
let hiding_challenge = Self::compute_random_oracle_challenge(bytes);
combined_commitment_proj += &(hiding_comm.mul(hiding_challenge) - &vk.s.mul(rand));
combined_commitment = combined_commitment_proj.into_affine();
}

// Challenge for each round
let mut round_challenges = Vec::with_capacity(log_d);
let mut round_challenge = Self::compute_random_oracle_challenge(
&ark_ff::to_bytes![combined_commitment, point, combined_v].unwrap(),
);
let mut byte_vec = Vec::new();
combined_commitment
.serialize_uncompressed(&mut byte_vec)
.unwrap();
point.serialize_uncompressed(&mut byte_vec).unwrap();
combined_v.serialize_uncompressed(&mut byte_vec).unwrap();
let bytes = byte_vec.as_slice();
let mut round_challenge = Self::compute_random_oracle_challenge(bytes);

let h_prime = vk.h.mul(round_challenge);

let mut round_commitment_proj =
combined_commitment_proj + &h_prime.mul(&combined_v.into_bigint());
let mut round_commitment_proj = combined_commitment_proj + &h_prime.mul(&combined_v);

let l_iter = proof.l_vec.iter();
let r_iter = proof.r_vec.iter();

for (l, r) in l_iter.zip(r_iter) {
round_challenge = Self::compute_random_oracle_challenge(
&ark_ff::to_bytes![round_challenge, l, r].unwrap(),
);
let mut byte_vec = Vec::new();
round_challenge
.serialize_uncompressed(&mut byte_vec)
.unwrap();
l.serialize_uncompressed(&mut byte_vec).unwrap();
r.serialize_uncompressed(&mut byte_vec).unwrap();
let bytes = byte_vec.as_slice();

round_challenge = Self::compute_random_oracle_challenge(bytes);
round_challenges.push(round_challenge);
round_commitment_proj +=
&(l.mul(round_challenge.inverse().unwrap()) + &r.mul(round_challenge));
Expand Down Expand Up @@ -295,11 +313,16 @@ where
let generators: Vec<_> = ark_std::cfg_into_iter!(0..num_generators)
.map(|i| {
let i = i as u64;
let mut hash = D::digest(&to_bytes![&Self::PROTOCOL_NAME, i].unwrap());
let mut hash =
D::digest([Self::PROTOCOL_NAME, &i.to_le_bytes()].concat().as_slice());
let mut g = G::from_random_bytes(&hash);
let mut j = 0u64;
while g.is_none() {
hash = D::digest(&to_bytes![&Self::PROTOCOL_NAME, i, j].unwrap());
// PROTOCOL NAME, i, j
let mut bytes = Self::PROTOCOL_NAME.to_vec();
bytes.extend(i.to_le_bytes());
bytes.extend(j.to_le_bytes());
hash = D::digest(bytes.as_slice());
g = G::from_random_bytes(&hash);
j += 1;
}
Expand All @@ -315,8 +338,9 @@ where
impl<G, D, P, S> PolynomialCommitment<G::ScalarField, P, S> for InnerProductArgPC<G, D, P, S>
where
G: AffineCurve,
G::Projective: VariableBaseMSM<MSMBase = G, Scalar = G::ScalarField>,
D: Digest,
P: UVPolynomial<G::ScalarField, Point = G::ScalarField>,
P: DenseUVPolynomial<G::ScalarField, Point = G::ScalarField>,
S: CryptographicSponge,
{
type UniversalParams = UniversalParams<G>;
Expand Down Expand Up @@ -563,8 +587,7 @@ where
let hiding_time = start_timer!(|| "Applying hiding.");
let mut hiding_polynomial = P::rand(d, &mut rng);
hiding_polynomial -= &P::from_coefficients_slice(&[hiding_polynomial.evaluate(point)]);

let hiding_rand = G::ScalarField::rand(rng);
let hiding_rand = G::ScalarField::rand(&mut rng);
let hiding_commitment_proj = Self::cm_commit(
ck.comm_key.as_slice(),
hiding_polynomial.coeffs(),
Expand All @@ -579,15 +602,18 @@ where
hiding_commitment = Some(batch.pop().unwrap());
combined_commitment = batch.pop().unwrap();

let hiding_challenge = Self::compute_random_oracle_challenge(
&ark_ff::to_bytes![
combined_commitment,
point,
combined_v,
hiding_commitment.unwrap()
]
.unwrap(),
);
let mut byte_vec = Vec::new();
combined_commitment
.serialize_uncompressed(&mut byte_vec)
.unwrap();
point.serialize_uncompressed(&mut byte_vec).unwrap();
combined_v.serialize_uncompressed(&mut byte_vec).unwrap();
hiding_commitment
.unwrap()
.serialize_uncompressed(&mut byte_vec)
.unwrap();
let bytes = byte_vec.as_slice();
let hiding_challenge = Self::compute_random_oracle_challenge(bytes);
combined_polynomial += (hiding_challenge, &hiding_polynomial);
combined_rand += &(hiding_challenge * &hiding_rand);
combined_commitment_proj +=
Expand All @@ -608,9 +634,14 @@ where
combined_commitment = combined_commitment_proj.into_affine();

// ith challenge
let mut round_challenge = Self::compute_random_oracle_challenge(
&ark_ff::to_bytes![combined_commitment, point, combined_v].unwrap(),
);
let mut byte_vec = Vec::new();
combined_commitment
.serialize_uncompressed(&mut byte_vec)
.unwrap();
point.serialize_uncompressed(&mut byte_vec).unwrap();
combined_v.serialize_uncompressed(&mut byte_vec).unwrap();
let bytes = byte_vec.as_slice();
let mut round_challenge = Self::compute_random_oracle_challenge(bytes);

let h_prime = ck.h.mul(round_challenge).into_affine();

Expand Down Expand Up @@ -662,9 +693,14 @@ where
l_vec.push(lr[0]);
r_vec.push(lr[1]);

round_challenge = Self::compute_random_oracle_challenge(
&ark_ff::to_bytes![round_challenge, lr[0], lr[1]].unwrap(),
);
let mut byte_vec = Vec::new();
round_challenge
.serialize_uncompressed(&mut byte_vec)
.unwrap();
lr[0].serialize_uncompressed(&mut byte_vec).unwrap();
lr[1].serialize_uncompressed(&mut byte_vec).unwrap();
let bytes = byte_vec.as_slice();
round_challenge = Self::compute_random_oracle_challenge(bytes);
let round_challenge_inv = round_challenge.inverse().unwrap();

ark_std::cfg_iter_mut!(coeffs_l)
Expand Down Expand Up @@ -1042,7 +1078,7 @@ mod tests {
use ark_ec::AffineCurve;
use ark_ed_on_bls12_381::{EdwardsAffine, Fr};
use ark_ff::PrimeField;
use ark_poly::{univariate::DensePolynomial as DensePoly, UVPolynomial};
use ark_poly::{univariate::DensePolynomial as DensePoly, DenseUVPolynomial};
use ark_sponge::poseidon::PoseidonSponge;
use blake2::Blake2s;
use rand_chacha::ChaCha20Rng;
Expand Down
Loading

0 comments on commit 88c97d2

Please sign in to comment.