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

feat!: remove the compress_selectors field from VerifyingKey #310

Merged
merged 13 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 10 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: 0 additions & 4 deletions halo2_backend/src/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ pub struct VerifyingKey<C: CurveAffine> {
cs_degree: usize,
/// The representative of this `VerifyingKey` in transcripts.
transcript_repr: C::Scalar,
/// Legacy field that indicates wether the circuit was compiled with compressed selectors or
/// not using the legacy API.
pub compress_selectors: Option<bool>,
}

// Current version of the VK
Expand Down Expand Up @@ -187,7 +184,6 @@ impl<C: CurveAffine> VerifyingKey<C> {
cs_degree,
// Temporary, this is not pinned.
transcript_repr: C::Scalar::ZERO,
compress_selectors: None,
};

let mut hasher = Blake2bParams::new()
Expand Down
4 changes: 2 additions & 2 deletions halo2_proofs/src/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ mod verifier {
pub use halo2_backend::plonk::verifier::verify_proof;
}

pub use keygen::{keygen_pk, keygen_vk, keygen_vk_custom};
pub use keygen::{keygen_pk, keygen_pk_custom, keygen_vk, keygen_vk_custom};

pub use prover::create_proof;
pub use prover::{create_proof, create_proof_custom};
pub use verifier::verify_proof;

pub use error::Error;
Expand Down
48 changes: 39 additions & 9 deletions halo2_proofs/src/plonk/keygen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ use halo2_frontend::plonk::Circuit;
use halo2_middleware::ff::FromUniformBytes;

/// Generate a `VerifyingKey` from an instance of `Circuit`.
/// By default, selector compression is turned **off**.
/// By default, selector compression is turned **ON**.
///
/// **NOTE**: This `keygen_vk` is legacy one, assuming that `compress_selector: true`.
/// Hence, it is HIGHLY recommended to pair this util with `keygen_pk`.
/// In addition, when using this for key generation, user MUST use `compress_selectors: true`.
pub fn keygen_vk<'params, C, P, ConcreteCircuit>(
params: &P,
circuit: &ConcreteCircuit,
Expand All @@ -26,6 +30,11 @@ where
/// Generate a `VerifyingKey` from an instance of `Circuit`.
///
/// The selector compression optimization is turned on only if `compress_selectors` is `true`.
///
/// **NOTE**: This `keygen_vk_custom` MUST share the same `compress_selectors` with
/// `ProvingKey` generation process.
/// Otherwise, the user could get unmatching pk/vk pair.
/// Hence, it is HIGHLY recommended to pair this util with `keygen_pk_custom`.
pub fn keygen_vk_custom<'params, C, P, ConcreteCircuit>(
params: &P,
circuit: &ConcreteCircuit,
Expand All @@ -38,12 +47,15 @@ where
C::Scalar: FromUniformBytes<64>,
{
let (compiled_circuit, _, _) = compile_circuit(params.k(), circuit, compress_selectors)?;
let mut vk = keygen_vk_v2(params, &compiled_circuit)?;
vk.compress_selectors = Some(compress_selectors);
Ok(vk)
Ok(keygen_vk_v2(params, &compiled_circuit)?)
}

/// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `Circuit`.
/// By default, selector compression is turned **ON**.
///
/// **NOTE**: This `keygen_pk` is legacy one, assuming that `compress_selector: true`.
/// Hence, it is HIGHLY recommended to pair this util with `keygen_vk`.
/// In addition, when using this for key generation, user MUST use `compress_selectors: true`.
pub fn keygen_pk<'params, C, P, ConcreteCircuit>(
params: &P,
vk: VerifyingKey<C>,
Expand All @@ -54,10 +66,28 @@ where
P: Params<'params, C>,
ConcreteCircuit: Circuit<C::Scalar>,
{
let (compiled_circuit, _, _) = compile_circuit(
params.k(),
circuit,
vk.compress_selectors.unwrap_or_default(),
)?;
keygen_pk_custom(params, vk, circuit, true)
}

