Skip to content

Commit

Permalink
more running claims API
Browse files Browse the repository at this point in the history
  • Loading branch information
winston-h-zhang committed Sep 20, 2023
1 parent beb7aac commit dec2f5a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 74 deletions.
6 changes: 5 additions & 1 deletion src/provider/pasta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ macro_rules! impl_traits {
type CE = CommitmentEngine<Self>;

#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
#[tracing::instrument(skip_all, level = "trace", name = "<_ as Group>::vartime_multiscalar_mul")]
#[tracing::instrument(
skip_all,
level = "trace",
name = "<_ as Group>::vartime_multiscalar_mul"
)]
fn vartime_multiscalar_mul(
scalars: &[Self::Scalar],
bases: &[Self::PreprocessedGroupElement],
Expand Down
6 changes: 5 additions & 1 deletion src/r1cs/sparse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ impl<F: PrimeField> SparseMatrix<F> {

/// Multiply by a dense vector; uses rayon/gpu.
/// This does not check that the shape of the matrix/vector are compatible.
#[tracing::instrument(skip_all, level = "trace", name = "SparseMatrix::multiply_vec_unchecked")]
#[tracing::instrument(
skip_all,
level = "trace",
name = "SparseMatrix::multiply_vec_unchecked"
)]
pub fn multiply_vec_unchecked(&self, vector: &[F]) -> Vec<F> {
self
.indptr
Expand Down
138 changes: 66 additions & 72 deletions src/supernova/mod.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
//! This library implements SuperNova, a Non-Uniform IVC based on Nova.

use std::io;
use std::marker::PhantomData;
use std::ops::Index;
use std::{cmp::max, io};

use crate::{
bellpepper::shape_cs::ShapeCS,
constants::{BN_LIMB_WIDTH, BN_N_LIMBS, NUM_HASH_BITS},
digest::{DigestComputer, Digestible, SimpleDigestible},
errors::NovaError,
r1cs::{
commitment_key, commitment_key_size, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance,
commitment_key_size, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance,
RelaxedR1CSWitness,
},
scalar_as_base,
traits::{
circuit_supernova::{EnforcingStepCircuit, StepCircuit, TrivialSecondaryCircuit},
commitment::CommitmentTrait,
commitment::{CommitmentEngineTrait, CommitmentTrait, Len},
AbsorbInROTrait, Group, ROConstants, ROConstantsCircuit, ROTrait,
},
Commitment, CommitmentKey,
Expand Down Expand Up @@ -189,8 +189,13 @@ where
// Once we serialize this struct, it's important to add this
// annotaiton to the digest field for it to be treated properly: #[serde(skip, default = "OnceCell::new")]
digest: OnceCell<G1::Scalar>,
stage: Stage,
_p: PhantomData<C1>,
}
enum Stage {
Incomplete,
Complete,
}

impl<G1, G2, C1> Index<usize> for RunningClaimParams<G1, G2, C1>
where
Expand Down Expand Up @@ -249,65 +254,97 @@ where
let mut running_claim_params = RunningClaimParams {
pp_vec,
digest: OnceCell::new(),
stage: Stage::Incomplete,
_p: PhantomData,
};

running_claim_params.set_commitment_keys();
running_claim_params.complete();
running_claim_params
}

