message: Fix the pedantic lints (2)

diff:
@@ -101,6 +101,7 @@ pub struct ProverCommitments<G: AffineCurve> {
#[serde_as]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
+#[allow(clippy::module_name_repetitions)]
pub struct ProverProof<G: AffineCurve> {
/// All the polynomial commitments required in the proof
pub commitments: ProverCommitments<G>,

diff:
@@ -114,7 +114,7 @@ impl<G: KimchiCurve> ProverProof<G>
where
G::BaseField: PrimeField,
{
- /// This function constructs prover's zk-proof from the witness & the ProverIndex against SRS instance
+ /// This function constructs prover's zk-proof from the witness & the `ProverIndex` against SRS instance
pub fn create<
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
EFrSponge: FrSponge<G::ScalarField>,
@@ -134,7 +134,8 @@ where
)
}
- /// This function constructs prover's recursive zk-proof from the witness & the ProverIndex against SRS instance
+ /// This function constructs prover's recursive zk-proof from the witness & the `ProverIndex` against SRS instance
+ #[allow(clippy::needless_pass_by_value, clippy::too_many_lines)]
pub fn create_recursive<
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
EFrSponge: FrSponge<G::ScalarField>,
@@ -583,7 +584,10 @@ where
let lagrange = index.cs.evaluate(&witness_poly, &z_poly);
let env = {
let mut index_evals = HashMap::new();
- use GateType::*;
+ use GateType::{
+ ChaCha0, ChaCha1, ChaCha2, ChaChaFinal, CompleteAdd, EndoMul, EndoMulScalar,
+ Poseidon, VarBaseMul,
+ };
index_evals.insert(Poseidon, &index.cs.ps8);
index_evals.insert(CompleteAdd, &index.cs.complete_addl4);
index_evals.insert(VarBaseMul, &index.cs.mull8);

diff:
-//! This module implements the prover index as [ProverIndex].
+//! This module implements the prover index as [`ProverIndex`].
use crate::{
alphas::Alphas,
circuits::{
constraints::ConstraintSystem,
expr::{Linearization, PolishToken},
- wires::*,
+ wires::PERMUTS,
},
curve::KimchiCurve,
linearization::expr_linearization,
@@ -137,7 +137,7 @@ impl<G: KimchiCurve> ProverIndex<G> {
}
pub mod testing {
- use super::*;
+ use super::{Arc, ConstraintSystem, EvaluationDomain, FqSponge, ProverIndex, SRS};
use crate::circuits::{
gate::CircuitGate,
lookup::{runtime_tables::RuntimeTableCfg, tables::LookupTable},
@@ -145,6 +145,7 @@ pub mod testing {
use commitment_dlog::srs::endos;
use mina_curves::pasta::{pallas::Pallas, vesta::Vesta, Fp};
+ #[must_use]
pub fn new_index_for_test_with_lookups(
gates: Vec<CircuitGate<Fp>>,
public: usize,
@@ -167,6 +168,7 @@ pub mod testing {
let (endo_q, _endo_r) = endos::<Pallas>();
ProverIndex::<Vesta>::create(cs, endo_q, srs)
}
+ #[must_use]
pub fn new_index_for_test(gates: Vec<CircuitGate<Fp>>, public: usize) -> ProverIndex<Vesta> {
new_index_for_test_with_lookups(gates, public, 0, vec![], None)
}

diff:
@@ -88,7 +88,7 @@ impl<Field: PrimeField> GateSpec<usize, Field> {
let wires: Vec<_> = wired_to
.into_iter()
.take(PERMUTS)
- .map(|x| x.to_rust_wire())
+ .map(Position::to_rust_wire)
.collect();
CircuitGate {
typ: kind,
@@ -147,9 +147,9 @@ pub enum BasicSnarkyConstraint<Var> {
R1CS(Var, Var, Var),
}
-/** A PLONK constraint (or gate) can be [Basic](KimchiConstraint::Basic), [Poseidon](KimchiConstraint::Poseidon),
- * [EcAddComplete](KimchiConstraint::EcAddComplete), [EcScale](KimchiConstraint::EcScale),
- * [EcEndoscale](KimchiConstraint::EcEndoscale), or [EcEndoscalar](KimchiConstraint::EcEndoscalar). */
+/** A PLONK constraint (or gate) can be [`Basic`](KimchiConstraint::Basic), [`Poseidon`](KimchiConstraint::Poseidon),
+ * [`EcAddComplete`](KimchiConstraint::EcAddComplete), [`EcScale`](KimchiConstraint::EcScale),
+ * [`EcEndoscale`](KimchiConstraint::EcEndoscale), or [`EcEndoscalar`](KimchiConstraint::EcEndoscalar). */
pub enum KimchiConstraint<Var, Field> {
Basic {
l: (Field, Var),
@@ -212,6 +212,7 @@ enum Circuit<Field, RustGates> {
}
/** The constraint system. */
+#[allow(clippy::module_name_repetitions)]
pub struct SnarkyConstraintSystem<Field, RustGates>
where
Field: ark_ff::Field,
@@ -257,7 +258,7 @@ where
}
impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field, Gates> {
- /** Converts the set of permutations (equivalence_classes) to
+ /** Converts the set of permutations (`equivalence_classes`) to
a hash table that maps each position to the next one.
For example, if one of the equivalence class is [pos1, pos3, pos7],
the function will return a hashtable that maps pos1 to pos3,
@@ -287,6 +288,9 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
/** Compute the witness, given the constraint system `sys`
and a function that converts the indexed secret inputs to their concrete values.
*/
+ /// # Panics
+ ///
+ /// Will panic if some inputs like `public_input_size` are unknown(None value).
pub fn compute_witness<F: Fn(usize) -> Field>(&self, external_values: F) -> Vec<Vec<Field>> {
let mut internal_values = HashMap::new();
let public_input_size = self.public_input_size.unwrap();
@@ -330,7 +334,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
}
fn union_find(&mut self, value: V) {
- self.union_finds.make_set(value)
+ self.union_finds.make_set(value);
}
fn create_internal(&mut self, constant: Option<Field>, lc: Vec<(Field, V)>) -> V {
@@ -365,18 +369,21 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
}
/** Returns the number of public inputs. */
+ /// # Panics
+ ///
+ /// Will panic if `public_input_size` is None.
pub fn get_primary_input_size(&self) -> usize {
self.public_input_size.unwrap()
}
/** Non-public part of the witness. */
pub fn set_auxiliary_input_size(&mut self, x: usize) {
- self.auxiliary_input_size = x
+ self.auxiliary_input_size = x;
}
/** Sets the number of public-input. It should only be called once. */
pub fn set_public_input_size(&mut self, x: usize) {
- self.public_input_size = Some(x)
+ self.public_input_size = Some(x);
}
/** Adds {row; col} to the system's wiring under a specific key.
@@ -388,12 +395,12 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
self.equivalence_classes
.entry(key)
.or_insert_with(Vec::new)
- .push(Position { row, col })
+ .push(Position { row, col });
}
/** Same as wire', except that the row must be given relatively to the end of the public-input rows. */
fn wire(&mut self, key: V, row: usize, col: usize) {
- self.wire_(key, Row::AfterPublicInput(row), col)
+ self.wire_(key, Row::AfterPublicInput(row), col);
}
/** Adds a row/gate/constraint to a constraint system `sys`. */
@@ -423,6 +430,11 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
self.rows.push(vars);
}
+ /// Fill the `gate` values(input and output), and finalize the `circuit`.
+ ///
+ /// # Panics
+ ///
+ /// Will panic if `circuit` is completed.
pub fn finalize(&mut self) {
// if it's already finalized, return early
if matches!(self.gates, Circuit::Compiled(..)) {
@@ -439,7 +451,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
// get gates without holding on an immutable reference
let gates = match std::mem::replace(&mut self.gates, Circuit::Unfinalized(vec![])) {
Circuit::Unfinalized(gates) => gates,
- _ => panic!("we expect the gates to be unfinalized"),
+ Circuit::Compiled(_, _) => panic!("we expect the gates to be unfinalized"),
};
/* Create rows for public input. */
@@ -503,7 +515,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
/* convert all the gates into our Gates.t Rust vector type */
let mut rust_gates = Gates::create();
let mut add_gates = |gates: Vec<_>| {
- for gate in gates.into_iter() {
+ for gate in gates {
let g = to_absolute_row(gate);
rust_gates.add(g.to_rust_gate());
}
@@ -518,7 +530,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
self.finalize();
match &mut self.gates {
Circuit::Compiled(_, gates) => gates,
- _ => unreachable!(),
+ Circuit::Unfinalized(_) => unreachable!(),
}
}
}
@@ -534,7 +546,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
*/
fn accumulate_terms<Field: PrimeField>(terms: Vec<(Field, usize)>) -> HashMap<usize, Field> {
let mut acc = HashMap::new();
- for (x, i) in terms.into_iter() {
+ for (x, i) in terms {
match acc.entry(i) {
std::collections::hash_map::Entry::Occupied(mut entry) => {
let res = x + entry.get();
@@ -560,6 +572,7 @@ pub trait SnarkyCvar: Clone {
fn to_constant_and_terms(&self) -> (Option<Self::Field>, Vec<(Self::Field, usize)>);
}
+#[allow(clippy::needless_pass_by_value)]
pub fn canonicalize<Cvar>(x: Cvar) -> Option<(Vec<(Cvar::Field, usize)>, usize, bool)>
where
Cvar: SnarkyCvar,
@@ -606,7 +619,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
}
}
- /** Converts a number of scaled additions \sum s_i * x_i
+ /** Converts a number of scaled additions \sum `s_i` * `x_i`
to as many constraints as needed,
creating temporary variables for each new row/constraint,
and returning the output variable.
@@ -654,6 +667,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
It returns the output variable as (1, `Var res),
unless the output is a constant, in which case it returns (c, `Constant).
*/
+ #[allow(clippy::needless_pass_by_value)]
fn reduce_lincom<Cvar>(&mut self, x: Cvar) -> (Field, ConstantOrVar)
where
Cvar: SnarkyCvar<Field = Field>,
@@ -758,6 +772,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
}
}
+ #[allow(clippy::too_many_lines)]
pub fn add_basic_snarky_constraint<Cvar>(&mut self, constraint: BasicSnarkyConstraint<Cvar>)
where
Cvar: SnarkyCvar<Field = Field>,
@@ -775,7 +790,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
Some(xl),
Some(xo),
vec![Field::zero(), Field::zero(), -so, sl * sl, Field::zero()],
- )
+ );
}
((sl, ConstantOrVar::Var(xl)), (so, ConstantOrVar::Constant)) =>
/* TODO: it's hard to read the array of selector values, name them! */
@@ -785,7 +800,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
Some(xl),
None,
vec![Field::zero(), Field::zero(), Field::zero(), sl * sl, -so],
- )
+ );
}
((sl, ConstantOrVar::Constant), (so, ConstantOrVar::Var(xo))) =>
/* sl^2 = so * xo */
@@ -795,10 +810,10 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
None,
Some(xo),
vec![Field::zero(), Field::zero(), so, Field::zero(), -(sl * sl)],
- )
+ );
}
((sl, ConstantOrVar::Constant), (so, ConstantOrVar::Constant)) => {
- assert_eq!(sl * sl, so)
+ assert_eq!(sl * sl, so);
}
}
}
@@ -821,7 +836,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
Some(x2),
Some(x3),
vec![Field::zero(), Field::zero(), s3, (-s1) * s2, Field::zero()],
- )
+ );
}
(
(s1, ConstantOrVar::Var(x1)),
@@ -845,7 +860,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
None,
Some(x3),
vec![(s1 * s2), Field::zero(), -s3, Field::zero(), Field::zero()],
- )
+ );
}
(
(s1, ConstantOrVar::Constant),
@@ -910,7 +925,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
Field::one(),
Field::zero(),
],
- )
+ );
}
ConstantOrVar::Constant => assert_eq!(s, (s * s)),
}
@@ -925,7 +940,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
self.union_find(x1);
self.union_find(x2);
assert!(self.union_finds.union(x1, x2).is_ok());
- }
+ };
} else if
/* s1 x1 - s2 x2 = 0 */
s1 != s2 {
@@ -934,14 +949,14 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
Some(x2),
None,
vec![s1, -s2, Field::zero(), Field::zero(), Field::zero()],
- )
+ );
} else {
self.add_generic_constraint(
Some(x1),
Some(x2),
None,
vec![s1, -s2, Field::zero(), Field::zero(), Field::zero()],
- )
+ );
}
}
(ConstantOrVar::Var(x1), ConstantOrVar::Constant) => {
@@ -996,6 +1011,12 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
}
}
+ ///
+ ///
+ /// # Panics
+ ///
+ /// Will panic if `witness` fields are empty.
+ #[allow(clippy::too_many_lines)]
pub fn add_constraint<Cvar>(&mut self, constraint: KimchiConstraint<Cvar, Field>)
where
Cvar: SnarkyCvar<Field = Field>,
@@ -1058,7 +1079,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
var(r),
var(o),
vec![coeff(l), coeff(r), coeff(o), m, c],
- )
+ );
}
// TODO: the code in circuit-writer was better
// TODO: also `rounds` would be a better name than `state`

