Skip to content
Snippets Groups Projects
Unverified Commit 8300ed76 authored by Weikeng Chen's avatar Weikeng Chen Committed by GitHub
Browse files

Add traits for constraints (#59)


* add the trait part of the constraints

* fix

* Update src/constraints.rs

Co-authored-by: default avatarPratyush Mishra <pratyushmishra@berkeley.edu>

* Update src/constraints.rs

Co-authored-by: default avatarPratyush Mishra <pratyushmishra@berkeley.edu>

* Update src/constraints.rs

Co-authored-by: default avatarPratyush Mishra <pratyushmishra@berkeley.edu>

* Update src/constraints.rs

Co-authored-by: default avatarPratyush Mishra <pratyushmishra@berkeley.edu>

* Update src/constraints.rs

Co-authored-by: default avatarPratyush Mishra <pratyushmishra@berkeley.edu>

* fix

Co-authored-by: default avatarPratyush Mishra <pratyushmishra@berkeley.edu>
parent 18619538
No related branches found
No related tags found
No related merge requests found
...@@ -27,6 +27,10 @@ ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = fa ...@@ -27,6 +27,10 @@ ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = fa
ark-poly = { git = "https://github.com/arkworks-rs/algebra", default-features = false } ark-poly = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false } ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false }
ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features = false, optional = true }
ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std", default-features = false, optional = true }
ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative", default-features = false, optional = true }
hashbrown = { version = "0.9", optional = true }
bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false }
...@@ -57,5 +61,6 @@ debug = true ...@@ -57,5 +61,6 @@ debug = true
[features] [features]
default = [ "std", "parallel" ] default = [ "std", "parallel" ]
std = [ "ark-ff/std", "ark-ec/std", "ark-poly/std", "ark-std/std", "ark-serialize/std" ] std = [ "ark-ff/std", "ark-ec/std", "ark-poly/std", "ark-std/std", "ark-serialize/std" ]
r1cs = [ "ark-relations", "ark-r1cs-std", "ark-nonnative-field", "hashbrown" ]
print-trace = [ "bench-utils/print-trace" ] print-trace = [ "bench-utils/print-trace" ]
parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ] parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ]
use crate::{
data_structures::LabeledCommitment, BatchLCProof, LCTerm, LinearCombination,
PolynomialCommitment, String, Vec,
};
use ark_ff::PrimeField;
use ark_nonnative_field::NonNativeFieldVar;
use ark_poly::Polynomial;
use ark_r1cs_std::{fields::fp::FpVar, prelude::*};
use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError};
use ark_std::{borrow::Borrow, cmp::Eq, cmp::PartialEq, hash::Hash, marker::Sized};
use hashbrown::{HashMap, HashSet};
/// Define the minimal interface of prepared allocated structures.
pub trait PrepareGadget<Unprepared, ConstraintF: PrimeField>: Sized {
/// Prepare from an unprepared element.
fn prepare(unprepared: &Unprepared) -> R1CSResult<Self>;
}
/// A coefficient of `LinearCombination`.
#[allow(non_camel_case_types)]
#[derive(Clone)]
pub enum LinearCombinationCoeffVar<TargetField: PrimeField, BaseField: PrimeField> {
/// Coefficient 1.
One,
/// Coefficient -1.
MinusOne,
/// Other coefficient, represented as a nonnative field element.
Var(NonNativeFieldVar<TargetField, BaseField>),
}
/// An allocated version of `LinearCombination`.
#[derive(Clone)]
pub struct LinearCombinationVar<TargetField: PrimeField, BaseField: PrimeField> {
/// The label.
pub label: String,
/// The linear combination of `(coeff, poly_label)` pairs.
pub terms: Vec<(LinearCombinationCoeffVar<TargetField, BaseField>, LCTerm)>,
}
impl<TargetField: PrimeField, BaseField: PrimeField>
AllocVar<LinearCombination<TargetField>, BaseField>
for LinearCombinationVar<TargetField, BaseField>
{
fn new_variable<T>(
cs: impl Into<Namespace<BaseField>>,
val: impl FnOnce() -> Result<T, SynthesisError>,
mode: AllocationMode,
) -> R1CSResult<Self>
where
T: Borrow<LinearCombination<TargetField>>,
{
let LinearCombination { label, terms } = val()?.borrow().clone();
let ns = cs.into();
let cs = ns.cs();
let new_terms: Vec<(LinearCombinationCoeffVar<TargetField, BaseField>, LCTerm)> = terms
.iter()
.map(|term| {
let (f, lc_term) = term;
let fg =
NonNativeFieldVar::new_variable(ark_relations::ns!(cs, "term"), || Ok(f), mode)
.unwrap();
(LinearCombinationCoeffVar::Var(fg), lc_term.clone())
})
.collect();
Ok(Self {
label,
terms: new_terms,
})
}
}
#[derive(Clone)]
/// A collection of random data used in the polynomial commitment checking.
pub struct PCCheckRandomDataVar<TargetField: PrimeField, BaseField: PrimeField> {
/// Opening challenges.
/// The prover and the verifier MUST use the same opening challenges.
pub opening_challenges: Vec<NonNativeFieldVar<TargetField, BaseField>>,
/// Bit representations of the opening challenges.
pub opening_challenges_bits: Vec<Vec<Boolean<BaseField>>>,
/// Batching random numbers.
/// The verifier can choose these numbers freely, as long as they are random.
pub batching_rands: Vec<NonNativeFieldVar<TargetField, BaseField>>,
/// Bit representations of the batching random numbers.
pub batching_rands_bits: Vec<Vec<Boolean<BaseField>>>,
}
/// Describes the interface for a gadget for a `PolynomialCommitment`
/// verifier.
pub trait PCCheckVar<
PCF: PrimeField,
P: Polynomial<PCF>,
PC: PolynomialCommitment<PCF, P>,
ConstraintF: PrimeField,
>: Clone
{
/// An allocated version of `PC::VerifierKey`.
type VerifierKeyVar: AllocVar<PC::VerifierKey, ConstraintF> + Clone + ToBytesGadget<ConstraintF>;
/// 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>;
/// An allocated version of `PC::PreparedCommitment`.
type PreparedCommitmentVar: AllocVar<PC::PreparedCommitment, ConstraintF>
+ PrepareGadget<Self::CommitmentVar, ConstraintF>
+ Clone;
/// An allocated version of `LabeledCommitment<PC::Commitment>`.
type LabeledCommitmentVar: AllocVar<LabeledCommitment<PC::Commitment>, ConstraintF> + Clone;
/// A prepared, allocated version of `LabeledCommitment<PC::Commitment>`.
type PreparedLabeledCommitmentVar: Clone;
/// An allocated version of `PC::Proof`.
type ProofVar: AllocVar<PC::Proof, ConstraintF> + Clone;
/// An allocated version of `PC::BatchLCProof`.
type BatchLCProofVar: AllocVar<BatchLCProof<PCF, P, PC>, ConstraintF> + Clone;
/// Add to `ConstraintSystemRef<ConstraintF>` new constraints that check that `proof_i` is a valid evaluation
/// proof at `point_i` for the polynomial in `commitment_i`.
fn batch_check_evaluations(
cs: ConstraintSystemRef<ConstraintF>,
verification_key: &Self::VerifierKeyVar,
commitments: &[Self::LabeledCommitmentVar],
query_set: &QuerySetVar<PCF, ConstraintF>,
evaluations: &EvaluationsVar<PCF, ConstraintF>,
proofs: &[Self::ProofVar],
rand_data: &PCCheckRandomDataVar<PCF, ConstraintF>,
) -> R1CSResult<Boolean<ConstraintF>>;
/// Add to `ConstraintSystemRef<ConstraintF>` new constraints that conditionally check that `proof` is a valid evaluation
/// proof at the points in `query_set` for the combinations `linear_combinations`.
fn prepared_check_combinations(
cs: ConstraintSystemRef<ConstraintF>,
prepared_verification_key: &Self::PreparedVerifierKeyVar,
linear_combinations: &[LinearCombinationVar<PCF, ConstraintF>],
prepared_commitments: &[Self::PreparedLabeledCommitmentVar],
query_set: &QuerySetVar<PCF, ConstraintF>,
evaluations: &EvaluationsVar<PCF, ConstraintF>,
proof: &Self::BatchLCProofVar,
rand_data: &PCCheckRandomDataVar<PCF, ConstraintF>,
) -> R1CSResult<Boolean<ConstraintF>>;
/// Create the labeled commitment gadget from the commitment gadget
fn create_labeled_commitment(
label: String,
commitment: Self::CommitmentVar,
degree_bound: Option<FpVar<ConstraintF>>,
) -> Self::LabeledCommitmentVar;
/// Create the prepared labeled commitment gadget from the commitment gadget
fn create_prepared_labeled_commitment(
label: String,
commitment: Self::PreparedCommitmentVar,
degree_bound: Option<FpVar<ConstraintF>>,
) -> Self::PreparedLabeledCommitmentVar;
}
#[derive(Clone, Hash, PartialEq, Eq)]
/// A labeled point variable, for queries to a polynomial commitment.
pub struct LabeledPointVar<TargetField: PrimeField, BaseField: PrimeField> {
/// The label of the point.
/// MUST be a unique identifier in a query set.
pub name: String,
/// The point value.
pub value: NonNativeFieldVar<TargetField, BaseField>,
}
/// An allocated version of `QuerySet`.
#[derive(Clone)]
pub struct QuerySetVar<TargetField: PrimeField, BaseField: PrimeField>(
pub HashSet<(String, LabeledPointVar<TargetField, BaseField>)>,
);
/// An allocated version of `Evaluations`.
#[derive(Clone)]
pub struct EvaluationsVar<TargetField: PrimeField, BaseField: PrimeField>(
pub HashMap<LabeledPointVar<TargetField, BaseField>, NonNativeFieldVar<TargetField, BaseField>>,
);
impl<TargetField: PrimeField, BaseField: PrimeField> EvaluationsVar<TargetField, BaseField> {
/// find the evaluation result
pub fn get_lc_eval(
&self,
lc_string: &str,
point: &NonNativeFieldVar<TargetField, BaseField>,
) -> Result<NonNativeFieldVar<TargetField, BaseField>, SynthesisError> {
let key = LabeledPointVar::<TargetField, BaseField> {
name: String::from(lc_string),
value: point.clone(),
};
Ok(self.0.get(&key).map(|v| (*v).clone()).unwrap())
}
}
...@@ -33,6 +33,12 @@ use ark_std::{ ...@@ -33,6 +33,12 @@ use ark_std::{
pub mod data_structures; pub mod data_structures;
pub use data_structures::*; pub use data_structures::*;
/// R1CS constraints for polynomial constraints.
#[cfg(feature = "r1cs")]
mod constraints;
#[cfg(feature = "r1cs")]
pub use constraints::*;
/// Errors pertaining to query sets. /// Errors pertaining to query sets.
pub mod error; pub mod error;
pub use error::*; pub use error::*;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment