Fix the pedantic lints (1)
MODIFY
circuit-construction/src/constants.rs
circuit-construction/src/constants.rs
@@ -14,6 +14,12 @@ pub struct Constants<F: Field + 'static> {
}
/// Constants for the base field of Pallas
+/// ///
+/// # Panics
+///
+/// Will panic if `PallasAffine::prime_subgroup_generator()` returns None.
+#[allow(clippy::module_name_repetitions)]
+#[must_use]
pub fn fp_constants() -> Constants<Fp> {
let (endo_q, _endo_r) = endos::<PallasAffine>();
let base = PallasAffine::prime_subgroup_generator()
@@ -27,6 +33,12 @@ pub fn fp_constants() -> Constants<Fp> {
}
/// Constants for the base field of Vesta
+///
+/// # Panics
+///
+/// Will panic if `VestaAffine::prime_subgroup_generator()` returns None.
+#[allow(clippy::module_name_repetitions)]
+#[must_use]
pub fn fq_constants() -> Constants<Fq> {
let (endo_q, _endo_r) = endos::<VestaAffine>();
let base = VestaAffine::prime_subgroup_generator()

MODIFY
circuit-construction/src/prover.rs
circuit-construction/src/prover.rs
@@ -101,11 +101,15 @@ impl Cycle for FqInner {
}
/// Given an index, a group map, custom blinders for the witness, a public input vector, and a circuit `main`, it creates a proof.
+///
+/// # Panics
+///
+/// Will panic if recursive proof creation returns `ProverError`.
pub fn prove<G, H, EFqSponge, EFrSponge>(
index: &ProverIndex<G>,
group_map: &G::Map,
blinders: Option<[Option<G::ScalarField>; COLUMNS]>,
- public_input: Vec<G::ScalarField>,
+ public_input: &[G::ScalarField],
mut main: H,
) -> ProverProof<G>
where
@@ -116,7 +120,7 @@ where
EFrSponge: FrSponge<G::ScalarField>,
{
// create the witness generator
- let mut gen: WitnessGenerator<G::ScalarField> = WitnessGenerator::new(&public_input);
+ let mut gen: WitnessGenerator<G::ScalarField> = WitnessGenerator::new(public_input);
// run the witness generation
let public_vars = public_input

MODIFY
circuit-construction/src/writer.rs
circuit-construction/src/writer.rs
@@ -6,7 +6,10 @@ use kimchi::circuits::{
},
wires::{Wire, COLUMNS},
};
-use oracle::{constants::*, permutation::full_round};
+use oracle::{
+ constants::{PlonkSpongeConstantsKimchi, SpongeConstants},
+ permutation::full_round,
+};
use std::array;
use std::collections::HashMap;
@@ -23,7 +26,10 @@ pub struct Var<F> {
impl<F: Copy> Var<F> {
/// Returns the value inside a variable [Var].
- /// It panics if it is `None`.
+ ///
+ /// # Panics
+ ///
+ /// Will panic if it is `None`.
pub fn val(&self) -> F {
self.value.unwrap()
}
@@ -50,6 +56,7 @@ impl<F: FftField> GateSpec<F> {
}
}
+ #[must_use]
pub fn get_var_idx(&self, col: usize) -> Option<usize> {
match self.row.get(col) {
Some(Some(var)) => Some(var.index),
@@ -60,7 +67,7 @@ impl<F: FftField> GateSpec<F> {
/// A set of gates within the circuit.
/// It carries the index for the next available variable,
-/// and the vector of [GateSpec] created so far.
+/// and the vector of [`GateSpec`] created so far.
/// It also keeps track of the queue of generic gates and cached constants.
#[derive(Default)]
pub struct System<F> {
@@ -145,7 +152,7 @@ pub trait Cs<F: PrimeField> {
})
}
- /// This function creates a [ShiftedScalar] variable from a field element that is
+ /// This function creates a [`ShiftedScalar`] variable from a field element that is
/// returned by function `g()`, and a length that should be a multiple of 5.
fn scalar<G, Fr: PrimeField>(&mut self, length: usize, g: G) -> ShiftedScalar<F>
where
@@ -264,7 +271,7 @@ pub trait Cs<F: PrimeField> {
let same_x = self.var(|| {
let same_x = x1.val() == x2.val();
same_x_bool = same_x;
- F::from(same_x as u64)
+ F::from(u64::from(same_x))
});
let inf = zero;
@@ -341,7 +348,7 @@ pub trait Cs<F: PrimeField> {
let same_x = self.var(|| {
let same_x = x1.val() == x2.val();
same_x_bool = same_x;
- F::from(same_x as u64)
+ F::from(u64::from(same_x))
});
let inf = zero;
@@ -407,7 +414,7 @@ pub trait Cs<F: PrimeField> {
/// For (1):
/// - Creates a row with left wire `t`, right wire `f`, and output wire `delta`
/// - Assigns `1` to the left coefficient, `-1` to the right coefficient, and `-1` to the output coefficient.
- /// - That way, it creates a first gate constraining: `1 * t - 1 * f - delta = 0``
+ /// - That way, it creates a first gate constraining: `1 * t - 1 * f - delta = 0`
/// For (2):
/// - Creates a row with left wire `b`, right wire `delta`, and output wire `res1`.
/// - Assigns `-1` to the output coefficient, and `1` to the multiplication coefficient.
@@ -455,7 +462,7 @@ pub trait Cs<F: PrimeField> {
res
}
- /// Performs a scalar multiplication between a [ShiftedScalar] and a point `(xt, yt)`.
+ /// Performs a scalar multiplication between a [`ShiftedScalar`] and a point `(xt, yt)`.
/// This function creates 51 rows pairs of rows.
fn scalar_mul(
&mut self,
@@ -521,7 +528,7 @@ pub trait Cs<F: PrimeField> {
row: row2.into_iter().map(Some).collect(),
typ: GateType::Zero,
coeffs: vec![],
- })
+ });
}
res.unwrap()
@@ -538,6 +545,7 @@ pub trait Cs<F: PrimeField> {
/// | r | `EndoMul` |
/// | r+1 | `Zero` |
///
+ #[allow(clippy::too_many_lines)]
fn endo(
&mut self,
zero: Var<F>,
@@ -563,9 +571,9 @@ pub trait Cs<F: PrimeField> {
.take(length_in_bits)
.copied()
.rev()
- .collect()
+ .collect();
}
- F::from(bits_[i] as u64)
+ F::from(u64::from(bits_[i]))
})
})
.collect();
@@ -759,7 +767,7 @@ pub trait Cs<F: PrimeField> {
/// Creates a Poseidon gadget for given constants and a given input.
/// It generates a number of `Poseidon` gates followed by a final `Zero` gate.
fn poseidon(&mut self, constants: &Constants<F>, input: Vec<Var<F>>) -> Vec<Var<F>> {
- use kimchi::circuits::polynomials::poseidon::*;
+ use kimchi::circuits::polynomials::poseidon::{POS_ROWS_PER_HASH, ROUNDS_PER_ROW};
let params = constants.poseidon;
let rc = &params.round_constants;
@@ -782,7 +790,7 @@ pub trait Cs<F: PrimeField> {
// Do one full round on the previous value
let mut acc = states[states.len() - 1]
.iter()
- .map(|x| x.val())
+ .map(crate::writer::Var::val)
.collect();
full_round::<F, PlonkSpongeConstantsKimchi>(
params,
@@ -863,7 +871,7 @@ impl<F: PrimeField> Cs<F> for WitnessGenerator<F> {
assert!(g.row.len() <= COLUMNS);
let row: [F; COLUMNS] = array::from_fn(|col| g.get_var_val_or(col, F::zero()));
- self.rows.push(row)
+ self.rows.push(row);
}
fn generic_queue(&mut self, gate: GateSpec<F>) -> Option<GateSpec<F>> {
@@ -948,6 +956,10 @@ impl<F: PrimeField> Cs<F> for System<F> {
impl<F: PrimeField> System<F> {
/// Compiles our intermediate representation into a circuit.
+ ///
+ /// # Panics
+ ///
+ /// Will not panic ever since it is permutation inside gates
pub fn gates(&mut self) -> Vec<CircuitGate<F>> {
let mut first_cell: HashMap<usize, Wire> = HashMap::new();
let mut most_recent_cell: HashMap<usize, Wire> = HashMap::new();

MODIFY
kimchi/src/verifier_index.rs
kimchi/src/verifier_index.rs
@@ -300,8 +300,15 @@ impl<G: KimchiCurve> VerifierIndex<G> {
Ok(verifier_index)
}
- /// Writes a [VerifierIndex] to a file, potentially appending it to the already-existing content (if append is set to true)
+ /// Writes a [`VerifierIndex`] to a file, potentially appending it to the already-existing content (if append is set to true)
// TODO: append should be a bool, not an option
+ /// # Errors
+ ///
+ /// Will give error if it fails to open a file or writes to the file.
+ ///
+ /// # Panics
+ ///
+ /// Will panic if `path` is invalid or `file serialization` has issue.
pub fn to_file(&self, path: &Path, append: Option<bool>) -> Result<(), String> {
let append = append.unwrap_or(true);
let file = OpenOptions::new()
@@ -315,7 +322,7 @@ impl<G: KimchiCurve> VerifierIndex<G> {
.map_err(|e| e.to_string())
}
- /// Compute the digest of the [VerifierIndex], which can be used for the Fiat-Shamir
+ /// Compute the digest of the [`VerifierIndex`], which can be used for the Fiat-Shamir
/// transformation while proving / verifying.
pub fn digest<EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>>(
&self,
@@ -359,10 +366,10 @@ impl<G: KimchiCurve> VerifierIndex<G> {
// Always present
for comm in sigma_comm.iter() {
- fq_sponge.absorb_g(&comm.unshifted)
+ fq_sponge.absorb_g(&comm.unshifted);
}
for comm in coefficients_comm.iter() {
- fq_sponge.absorb_g(&comm.unshifted)
+ fq_sponge.absorb_g(&comm.unshifted);
}
fq_sponge.absorb_g(&generic_comm.unshifted);
fq_sponge.absorb_g(&psm_comm.unshifted);

MODIFY
signer/src/keypair.rs
signer/src/keypair.rs
@@ -10,6 +10,7 @@ use rand::{self, CryptoRng, RngCore};
use thiserror::Error;
/// Keypair error
+#[allow(clippy::module_name_repetitions)]
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum KeypairError {
/// Invalid secret key hex
@@ -37,6 +38,8 @@ pub struct Keypair {
impl Keypair {
/// Create a keypair from scalar field `secret` element and curve point `public`
/// Note: Does not check point `public` is on curve
+ #[allow(clippy::needless_pass_by_value)]
+ #[must_use]
pub fn from_parts_unsafe(secret: ScalarField, public: CurvePoint) -> Self {
Self {
secret: SecKey::new(secret),
@@ -57,6 +60,10 @@ impl Keypair {
}
/// Deserialize a keypair from secret key hex
+ ///
+ /// # Errors
+ ///
+ /// Will give error if `hex` string does not match certain requirements.
pub fn from_hex(secret_hex: &str) -> Result<Self> {
let mut bytes: Vec<u8> = hex::decode(secret_hex).map_err(|_| KeypairError::SecretKeyHex)?;
bytes.reverse(); // mina scalars hex format is in big-endian order
@@ -75,6 +82,7 @@ impl Keypair {
}
/// Obtain the Mina address corresponding to the keypair's public key
+ #[must_use]
pub fn get_address(self) -> String {
self.public.into_address()
}

MODIFY
signer/src/pubkey.rs
signer/src/pubkey.rs
@@ -54,11 +54,16 @@ pub struct PubKey(CurvePoint);
impl PubKey {
/// Create a public key from curve point
/// Note: Does not check point is on curve
+ #[must_use]
pub fn from_point_unsafe(point: CurvePoint) -> Self {
Self(point)
}
/// Deserialize Mina address into public key
+ ///
+ /// # Errors
+ ///
+ /// Will give error if `address` string does not match certain requirements.
pub fn from_address(address: &str) -> Result<Self> {
if address.len() != MINA_ADDRESS_LEN {
return Err(PubKeyError::AddressLength);
@@ -113,6 +118,7 @@ impl PubKey {
}
/// Convert public key into compressed public key
+ #[must_use]
pub fn into_compressed(&self) -> CompressedPubKey {
let point = self.0;
CompressedPubKey {
@@ -122,6 +128,7 @@ impl PubKey {
}
/// Serialize public key into corresponding Mina address
+ #[must_use]
pub fn into_address(&self) -> String {
let point = self.point();
into_address(&point.x, point.y.into_repr().is_odd())
@@ -161,7 +168,7 @@ fn into_address(x: &BaseField, is_odd: bool) -> String {
raw.extend(x.to_bytes());
// pub key y-coordinate parity
- raw.push(is_odd as u8);
+ raw.push(u8::from(is_odd));
// 4-byte checksum
let hash = Sha256::digest(&Sha256::digest(&raw[..])[..]);
@@ -173,17 +180,23 @@ fn into_address(x: &BaseField, is_odd: bool) -> String {
impl CompressedPubKey {
/// Serialize compressed public key into corresponding Mina address
+ #[must_use]
pub fn into_address(&self) -> String {
into_address(&self.x, self.is_odd)
}
- /// Deserialize Mina address into compressed public key (via an uncompressed PubKey)
+ /// Deserialize Mina address into compressed public key (via an uncompressed `PubKey`)
+ ///
+ /// # Errors
+ ///
+ /// Will give error if `PubKey::from_address()` returns error.
pub fn from_address(address: &str) -> Result<Self> {
Ok(PubKey::from_address(address)?.into_compressed())
}
- /// The empty [CompressedPubKey] value that is used as `public_key` in empty account
+ /// The empty [`CompressedPubKey`] value that is used as `public_key` in empty account
/// and [None] value for calculating the hash of [Option<CompressedPubKey>], etc.
+ #[must_use]
pub fn empty() -> Self {
Self {
x: BaseField::zero(),

MODIFY
signer/src/schnorr.rs
signer/src/schnorr.rs
@@ -136,6 +136,7 @@ impl<H: 'static + Hashable> Schnorr<H> {
/// randomly distributed scalar field element. It uses Mina's variant of the Poseidon
/// SNARK-friendly cryptographic hash function.
/// Details: <https://github.com/o1-labs/cryptography-rfcs/blob/httpsnapps-notary-signatures/mina/001-poseidon-sponge.md>
+ #[allow(clippy::needless_pass_by_value)]
fn message_hash(&mut self, pub_key: &PubKey, rx: BaseField, input: &H) -> ScalarField {
let schnorr_input = Message::<H> {
input: input.clone(),

MODIFY
signer/src/seckey.rs
signer/src/seckey.rs
@@ -17,16 +17,20 @@ impl SecKey {
}
/// Create a secret key from scalar field element
+ #[must_use]
+ #[allow(clippy::needless_pass_by_value)]
pub fn new(scalar: ScalarField) -> Self {
Self(scalar)
}
/// Borrows secret key as scalar field element
+ #[must_use]
pub fn scalar(&self) -> &ScalarField {
&self.0
}
/// Convert secret key into scalar field element
+ #[must_use]
pub fn into_scalar(self) -> ScalarField {
self.0
}

MODIFY
signer/src/signature.rs
signer/src/signature.rs
@@ -16,6 +16,8 @@ pub struct Signature {
impl Signature {
/// Create a new signature
+ #[must_use]
+ #[allow(clippy::needless_pass_by_value)]
pub fn new(rx: BaseField, s: ScalarField) -> Self {
Self { rx, s }
}

MODIFY
tools/kimchi-visu/src/lib.rs
tools/kimchi-visu/src/lib.rs
@@ -44,7 +44,10 @@ where
F: PrimeField,
{
fn latex() -> Vec<Vec<String>> {
- Self::constraints().iter().map(|c| c.latex_str()).collect()
+ Self::constraints()
+ .iter()
+ .map(kimchi::circuits::expr::Expr::latex_str)
+ .collect()
}
}
@@ -57,6 +60,7 @@ where
}
///
+#[must_use]
pub fn latex_constraints<G>() -> HashMap<&'static str, Vec<Vec<String>>>
where
G: CommitmentCurve,
@@ -75,6 +79,10 @@ where
}
/// Produces a `circuit.html` in the current folder.
+///
+/// # Panics
+///
+/// Will panic if `TinyTemplate::render()` returns `Error` or `std::fs::File::create()` returns `Error`.
pub fn visu<G: KimchiCurve>(index: &ProverIndex<G>, witness: Option<Witness<G::ScalarField>>) {
// serialize index
let index = serde_json::to_string(index).expect("couldn't serialize index");

MODIFY
tools/kimchi-visu/src/witness.rs
tools/kimchi-visu/src/witness.rs
@@ -23,6 +23,7 @@ where
{
/// Creates a new witness with `rows` rows.
// TODO: deprecate this
+ #[must_use]
pub fn new(rows: usize) -> Self {
Witness {
inner: array::from_fn(|_| vec![F::zero(); rows]),
@@ -31,6 +32,7 @@ where
/// Returns the inner witness.
// TODO: deprecate this
+ #[must_use]
pub fn inner(self) -> [Vec<F>; COLUMNS] {
self.inner
}

Fix the pedantic lints (1)