diff:
@@ -9,7 +9,7 @@ use crate::{
lookup::{lookups::LookupsUsed, tables::combine_table},
polynomials::{generic, permutation},
scalars::RandomOracles,
- wires::*,
+ wires::{COLUMNS, PERMUTS},
},
curve::KimchiCurve,
error::VerifyError,
@@ -35,6 +35,7 @@ where
G::BaseField: PrimeField,
{
/// This function runs the random oracle argument
+ #[allow(clippy::too_many_lines)]
pub fn oracles<
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
EFrSponge: FrSponge<G::ScalarField>,
@@ -210,7 +211,9 @@ where
//~ 1. Evaluate the negated public polynomial (if present) at $\zeta$ and $\zeta\omega$.
//~
//~ NOTE: this works only in the case when the poly segment size is not smaller than that of the domain.
- let public_evals = if !self.public.is_empty() {
+ let public_evals = if self.public.is_empty() {
+ [vec![G::ScalarField::zero()], vec![G::ScalarField::zero()]]
+ } else {
[
vec![
(self
@@ -235,8 +238,6 @@ where
* (zetaw.pow(&[n as u64]) - G::ScalarField::one()),
],
]
- } else {
- [vec![G::ScalarField::zero()], vec![G::ScalarField::zero()]]
};
println!("verifier public eval: {:?}", public_evals);
@@ -299,10 +300,10 @@ where
.map(|(w, s)| (beta * s) + w + gamma)
.fold(init, |x, y| x * y);
- ft_eval0 -= if !public_evals[0].is_empty() {
- public_evals[0][0]
- } else {
+ ft_eval0 -= if public_evals[0].is_empty() {
G::ScalarField::zero()
+ } else {
+ public_evals[0][0]
};
ft_eval0 -= evals[0]
@@ -399,6 +400,7 @@ where
};
let oracles = RandomOracles {
+ joint_combiner,
beta,
gamma,
alpha_chal,
@@ -409,7 +411,6 @@ where
zeta_chal,
v_chal,
u_chal,
- joint_combiner,
};
Ok(OraclesResult {
@@ -427,6 +428,7 @@ where
}
}
+#[allow(clippy::too_many_lines)]
fn to_batch<'a, G, EFqSponge, EFrSponge>(
index: &VerifierIndex<G>,
proof: &'a ProverProof<G>,
@@ -553,15 +555,18 @@ where
PolishToken::evaluate(tokens, index.domain, oracles.zeta, &evals, &constants)
.expect("should evaluate");
- use Column::*;
+ use Column::{
+ Coefficient, Index, LookupAggreg, LookupKindIndex, LookupRuntimeSelector,
+ LookupRuntimeTable, LookupSorted, LookupTable, Witness, Z,
+ };
match col {
Witness(i) => {
scalars.push(scalar);
- commitments.push(&proof.commitments.w_comm[*i])
+ commitments.push(&proof.commitments.w_comm[*i]);
}
Coefficient(i) => {
scalars.push(scalar);
- commitments.push(&index.coefficients_comm[*i])
+ commitments.push(&index.coefficients_comm[*i]);
}
Z => {
scalars.push(scalar);
@@ -574,7 +579,7 @@ where
.as_ref()
.ok_or(VerifyError::LookupCommitmentMissing)?;
scalars.push(scalar);
- commitments.push(&lookup_coms.sorted[*i])
+ commitments.push(&lookup_coms.sorted[*i]);
}
LookupAggreg => {
let lookup_coms = proof
@@ -583,7 +588,7 @@ where
.as_ref()
.ok_or(VerifyError::LookupCommitmentMissing)?;
scalars.push(scalar);
- commitments.push(&lookup_coms.aggreg)
+ commitments.push(&lookup_coms.aggreg);
}
LookupKindIndex(i) => match index.lookup_index.as_ref() {
None => {
@@ -616,7 +621,11 @@ where
panic!("runtime lookup table is unused in the linearization")
}
Index(t) => {
- use GateType::*;
+ use GateType::{
+ CairoClaim, CairoFlags, CairoInstruction, CairoTransition, ChaCha0,
+ ChaCha1, ChaCha2, ChaChaFinal, CompleteAdd, EndoMul, EndoMulScalar,
+ Generic, Lookup, Poseidon, RangeCheck0, RangeCheck1, VarBaseMul, Zero,
+ };
let c = match t {
Zero | Generic | Lookup => {
panic!("Selector for {:?} not defined", t)
@@ -802,7 +811,7 @@ where
let joint_combiner = oracles
.joint_combiner
.expect("joint_combiner should be present if lookups are used");
- let table_id_combiner = joint_combiner.1.pow([li.max_joint_size as u64]);
+ let table_id_combiner = joint_combiner.1.pow([u64::from(li.max_joint_size)]);
let lookup_table: Vec<_> = li.lookup_table.iter().collect();
let runtime = lookup_comms.runtime.as_ref();
@@ -859,7 +868,7 @@ where
})
}
-/// Verify a proof [ProverProof] using a [VerifierIndex] and a `group_map`.
+/// Verify a proof [`ProverProof`] using a [`VerifierIndex`] and a `group_map`.
pub fn verify<G, EFqSponge, EFrSponge>(
group_map: &G::Map,
verifier_index: &VerifierIndex<G>,
@@ -877,7 +886,7 @@ where
/// This function verifies the batch of zk-proofs
/// proofs: vector of Plonk proofs
-/// index: VerifierIndex
+/// index: `VerifierIndex`
/// RETURN: verification status
pub fn batch_verify<G, EFqSponge, EFrSponge>(
group_map: &G::Map,
@@ -922,8 +931,9 @@ where
}
//~ 1. Use the [`PolyCom.verify`](#polynomial-commitments) to verify the partially evaluated proofs.
- match srs.verify::<EFqSponge, _>(group_map, &mut batch, &mut thread_rng()) {
- false => Err(VerifyError::OpenProof),
- true => Ok(()),
+ if srs.verify::<EFqSponge, _>(group_map, &mut batch, &mut thread_rng()) {
+ Ok(())
+ } else {
+ Err(VerifyError::OpenProof)
}
}

diff:
-//! This module implements the verifier index as [VerifierIndex].
-//! You can derive this struct from the [ProverIndex] struct.
+//! This module implements the verifier index as [`VerifierIndex`].
+//! You can derive this struct from the [`ProverIndex`] struct.
use crate::{
alphas::Alphas,
@@ -10,7 +10,7 @@ use crate::{
permutation::{zk_polynomial, zk_w3},
range_check,
},
- wires::*,
+ wires::{COLUMNS, PERMUTS},
},
curve::KimchiCurve,
error::VerifierIndexError,
@@ -37,6 +37,7 @@ use std::{
//~spec:startcode
#[serde_as]
#[derive(Serialize, Deserialize, Debug, Clone)]
+#[allow(clippy::module_name_repetitions)]
pub struct LookupVerifierIndex<G: CommitmentCurve> {
pub lookup_used: LookupsUsed,
#[serde(bound = "PolyComm<G>: Serialize + DeserializeOwned")]
@@ -139,7 +140,11 @@ pub struct VerifierIndex<G: KimchiCurve> {
//~spec:endcode
impl<G: KimchiCurve> ProverIndex<G> {
- /// Produces the [VerifierIndex] from the prover's [ProverIndex].
+ /// Produces the [`VerifierIndex`] from the prover's [`ProverIndex`].
+ ///
+ /// # Panics
+ ///
+ /// Will panic if `srs` cannot be in `cell`.
pub fn verifier_index(&self) -> VerifierIndex<G> {
if let Some(verifier_index) = &self.verifier_index {
return verifier_index.clone();
@@ -244,7 +249,7 @@ impl<G: KimchiCurve> ProverIndex<G> {
}
impl<G: KimchiCurve> VerifierIndex<G> {
- /// Gets srs from [VerifierIndex] lazily
+ /// Gets srs from [`VerifierIndex`] lazily
pub fn srs(&self) -> &Arc<SRS<G>>
where
G::BaseField: PrimeField,
@@ -256,17 +261,21 @@ impl<G: KimchiCurve> VerifierIndex<G> {
})
}
- /// Gets zkpm from [VerifierIndex] lazily
+ /// Gets zkpm from [`VerifierIndex`] lazily
pub fn zkpm(&self) -> &DensePolynomial<G::ScalarField> {
self.zkpm.get_or_init(|| zk_polynomial(self.domain))
}
- /// Gets w from [VerifierIndex] lazily
+ /// Gets w from [`VerifierIndex`] lazily
pub fn w(&self) -> &G::ScalarField {
self.w.get_or_init(|| zk_w3(self.domain))
}
- /// Deserializes a [VerifierIndex] from a file, given a pointer to an SRS and an optional offset in the file.
+ /// Deserializes a [`VerifierIndex`] from a file, given a pointer to an SRS and an optional offset in the file.
+ ///
+ /// # Errors
+ ///
+ /// Will give error if it fails to deserialize from file or unable to set `srs` in `verifier_index`.
pub fn from_file(
srs: Option<Arc<SRS<G>>>,
path: &Path,
@@ -288,10 +297,10 @@ impl<G: KimchiCurve> VerifierIndex<G> {
.map_err(|e| e.to_string())?;
// fill in the rest
- if srs.is_some() {
+ if let Some(srs) = srs {
verifier_index
.srs
- .set(srs.unwrap())
+ .set(srs)
.map_err(|_| VerifierIndexError::SRSHasBeenSet.to_string())?;
};

original_message: Fix the pedantic lints (2)


message: Fix the pedantic lints (3)

change_type: MODIFY

diff:
@@ -160,6 +160,10 @@ where
}
/// Creates the prover index on input an `srs`, used `constants`, parameters for Poseidon, number of public inputs, and a specific circuit
+///
+/// # Panics
+///
+/// Will panic if `constraint_system` is not built with `public` input.
pub fn generate_prover_index<C, H>(
srs: std::sync::Arc<SRS<C::Outer>>,
public: usize,
@@ -190,7 +194,7 @@ where
main(&mut system, public_input);
let gates = system.gates();
- println!("gates: {}", gates.len());
+
// Other base field = self scalar field
let (endo_q, _endo_r) = endos::<C::Inner>();

diff:
@@ -28,17 +28,20 @@ pub struct Wire {
impl Wire {
/// Creates a new set of wires for a given row.
+ #[must_use]
pub fn new(row: usize) -> [Self; PERMUTS] {
array::from_fn(|col| Self { row, col })
}
}
-/// GateWires document the wiring of a gate. More specifically, each value either
+/// `GateWires` document the wiring of a gate. More specifically, each value either
/// represents the same cell (row and column) or a different cell in another row.
/// (This is to help the permutation argument.)
+#[allow(clippy::module_name_repetitions)]
pub type GateWires = [Wire; PERMUTS];
impl ToBytes for Wire {
+ #[allow(clippy::cast_possible_truncation)]
#[inline]
fn write<W: Write>(&self, mut w: W) -> IoResult<()> {
(self.row as u32).write(&mut w)?;

diff:
@@ -8,6 +8,7 @@ use once_cell::sync::Lazy;
use oracle::poseidon::ArithmeticSpongeParams;
///Represents additional information that a curve needs in order to be used with Kimchi
+#[allow(clippy::module_name_repetitions)]
pub trait KimchiCurve: CommitmentCurve {
/// The other curve that forms the cycle used for recursion
type OtherCurve: KimchiCurve<
@@ -17,7 +18,7 @@ pub trait KimchiCurve: CommitmentCurve {
>;
/// Provides the sponge params to be used with this curve
- /// If the params for the base field are needed, they can be obtained from [KimchiCurve::OtherCurve]
+ /// If the params for the base field are needed, they can be obtained from [`KimchiCurve::OtherCurve`]
fn sponge_params() -> &'static ArithmeticSpongeParams<Self::ScalarField>;
/// Provides the coefficients for the curve endomorphism

diff:
-//! This module implements the [ProverError] type.
+//! This module implements the [`ProverError`] type.
use commitment_dlog::error::CommitmentError;
use thiserror::Error;
/// Errors that can arise when creating a proof
// TODO(mimoo): move this out of oracle
+#[allow(clippy::module_name_repetitions)]
#[derive(Error, Debug, Clone, Copy)]
pub enum ProverError {
#[error("the circuit is too large")]
@@ -33,6 +34,7 @@ pub enum ProverError {
}
/// Errors that can arise when verifying a proof
+#[allow(clippy::module_name_repetitions)]
#[derive(Error, Debug, Clone, Copy)]
pub enum VerifyError {
#[error("the commitment to {0} is of an unexpected size")]
@@ -67,6 +69,7 @@ pub enum VerifyError {
}
/// Errors that can arise when preparing the setup
+#[allow(clippy::module_name_repetitions)]
#[derive(Error, Debug, Clone)]
pub enum SetupError {
#[error("the domain could not be constructed: {0}")]
@@ -77,6 +80,7 @@ pub enum SetupError {
}
/// Errors that can arise when creating a verifier index
+#[allow(clippy::module_name_repetitions)]
#[derive(Error, Debug, Clone)]
pub enum VerifierIndexError {
#[error("srs has already been set")]

diff:
@@ -15,10 +15,16 @@ use crate::circuits::polynomials::varbasemul::VarbaseMul;
use crate::circuits::{
expr::{Column, ConstantExpr, Expr, Linearization, PolishToken},
gate::GateType,
- wires::*,
+ wires::COLUMNS,
};
use ark_ff::{FftField, SquareRootField};
+/// Get the expresion of constraints.
+///
+/// # Panics
+///
+/// Will panic if `generic_gate` is not associate with `alpha^0`.
+#[must_use]
pub fn constraints_expr<F: FftField + SquareRootField>(
chacha: bool,
range_check: bool,
@@ -85,11 +91,13 @@ pub fn constraints_expr<F: FftField + SquareRootField>(
/// Adds the polynomials that are evaluated as part of the proof
/// for the linearization to work.
+#[must_use]
+#[allow(clippy::module_name_repetitions)]
pub fn linearization_columns<F: FftField + SquareRootField>(
lookup_constraint_system: Option<&LookupConfiguration<F>>,
) -> std::collections::HashSet<Column> {
let mut h = std::collections::HashSet::new();
- use Column::*;
+ use Column::{Index, LookupAggreg, LookupRuntimeTable, LookupSorted, LookupTable, Witness, Z};
// the witness polynomials
for i in 0..COLUMNS {
@@ -98,7 +106,7 @@ pub fn linearization_columns<F: FftField + SquareRootField>(
// the lookup polynomials
if let Some(lcs) = &lookup_constraint_system {
- for i in 0..(lcs.lookup_info.max_per_row + 1) {
+ for i in 0..=lcs.lookup_info.max_per_row {
h.insert(LookupSorted(i));
}
h.insert(LookupAggreg);
@@ -122,6 +130,12 @@ pub fn linearization_columns<F: FftField + SquareRootField>(
h
}
+/// Linearize the `expr`.
+///
+/// # Panics
+///
+/// Will panic if the `linearization` process fails.
+#[must_use]
pub fn expr_linearization<F: FftField + SquareRootField>(
chacha: bool,
range_check: bool,
@@ -134,7 +148,7 @@ pub fn expr_linearization<F: FftField + SquareRootField>(
let linearization = expr
.linearize(evaluated_cols)
.unwrap()
- .map(|e| e.to_polish());
+ .map(crate::circuits::expr::Expr::to_polish);
(linearization, powers_of_alpha)
}

diff:
@@ -17,7 +17,7 @@ pub trait FrSponge<Fr: Field> {
/// Absorbs a slice of field elements into the sponge.
fn absorb_multiple(&mut self, x: &[Fr]);
- /// Creates a [ScalarChallenge] by squeezing the sponge.
+ /// Creates a [`ScalarChallenge`] by squeezing the sponge.
fn challenge(&mut self) -> ScalarChallenge<Fr>;
/// Consumes the sponge and returns the current digest, by squeezing.

diff:
@@ -143,6 +143,11 @@ where
//~ spec:endcode
impl<F> ProofEvaluations<F> {
+ /// Transpose the `ProofEvaluations`.
+ ///
+ /// # Panics
+ ///
+ /// Will panic if `ProofEvaluation` is None.
pub fn transpose<const N: usize>(
evals: [&ProofEvaluations<F>; N],
) -> ProofEvaluations<[&F; N]> {

diff:
@@ -135,7 +135,15 @@ where
}
/// This function constructs prover's recursive zk-proof from the witness & the `ProverIndex` against SRS instance
- #[allow(clippy::needless_pass_by_value, clippy::too_many_lines)]
+ ///
+ /// # Errors
+ ///
+ /// Will give error if inputs(like `lookup_context.joint_lookup_table_d8`) are None.
+ #[allow(
+ clippy::needless_pass_by_value,
+ clippy::too_many_lines,
+ clippy::cast_possible_truncation
+ )]
pub fn create_recursive<
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
EFrSponge: FrSponge<G::ScalarField>,

diff:
@@ -57,6 +57,10 @@ pub struct ProverIndex<G: KimchiCurve> {
impl<G: KimchiCurve> ProverIndex<G> {
/// this function compiles the index from constraints
+ ///
+ /// # Panics
+ ///
+ /// Will panic if `polynomial segment size` is bigger than `circuit`.
pub fn create(
mut cs: ConstraintSystem<G::ScalarField>,
endo_q: G::ScalarField,
@@ -145,6 +149,11 @@ pub mod testing {
use commitment_dlog::srs::endos;
use mina_curves::pasta::{pallas::Pallas, vesta::Vesta, Fp};
+ /// Create new index for lookups.
+ ///
+ /// # Panics
+ ///
+ /// Will panic if `constraint system` is not built with `gates` input.
#[must_use]
pub fn new_index_for_test_with_lookups(
gates: Vec<CircuitGate<Fp>>,

diff:
@@ -52,7 +52,7 @@ impl Position<usize> {
}
/** A gate/row/constraint consists of a type (kind), a row, the other cells its columns/cells are
-connected to (wired_to), and the selector polynomial associated with the gate. */
+connected to (`wired_to`), and the selector polynomial associated with the gate. */
struct GateSpec<Row, Field> {
kind: GateType,
wired_to: Vec<Position<Row>>,
@@ -60,7 +60,7 @@ struct GateSpec<Row, Field> {
}
impl<Row, Field> GateSpec<Row, Field> {
- /** Applies a function [f] to the [row] of [t] and all the rows of its [wired_to]. */
+ /** Applies a function [f] to the [row] of [t] and all the rows of its [`wired_to`]. */
fn map_rows<Row2, F: Fn(Row) -> Row2>(self, f: F) -> GateSpec<Row2, Field> {
let GateSpec {
kind,
@@ -285,9 +285,9 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
res
}
- /** Compute the witness, given the constraint system `sys`
- and a function that converts the indexed secret inputs to their concrete values.
- */
+ /// Compute the witness, given the constraint system `sys`
+ /// and a function that converts the indexed secret inputs to their concrete values.
+ ///
/// # Panics
///
/// Will panic if some inputs like `public_input_size` are unknown(None value).
@@ -368,7 +368,8 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
self.auxiliary_input_size
}
- /** Returns the number of public inputs. */
+ /// Returns the number of public inputs.
+ ///
/// # Panics
///
/// Will panic if `public_input_size` is None.
@@ -772,6 +773,12 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
}
}
+ /// Applies the basic `SnarkyConstraint`.
+ /// Simply, place the values of `selector`(`sl`, `sr`, `so` ...) and `input`(`l`, `r`, `o`, `m`).
+ ///
+ /// # Panics
+ ///
+ /// Will panic if `constant selector` constraints are not matching.
#[allow(clippy::too_many_lines)]
pub fn add_basic_snarky_constraint<Cvar>(&mut self, constraint: BasicSnarkyConstraint<Cvar>)
where
@@ -1011,7 +1018,7 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
}
}
- ///
+ /// Applies the `KimchiConstraint(s)` to the `circuit`.
///
/// # Panics
///

diff:
@@ -35,6 +35,14 @@ where
G::BaseField: PrimeField,
{
/// This function runs the random oracle argument
+ ///
+ /// # Errors
+ ///
+ /// Will give error if `commitment(s)` are invalid(missing or wrong length), or `proof` is verified as invalid.
+ ///
+ /// # Panics
+ ///
+ /// Will panic if `PolishToken` evaluation is invalid.
#[allow(clippy::too_many_lines)]
pub fn oracles<
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
@@ -240,8 +248,6 @@ where
]
};
- println!("verifier public eval: {:?}", public_evals);
-
//~ 1. Absorb the unique evaluation of ft: $ft(\zeta\omega)$.
fr_sponge.absorb(&self.ft_eval1);
@@ -869,6 +875,10 @@ where
}
/// Verify a proof [`ProverProof`] using a [`VerifierIndex`] and a `group_map`.
+///
+/// # Errors
+///
+/// Will give error if `proof(s)` are not verified as valid.
pub fn verify<G, EFqSponge, EFrSponge>(
group_map: &G::Map,
verifier_index: &VerifierIndex<G>,
@@ -888,6 +898,10 @@ where
/// proofs: vector of Plonk proofs
/// index: `VerifierIndex`
/// RETURN: verification status
+///
+/// # Errors
+///
+/// Will give error if `srs` of `proof` is invalid or `verify` process fails.
pub fn batch_verify<G, EFqSponge, EFrSponge>(
group_map: &G::Map,
proofs: &[(&VerifierIndex<G>, &ProverProof<G>)],

license: Apache License 2.0

original_message: Fix the pedantic lints (3)


message: Fix the pedantic lints (5)

diff:
@@ -1618,6 +1618,7 @@ impl<F: Neg<Output = F> + Clone + One + Zero + PartialEq> Expr<F> {
// is called repeatedly in monomials, yielding quadratic behavior for
// that function. It's ok for now as we only call that function once on
// a small input when producing the verification key.
+ #[allow(clippy::match_same_arms)]
fn is_constant(&self, evaluated: &HashSet<Column>) -> bool {
use Expr::*;
match self {
@@ -1640,7 +1641,10 @@ impl<F: Neg<Output = F> + Clone + One + Zero + PartialEq> Expr<F> {
h
};
let constant = |e: Expr<F>| sing(vec![], e);
- use Expr::*;
+ use Expr::{
+ BinOp, Cache, Cell, Constant, Double, Pow, Square, UnnormalizedLagrangeBasis,
+ VanishesOnLast4Rows,
+ };
if self.is_constant(ev) {
return constant(self.clone());
@@ -1735,6 +1739,7 @@ impl<F: Neg<Output = F> + Clone + One + Zero + PartialEq> Expr<F> {
/// this function computes `lin_or_err(factor_{V_0}(e))`, although it does not
/// compute it in that way. Instead, it computes it by reducing the expression into
/// a sum of monomials with `F` coefficients, and then factors the monomials.
+ #[allow(clippy::needless_pass_by_value)]
pub fn linearize(
&self,
evaluated: HashSet<Column>,
@@ -1827,7 +1832,7 @@ impl<F: One + Neg<Output = F>> Neg for ConstantExpr<F> {
impl<F: Field> Add<ConstantExpr<F>> for ConstantExpr<F> {
type Output = ConstantExpr<F>;
fn add(self, other: Self) -> Self {
- use ConstantExpr::*;
+ use ConstantExpr::{Add, Literal};
if self.is_zero() {
return other;
}
@@ -1844,7 +1849,7 @@ impl<F: Field> Add<ConstantExpr<F>> for ConstantExpr<F> {
impl<F: Field> Sub<ConstantExpr<F>> for ConstantExpr<F> {
type Output = ConstantExpr<F>;
fn sub(self, other: Self) -> Self {
- use ConstantExpr::*;
+ use ConstantExpr::{Literal, Sub};
if other.is_zero() {
return self;
}
@@ -1858,7 +1863,7 @@ impl<F: Field> Sub<ConstantExpr<F>> for ConstantExpr<F> {
impl<F: Field> Mul<ConstantExpr<F>> for ConstantExpr<F> {
type Output = ConstantExpr<F>;
fn mul(self, other: Self) -> Self {
- use ConstantExpr::*;
+ use ConstantExpr::{Literal, Mul};
if self.is_one() {
return other;
}
@@ -1931,7 +1936,7 @@ impl<F: Zero + Clone> AddAssign<Expr<F>> for Expr<F> {
if self.is_zero() {
*self = other;
} else if !other.is_zero() {
- *self = Expr::BinOp(Op2::Add, Box::new(self.clone()), Box::new(other))
+ *self = Expr::BinOp(Op2::Add, Box::new(self.clone()), Box::new(other));
}
}
}
@@ -2010,7 +2015,9 @@ impl<F: Field> Mul<F> for Expr<ConstantExpr<F>> {
impl<F: PrimeField> ConstantExpr<F> {
fn ocaml(&self) -> String {
- use ConstantExpr::*;
+ use ConstantExpr::{
+ Add, Alpha, Beta, EndoCoefficient, Gamma, JointCombiner, Literal, Mds, Mul, Pow, Sub,
+ };
match self {
Alpha => "alpha".to_string(),
Beta => "beta".to_string(),
@@ -2030,7 +2037,9 @@ impl<F: PrimeField> ConstantExpr<F> {
}
fn latex(&self) -> String {
- use ConstantExpr::*;
+ use ConstantExpr::{
+ Add, Alpha, Beta, EndoCoefficient, Gamma, JointCombiner, Literal, Mds, Mul, Pow, Sub,
+ };
match self {
Alpha => "\\alpha".to_string(),
Beta => "\\beta".to_string(),
@@ -2065,7 +2074,7 @@ where
env.sort_by(|(x, _), (y, _)| x.cmp(y));
let mut res = String::new();
- for (k, v) in env.into_iter() {
+ for (k, v) in env {
let rhs = v.ocaml_str();
let cached = format!("let {} = {rhs} in ", k.var_name());
res.push_str(&cached);
@@ -2078,7 +2087,10 @@ where
/// Recursively print the expression,
/// except for the cached expression that are stored in the `cache`.
fn ocaml(&self, cache: &mut HashMap<CacheId, Expr<ConstantExpr<F>>>) -> String {
- use Expr::*;
+ use Expr::{
+ BinOp, Cache, Cell, Constant, Double, Pow, Square, UnnormalizedLagrangeBasis,
+ VanishesOnLast4Rows,
+ };
match self {
Double(x) => format!("double({})", x.ocaml(cache)),
Constant(x) => x.ocaml(),
@@ -2108,7 +2120,7 @@ where
env.sort_by(|(x, _), (y, _)| x.cmp(y));
let mut res = vec![];
- for (k, v) in env.into_iter() {
+ for (k, v) in env {
let mut rhs = v.latex_str();
let last = rhs.pop().expect("returned an empty expression");
res.push(format!("{} = {last}", k.latex_name()));
@@ -2119,7 +2131,10 @@ where
}
fn latex(&self, cache: &mut HashMap<CacheId, Expr<ConstantExpr<F>>>) -> String {
- use Expr::*;
+ use Expr::{
+ BinOp, Cache, Cell, Constant, Double, Pow, Square, UnnormalizedLagrangeBasis,
+ VanishesOnLast4Rows,
+ };
match self {
Double(x) => format!("2 ({})", x.latex(cache)),
Constant(x) => x.latex(),
@@ -2168,12 +2183,15 @@ pub mod constraints {
Self: std::marker::Sized,
{
/// Double the value
+ #[must_use]
fn double(&self) -> Self;
/// Compute the square of this value
+ #[must_use]
fn square(&self) -> Self;
/// Raise the value to the given power
+ #[must_use]
fn pow(&self, p: u64) -> Self;
/// Constrain to boolean
@@ -2308,25 +2326,30 @@ pub fn constant<F>(x: F) -> E<F> {
}
/// Helper function to quickly create an expression for a witness.
+#[must_use]
pub fn witness<F>(i: usize, row: CurrOrNext) -> E<F> {
E::<F>::cell(Column::Witness(i), row)
}
/// Same as [witness] but for the current row.
+#[must_use]
pub fn witness_curr<F>(i: usize) -> E<F> {
witness(i, CurrOrNext::Curr)
}
/// Same as [witness] but for the next row.
+#[must_use]
pub fn witness_next<F>(i: usize) -> E<F> {
witness(i, CurrOrNext::Next)
}
/// Handy function to quickly create an expression for a gate.
+#[must_use]
pub fn index<F>(g: GateType) -> E<F> {
E::<F>::cell(Column::Index(g), CurrOrNext::Curr)
}
+#[must_use]
pub fn coeff<F>(i: usize) -> E<F> {
E::<F>::cell(Column::Coefficient(i), CurrOrNext::Curr)
}

diff:
@@ -43,6 +43,7 @@ impl CurrOrNext {
/// Compute the offset corresponding to the `CurrOrNext` value.
/// - `Curr.shift() == 0`
/// - `Next.shift() == 1`
+ #[must_use]
pub fn shift(&self) -> usize {
match self {
CurrOrNext::Curr => 0,
@@ -77,6 +78,7 @@ impl CurrOrNext {
)]
#[cfg_attr(feature = "wasm_types", wasm_bindgen::prelude::wasm_bindgen)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
+#[allow(clippy::module_name_repetitions)]
pub enum GateType {
/// Zero gate
Zero = 0,
@@ -160,6 +162,7 @@ pub type CircuitGateResult<T> = std::result::Result<T, CircuitGateError>;
#[serde_as]
#[derive(Clone, Debug, Serialize, Deserialize)]
+#[allow(clippy::module_name_repetitions)]
/// A single gate in a circuit.
pub struct CircuitGate<F: PrimeField> {
/// type of the gate
@@ -172,12 +175,13 @@ pub struct CircuitGate<F: PrimeField> {
}
impl<F: PrimeField> ToBytes for CircuitGate<F> {
+ #[allow(clippy::cast_possible_truncation)]
#[inline]
fn write<W: Write>(&self, mut w: W) -> IoResult<()> {
let typ: u8 = ToPrimitive::to_u8(&self.typ).unwrap();
typ.write(&mut w)?;
for i in 0..COLUMNS {
- self.wires[i].write(&mut w)?
+ self.wires[i].write(&mut w)?;
}
(self.coeffs.len() as u8).write(&mut w)?;
@@ -190,6 +194,7 @@ impl<F: PrimeField> ToBytes for CircuitGate<F> {
impl<F: PrimeField> CircuitGate<F> {
/// this function creates "empty" circuit gate
+ #[must_use]
pub fn zero(wires: GateWires) -> Self {
CircuitGate {
typ: GateType::Zero,
@@ -200,6 +205,11 @@ impl<F: PrimeField> CircuitGate<F> {
/// This function verifies the consistency of the wire
/// assignments (witness) against the constraints
+ ///
+ /// # Errors
+ ///
+ /// Will give error if verify process returns error.
+ #[allow(clippy::match_same_arms)]
pub fn verify<G: KimchiCurve<ScalarField = F>>(
&self,
row: usize,
@@ -207,7 +217,11 @@ impl<F: PrimeField> CircuitGate<F> {
cs: &ConstraintSystem<F>,
public: &[F],
) -> Result<(), String> {
- use GateType::*;
+ use GateType::{
+ CairoClaim, CairoFlags, CairoInstruction, CairoTransition, ChaCha0, ChaCha1, ChaCha2,
+ ChaChaFinal, CompleteAdd, EndoMul, EndoMulScalar, Generic, Lookup, Poseidon,
+ RangeCheck0, RangeCheck1, VarBaseMul, Zero,
+ };
match self.typ {
Zero => Ok(()),
Generic => self.verify_generic(row, witness, public),
@@ -353,7 +367,7 @@ impl<F: PrimeField> CircuitGate<F> {
/// Trait to connect a pair of cells in a circuit
pub trait Connect {
/// Connect the pair of cells specified by the cell1 and cell2 parameters
- /// cell_pre --> cell_new && cell_new --> wire_tmp
+ /// `cell_pre` --> `cell_new` && `cell_new` --> `wire_tmp`
///
/// Note: This function assumes that the targeted cells are freshly instantiated
/// with self-connections. If the two cells are transitively already part
@@ -369,7 +383,7 @@ impl<F: PrimeField> Connect for Vec<CircuitGate<F>> {
}
}
-/// A circuit is specified as a series of [CircuitGate].
+/// A circuit is specified as a series of [`CircuitGate`].
#[derive(Serialize)]
pub struct Circuit<'a, F: PrimeField>(
#[serde(bound = "CircuitGate<F>: Serialize")] pub &'a [CircuitGate<F>],
@@ -477,6 +491,8 @@ pub mod caml {
#[cfg(test)]
mod tests {
+ use crate::circuits::wires::PERMUTS;
+
use super::*;
use ark_ff::UniformRand as _;
use mina_curves::pasta::Fp;

diff:
use crate::{
circuits::{
- expr::{prologue::*, Column, ConstantExpr},
+ expr::{
+ prologue::{witness, E},
+ Column, ConstantExpr,
+ },
gate::{CircuitGate, CurrOrNext},
lookup::lookups::{
JointLookup, JointLookupSpec, JointLookupValue, LocalPosition, LookupInfo, LookupsUsed,
@@ -28,6 +31,10 @@ pub const ZK_ROWS: usize = 3;
/// Pad with zeroes and then add 3 random elements in the last two
/// rows for zero knowledge.
+///
+/// # Panics
+///
+/// Will panic if `evaluation` and `domain` length do not meet the requirement.
pub fn zk_patch<R: Rng + ?Sized, F: FftField>(
mut e: Vec<F>,
d: D<F>,
@@ -77,6 +84,10 @@ pub fn zk_patch<R: Rng + ?Sized, F: FftField>(
//~
/// Computes the sorted lookup tables required by the lookup argument.
+///
+/// # Panics
+///
+/// Will panic if `value(s)` are missing from the `table`.
#[allow(clippy::too_many_arguments)]
pub fn sorted<F: PrimeField>(
dummy_lookup_value: F,
@@ -214,7 +225,11 @@ pub fn sorted<F: PrimeField>(
///
/// after multiplying all of the values, all of the terms will have cancelled if s is a sorting of f and t, and the final term will be 1
/// because of the random choice of beta and gamma, there is negligible probability that the terms will cancel if s is not a sorting of f and t
-#[allow(clippy::too_many_arguments)]
+///
+/// # Panics
+///
+/// Will panic if final evaluation is not 1.
+#[allow(clippy::too_many_arguments, clippy::manual_assert)]
pub fn aggregation<R, F>(
dummy_lookup_value: F,
joint_lookup_table_d8: &Evaluations<F, D<F>>,
@@ -260,8 +275,8 @@ where
let complements_with_beta_term = {
let mut v = vec![F::one()];
let x = gamma + dummy_lookup_value;
- for i in 1..(max_lookups_per_row + 1) {
- v.push(v[i - 1] * x)
+ for i in 1..=max_lookups_per_row {
+ v.push(v[i - 1] * x);
}
let beta1_per_row = beta1.pow(&[max_lookups_per_row as u64]);
@@ -340,6 +355,11 @@ pub struct LookupConfiguration<F: FftField> {
}
/// Specifies the lookup constraints as expressions.
+///
+/// # Panics
+///
+/// Will panic if single `element` length is bigger than `max_per_row` length.
+#[allow(clippy::cast_possible_truncation, clippy::too_many_lines)]
pub fn constraints<F: FftField>(configuration: &LookupConfiguration<F>) -> Vec<E<F>> {
// Something important to keep in mind is that the last 2 rows of
// all columns will have random values in them to maintain zero-knowledge.
@@ -403,8 +423,8 @@ pub fn constraints<F: FftField>(configuration: &LookupConfiguration<F>) -> Vec<E
// v[i] = (gamma + dummy)^i
let mut dummies = vec![ConstantExpr::one()];
let dummy = ConstantExpr::Gamma + dummy_lookup;
- for i in 1..(lookup_info.max_per_row + 1) {
- dummies.push(dummies[i - 1].clone() * dummy.clone())
+ for i in 1..=lookup_info.max_per_row {
+ dummies.push(dummies[i - 1].clone() * dummy.clone());
}
// TODO: we can just multiply with (1+beta)^max_per_row at the end for any f_term, it feels weird to do it here
@@ -552,7 +572,11 @@ pub fn constraints<F: FftField>(configuration: &LookupConfiguration<F>) -> Vec<E
}
/// Checks that all the lookup constraints are satisfied.
-#[allow(clippy::too_many_arguments)]
+///
+/// # Panics
+///
+/// Will panic if `d1` and `s` domain sizes do not match.
+#[allow(clippy::too_many_arguments, clippy::manual_assert)]
pub fn verify<F: PrimeField, I: Iterator<Item = F>, TABLE: Fn() -> I>(
dummy_lookup_value: F,
lookup_table: TABLE,
@@ -587,9 +611,9 @@ pub fn verify<F: PrimeField, I: Iterator<Item = F>, TABLE: Fn() -> I>(
for (i, s) in sorted.iter().enumerate() {
let es = s.evals.iter().take(lookup_rows + 1);
if i % 2 == 0 {
- sorted_joined.extend(es)
+ sorted_joined.extend(es);
} else {
- sorted_joined.extend(es.rev())
+ sorted_joined.extend(es.rev());
}
}
@@ -609,11 +633,11 @@ pub fn verify<F: PrimeField, I: Iterator<Item = F>, TABLE: Fn() -> I>(
for (i, s) in sorted.iter().enumerate() {
if i % 2 == 0 {
for x in s.evals.iter().take(lookup_rows) {
- *counts.entry(*x).or_insert(0) += 1
+ *counts.entry(*x).or_insert(0) += 1;
}
} else {
for x in s.evals.iter().skip(1).take(lookup_rows) {
- *counts.entry(*x).or_insert(0) += 1
+ *counts.entry(*x).or_insert(0) += 1;
}
}
}
@@ -635,10 +659,10 @@ pub fn verify<F: PrimeField, I: Iterator<Item = F>, TABLE: Fn() -> I>(
for joint_lookup in spec.iter() {
let joint_lookup_evaluation =
joint_lookup.evaluate(joint_combiner, table_id_combiner, &eval);
- *all_lookups.entry(joint_lookup_evaluation).or_insert(0) += 1
+ *all_lookups.entry(joint_lookup_evaluation).or_insert(0) += 1;
}
- *all_lookups.entry(dummy_lookup_value).or_insert(0) += lookup_info.max_per_row - spec.len()
+ *all_lookups.entry(dummy_lookup_value).or_insert(0) += lookup_info.max_per_row - spec.len();
}
assert_eq!(

diff:
@@ -194,6 +194,12 @@ pub struct LookupConstraintSystem<F: FftField> {
}
impl<F: PrimeField + SquareRootField> LookupConstraintSystem<F> {
+ /// Create the `LookupConstraintSystem`.
+ ///
+ /// # Errors
+ ///
+ /// Will give error if inputs validation do not match.
+ #[allow(clippy::cast_possible_truncation, clippy::too_many_lines)]
pub fn create(
gates: &[CircuitGate<F>],
lookup_tables: Vec<LookupTable<F>>,
@@ -268,7 +274,7 @@ impl<F: PrimeField + SquareRootField> LookupConstraintSystem<F> {
// create fixed tables for indexing the runtime tables
for runtime_table in runtime_tables {
- use RuntimeTableCfg::*;
+ use RuntimeTableCfg::{Custom, Indexed};
let (id, first_column) = match runtime_table {
&Indexed(RuntimeTableSpec { id, len }) => {
let indexes = (0..(len as u32)).map(F::from).collect();
@@ -355,13 +361,13 @@ impl<F: PrimeField + SquareRootField> LookupConstraintSystem<F> {
for table in &lookup_tables {
let table_len = table.data[0].len();
- if table.id != 0 {
- non_zero_table_id = true;
- } else {
+ if table.id == 0 {
has_table_id_0 = true;
if table.has_zero_entry() {
has_table_id_0_with_zero_entry = true;
}
+ } else {
+ non_zero_table_id = true;
}
//~~ - Update the corresponding entries in a table id vector (of size the domain as well)
@@ -379,7 +385,7 @@ impl<F: PrimeField + SquareRootField> LookupConstraintSystem<F> {
//~~ - Fill in any unused columns with 0 (to match the dummy value)
for lookup_table in lookup_table.iter_mut().skip(table.data.len()) {
- lookup_table.extend(repeat_n(F::zero(), table_len))
+ lookup_table.extend(repeat_n(F::zero(), table_len));
}
}
@@ -415,7 +421,7 @@ impl<F: PrimeField + SquareRootField> LookupConstraintSystem<F> {
//~ 8. pre-compute polynomial and evaluation form for the look up tables
let mut lookup_table_polys: Vec<DP<F>> = vec![];
let mut lookup_table8: Vec<E<F, D<F>>> = vec![];
- for col in lookup_table.into_iter() {
+ for col in lookup_table {
let poly = E::<F, D<F>>::from_vec_and_domain(col, domain.d1).interpolate();
let eval = poly.evaluate_over_domain_by_ref(domain.d8);
lookup_table_polys.push(poly);

original_message: Fix the pedantic lints (5)


message: Update the order of macros in some files

diff:
@@ -57,6 +57,7 @@ impl CurrOrNext {
/// they cannot be used at the same time on single row.
/// If we were ever to support this feature, we would have to make sure
/// not to re-use powers of alpha across constraints.
+#[allow(clippy::module_name_repetitions)]
#[repr(C)]
#[derive(
Clone,
@@ -78,7 +79,6 @@ impl CurrOrNext {
)]
#[cfg_attr(feature = "wasm_types", wasm_bindgen::prelude::wasm_bindgen)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
-#[allow(clippy::module_name_repetitions)]
pub enum GateType {
/// Zero gate
Zero = 0,
@@ -160,9 +160,9 @@ pub enum CircuitGateError {
/// Gate result
pub type CircuitGateResult<T> = std::result::Result<T, CircuitGateError>;
+#[allow(clippy::module_name_repetitions)]
#[serde_as]
#[derive(Clone, Debug, Serialize, Deserialize)]
-#[allow(clippy::module_name_repetitions)]
/// A single gate in a circuit.
pub struct CircuitGate<F: PrimeField> {
/// type of the gate

diff:
@@ -25,8 +25,8 @@ fn max_lookups_per_row(kinds: &[LookupPattern]) -> usize {
/// Specifies whether a constraint system uses joint lookups. Used to make sure we
/// squeeze the challenge `joint_combiner` when needed, and not when not needed.
-#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[allow(clippy::module_name_repetitions)]
+#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum LookupsUsed {
Single,
Joint,

diff:
@@ -42,13 +42,13 @@ pub struct LookupEvaluations<Field> {
/// Polynomial evaluations contained in a `ProverProof`.
/// - **Chunked evaluations** `Field` is instantiated with vectors with a length that equals the length of the chunk
/// - **Non chunked evaluations** `Field` is instantiated with a field, so they are single-sized#[serde_as]
+#[allow(clippy::module_name_repetitions)]
#[serde_as]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound(
serialize = "Vec<o1_utils::serialization::SerdeAs>: serde_with::SerializeAs<Field>",
deserialize = "Vec<o1_utils::serialization::SerdeAs>: serde_with::DeserializeAs<'de, Field>"
))]
-#[allow(clippy::module_name_repetitions)]
pub struct ProofEvaluations<Field> {
/// witness polynomials
#[serde_as(as = "[Vec<o1_utils::serialization::SerdeAs>; COLUMNS]")]
@@ -99,10 +99,10 @@ pub struct ProverCommitments<G: AffineCurve> {
}
/// The proof that the prover creates from a [ProverIndex](super::prover_index::ProverIndex) and a `witness`.
+#[allow(clippy::module_name_repetitions)]
#[serde_as]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
-#[allow(clippy::module_name_repetitions)]
pub struct ProverProof<G: AffineCurve> {
/// All the polynomial commitments required in the proof
pub commitments: ProverCommitments<G>,

diff:
@@ -35,9 +35,9 @@ use std::{
};
//~spec:startcode
+#[allow(clippy::module_name_repetitions)]
#[serde_as]
#[derive(Serialize, Deserialize, Debug, Clone)]
-#[allow(clippy::module_name_repetitions)]
pub struct LookupVerifierIndex<G: CommitmentCurve> {
pub lookup_used: LookupsUsed,
#[serde(bound = "PolyComm<G>: Serialize + DeserializeOwned")]


message: Remove some lints allowance macros for specification CI

diff:
@@ -42,7 +42,6 @@ pub struct LookupEvaluations<Field> {
/// Polynomial evaluations contained in a `ProverProof`.
/// - **Chunked evaluations** `Field` is instantiated with vectors with a length that equals the length of the chunk
/// - **Non chunked evaluations** `Field` is instantiated with a field, so they are single-sized#[serde_as]
-#[allow(clippy::module_name_repetitions)]
#[serde_as]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound(
@@ -99,7 +98,6 @@ pub struct ProverCommitments<G: AffineCurve> {
}
/// The proof that the prover creates from a [ProverIndex](super::prover_index::ProverIndex) and a `witness`.
-#[allow(clippy::module_name_repetitions)]
#[serde_as]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]

diff:
@@ -35,7 +35,6 @@ use std::{
};
//~spec:startcode
-#[allow(clippy::module_name_repetitions)]
#[serde_as]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct LookupVerifierIndex<G: CommitmentCurve> {


message: Re-introduce the wildcard when importing multipl enum/structs

diff:
@@ -1640,10 +1640,7 @@ impl<F: Neg<Output = F> + Clone + One + Zero + PartialEq> Expr<F> {
h
};
let constant = |e: Expr<F>| sing(vec![], e);
- use Expr::{
- BinOp, Cache, Cell, Constant, Double, Pow, Square, UnnormalizedLagrangeBasis,
- VanishesOnLast4Rows,
- };
+ use Expr::*;
if self.is_constant(ev) {
return constant(self.clone());
@@ -2013,9 +2010,7 @@ impl<F: Field> Mul<F> for Expr<ConstantExpr<F>> {
impl<F: PrimeField> ConstantExpr<F> {
fn ocaml(&self) -> String {
- use ConstantExpr::{
- Add, Alpha, Beta, EndoCoefficient, Gamma, JointCombiner, Literal, Mds, Mul, Pow, Sub,
- };
+ use ConstantExpr::*;
match self {
Alpha => "alpha".to_string(),
Beta => "beta".to_string(),
@@ -2035,9 +2030,7 @@ impl<F: PrimeField> ConstantExpr<F> {
}
fn latex(&self) -> String {
- use ConstantExpr::{
- Add, Alpha, Beta, EndoCoefficient, Gamma, JointCombiner, Literal, Mds, Mul, Pow, Sub,
- };
+ use ConstantExpr::*;
match self {
Alpha => "\\alpha".to_string(),
Beta => "\\beta".to_string(),
@@ -2353,7 +2346,7 @@ pub fn coeff<F>(i: usize) -> E<F> {
/// You can import this module like `use kimchi::circuits::expr::prologue::*` to obtain a number of handy aliases and helpers
pub mod prologue {
- pub use super::{coeff, constant, index, witness, witness_curr, witness_next, E};
+ pub use super::*;
}
#[cfg(test)]

diff:
@@ -314,10 +314,7 @@ impl<F: PrimeField> ConstraintSystem<F> {
// -------------------------------------------------
pub mod testing {
- use super::{
- array, CircuitGate, ConstraintSystem, DensePolynomial, FftField, GateType, GenericGateSpec,
- PrimeField, Zero, COLUMNS, GENERIC_COEFFS, GENERIC_REGISTERS,
- };
+ use super::*;
use crate::circuits::wires::Wire;
use itertools::iterate;

diff:
@@ -274,7 +274,7 @@ impl<F: PrimeField> CircuitGate<F> {
}
pub mod witness {
- use super::{CairoInstruction, CairoProgram, Field, FlagBits, Offsets, Pointers, COLUMNS};
+ use super::*;
/// Returns the witness of an execution of a Cairo program in `CircuitGate` format
pub fn cairo_witness<F: Field>(prog: &CairoProgram<F>) -> [Vec<F>; COLUMNS] {
@@ -425,7 +425,7 @@ pub mod witness {
}
pub mod testing {
- use super::{array, CircuitGate, FftField, GateType, PrimeField, COLUMNS, NUM_FLAGS};
+ use super::*;
/// verifies that the Cairo gate constraints are solved by the witness depending on its type
///

diff:
@@ -4,7 +4,7 @@ use crate::alphas::Alphas;
use crate::circuits::argument::{Argument, ArgumentType};
use crate::circuits::lookup;
use crate::circuits::lookup::constraints::LookupConfiguration;
-use crate::circuits::polynomials::chacha::{ChaCha0, ChaCha1, ChaCha2, ChaChaFinal};
+use crate::circuits::polynomials::chacha::*;
use crate::circuits::polynomials::complete_add::CompleteAdd;
use crate::circuits::polynomials::endomul_scalar::EndomulScalar;
use crate::circuits::polynomials::endosclmul::EndosclMul;
@@ -95,7 +95,7 @@ pub fn linearization_columns<F: FftField + SquareRootField>(
lookup_constraint_system: Option<&LookupConfiguration<F>>,
) -> std::collections::HashSet<Column> {
let mut h = std::collections::HashSet::new();
- use Column::{Index, LookupAggreg, LookupRuntimeTable, LookupSorted, LookupTable, Witness, Z};
+ use Column::*;
// the witness polynomials
for i in 0..COLUMNS {

diff:
@@ -600,10 +600,7 @@ where
let lagrange = index.cs.evaluate(&witness_poly, &z_poly);
let env = {
let mut index_evals = HashMap::new();
- use GateType::{
- ChaCha0, ChaCha1, ChaCha2, ChaChaFinal, CompleteAdd, EndoMul, EndoMulScalar,
- Poseidon, VarBaseMul,
- };
+ use GateType::*;
index_evals.insert(Poseidon, &index.cs.ps8);
index_evals.insert(CompleteAdd, &index.cs.complete_addl4);
index_evals.insert(VarBaseMul, &index.cs.mull8);

diff:
@@ -141,7 +141,7 @@ impl<G: KimchiCurve> ProverIndex<G> {
}
pub mod testing {
- use super::{Arc, ConstraintSystem, EvaluationDomain, ProverIndex, SRS};
+ use super::*;
use crate::circuits::{
gate::CircuitGate,
lookup::{runtime_tables::RuntimeTableCfg, tables::LookupTable},


message: Fix the issues of comments

diff:
@@ -788,7 +788,7 @@ pub trait Cs<F: PrimeField> {
// Do one full round on the previous value
let mut acc = states[states.len() - 1]
.iter()
- .map(crate::writer::Var::val)
+ .map(|x| x.val())
.collect();
full_round::<F, PlonkSpongeConstantsKimchi>(
params,

diff:
@@ -1583,7 +1583,6 @@ impl<F: FftField> Linearization<Expr<ConstantExpr<F>>> {
impl<F: One> Expr<F> {
/// Exponentiate an expression
-
pub fn pow(self, p: u64) -> Self {
use Expr::*;
if p == 0 {
@@ -2007,7 +2006,6 @@ impl<F: Field> Mul<F> for Expr<ConstantExpr<F>> {
//
// Display
//
-
impl<F: PrimeField> ConstantExpr<F> {
fn ocaml(&self) -> String {
use ConstantExpr::*;
@@ -2174,15 +2172,12 @@ pub mod constraints {
Self: std::marker::Sized,
{
/// Double the value
-
fn double(&self) -> Self;
/// Compute the square of this value
-
fn square(&self) -> Self;
/// Raise the value to the given power
-
fn pow(&self, p: u64) -> Self;
/// Constrain to boolean
@@ -2317,25 +2312,21 @@ pub fn constant<F>(x: F) -> E<F> {
}
/// Helper function to quickly create an expression for a witness.
-
pub fn witness<F>(i: usize, row: CurrOrNext) -> E<F> {
E::<F>::cell(Column::Witness(i), row)
}
/// Same as [witness] but for the current row.
-
pub fn witness_curr<F>(i: usize) -> E<F> {
witness(i, CurrOrNext::Curr)
}
/// Same as [witness] but for the next row.
-
pub fn witness_next<F>(i: usize) -> E<F> {
witness(i, CurrOrNext::Next)
}
/// Handy function to quickly create an expression for a gate.
-
pub fn index<F>(g: GateType) -> E<F> {
E::<F>::cell(Column::Index(g), CurrOrNext::Curr)
}
@@ -2346,7 +2337,7 @@ pub fn coeff<F>(i: usize) -> E<F> {
/// You can import this module like `use kimchi::circuits::expr::prologue::*` to obtain a number of handy aliases and helpers
pub mod prologue {
- pub use super::*;
+ pub use super::{coeff, constant, index, witness, witness_curr, witness_next, E};
}
#[cfg(test)]

diff:
//! This module implements Plonk constraint gate primitive.
-
use crate::{
circuits::{
argument::{Argument, ArgumentEnv},
@@ -43,7 +42,6 @@ impl CurrOrNext {
/// Compute the offset corresponding to the `CurrOrNext` value.
/// - `Curr.shift() == 0`
/// - `Next.shift() == 1`
-
pub fn shift(&self) -> usize {
match self {
CurrOrNext::Curr => 0,
@@ -191,7 +189,6 @@ impl<F: PrimeField> ToBytes for CircuitGate<F> {
impl<F: PrimeField> CircuitGate<F> {
/// this function creates "empty" circuit gate
-
pub fn zero(wires: GateWires) -> Self {
CircuitGate {
typ: GateType::Zero,
@@ -213,11 +210,7 @@ impl<F: PrimeField> CircuitGate<F> {
cs: &ConstraintSystem<F>,
public: &[F],
) -> Result<(), String> {
- use GateType::{
- CairoClaim, CairoFlags, CairoInstruction, CairoTransition, ChaCha0, ChaCha1, ChaCha2,
- ChaChaFinal, CompleteAdd, EndoMul, EndoMulScalar, Generic, Lookup, Poseidon,
- RangeCheck0, RangeCheck1, VarBaseMul, Zero,
- };
+ use GateType::*;
match self.typ {
Zero => Ok(()),
Generic => self.verify_generic(row, witness, public),

diff:
use crate::{
circuits::{
- expr::{
- prologue::{witness, E},
- Column, ConstantExpr,
- },
+ expr::{prologue::*, Column, ConstantExpr},
gate::{CircuitGate, CurrOrNext},
lookup::lookups::{
JointLookup, JointLookupSpec, JointLookupValue, LocalPosition, LookupInfo, LookupsUsed,

diff:
//! At proving time, the prover can use [`RuntimeTable`] to specify the actual tables.
use crate::circuits::{
- expr::{prologue::E, Column},
+ expr::{prologue::*, Column},
gate::CurrOrNext,
};
use ark_ff::Field;

diff:
@@ -145,7 +145,7 @@ pub fn expr_linearization<F: FftField + SquareRootField>(
let linearization = expr
.linearize(evaluated_cols)
.unwrap()
- .map(crate::circuits::expr::Expr::to_polish);
+ .map(|x| x.to_polish());
(linearization, powers_of_alpha)
}

diff:
@@ -147,11 +147,6 @@ where
/// # Panics
///
/// Will panic if `lookup_context.joint_lookup_table_d8` is None.
- #[allow(
- clippy::needless_pass_by_value,
- clippy::too_many_lines,
- clippy::cast_possible_truncation
- )]
pub fn create_recursive<
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
EFrSponge: FrSponge<G::ScalarField>,

diff:
@@ -62,6 +62,7 @@ impl TestFramework {
self
}
+ #[must_use]
pub(crate) fn public_inputs(mut self, public_inputs: Vec<Fp>) -> Self {
self.public_inputs = public_inputs;
self

diff:
@@ -44,10 +44,7 @@ where
F: PrimeField,
{
fn latex() -> Vec<Vec<String>> {
- Self::constraints()
- .iter()
- .map(kimchi::circuits::expr::Expr::latex_str)
- .collect()
+ Self::constraints().iter().map(|c| c.latex_str()).collect()
}
}

original_message: Fix the issues of comments


message: Fix the missing lint warnings

diff:
@@ -2006,6 +2006,7 @@ impl<F: Field> Mul<F> for Expr<ConstantExpr<F>> {
//
// Display
//
+
impl<F: PrimeField> ConstantExpr<F> {
fn ocaml(&self) -> String {
use ConstantExpr::*;

diff:
@@ -405,7 +405,7 @@ impl LookupPattern {
/// Returns the lookup pattern used by a [`GateType`] on a given row (current or next).
pub fn from_gate(gate_type: GateType, curr_or_next: CurrOrNext) -> Option<Self> {
use CurrOrNext::{Curr, Next};
- use GateType::{ChaCha0, ChaCha1, ChaCha2, ChaChaFinal, Lookup, RangeCheck0, RangeCheck1};
+ use GateType::*;
match (gate_type, curr_or_next) {
(ChaCha0 | ChaCha1 | ChaCha2, Curr | Next) => Some(LookupPattern::ChaCha),
(ChaChaFinal, Curr | Next) => Some(LookupPattern::ChaChaFinal),

diff:
@@ -422,7 +422,6 @@ pub mod testing {
/// # Panics
///
/// Will panic if `gates_row` is None.
-
pub fn create_circuit<F: PrimeField>(start_row: usize, public: usize) -> Vec<CircuitGate<F>> {
// create constraint system with a single generic gate
let mut gates = vec![];

diff:
@@ -144,7 +144,7 @@ pub fn expr_linearization<F: FftField + SquareRootField>(
let linearization = expr
.linearize(evaluated_cols)
.unwrap()
- .map(|x| x.to_polish());
+ .map(|e| e.to_polish());
(linearization, powers_of_alpha)
}

diff:
@@ -88,7 +88,7 @@ impl<Field: PrimeField> GateSpec<usize, Field> {
let wires: Vec<_> = wired_to
.into_iter()
.take(PERMUTS)
- .map(Position::to_rust_wire)
+ .map(|x| x.to_rust_wire())
.collect();
CircuitGate {
typ: kind,
@@ -666,7 +666,6 @@ impl<Field: PrimeField, Gates: GateVector<Field>> SnarkyConstraintSystem<Field,
It returns the output variable as (1, `Var res),
unless the output is a constant, in which case it returns (c, `Constant).
*/
-
fn reduce_lincom<Cvar>(&mut self, x: Cvar) -> (Field, ConstantOrVar)
where
Cvar: SnarkyCvar<Field = Field>,

diff:
@@ -57,6 +57,7 @@ impl TestFramework {
self.gates = Some(gates);
self
}
+
#[must_use]
pub(crate) fn witness(mut self, witness: [Vec<Fp>; COLUMNS]) -> Self {
self.witness = Some(witness);

original_message: Fix the missing lint warnings


message: Fix the missing lint warnings (2)

diff:
@@ -1583,6 +1583,7 @@ impl<F: FftField> Linearization<Expr<ConstantExpr<F>>> {
impl<F: One> Expr<F> {
/// Exponentiate an expression
+ #[must_use]
pub fn pow(self, p: u64) -> Self {
use Expr::*;
if p == 0 {
@@ -2077,10 +2078,7 @@ where
/// Recursively print the expression,
/// except for the cached expression that are stored in the `cache`.
fn ocaml(&self, cache: &mut HashMap<CacheId, Expr<ConstantExpr<F>>>) -> String {
- use Expr::{
- BinOp, Cache, Cell, Constant, Double, Pow, Square, UnnormalizedLagrangeBasis,
- VanishesOnLast4Rows,
- };
+ use Expr::*;
match self {
Double(x) => format!("double({})", x.ocaml(cache)),
Constant(x) => x.ocaml(),

diff:
@@ -350,6 +350,7 @@ pub struct VarbaseMulResult<F> {
pub acc: (F, F),
pub n: F,
}
+
/// Apply the `witness` value.
///
/// # Panics

original_message: Fix the missing lint warnings (2)


message: Update the "absorb_evaluations" for "FrSponge" trait

diff:
@@ -59,36 +59,25 @@ impl<Fr: PrimeField> FrSponge<Fr> for DefaultFrSponge<Fr, SC> {
fn absorb_evaluations<const N: usize>(&mut self, e: [&ProofEvaluations<Vec<Fr>>; N]) {
self.last_squeezed = vec![];
- let e = ProofEvaluations::transpose(e);
-
- let mut points = vec![
- &e.z,
- &e.generic_selector,
- &e.poseidon_selector,
- &e.w[0],
- &e.w[1],
- &e.w[2],
- &e.w[3],
- &e.w[4],
- &e.w[5],
- &e.w[6],
- &e.w[7],
- &e.w[8],
- &e.w[9],
- &e.w[10],
- &e.w[11],
- &e.w[12],
- &e.w[13],
- &e.w[14],
- &e.s[0],
- &e.s[1],
- &e.s[2],
- &e.s[3],
- &e.s[4],
- &e.s[5],
- ];
-
- if let Some(l) = e.lookup.as_ref() {
+ let ProofEvaluations {
+ w,
+ z,
+ s,
+ lookup,
+ generic_selector,
+ poseidon_selector,
+ } = ProofEvaluations::transpose(e);
+
+ let mut points = vec![&z, &generic_selector, &poseidon_selector];
+
+ for w in w.iter() {
+ points.push(w);
+ }
+ for s in s.iter() {
+ points.push(s);
+ }
+
+ if let Some(l) = lookup.as_ref() {
points.push(&l.aggreg);
points.push(&l.table);
for s in &l.sorted {


message: Add the "ChunkedEvaluations" type for "ProofEvaluations" refactor

change_type: ADD

diff:
+//! This module contains a type [ChunkedEvaluations],
+
+use serde::{Deserialize, Serialize};
+use serde_with::serde_as;
+
+/// This struct contains multiple chunk evaluations.
+#[serde_as]
+#[derive(Clone, Serialize, Deserialize)]
+#[serde(bound = "F: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
+pub struct ChunkedEvaluations<F> {
+ /// The chunk evaluations.
+ #[serde_as(as = "Vec<crate::serialization::SerdeAs>")]
+ pub chunks: Vec<F>,
+
+ /// Each chunk polynomial has degree `size-1`.
+ pub size: usize,
+}

diff:
//! A collection of utility functions and constants that can be reused from multiple projects
pub mod adjacent_pairs;
+pub mod chunked_evaluations;
pub mod chunked_polynomial;
pub mod dense_polynomial;
pub mod evaluations;
@@ -12,6 +13,7 @@ pub mod hasher;
pub mod math;
pub mod serialization;
+pub use chunked_evaluations::ChunkedEvaluations;
pub use dense_polynomial::ExtendedDensePolynomial;
pub use evaluations::ExtendedEvaluations;
pub use field_helpers::FieldHelpers;


message: Update the generic type bound in "ChunkedEvaluations" type

diff:
//! This module contains a type [ChunkedEvaluations],
+use ark_ff::PrimeField;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
/// This struct contains multiple chunk evaluations.
#[serde_as]
#[derive(Clone, Serialize, Deserialize)]
-#[serde(bound = "F: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
-pub struct ChunkedEvaluations<F> {
+pub struct ChunkedEvaluations<F>
+where
+ F: PrimeField,
+{
/// The chunk evaluations.
#[serde_as(as = "Vec<crate::serialization::SerdeAs>")]
pub chunks: Vec<F>,


message: Add the deconstruction code in "kimchi/plonk_sponge/absorb_evaluations"

diff:
@@ -59,51 +59,59 @@ impl<Fr: PrimeField> FrSponge<Fr> for DefaultFrSponge<Fr, SC> {
fn absorb_evaluations<const N: usize>(&mut self, e: [&ProofEvaluations<Vec<Fr>>; N]) {
self.last_squeezed = vec![];
- let e = ProofEvaluations::transpose(e);
+ let ProofEvaluations {
+ w,
+ z,
+ s,
+ coefficients,
+ lookup,
+ generic_selector,
+ poseidon_selector,
+ } = ProofEvaluations::transpose(e);
let mut points = vec![
- &e.z,
- &e.generic_selector,
- &e.poseidon_selector,
- &e.w[0],
- &e.w[1],
- &e.w[2],
- &e.w[3],
- &e.w[4],
- &e.w[5],
- &e.w[6],
- &e.w[7],
- &e.w[8],
- &e.w[9],
- &e.w[10],
- &e.w[11],
- &e.w[12],
- &e.w[13],
- &e.w[14],
- &e.coefficients[0],
- &e.coefficients[1],
- &e.coefficients[2],
- &e.coefficients[3],
- &e.coefficients[4],
- &e.coefficients[5],
- &e.coefficients[6],
- &e.coefficients[7],
- &e.coefficients[8],
- &e.coefficients[9],
- &e.coefficients[10],
- &e.coefficients[11],
- &e.coefficients[12],
- &e.coefficients[13],
- &e.coefficients[14],
- &e.s[0],
- &e.s[1],
- &e.s[2],
- &e.s[3],
- &e.s[4],
- &e.s[5],
+ &z,
+ &generic_selector,
+ &poseidon_selector,
+ &w[0],
+ &w[1],
+ &w[2],
+ &w[3],
+ &w[4],
+ &w[5],
+ &w[6],
+ &w[7],
+ &w[8],
+ &w[9],
+ &w[10],
+ &w[11],
+ &w[12],
+ &w[13],
+ &w[14],
+ &coefficients[0],
+ &coefficients[1],
+ &coefficients[2],
+ &coefficients[3],
+ &coefficients[4],
+ &coefficients[5],
+ &coefficients[6],
+ &coefficients[7],
+ &coefficients[8],
+ &coefficients[9],
+ &coefficients[10],
+ &coefficients[11],
+ &coefficients[12],
+ &coefficients[13],
+ &coefficients[14],
+ &s[0],
+ &s[1],
+ &s[2],
+ &s[3],
+ &s[4],
+ &s[5],
];
- if let Some(l) = e.lookup.as_ref() {
+ if let Some(l) = lookup.as_ref() {
points.push(&l.aggreg);
points.push(&l.table);
for s in &l.sorted {

diff:
use crate::circuits::wires::{COLUMNS, PERMUTS};
use ark_ec::AffineCurve;
-use ark_ff::{FftField, One, Zero};
+use ark_ff::{FftField, Field, One, Zero};
use ark_poly::univariate::DensePolynomial;
use commitment_dlog::{
commitment::{b_poly, b_poly_coefficients, PolyComm},
evaluation_proof::OpeningProof,
};
+use itertools::chain;
use o1_utils::ExtendedDensePolynomial;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;


message: Remove the unnecessary imports

diff:
use crate::circuits::wires::{COLUMNS, PERMUTS};
use ark_ec::AffineCurve;
-use ark_ff::{FftField, Field, One, Zero};
+use ark_ff::{FftField, One, Zero};
use ark_poly::univariate::DensePolynomial;
use commitment_dlog::{
commitment::{b_poly, b_poly_coefficients, PolyComm},
evaluation_proof::OpeningProof,
};
-use itertools::chain;
use o1_utils::ExtendedDensePolynomial;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;

original_message: Remove the unnecessary imports


message: Integrate the "clippy-beta" feature into the github CI

diff:
@@ -78,6 +78,13 @@ jobs:
command: clippy
args: --all-features -- -D warnings
+ - name: Run Clippy (beta)
+ uses: actions-rs/clippy-check@v1
+ continue-on-error: true
+ with:
+ name: Clippy (beta)
+ args: --all-features --all-targets -- -W clippy::all
+
#
# Doc & Spec
#


message: Add the required "token" field to "clippy-check" CI action

diff:
@@ -83,6 +83,7 @@ jobs:
continue-on-error: true
with:
name: Clippy (beta)
+ token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features --all-targets -- -W clippy::all
#


message: Fix the wrong formulas in "book/src/fundamentals/zkbook_commitment.md"

diff:
@@ -228,7 +228,7 @@ $$
and commit to it as above to get a commitment $c_q$. And $c_q$ will be the opening proof. It remains only to describe verification. It works like this
$$
-\mathsf{verify}(c_f, (b, c_q)) := e(c_q, w - a \cdot g_2)=_? e(c_f, g_2)
+\mathsf{verify}(c_f, (b, c_q)) := e(c_q, w - a \cdot g_2)=_? e(c_f - b \cdot g_1, g_2)
$$
This amounts to checking: *"is the polynomial committed to $c_f$ equal to the polynomial committed to by $c_q$ times $x - a$"?*
@@ -236,13 +236,13 @@ This amounts to checking: *"is the polynomial committed to $c_f$ equal to the po
To see why, remember that $w = \tau \cdot g_2$, and say $c_q = s_q\cdot g_1$ and $c_f = s_f \cdot g_1$ so we are checking
$$
-e(s_q \cdot g_1, (\tau - a) \cdot g_2) =_? e(s_f \cdot g_1, g_2)
+e(s_q \cdot g_1, (\tau - a) \cdot g_2) =_? e((s_f - b) \cdot g_1, g_2)
$$
which by the bilinearity of the pairing is the same as checking
$$
-s_q \cdot (\tau - a) = s_f
+s_q \cdot (\tau - a) = s_f - b
$$
## Bootleproof inner product argument


message: Add the "LookupEvaluations" deconstruction code

diff:
@@ -5,7 +5,7 @@ use mina_poseidon::{
poseidon::{ArithmeticSponge, ArithmeticSpongeParams, Sponge},
};
-use crate::proof::ProofEvaluations;
+use crate::proof::{LookupEvaluations, ProofEvaluations};
pub trait FrSponge<Fr: Field> {
/// Creates a new Fr-Sponge.
@@ -112,12 +112,18 @@ impl<Fr: PrimeField> FrSponge<Fr> for DefaultFrSponge<Fr, SC> {
];
if let Some(l) = lookup.as_ref() {
- points.push(&l.aggreg);
- points.push(&l.table);
- for s in &l.sorted {
+ let LookupEvaluations {
+ sorted,
+ aggreg,
+ table,
+ runtime,
+ } = l;
+ points.push(&aggreg);
+ points.push(&table);
+ for s in sorted {
points.push(s);
}
- l.runtime.iter().for_each(|x| points.push(x));
+ runtime.iter().for_each(|x| points.push(x));
}
for p in points {


message: Replace the horner method with arkworks crate method

diff:
//! This adds a few utility functions for the [DensePolynomial] arkworks type.
use ark_ff::Field;
-use ark_poly::{univariate::DensePolynomial, UVPolynomial};
+use ark_poly::{univariate::DensePolynomial, Polynomial, UVPolynomial};
use rayon::prelude::*;
use crate::chunked_polynomial::ChunkedPolynomial;
@@ -43,13 +43,7 @@ impl<F: Field> ExtendedDensePolynomial<F> for DensePolynomial<F> {
}
fn eval_polynomial(coeffs: &[F], x: F) -> F {
- // this uses https://en.wikipedia.org/wiki/Horner%27s_method
- let mut res = F::zero();
- for c in coeffs.iter().rev() {
- res *= &x;
- res += c;
- }
- res
+ DensePolynomial::from_coefficients_slice(coeffs).evaluate(&x)
}
fn to_chunked_polynomial(&self, chunk_size: usize) -> ChunkedPolynomial<F> {


message: Fix the error of protocol explain in "book/src/plonk/inner_product.md"

diff:
@@ -113,6 +113,7 @@ We can picture the protocol as follows:
1. The prover first sends a commitment to the polynomial $f$.
2. The verifier sends a point $s$, asking for the value $f(s)$. To help the prover perform a proof of correct evaluation, they also send a random challenge $x$.
+(NOTE: The verifier sends the random challenge $x$ ONLY AFTER they receive the $z=f(s)$)
3. The prover sends the result of the evaluation, $z$, as well as a proof.
![inner 1](../img/inner1.png)


message: Remove the "max_quot_size" field from both "prover_index" & "verifier_index"

diff:
@@ -5,7 +5,6 @@ use crate::{
circuits::{
constraints::ConstraintSystem,
expr::{Linearization, PolishToken},
- wires::PERMUTS,
},
curve::KimchiCurve,
linearization::expr_linearization,
@@ -42,9 +41,6 @@ pub struct ProverIndex<G: KimchiCurve> {
/// maximal size of polynomial section
pub max_poly_size: usize,
- /// maximal size of the quotient polynomial according to the supported constraints
- pub max_quot_size: usize,
-
/// The verifier index corresponding to this prover index
#[serde(skip)]
pub verifier_index: Option<VerifierIndex<G>>,
@@ -87,19 +83,12 @@ impl<G: KimchiCurve> ProverIndex<G> {
true,
);
- // set `max_quot_size` to the degree of the quotient polynomial,
- // which is obtained by looking at the highest monomial in the sum
- // $$\sum_{i=0}^{PERMUTS} (w_i(x) + \beta k_i x + \gamma)$$
- // where the $w_i(x)$ are of degree the size of the domain.
- let max_quot_size = PERMUTS * cs.domain.d1.size();
-
ProverIndex {
cs,
linearization,
powers_of_alpha,
srs,
max_poly_size,
- max_quot_size,
verifier_index: None,
verifier_index_digest: None,
}

diff:
@@ -66,8 +66,6 @@ pub struct VerifierIndex<G: KimchiCurve> {
pub domain: D<G::ScalarField>,
/// maximal size of polynomial section
pub max_poly_size: usize,
- /// maximal size of the quotient polynomial according to the supported constraints
- pub max_quot_size: usize,
/// polynomial commitment keys
#[serde(skip)]
pub srs: OnceCell<Arc<SRS<G>>>,
@@ -202,7 +200,6 @@ impl<G: KimchiCurve> ProverIndex<G> {
VerifierIndex {
domain,
max_poly_size: self.max_poly_size,
- max_quot_size: self.max_quot_size,
powers_of_alpha: self.powers_of_alpha.clone(),
public: self.cs.public,
prev_challenges: self.cs.prev_challenges,
@@ -376,7 +373,6 @@ impl<G: KimchiCurve> VerifierIndex<G> {
let VerifierIndex {
domain: _,
max_poly_size: _,
- max_quot_size: _,
srs: _,
public: _,
prev_challenges: _,


message: Fix the typo in "ProverIndex::create()" method

diff:
@@ -66,7 +66,7 @@ impl<G: KimchiCurve> ProverIndex<G> {
if cs.public > 0 {
assert!(
max_poly_size >= cs.domain.d1.size(),
- "polynomial segment size has to be not smaller that that of the circuit!"
+ "polynomial segment size has to be not smaller than that of the circuit!"
);
}
cs.endo = endo_q;


message: Fix the kimchi spec for removed field - "max_quot_size"

diff:
@@ -1516,9 +1516,6 @@ pub struct ProverIndex<G: KimchiCurve> {
/// maximal size of polynomial section
pub max_poly_size: usize,
- /// maximal size of the quotient polynomial according to the supported constraints
- pub max_quot_size: usize,
-
/// The verifier index corresponding to this prover index
#[serde(skip)]
pub verifier_index: Option<VerifierIndex<G>>,
@@ -1565,8 +1562,6 @@ pub struct VerifierIndex<G: KimchiCurve> {
pub domain: D<G::ScalarField>,
/// maximal size of polynomial section
pub max_poly_size: usize,
- /// maximal size of the quotient polynomial according to the supported constraints
- pub max_quot_size: usize,
/// polynomial commitment keys
#[serde(skip)]
pub srs: OnceCell<Arc<SRS<G>>>,


message: Remove the "endo_r" & "endo_q" fields from SRS struct since irrelevant

diff:
//! producing the batched opening proof
//! 3. Verify batch of batched opening proofs
+use crate::srs::endos;
use crate::{error::CommitmentError, srs::SRS};
use ark_ec::{
models::short_weierstrass_jacobian::GroupAffine as SWJAffine, msm::VariableBaseMSM,
@@ -692,6 +693,8 @@ impl<G: CommitmentCurve> SRS<G> {
let padded_length = 1 << max_rounds;
+ let (_, endo_r) = endos::<G>();
+
// TODO: This will need adjusting
let padding = padded_length - nonzero_length;
let mut points = vec![self.h];
@@ -748,11 +751,10 @@ impl<G: CommitmentCurve> SRS<G> {
let t = sponge.challenge_fq();
let u: G = to_group(group_map, t);
- let Challenges { chal, chal_inv } =
- opening.challenges::<EFqSponge>(&self.endo_r, sponge);
+ let Challenges { chal, chal_inv } = opening.challenges::<EFqSponge>(&endo_r, sponge);
sponge.absorb_g(&[opening.delta]);
- let c = ScalarChallenge(sponge.challenge()).to_field(&self.endo_r);
+ let c = ScalarChallenge(sponge.challenge()).to_field(&endo_r);
// < s, sum_i evalscale^i pows(evaluation_point[i]) >
// ==

diff:
-use crate::commitment::*;
use crate::srs::SRS;
+use crate::{commitment::*, srs::endos};
use ark_ec::{msm::VariableBaseMSM, AffineCurve, ProjectiveCurve};
use ark_ff::{Field, One, PrimeField, UniformRand, Zero};
use ark_poly::{univariate::DensePolynomial, UVPolynomial};
@@ -96,6 +96,8 @@ impl<G: CommitmentCurve> SRS<G> {
RNG: RngCore + CryptoRng,
G::BaseField: PrimeField,
{
+ let (endo_q, endo_r) = endos::<G>();
+
let rounds = math::ceil_log2(self.g.len());
let padded_length = 1 << rounds;
@@ -223,7 +225,7 @@ impl<G: CommitmentCurve> SRS<G> {
sponge.absorb_g(&[r]);
let u_pre = squeeze_prechallenge(&mut sponge);
- let u = u_pre.to_field(&self.endo_r);
+ let u = u_pre.to_field(&endo_r);
let u_inv = u.inverse().unwrap();
chals.push(u);
@@ -253,7 +255,7 @@ impl<G: CommitmentCurve> SRS<G> {
})
.collect();
- g = G::combine_one_endo(self.endo_r, self.endo_q, &g_lo, &g_hi, u_pre);
+ g = G::combine_one_endo(endo_r, endo_q, &g_lo, &g_hi, u_pre);
}
assert!(g.len() == 1);
@@ -275,7 +277,7 @@ impl<G: CommitmentCurve> SRS<G> {
.into_affine();
sponge.absorb_g(&[delta]);
- let c = ScalarChallenge(sponge.challenge()).to_field(&self.endo_r);
+ let c = ScalarChallenge(sponge.challenge()).to_field(&endo_r);
let z1 = a0 * c + d;
let z2 = c * r_prime + r_delta;

diff:
@@ -27,12 +27,6 @@ pub struct SRS<G: CommitmentCurve> {
/// Commitments to Lagrange bases, per domain size
#[serde(skip)]
pub lagrange_bases: HashMap<usize, Vec<PolyComm<G>>>,
- /// Coefficient for the curve endomorphism
- #[serde(skip)]
- pub endo_r: G::ScalarField,
- /// Coefficient for the curve endomorphism
- #[serde(skip)]
- pub endo_q: G::BaseField,
}
pub fn endos<G: CommitmentCurve>() -> (G::BaseField, G::ScalarField)
@@ -228,8 +222,6 @@ where
})
.collect();
- let (endo_q, endo_r) = endos::<G>();
-
const MISC: usize = 1;
let [h]: [G; MISC] = array::from_fn(|i| {
let mut h = Blake2b512::new();
@@ -242,8 +234,6 @@ where
g,
h,
lagrange_bases: HashMap::new(),
- endo_r,
- endo_q,
}
}
}


message: Remove the "endo" spec from URS documentation

diff:
@@ -61,10 +61,6 @@ def point_of_random_bytes(random_bytes):
TODO: specify `map.to_group` in the previous section.
-## Endo stuff
-
-TODO: specify endo_r, endo_q
-
## URS values in practice
As there is no limit to the number of commitment curve points you can generate, we only provide the first three ones to serve as test vectors.


message: Move the "endo" values from "URS" document to "pasta" curve document


message: Replace the for loops with iter in "plonk_sponge"(absorb_evaluations)

diff:
@@ -69,47 +69,10 @@ impl<Fr: PrimeField> FrSponge<Fr> for DefaultFrSponge<Fr, SC> {
poseidon_selector,
} = e;
- let mut points = vec![
- z,
- generic_selector,
- poseidon_selector,
- &w[0],
- &w[1],
- &w[2],
- &w[3],
- &w[4],
- &w[5],
- &w[6],
- &w[7],
- &w[8],
- &w[9],
- &w[10],
- &w[11],
- &w[12],
- &w[13],
- &w[14],
- &coefficients[0],
- &coefficients[1],
- &coefficients[2],
- &coefficients[3],
- &coefficients[4],
- &coefficients[5],
- &coefficients[6],
- &coefficients[7],
- &coefficients[8],
- &coefficients[9],
- &coefficients[10],
- &coefficients[11],
- &coefficients[12],
- &coefficients[13],
- &coefficients[14],
- &s[0],
- &s[1],
- &s[2],
- &s[3],
- &s[4],
- &s[5],
- ];
+ let mut points = vec![z, generic_selector, poseidon_selector];
+ w.iter().for_each(|w_i| points.push(w_i));
+ coefficients.iter().for_each(|c_i| points.push(c_i));
+ s.iter().for_each(|s_i| points.push(s_i));
if let Some(l) = lookup.as_ref() {
let LookupEvaluations {
@@ -120,15 +83,13 @@ impl<Fr: PrimeField> FrSponge<Fr> for DefaultFrSponge<Fr, SC> {
} = l;
points.push(aggreg);
points.push(table);
- for s in sorted {
- points.push(s);
- }
+ sorted.iter().for_each(|s| points.push(s));
runtime.iter().for_each(|x| points.push(x));
}
- for p in points {
+ points.into_iter().for_each(|p| {
self.sponge.absorb(&p.zeta);
self.sponge.absorb(&p.zeta_omega);
- }
+ })
}
}


diff:
@@ -149,8 +149,15 @@ int openssl_init(void)
(void)signal(SIGPIPE, sigpipe_handler);
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ int err;
+ err = OPENSSL_init_ssl(OPENSSL_INIT_SSL_DEFAULT, NULL);
+ if (!err)
+ return !err;
+#else
SSL_library_init();
SSL_load_error_strings();
+#endif
return 0;
}
@@ -158,7 +165,9 @@ int openssl_init(void)
void openssl_close(void)
{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
ERR_free_strings();
+#endif
#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
lockv = mem_deref(lockv);
#endif

diff:
@@ -297,9 +297,15 @@ int tls_set_selfsigned_rsa(struct tls *tls, const char *cn, size_t bits)
!X509_set_subject_name(cert, subj))
goto out;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ if (!X509_gmtime_adj(X509_getm_notBefore(cert), -3600*24*365) ||
+ !X509_gmtime_adj(X509_getm_notAfter(cert), 3600*24*365*10))
+ goto out;
+#else
if (!X509_gmtime_adj(X509_get_notBefore(cert), -3600*24*365) ||
!X509_gmtime_adj(X509_get_notAfter(cert), 3600*24*365*10))
goto out;
+#endif
if (!X509_set_pubkey(cert, key))
goto out;

license: BSD 3-Clause New or Revised License

repo: baresip/re

original_message: openssl, tls: replace deprecated openssl 1.1.0 functions (#5)


message: tls: add functions to verify server cert, purpose and hostname

diff:
@@ -49,6 +49,9 @@ int tls_fingerprint(const struct tls *tls, enum tls_fingerprint type,
int tls_peer_fingerprint(const struct tls_conn *tc, enum tls_fingerprint type,
uint8_t *md, size_t size);
int tls_peer_common_name(const struct tls_conn *tc, char *cn, size_t size);
+int tls_peer_set_verify_host(struct tls_conn *tc, const char *hostname);
+int tls_set_verify_purpose(struct tls *tls, const char *purpose);
+int tls_set_hostname(char *tls_hostname, const struct pl *hostname);
int tls_peer_verify(const struct tls_conn *tc);
int tls_srtp_keyinfo(const struct tls_conn *tc, enum srtp_suite *suite,
uint8_t *cli_key, size_t cli_key_size,

diff:
@@ -229,6 +229,90 @@ int tls_add_ca(struct tls *tls, const char *cafile)
}
+/**
+ * Set SSL verification of the certificate purpose
+ *
+ * @param tls TLS Context
+ * @param purpose Certificate purpose as string
+ *
+ * @return int 0 if success, errorcode otherwise
+ */
+int tls_set_verify_purpose(struct tls *tls, const char *purpose)
+{
+ int err;
+ int i;
+ X509_PURPOSE *xptmp;
+
+ if (!tls || !purpose)
+ return EINVAL;
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ i = X509_PURPOSE_get_by_sname(purpose);
+#else
+ i = X509_PURPOSE_get_by_sname((char *) purpose);
+#endif
+
+ if (i < 0)
+ return EINVAL;
+
+ /* purpose index -> purpose object */
+ /* purpose object -> purpose value */
+ xptmp = X509_PURPOSE_get0(i);
+ i = X509_PURPOSE_get_id(xptmp);
+ err = SSL_CTX_set_purpose(tls->ctx, i);
+
+ return err == 1 ? 0 : EINVAL;
+}
+
+
+/**
+ * Set SSL verification of hostname
+ *
+ * @param tc TLS Connection
+ * @param hostname Certificate hostname
+ *
+ * @return int 0 if success, errorcode otherwise
+ */
+int tls_peer_set_verify_host(struct tls_conn *tc, const char *hostname)
+{
+ int err = 0;
+
+ if (!tc)
+ return EINVAL;
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ err = SSL_set1_host(tc->ssl, hostname);
+#else
+ DEBUG_WARNING("verify hostname needs openssl version 1.1.0\n");
+ return ENOSYS;
+#endif
+
+ return err == 1 ? 0 : EINVAL;
+}
+
+
+/**
+ * Convert string hostname to pl hostname
+ *
+ * @param tls_hostname Certificate hostname as string
+ * @param hostname Certificate hostname as pl
+ *
+ * @return int 0 if success, errorcode otherwise
+ */
+int tls_set_hostname(char *tls_hostname, const struct pl *hostname)
+{
+ if (!tls_hostname || !hostname)
+ return EINVAL;
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ DEBUG_WARNING("verify hostname needs openssl version 1.1.0\n");
+ return ENOSYS;
+#endif
+
+ return pl_strdup(&tls_hostname, hostname);
+}
+
+
/**
* Generate and set selfsigned certificate on TLS context
*


message: http: client should use tls functions to verify server certs, purpose and hostname

diff:
@@ -125,6 +125,8 @@ typedef void (http_conn_h)(struct tcp_conn *tc, struct tls_conn *sc,
void *arg);
int http_client_alloc(struct http_cli **clip, struct dnsc *dnsc);
+int http_client_add_ca(struct http_cli *cli, const char *tls_ca);
+int http_client_set_tls_hostname(struct http_cli *cli, const struct pl *hostname);
int http_request(struct http_req **reqp, struct http_cli *cli, const char *met,
const char *uri, http_resp_h *resph, http_data_h *datah,
void *arg, const char *fmt, ...);

diff:
@@ -35,6 +35,7 @@ struct http_cli {
struct hash *ht_conn;
struct dnsc *dnsc;
struct tls *tls;
+ char *tls_hostname;
};
struct conn;
@@ -97,6 +98,7 @@ static void cli_destructor(void *arg)
mem_deref(cli->ht_conn);
mem_deref(cli->dnsc);
mem_deref(cli->tls);
+ mem_deref(cli->tls_hostname);
}
@@ -683,11 +685,15 @@ int http_client_alloc(struct http_cli **clip, struct dnsc *dnsc)
#ifdef USE_TLS
err = tls_alloc(&cli->tls, TLS_METHOD_SSLV23, NULL, NULL);
+ if (err)
+ goto out;
+
+ err = tls_set_verify_purpose(cli->tls, "sslserver");
+ if (err)
+ goto out;
#else
err = 0;
#endif
- if (err)
- goto out;
cli->dnsc = mem_ref(dnsc);
@@ -699,3 +705,39 @@ int http_client_alloc(struct http_cli **clip, struct dnsc *dnsc)
return err;
}
+
+
+#ifdef USE_TLS
+/**
+ * Add trusted CA certificates
+ *
+ * @param cli HTTP client
+ * @param capath Path to CA certificates
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int http_client_add_ca(struct http_cli *cli, const char *tls_ca)
+{
+ if (!cli || !tls_ca)
+ return EINVAL;
+
+ return tls_add_ca(cli->tls, tls_ca);
+}
+
+
+/**
+ * Set verify host name
+ *
+ * @param cli HTTP client
+ * @param hostname String for alternative name validation.
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int http_client_set_tls_hostname(struct http_cli *cli, const struct pl *hostname)
+{
+ if (!cli || !hostname)
+ return EINVAL;
+
+ return tls_set_hostname(cli->tls_hostname, hostname);
+}
+#endif


message: http: codingstandard corrections

diff:
@@ -126,7 +126,8 @@ typedef void (http_conn_h)(struct tcp_conn *tc, struct tls_conn *sc,
int http_client_alloc(struct http_cli **clip, struct dnsc *dnsc);
int http_client_add_ca(struct http_cli *cli, const char *tls_ca);
-int http_client_set_tls_hostname(struct http_cli *cli, const struct pl *hostname);
+int http_client_set_tls_hostname(struct http_cli *cli,
+ const struct pl *hostname);
int http_request(struct http_req **reqp, struct http_cli *cli, const char *met,
const char *uri, http_resp_h *resph, http_data_h *datah,
void *arg, const char *fmt, ...);

diff:
@@ -446,7 +446,8 @@ static int conn_connect(struct http_req *req)
goto out;
if (req->cli->tls_hostname)
- err = tls_peer_set_verify_host(conn->sc, req->cli->tls_hostname);
+ err = tls_peer_set_verify_host(conn->sc,
+ req->cli->tls_hostname);
if (err)
goto out;
@@ -743,7 +744,8 @@ int http_client_add_ca(struct http_cli *cli, const char *tls_ca)
*
* @return 0 if success, otherwise errorcode
*/
-int http_client_set_tls_hostname(struct http_cli *cli, const struct pl *hostname)
+int http_client_set_tls_hostname(struct http_cli *cli,
+ const struct pl *hostname)
{
if (!cli || !hostname)
return EINVAL;

original_message: http: codingstandard corrections


message: tls: functions to get the certificate issuer and subject

diff:
@@ -61,6 +61,8 @@ int tls_set_ciphers(struct tls *tls, const char *cipherv[], size_t count);
int tls_set_servername(struct tls_conn *tc, const char *servername);
int tls_set_verify_server(struct tls_conn *tc, const char *host);
+int tls_get_issuer(struct tls *tls, struct mbuf *mb);
+int tls_get_subject(struct tls *tls, struct mbuf *mb);
/* TCP */

diff:
@@ -1033,3 +1033,129 @@ struct ssl_ctx_st *tls_openssl_context(const struct tls *tls)
{
return tls ? tls->ctx : NULL;
}
+
+
+/**
+ * Convert a X509_NAME object into a human-readable form placed in an mbuf
+ *
+ * @param field X509_NAME of Cert field
+ * @param mb Memorybuffer to store the readable format
+ * @param flags X509_NAME_print_ex flags
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+static int convert_X509_NAME_to_mbuf(X509_NAME *field, struct mbuf *mb,
+ unsigned long flags)
+{
+ BIO *outbio;
+ char *p;
+ long size;
+ int err = ENOMEM;
+
+ if (!field || !mb)
+ return EINVAL;
+
+ outbio = BIO_new(BIO_s_mem());
+ if (!outbio)
+ return ENOMEM;
+
+ if (X509_NAME_print_ex(outbio, field, 1, flags) <= 0)
+ goto out;
+
+ if (BIO_eof(outbio))
+ goto out;
+
+ size = BIO_get_mem_data(outbio, &p);
+ err = mbuf_write_mem(mb, (uint8_t *)p, size);
+ if (err)
+ goto out;
+
+ err = 0;
+
+ out:
+ if (outbio)
+ BIO_free(outbio);
+
+ return err;
+}
+
+
+/**
+ * Extract a X509 certficate issuer/subject and write the result into an mbuf
+ *
+ * @param tls TLS Object
+ * @param mb Memory buffer
+ * @param field_getter Functionpointer to the X509 getter functon
+ * @param flags X509_NAME_print_ex flags
+ *
+ * @return 0 if success, othewise errorcode
+ */
+static int tls_get_ca_chain_field(struct tls *tls, struct mbuf *mb,
+ tls_get_certfield_h *field_getter, unsigned long flags)
+{
+ STACK_OF(X509) *certstack;
+ X509 *cert;
+ X509_NAME *field;
+ int err = EINVAL;
+
+ if (!field_getter)
+ return EINVAL;
+
+ if (!SSL_CTX_get0_chain_certs(tls->ctx, &certstack) || !certstack)
+ goto out;
+
+ for (int i = 0; i < sk_X509_num(certstack); i++) {
+ cert = sk_X509_value(certstack, i);
+ if (!cert)
+ goto out;
+
+ field = field_getter(cert);
+ if (!field)
+ goto out;
+
+ err = convert_X509_NAME_to_mbuf(field, mb, flags);
+ if (err)
+ goto out;
+ }
+
+ err = 0;
+
+ out:
+ return err;
+}
+
+
+/**
+ * Get the issuers fields of a certificate chain
+ *
+ * @param tls TLS Object
+ * @param mb Memory Buffer
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int tls_get_issuer(struct tls *tls, struct mbuf *mb)
+{
+ if (!tls || !tls->ctx || !mb)
+ return EINVAL;
+
+ return tls_get_ca_chain_field(tls, mb, &X509_get_issuer_name,
+ XN_FLAG_RFC2253);
+}
+
+
+/**
+ * Get the subject fields of a certificate chain
+ *
+ * @param tls TLS Object
+ * @param mb Memory Buffer
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int tls_get_subject(struct tls *tls, struct mbuf *mb)
+{
+ if (!tls || !tls->ctx || !mb)
+ return EINVAL;
+
+ return tls_get_ca_chain_field(tls, mb, &X509_get_subject_name,
+ XN_FLAG_RFC2253);
+}

diff:
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+typedef X509_NAME*(tls_get_certfield_h)(const X509 *);
+#else
+typedef X509_NAME*(tls_get_certfield_h)(X509 *);
+#endif
+
+
struct tls {
SSL_CTX *ctx;
X509 *cert;


message: tls: set selfsigned Elliptic Curve (EC) function

diff:
@@ -36,6 +36,8 @@ int tls_add_ca(struct tls *tls, const char *cafile);
int tls_add_capem(struct tls *tls, const char *capem);
int tls_set_selfsigned(struct tls *tls, const char *cn);
int tls_set_selfsigned_rsa(struct tls *tls, const char *cn, size_t bits);
+int tls_set_selfsigned_ec(struct tls *tls, const char *cn,
+ const char *curve_n);
int tls_set_certificate_pem(struct tls *tls, const char *cert, size_t len_cert,
const char *key, size_t len_key);
int tls_set_certificate_der(struct tls *tls, enum tls_keytype keytype,

diff:
@@ -347,69 +347,179 @@ int tls_set_selfsigned(struct tls *tls, const char *cn)
}
-int tls_set_selfsigned_rsa(struct tls *tls, const char *cn, size_t bits)
+static int tls_generate_cert(X509 **pcert, const char *cn)
{
+ X509 *cert = NULL;
X509_NAME *subj = NULL;
+ int e = 0;
+
+ if (!pcert || !cn)
+ goto err;
+
+ cert = X509_new();
+ if (!cert)
+ goto err;
+
+ if (!X509_set_version(cert, 2))
+ goto err;
+
+ if (!ASN1_INTEGER_set(X509_get_serialNumber(cert), rand_u32()))
+ goto err;
+
+ subj = X509_NAME_new();
+ if (!subj)
+ goto err;
+
+ if (!X509_NAME_add_entry_by_txt(subj, "CN", MBSTRING_ASC,
+ (unsigned char *)cn,
+ (int)strlen(cn), -1, 0))
+ goto err;
+
+ if (!X509_set_issuer_name(cert, subj) ||
+ !X509_set_subject_name(cert, subj))
+ goto err;
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ if (!X509_gmtime_adj(X509_getm_notBefore(cert), -3600*24*365) ||
+ !X509_gmtime_adj(X509_getm_notAfter(cert), 3600*24*365*10))
+ goto err;
+#else
+ if (!X509_gmtime_adj(X509_get_notBefore(cert), -3600*24*365) ||
+ !X509_gmtime_adj(X509_get_notAfter(cert), 3600*24*365*10))
+ goto err;
+#endif
+
+ goto out;
+
+ err:
+ e = 1;
+
+ out:
+ if (e)
+ X509_free(cert);
+ else
+ *pcert = cert;
+
+ X509_NAME_free(subj);
+ return e;
+}
+
+
+/**
+ * Create a selfsigned X509 certificate using EC
+ *
+ * @param tls TLS Contect
+ * @param cn Common Name
+ * @param curve_n Known EC curve name
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int tls_set_selfsigned_ec(struct tls *tls, const char *cn, const char *curve_n)
+{
+ EC_KEY *eckey = NULL;
EVP_PKEY *key = NULL;
X509 *cert = NULL;
- BIGNUM *bn = NULL;
- RSA *rsa = NULL;
- int r, err = ENOMEM;
+ int r, eccgrp, err = ENOMEM;
if (!tls || !cn)
return EINVAL;
- rsa = RSA_new();
- if (!rsa)
- goto out;
+ eccgrp = OBJ_txt2nid(curve_n);
+ if (eccgrp == NID_undef)
+ return ENOTSUP;
- bn = BN_new();
- if (!bn)
+ eckey = EC_KEY_new_by_curve_name(eccgrp);
+ if (!eckey)
goto out;
- BN_set_word(bn, RSA_F4);
- if (!RSA_generate_key_ex(rsa, (int)bits, bn, NULL))
+ if (!EC_KEY_generate_key(eckey))
goto out;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
+#else
+ EC_KEY_set_asn1_flag(eckey, 0);
+#endif
+
key = EVP_PKEY_new();
if (!key)
goto out;
- if (!EVP_PKEY_set1_RSA(key, rsa))
+ if (!EVP_PKEY_set1_EC_KEY(key, eckey))
goto out;
- cert = X509_new();
- if (!cert)
+ if (tls_generate_cert(&cert, cn))
goto out;
- if (!X509_set_version(cert, 2))
+ if (!X509_set_pubkey(cert, key))
goto out;
- if (!ASN1_INTEGER_set(X509_get_serialNumber(cert), rand_u32()))
+ if (!X509_sign(cert, key, EVP_sha256()))
goto out;
- subj = X509_NAME_new();
- if (!subj)
+ r = SSL_CTX_use_certificate(tls->ctx, cert);
+ if (r != 1)
goto out;
- if (!X509_NAME_add_entry_by_txt(subj, "CN", MBSTRING_ASC,
- (unsigned char *)cn,
- (int)strlen(cn), -1, 0))
+ r = SSL_CTX_use_PrivateKey(tls->ctx, key);
+ if (r != 1)
goto out;
- if (!X509_set_issuer_name(cert, subj) ||
- !X509_set_subject_name(cert, subj))
+ if (tls->cert)
+ X509_free(tls->cert);
+
+ tls->cert = cert;
+ cert = NULL;
+
+ err = 0;
+
+ out:
+ if (eckey)
+ EC_KEY_free(eckey);
+
+ if (key)
+ EVP_PKEY_free(key);
+
+ if (cert)
+ X509_free(cert);
+
+
+ return err;
+}
+
+
+int tls_set_selfsigned_rsa(struct tls *tls, const char *cn, size_t bits)
+{
+ EVP_PKEY *key = NULL;
+ X509 *cert = NULL;
+ BIGNUM *bn = NULL;
+ RSA *rsa = NULL;
+ int r, err = ENOMEM;
+
+ if (!tls || !cn)
+ return EINVAL;
+
+ rsa = RSA_new();
+ if (!rsa)
goto out;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
- if (!X509_gmtime_adj(X509_getm_notBefore(cert), -3600*24*365) ||
- !X509_gmtime_adj(X509_getm_notAfter(cert), 3600*24*365*10))
+ bn = BN_new();
+ if (!bn)
goto out;
-#else
- if (!X509_gmtime_adj(X509_get_notBefore(cert), -3600*24*365) ||
- !X509_gmtime_adj(X509_get_notAfter(cert), 3600*24*365*10))
+
+ BN_set_word(bn, RSA_F4);
+ if (!RSA_generate_key_ex(rsa, (int)bits, bn, NULL))
+ goto out;
+
+ key = EVP_PKEY_new();
+ if (!key)
+ goto out;
+
+ if (!EVP_PKEY_set1_RSA(key, rsa))
+ goto out;
+
+ if (tls_generate_cert(&cert, cn))
goto out;
-#endif
if (!X509_set_pubkey(cert, key))
goto out;
@@ -434,9 +544,6 @@ int tls_set_selfsigned_rsa(struct tls *tls, const char *cn, size_t bits)
err = 0;
out:
- if (subj)
- X509_NAME_free(subj);
-
if (cert)
X509_free(cert);


message: http: httpreq should not handle any connections

diff:
@@ -47,8 +47,6 @@ struct http_reqconn {
struct sa peer; /**< Peer address */
struct http_req *req; /**< Current HTTP request */
- struct tcp_conn *tc; /**< TCP connection */
- struct tls_conn *sc; /**< TLS connection */
char *uri; /**< Request URI */
char *met; /**< Request Method */
@@ -77,9 +75,6 @@ static void destructor(void *arg)
struct http_reqconn *conn = arg;
mem_deref(conn->req);
- mem_deref(conn->tc);
- mem_deref(conn->sc);
-
mem_deref(conn->uri);
mem_deref(conn->met);
mem_deref(conn->path);
@@ -262,15 +257,6 @@ static int data_handler(const uint8_t *buf, size_t size,
}
-static void conn_handler(struct tcp_conn *tc, struct tls_conn *sc, void *arg)
-{
- struct http_reqconn *conn = arg;
-
- conn->tc = mem_ref(tc);
- conn->sc = mem_ref(sc);
-}
-
-
static int send_req(struct http_reqconn *conn, const struct pl *auth)
{
int err;
@@ -316,8 +302,6 @@ static int send_req(struct http_reqconn *conn, const struct pl *auth)
if (conn->custhdr)
pl_set_mbuf(&custh, conn->custhdr);
- conn->tc = mem_deref(conn->tc);
- conn->sc = mem_deref(conn->sc);
err = http_request(&conn->req, conn->client,
conn->met, conn->uri,
resp_handler, conn->datah ? data_handler : NULL, conn,
@@ -342,8 +326,6 @@ static int send_req(struct http_reqconn *conn, const struct pl *auth)
return err;
}
- http_req_set_conn_handler(conn->req, conn_handler);
-
/* keep internal reference for resp_handler */
conn = mem_ref(conn);
return 0;


message: http: httpreq mem leak fix if multiple requests are send via the conn object

diff:
@@ -228,14 +228,13 @@ static void resp_handler(int err, const struct http_msg *msg, void *arg)
if (err)
goto disconnect;
- mem_deref(abuf);
- mem_deref(basic);
- return;
+ goto out;
disconnect:
if (conn && conn->resph)
conn->resph(err, msg, conn->arg);
+ out:
mem_deref(abuf);
mem_deref(basic);
mem_deref(conn);