Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plonk: multiprover: proof-system: Add MpcCircuit and MpcArithmetization traits #7

Merged
merged 2 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions plonk/src/multiprover/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! The `multiprover` module extends the `jellyfish` plonk implementation to
//! support collaborative proofs as examined by Ozdemir and Boneh: https://eprint.iacr.org/2021/1530

pub mod mpc_transcript;
pub mod multiprover_kzg;
pub mod primitives;
pub mod proof_system;
7 changes: 7 additions & 0 deletions plonk/src/multiprover/primitives/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//! Defines primitives used in the collaborative SNARK

mod mpc_transcript;
mod multiprover_kzg;

pub use mpc_transcript::*;
pub use multiprover_kzg::*;
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ mod test {
use rand::{thread_rng, CryptoRng, Rng, RngCore};

use crate::{
multiprover::mpc_transcript::MpcTranscript,
multiprover::primitives::MpcTranscript,
transcript::{PlonkTranscript, SolidityTranscript},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ mod test {
use jf_utils::test_rng;
use rand::Rng;

use crate::multiprover::multiprover_kzg::MultiproverKZG;
use crate::multiprover::primitives::MultiproverKZG;

/// The curve used for testing
type TestCurve = Bn254;
Expand Down
231 changes: 231 additions & 0 deletions plonk/src/multiprover/proof_system/constraint_system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
//! Defines the arithmetization and circuit abstractions over a base
//! MPC-enabled arithmetic

use ark_ec::CurveGroup;
use ark_ff::FftField;
use ark_mpc::algebra::{AuthenticatedDensePoly, AuthenticatedScalarResult};
use ark_poly::univariate::DensePolynomial;

use super::MpcCircuitError;

/// The variable type in an MPC constraint system
joeykraut marked this conversation as resolved.
Show resolved Hide resolved
///
/// This represents an index into the wire assignments as flattened out
/// canonically
pub type MpcVariable = usize;
/// A variable of boolean type
pub struct MpcBoolVar(usize);

impl From<MpcBoolVar> for MpcVariable {
fn from(value: MpcBoolVar) -> Self {
value.0
}
}

impl MpcBoolVar {
/// Create a new boolean variable from a variable index
///
/// Do not constrain the underlying value to be boolean
pub(crate) fn new_unchecked(inner: usize) -> Self {
Self(inner)
}
}

/// The circuit abstraction; contains information about circuit structure and
/// methods for constructing the circuit gate-by-gate
///
/// This is largely a re-implementation of the existing `Circuit` trait, made to
/// work over a secret shared field
pub trait MpcCircuit<C: CurveGroup> {
/// The number of constraints
fn num_gates(&self) -> usize;

/// The number of variables
fn num_variables(&self) -> usize;

/// The number of public inputs
fn num_inputs(&self) -> usize;

/// The number of wire types
///
/// We do not support UltraPlonk so this will likely be static
fn num_wire_types(&self) -> usize;

/// The public input to the circuit
///
/// Note that while the input is public, it may not have yet been *made*
/// public so the result type is a secret shared field element
fn public_input(&self) -> Result<Vec<AuthenticatedScalarResult<C>>, MpcCircuitError>;

/// Check whether the circuit constraints are satisfied
fn check_circuit_satisfiability(
&self,
public_input: &[AuthenticatedScalarResult<C>],
) -> Result<(), MpcCircuitError>;

/// Create a constant variable in the circuit, returning the index of the
/// variable
fn create_constant_variable(
&mut self,
val: AuthenticatedScalarResult<C>,
) -> Result<MpcVariable, MpcCircuitError>;

/// Add a variable to the circuit; returns the index of the variable
fn create_variable(
&mut self,
val: AuthenticatedScalarResult<C>,
) -> Result<MpcVariable, MpcCircuitError>;

/// Add a bool variable to the circuit; return the index of the variable.
///
/// In the single-prover version of this method; the input is a `bool`.
/// However, inputs to the multi-prover constraint system are secret
/// shared, so we take in a generic field element.
///
/// We do, however, constrain the underlying shared value to be boolean in
/// the same way the single-prover constraint system does
fn create_boolean_variable(
&mut self,
val: AuthenticatedScalarResult<C>,
) -> Result<MpcBoolVar, MpcCircuitError> {
let var = self.create_variable(val)?;
self.enforce_bool(var)?;
Ok(MpcBoolVar(var))
}

/// Add a public input variable; return the index of the variable.
fn create_public_variable(
&mut self,
val: AuthenticatedScalarResult<C>,
) -> Result<MpcVariable, MpcCircuitError>;

/// Set a variable to a public variable
fn set_variable_public(&mut self, var: MpcVariable) -> Result<(), MpcCircuitError>;

/// Return a default variable with value zero.
fn zero(&self) -> MpcVariable;

/// Return a default variable with value one.
fn one(&self) -> MpcVariable;

/// Return a default variable with value `false` (namely zero).
fn false_var(&self) -> MpcBoolVar {
MpcBoolVar::new_unchecked(self.zero())
}

/// Return a default variable with value `true` (namely one).
fn true_var(&self) -> MpcBoolVar {
MpcBoolVar::new_unchecked(self.one())
}

/// Return the witness value of variable `idx`.
/// Return error if the input variable is invalid.
fn witness(&self, idx: MpcVariable) -> Result<AuthenticatedScalarResult<C>, MpcCircuitError>;

/// Common gates that should be implemented in any constraint systems.
///
/// Constrain a variable to a constant.
/// Return error if `var` is an invalid variable.
fn enforce_constant(
&mut self,
var: MpcVariable,
constant: AuthenticatedScalarResult<C>,
) -> Result<(), MpcCircuitError>;

/// Constrain variable `c` to the addition of `a` and `b`.
/// Return error if the input variables are invalid.
fn add_gate(
&mut self,
a: MpcVariable,
b: MpcVariable,
c: MpcVariable,
) -> Result<(), MpcCircuitError>;

/// Obtain a variable representing an addition.
/// Return the index of the variable.
/// Return error if the input variables are invalid.
fn add(&mut self, a: MpcVariable, b: MpcVariable) -> Result<MpcVariable, MpcCircuitError>;

/// Constrain variable `c` to the subtraction of `a` and `b`.
/// Return error if the input variables are invalid.
fn sub_gate(
&mut self,
a: MpcVariable,
b: MpcVariable,
c: MpcVariable,
) -> Result<(), MpcCircuitError>;

/// Obtain a variable representing a subtraction.
/// Return the index of the variable.
/// Return error if the input variables are invalid.
fn sub(&mut self, a: MpcVariable, b: MpcVariable) -> Result<MpcVariable, MpcCircuitError>;

/// Constrain variable `c` to the multiplication of `a` and `b`.
/// Return error if the input variables are invalid.
fn mul_gate(
&mut self,
a: MpcVariable,
b: MpcVariable,
c: MpcVariable,
) -> Result<(), MpcCircuitError>;

/// Obtain a variable representing a multiplication.
/// Return the index of the variable.
/// Return error if the input variables are invalid.
fn mul(&mut self, a: MpcVariable, b: MpcVariable) -> Result<MpcVariable, MpcCircuitError>;

/// Constrain a variable to a bool.
/// Return error if the input is invalid.
fn enforce_bool(&mut self, a: MpcVariable) -> Result<(), MpcCircuitError>;

/// Constrain two variables to have the same value.
/// Return error if the input variables are invalid.
fn enforce_equal(&mut self, a: MpcVariable, b: MpcVariable) -> Result<(), MpcCircuitError>;

/// Pad the circuit with n dummy gates
fn pad_gates(&mut self, n: usize);
}

/// An abstraction shimming the `Circuit` abstraction and the PIOP based
/// arguments in the MPC prover. The `MpcArithmetization` takes circuit wire
/// assignments and constructs polynomial representations of the assignment
pub trait MpcArithmetization<C: CurveGroup>: MpcCircuit<C>
joeykraut marked this conversation as resolved.
Show resolved Hide resolved
where
C::ScalarField: FftField,
{
/// The required SRS size for the circuit.
fn srs_size(&self) -> Result<usize, MpcCircuitError>;

/// Get the size of the evaluation domain for arithmetization (after circuit
/// has been finalized).
fn eval_domain_size(&self) -> Result<usize, MpcCircuitError>;

/// Compute and return selector polynomials.
/// Return an error if the circuit has not been finalized yet.
fn compute_selector_polynomials(
&self,
) -> Result<Vec<DensePolynomial<C::ScalarField>>, MpcCircuitError>;

/// Compute and return extended permutation polynomials.
/// Return an error if the circuit has not been finalized yet.
fn compute_extended_permutation_polynomials(
&self,
) -> Result<Vec<AuthenticatedDensePoly<C>>, MpcCircuitError>;

/// Compute and return the product polynomial for permutation arguments.
/// Return an error if the circuit has not been finalized yet.
fn compute_prod_permutation_polynomial(
&self,
beta: &C::ScalarField,
gamma: &C::ScalarField,
) -> Result<AuthenticatedDensePoly<C>, MpcCircuitError>;

/// Compute and return the list of wiring witness polynomials.
/// Return an error if the circuit has not been finalized yet.
fn compute_wire_polynomials(&self) -> Result<Vec<AuthenticatedDensePoly<C>>, MpcCircuitError>;

/// Compute and return the public input polynomial.
/// Return an error if the circuit has not been finalized yet.
/// The IO gates of the circuit are guaranteed to be in the front.
fn compute_pub_input_polynomial(&self) -> Result<AuthenticatedDensePoly<C>, MpcCircuitError>;
}
15 changes: 15 additions & 0 deletions plonk/src/multiprover/proof_system/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//! Error types generated by an MPC constraint system

use core::fmt::Display;
use std::error::Error;

/// The error type emitted by MPC circuit operations
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MpcCircuitError {}

impl Display for MpcCircuitError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{self:?}")
}
}
impl Error for MpcCircuitError {}
11 changes: 11 additions & 0 deletions plonk/src/multiprover/proof_system/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! The `proof_system` module defines all the multi-prover components necessary
//! to construct an arithmetization and proofs of satisfaction for this
//! arithmetization

mod constraint_system;
mod error;
mod snark;

pub use constraint_system::*;
pub use error::*;
pub use snark::*;
21 changes: 21 additions & 0 deletions plonk/src/multiprover/proof_system/snark.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! Defines the multiprover analog to the `PlonkKzgSnark` defined in the
//! `proof_system` module of this crate
//!
//! The implementation is designed to closely match the singleprover
//! implementation in structure

use core::marker::PhantomData;

use ark_ec::pairing::Pairing;

/// A multiprover Plonk instantiated with KZG as the underlying polynomial
/// commitment scheme
#[derive(Default)]
pub struct MultiproverPlonkKzgSnark<E: Pairing>(PhantomData<E>);

impl<E: Pairing> MultiproverPlonkKzgSnark<E> {
/// Constructor
pub fn new() -> Self {
Self(PhantomData)
}
}
Loading