Skip to content

Commit

Permalink
refactor: Refactor trait requirements and update CurveCycleEquipped
Browse files Browse the repository at this point in the history
**Context**:

Developing [zeromorph](https://github.com/lurk-lab/arecibo/tree/zeromorph) forced me to abstract several Nova APIs over the used `EvaluationEngineTrait` (which was the point of the whole exercise).
And it forced me to realize that Nova APIs that genericise over the group implementations, in order to represent the concept of a given curve cycle, become a lot simpler when they jointly abstract over the associated `EvaluationEngine`.

This insight led to microsoft/Nova#234

**This PR**:

We prepare the code base from where it is now (hard-coding that the Evaluation Engine used in nova is the IPA, and requiring the corresponding idiosyncratic trait bound `CommitmentKeyExtTrait`) to
something that's Zeromorph-ready (recognizing that any curve cycle may have its unspecified choice of `EvaluationEngineTrait` implementations). We reap the associated simplicity benefits.

**In Detail**:

- Removed Sync and Send trait requirements for multiple associated types across various modules, simplifying the codebase.
- Significant updates made to the trait `CurveCycleEquipped` in `nova.rs`. Removed four previous type and introduced two new ones, `EE1` and `EE2`, shifting the focus towards an improved Evaluation Engine.
- This change in trait `CurveCycleEquipped` is also reflected in the pallas::Scalar and bn256::Scalar trait implementations.
- The necessity for detailed explanations about the removed type aliases in `CurveCycleEquipped` was eliminated. Added brief explanations for the new type aliases.
- Removed `Sync + Send` trait bounds from `F::CK1` and `F::CK2` in the `public_params`, `supernova_circuit_params`, and `supernova_aux_params` functions, resulting in simpler functions.
  • Loading branch information
huitseeker committed Nov 3, 2023
1 parent 014c4d1 commit 68714f5
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 55 deletions.
4 changes: 0 additions & 4 deletions src/cli/lurk_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ impl<'a, F: CurveCycleEquipped + Serialize, M: MultiFrameTrait<'a, F, Coproc<F>>
where
<<G1<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<<G2<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<F as CurveCycleEquipped>::CK1: Sync + Send,
<F as CurveCycleEquipped>::CK2: Sync + Send,
{
#[inline]
pub(crate) fn persist(self, proof_key: &str) -> Result<()> {
Expand All @@ -119,8 +117,6 @@ impl<
where
<<G1<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<<G2<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<F as CurveCycleEquipped>::CK1: Sync + Send,
<F as CurveCycleEquipped>::CK2: Sync + Send,
{
pub(crate) fn verify_proof(proof_key: &str) -> Result<()> {
let lurk_proof: LurkProof<'_, F, Coproc<F>, M> = load(&proof_path(proof_key))?;
Expand Down
2 changes: 0 additions & 2 deletions src/cli/repl/meta_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,6 @@ where
// TODO(huitseeker): this is a bit pedantic, revisit later.
<<G1<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<<G2<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<F as CurveCycleEquipped>::CK1: Sync + Send,
<F as CurveCycleEquipped>::CK2: Sync + Send,
{
const VERIFY: MetaCmd<F> = MetaCmd {
name:
Expand Down
61 changes: 22 additions & 39 deletions src/proof/nova.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ use ff::Field;
use nova::{
errors::NovaError,
provider::bn256_grumpkin::{bn256, grumpkin},
provider::pedersen::CommitmentKeyExtTrait,
traits::{
circuit::{StepCircuit, TrivialCircuit},
commitment::CommitmentEngineTrait,
snark::RelaxedR1CSSNARKTrait,
Group,
Group, evaluation::EvaluationEngineTrait,
},
CircuitShape, CompressedSNARK, ProverKey, RecursiveSNARK, VerifierKey,
};
Expand Down Expand Up @@ -45,53 +43,38 @@ use crate::{
/// (currently Pallas/Vesta and BN254/Grumpkin). It being pegged on the `LurkField` trait encodes that we do
/// not expect more than one such cycle to be supported at a time for a given field.
pub trait CurveCycleEquipped: LurkField {
/// ## Why the next 4 types?
///
/// The next 4 types are purely technical, and aim at laying out type bounds in a way that rust can find them.
/// They should eventually be replaceable by a bound on projections, once bounds on associated types progress.
/// They are technically equivalent to bounds of
/// <Self::G1::CE as CommitmentEngineTrait<Self::G1>>::CommitmentKey: CommitmentKeyExtTrait<Self::G1, CE = <Self::G1 as Group>::CE>,
/// <Self::G2::CE as CommitmentEngineTrait<Self::G2>>::CommitmentKey: CommitmentKeyExtTrait<Self::G2, CE = <G2 as Group>::CE>,
/// but where clauses can't be *found* by the compiler at the point where Self::G1, Self::G2 are used

/// ## OK, but why do we need bounds at all in the first place?
///
/// As to *why* those see https://github.com/microsoft/Nova/pull/200
/// and the bound `CommitmentKey<G>: CommitmentKeyExtTrait<G, CE = G::CE>` on [`nova::provider::ipa_pc::EvaluationEngine<G>`]
/// Essentially, Nova relies on a commitment scheme that is additively homomorphic, but encodes the practicalities of this
/// (properties are unwieldy to encode) in the form of this CommitmentKeyExtTrait.

/// The type of the commitment key used for points of the first curve in the cycle.
type CK1: CommitmentKeyExtTrait<Self::G1>;
/// The type of the commitment key used for points of the second curve in the cycle.
type CK2: CommitmentKeyExtTrait<Self::G2>;
/// The commitment engine type for the first curve in the cycle.
type CE1: CommitmentEngineTrait<Self::G1, CommitmentKey = Self::CK1>;
/// The commitment engine type for the second curve in the cycle.
type CE2: CommitmentEngineTrait<Self::G2, CommitmentKey = Self::CK2>;
/// ## Why the next 2 types?

/// In theory it would be sufficient to abstract over the two group types of the curve cycle, but in practice Nova is a
/// bit idiosyncratic in the [`nova::traits::evaluation::EvaluationEngineTrait<G>`], (PCS) it uses on these (its multilinear IPA : [`nova::provider::ipa_pc::EvaluationEngine<G>`])
/// *and* that implementation requires an additional trait bound `CommitmentKeyExtTrait` for this type.
///
/// The following abstracts over curve cycle groups for which there exists an implementation of [`nova::traits::evaluation::EvaluationEngineTrait<G>`],
/// encapsulating these idiosyncracies within Nova.

/// a concrete implementation of an [`nova::traits::evaluation::EvaluationEngineTrait<G>`] for G1,
type EE1: EvaluationEngineTrait<Self::G1>;
/// a concrete implementation of an [`nova::traits::evaluation::EvaluationEngineTrait<G>`] for G2,
type EE2: EvaluationEngineTrait<Self::G2>;

/// The group type for the first curve in the cycle.
type G1: Group<Base = <Self::G2 as Group>::Scalar, Scalar = Self, CE = Self::CE1>;
type G1: Group<Base = <Self::G2 as Group>::Scalar, Scalar = Self>;
/// The group type for the second curve in the cycle.
type G2: Group<Base = <Self::G1 as Group>::Scalar, CE = Self::CE2>;
type G2: Group<Base = <Self::G1 as Group>::Scalar>;
}

impl CurveCycleEquipped for pallas::Scalar {
type CK1 = nova::provider::pedersen::CommitmentKey<pallas::Point>;
type CK2 = nova::provider::pedersen::CommitmentKey<vesta::Point>;
type CE1 = nova::provider::pedersen::CommitmentEngine<pallas::Point>;
type CE2 = nova::provider::pedersen::CommitmentEngine<vesta::Point>;
type EE1 = nova::provider::ipa_pc::EvaluationEngine<Self::G1>;
type EE2 = nova::provider::ipa_pc::EvaluationEngine<Self::G2>;

type G1 = pallas::Point;
type G2 = vesta::Point;
}
// The impl CurveCycleEquipped for vesta::Scalar is academically possible, but voluntarily omitted to avoid confusion.

impl CurveCycleEquipped for bn256::Scalar {
type CK1 = nova::provider::pedersen::CommitmentKey<bn256::Point>;
type CK2 = nova::provider::pedersen::CommitmentKey<grumpkin::Point>;
type CE1 = nova::provider::pedersen::CommitmentEngine<bn256::Point>;
type CE2 = nova::provider::pedersen::CommitmentEngine<grumpkin::Point>;
type EE1 = nova::provider::ipa_pc::EvaluationEngine<Self::G1>;
type EE2 = nova::provider::ipa_pc::EvaluationEngine<Self::G2>;

type G1 = bn256::Point;
type G2 = grumpkin::Point;
Expand All @@ -104,9 +87,9 @@ pub type G1<F> = <F as CurveCycleEquipped>::G1;
pub type G2<F> = <F as CurveCycleEquipped>::G2;

/// Type alias for the Evaluation Engine using G1 group elements.
pub type EE1<F> = nova::provider::ipa_pc::EvaluationEngine<G1<F>>;
pub type EE1<F> = <F as CurveCycleEquipped>::EE1;
/// Type alias for the Evaluation Engine using G2 group elements.
pub type EE2<F> = nova::provider::ipa_pc::EvaluationEngine<G2<F>>;
pub type EE2<F> = <F as CurveCycleEquipped>::EE2;

/// Type alias for the Relaxed R1CS Spartan SNARK using G1 group elements, EE1.
// NOTE: this is not a SNARK that uses computational commitments,
Expand Down
2 changes: 0 additions & 2 deletions src/public_parameters/mem_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ impl PublicParamMemCache {
default: Fn,
) -> Result<Arc<PublicParams<F, M>>, Error>
where
F::CK1: Sync + Send,
F::CK2: Sync + Send,
<<G1<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<<G2<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
{
Expand Down
8 changes: 0 additions & 8 deletions src/public_parameters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ pub fn public_params<
instance: &Instance<'static, F, C, M>,
) -> Result<Arc<PublicParams<F, M>>, Error>
where
F::CK1: Sync + Send,
F::CK2: Sync + Send,
<<G1<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<<G2<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
{
Expand Down Expand Up @@ -90,8 +88,6 @@ pub fn supernova_circuit_params<
instance: &Instance<'a, F, C, M>,
) -> Result<NovaCircuitShape<F>, Error>
where
F::CK1: Sync + Send,
F::CK2: Sync + Send,
<<G1<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<<G2<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
{
Expand All @@ -118,8 +114,6 @@ pub fn supernova_aux_params<
instance: &Instance<'a, F, C, M>,
) -> Result<SuperNovaAuxParams<F>, Error>
where
F::CK1: Sync + Send,
F::CK2: Sync + Send,
<<G1<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<<G2<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
{
Expand Down Expand Up @@ -151,8 +145,6 @@ pub fn supernova_public_params<
instance_primary: &Instance<'a, F, C, M>,
) -> Result<supernova::PublicParams<F, M>, Error>
where
F::CK1: Sync + Send,
F::CK2: Sync + Send,
<<G1<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
<<G2<F> as Group>::Scalar as ff::PrimeField>::Repr: Abomonation,
{
Expand Down

0 comments on commit 68714f5

Please sign in to comment.