/// Generate a `ProvingKey` from an instance of `Circuit`.
///
/// The selector compression optimization is turned on only if `compress_selectors` is `true`.
///
/// **NOTE**: This `keygen_pk_custom` MUST share the same `compress_selectors` with
/// `VerifyingKey` generation process.
/// Otherwise, the user could get unmatching pk/vk pair.
/// Hence, it is HIGHLY recommended to pair this util with `keygen_vk_custom`.
pub fn keygen_pk_custom<'params, C, P, ConcreteCircuit>(
params: &P,
vk: VerifyingKey<C>,
circuit: &ConcreteCircuit,
compress_selectors: bool,
) -> Result<ProvingKey<C>, Error>
where
C: CurveAffine,
P: Params<'params, C>,
ConcreteCircuit: Circuit<C::Scalar>,
{
let (compiled_circuit, _, _) = compile_circuit(params.k(), circuit, compress_selectors)?;
Ok(keygen_pk_v2(params, vk, &compiled_circuit)?)
}
91 changes: 90 additions & 1 deletion halo2_proofs/src/plonk/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,44 @@ pub fn create_proof<
rng: R,
transcript: &mut T,
) -> Result<(), Error>
where
Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>,
{
create_proof_custom::<Scheme, P, E, R, T, ConcreteCircuit>(
params, pk, true, circuits, instances, rng, transcript,
)
}

/// This creates a proof for the provided `circuit` when given the public
/// parameters `params` and the proving key [`ProvingKey`] that was
/// generated previously for the same circuit. The provided `instances`
/// are zero-padded internally.
/// In addition, this needs the `compress_selectors` field.
pub fn create_proof_custom<
'params,
Scheme: CommitmentScheme,
P: Prover<'params, Scheme>,
E: EncodedChallenge<Scheme::Curve>,
R: RngCore,
T: TranscriptWrite<Scheme::Curve, E>,
ConcreteCircuit: Circuit<Scheme::Scalar>,
>(
params: &'params Scheme::ParamsProver,
pk: &ProvingKey<Scheme::Curve>,
compress_selectors: bool,
circuits: &[ConcreteCircuit],
instances: &[&[&[Scheme::Scalar]]],
rng: R,
transcript: &mut T,
) -> Result<(), Error>
where
Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>,
{
if circuits.len() != instances.len() {
return Err(Error::Backend(ErrorBack::InvalidInstances));
}
let (config, cs, _) = compile_circuit_cs::<_, ConcreteCircuit>(
pk.get_vk().compress_selectors.unwrap_or_default(),
compress_selectors,
#[cfg(feature = "circuit-params")]
circuits[0].params(),
);
Expand Down Expand Up @@ -126,3 +156,62 @@ fn test_create_proof() {
)
.expect("proof generation should not fail");
}

#[test]
fn test_create_proof_custom() {
use crate::{
circuit::SimpleFloorPlanner,
plonk::{keygen_pk_custom, keygen_vk_custom, ConstraintSystem, ErrorFront},
poly::kzg::{
commitment::{KZGCommitmentScheme, ParamsKZG},
multiopen::ProverSHPLONK,
},
transcript::{Blake2bWrite, Challenge255, TranscriptWriterBuffer},
};
use halo2_middleware::ff::Field;
use halo2curves::bn256::Bn256;
use rand_core::OsRng;

#[derive(Clone, Copy)]
struct MyCircuit;

impl<F: Field> Circuit<F> for MyCircuit {
type Config = ();
type FloorPlanner = SimpleFloorPlanner;
#[cfg(feature = "circuit-params")]
type Params = ();

fn without_witnesses(&self) -> Self {
*self
}

fn configure(_meta: &mut ConstraintSystem<F>) -> Self::Config {}

fn synthesize(
&self,
_config: Self::Config,
_layouter: impl crate::circuit::Layouter<F>,
) -> Result<(), ErrorFront> {
Ok(())
}
}

let params: ParamsKZG<Bn256> = ParamsKZG::setup(3, OsRng);
let compress_selectors = true;
let vk = keygen_vk_custom(&params, &MyCircuit, compress_selectors)
.expect("keygen_vk_custom should not fail");
let pk = keygen_pk_custom(&params, vk, &MyCircuit, compress_selectors)
.expect("keygen_pk_custom should not fail");
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);

create_proof_custom::<KZGCommitmentScheme<_>, ProverSHPLONK<_>, _, _, _, _>(
&params,
&pk,
compress_selectors,
&[MyCircuit, MyCircuit],
&[&[], &[]],
OsRng,
&mut transcript,
)
.expect("proof generation should not fail");
}
Loading