/// AHHHH
pub fn from_pp_vec(pp_vec: Vec<PublicParams<G1, G2>>) -> Self {
RunningClaimParams {
pub fn from_pp_vec(pp_vec: Vec<PublicParams<G1, G2>>, digest: OnceCell<G1::Scalar>) -> Self {
let num_pp = pp_vec.len();
let primary_len = &pp_vec[0].ck_primary.as_ref().map_or(0, Len::length);
let secondary_len = &pp_vec[0].ck_secondary.as_ref().map_or(0, Len::length);
let num_complete = pp_vec
.iter()
.filter(|pp| {
pp.ck_primary.is_some()
&& pp.ck_secondary.is_some()
&& &pp.ck_primary.as_ref().unwrap().length() == primary_len
&& &pp.ck_secondary.as_ref().unwrap().length() == secondary_len
})
.count();

let stage = if num_complete == num_pp {
Stage::Complete
} else {
Stage::Incomplete
};

let mut running_claim_params = RunningClaimParams {
pp_vec,
digest: OnceCell::new(),
digest,
stage,
_p: PhantomData,
}
};

running_claim_params.complete();
running_claim_params
}

/// Compute primary and secondary commitment keys sized to handle the largest of the circuits in the provided
/// `PublicParams`.
pub fn compute_commitment_keys(&self) -> (CommitmentKey<G1>, CommitmentKey<G2>) {
macro_rules! max_shape {
($shape_getter:ident) => {
fn compute_commitment_keys(&self) -> (CommitmentKey<G1>, CommitmentKey<G2>) {
macro_rules! max_size {
($shape_getter:ident, $ck_getter:ident) => {
self
.pp_vec
.iter()
.map(|params| {
let shape = &params.$shape_getter;
let size = commitment_key_size(&shape, None);
(shape, size)
.map(|pp| {
let ck_len = if let Some(ck) = &pp.$ck_getter {
ck.length()
} else {
0
};
max(ck_len, commitment_key_size(&pp.$shape_getter, None))
})
.max_by(|a, b| a.1.cmp(&b.1))
.max()
.unwrap()
.0
};
}

let shape_primary = max_shape!(r1cs_shape_primary);
let shape_secondary = max_shape!(r1cs_shape_secondary);
let size_primary = max_size!(r1cs_shape_primary, ck_primary);
let size_secondary = max_size!(r1cs_shape_secondary, ck_secondary);

let ck_primary = commitment_key(shape_primary, None);
let ck_secondary = commitment_key(shape_secondary, None);
let ck_primary = G1::CE::setup(b"ck", size_primary);
let ck_secondary = G2::CE::setup(b"ck", size_secondary);

(ck_primary, ck_secondary)
}

/// get primary/secondary circuit r1cs shape
// pub fn get_r1cs_shape(&self) -> (&R1CSShape<G1>, &R1CSShape<G2>) {
// (
// &self.params.r1cs_shape_primary,
// &self.params.r1cs_shape_secondary,
// )
// }
/// Completes the set of public params
pub fn complete(&mut self) {
if matches!(self.stage, Stage::Complete) {
return;
}

self.set_commitment_keys();
self.digest();
}

/// set primary/secondary commitment key for all the params
pub fn set_commitment_keys(&mut self) {
fn set_commitment_keys(&mut self) {
if matches!(self.stage, Stage::Complete) {
return;
}
let (ck_primary, ck_secondary) = self.compute_commitment_keys();
for pp in self.pp_vec.iter_mut() {
pp.ck_primary = Some(ck_primary.clone()); // TODO: the keys should be shared across all the params
pp.ck_secondary = Some(ck_secondary.clone()); // TODO: the keys should be shared across all the params
}
self.stage = Stage::Complete;
}

/// Return the [RunningClaimParams]' digest.
Expand Down Expand Up @@ -403,29 +440,6 @@ where
}
}

/// get primary/secondary circuit r1cs shape
// pub fn get_r1cs_shape(&self) -> (&R1CSShape<G1>, &R1CSShape<G2>) {
// (
// &self.params.r1cs_shape_primary,
// &self.params.r1cs_shape_secondary,
// )
// }

/// set primary/secondary commitment key
// pub fn set_commitment_key(
// &mut self,
// ck_primary: CommitmentKey<G1>,
// ck_secondary: CommitmentKey<G2>,
// ) {
// self.params.ck_primary = Some(ck_primary);
// self.params.ck_secondary = Some(ck_secondary);
// }

/// Get the `PublicParams`.
// pub fn get_public_params(&self) -> &PublicParams<G1, G2> {
// &self.params
// }

/// Get this `RunningClaim`'s augmented circuit index.
pub fn get_circuit_index(&self) -> usize {
self.augmented_circuit_index
Expand Down Expand Up @@ -476,8 +490,6 @@ where
z0_primary: &[G1::Scalar],
z0_secondary: &[G2::Scalar],
) -> Result<Self, SuperNovaError> {
tracing::info_span!("bang!").in_scope(|| {});
// let pp = &claim.get_public_params();
let c_secondary = &claim.c_secondary;
// commitment key for primary & secondary circuit
let ck_primary = pp.ck_primary.as_ref().ok_or(SuperNovaError::MissingCK)?;
Expand All @@ -489,8 +501,6 @@ where
));
}

tracing::info_span!("bang!").in_scope(|| {});

// base case for the primary
let mut cs_primary: SatisfyingAssignment<G1> = SatisfyingAssignment::new();
let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, G2> =
Expand All @@ -506,8 +516,6 @@ where
G1::Scalar::ZERO, // set augmented circuit index selector to 0 in base case
);

tracing::info_span!("bang!").in_scope(|| {});

let circuit_primary: SuperNovaAugmentedCircuit<'_, G2, C1> = SuperNovaAugmentedCircuit::new(
&pp.augmented_circuit_params_primary,
Some(inputs_primary),
Expand All @@ -516,8 +524,6 @@ where
num_augmented_circuits,
);

tracing::info_span!("bang!").in_scope(|| {});

let (zi_primary_pc_next, zi_primary) =
circuit_primary.synthesize(&mut cs_primary).map_err(|err| {
debug!("err {:?}", err);
Expand All @@ -535,8 +541,6 @@ where
SuperNovaError::NovaError(NovaError::SynthesisError)
})?;

tracing::info_span!("bang!").in_scope(|| {});

// base case for the secondary
let mut cs_secondary: SatisfyingAssignment<G2> = SatisfyingAssignment::new();
let inputs_secondary: SuperNovaAugmentedCircuitInputs<'_, G1> =
Expand Down Expand Up @@ -570,8 +574,6 @@ where
.r1cs_instance_and_witness(&pp.r1cs_shape_secondary, ck_secondary)
.map_err(|_| SuperNovaError::NovaError(NovaError::UnSat))?;

tracing::info_span!("bang!").in_scope(|| {});

// IVC proof for the primary circuit
let l_w_primary = w_primary;
let l_u_primary = u_primary;
Expand All @@ -580,8 +582,6 @@ where
let r_U_primary =
RelaxedR1CSInstance::from_r1cs_instance(ck_primary, &pp.r1cs_shape_primary, &l_u_primary);

tracing::info_span!("bang!").in_scope(|| {});

// IVC proof of the secondary circuit
let l_w_secondary = w_secondary;
let l_u_secondary = u_secondary;
Expand All @@ -593,8 +593,6 @@ where
&pp.r1cs_shape_secondary,
))];

tracing::info_span!("bang!").in_scope(|| {});

// Outputs of the two circuits and next program counter thus far.
let zi_primary = zi_primary
.iter()
Expand All @@ -615,8 +613,6 @@ where
})
.collect::<Result<Vec<<G2 as Group>::Scalar>, SuperNovaError>>()?;

tracing::info_span!("bang!").in_scope(|| {});

// handle the base case by initialize U_next in next round
let r_W_primary_initial_list = (0..num_augmented_circuits)
.map(|i| (i == first_augmented_circuit_index).then(|| r_W_primary.clone()))
Expand All @@ -626,8 +622,6 @@ where
.map(|i| (i == first_augmented_circuit_index).then(|| r_U_primary.clone()))
.collect::<Vec<Option<RelaxedR1CSInstance<G1>>>>();

tracing::info_span!("bang!").in_scope(|| {});

Ok(Self {
r_W_primary: r_W_primary_initial_list,
r_U_primary: r_U_primary_initial_list,
Expand Down

0 comments on commit dec2f5a

Please sign in to comment.