Skip to content

Commit

Permalink
feat: proofs crate cargo docs (#478)
Browse files Browse the repository at this point in the history
* feat: proofs crate cargo docs

* chore: lints

* fix: unwrap in notary from error handling in proofs

* chore: fmt

* feat: incorporate review feedback
  • Loading branch information
0xJepsen authored Feb 17, 2025
1 parent 1c90462 commit f67a7f1
Show file tree
Hide file tree
Showing 21 changed files with 609 additions and 173 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name ="client"
version="0.3.0"
version="0.4.0"
edition="2021"
build ="build.rs"
publish=false
Expand Down
2 changes: 1 addition & 1 deletion client_ios/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name ="client_ios"
version="0.3.0"
version="0.4.0"
edition="2021"
build ="build.rs"
publish=false
Expand Down
2 changes: 1 addition & 1 deletion client_wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name ="client_wasm"
version="0.3.0"
version="0.4.0"
edition="2021"
build ="build.rs"
publish=false
Expand Down
2 changes: 1 addition & 1 deletion notary/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name ="notary"
version="0.3.0"
version="0.4.0"
edition="2021"
build ="build.rs"

Expand Down
2 changes: 1 addition & 1 deletion notary/src/origo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ pub async fn verify(
proof: payload.origo_proof.proof.proof.clone(),
verifier_digest: payload.origo_proof.proof.verifier_digest.clone(),
}
.deserialize();
.deserialize()?;

debug!("verifier_digest: {:?}", proof.verifier_digest.clone());

Expand Down
2 changes: 1 addition & 1 deletion proofs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name ="proofs"
version="0.3.0"
version="0.4.0"
edition="2021"
publish=false
build ="build.rs"
Expand Down
46 changes: 44 additions & 2 deletions proofs/src/circom/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
//! # Circom Module
//!
//! The `circom` module provides utilities for working with Circom circuits within the `proofs`
//! crate. It includes functionalities for handling R1CS (Rank-1 Constraint System) representations
//! of circuits, managing circuit inputs, and generating witnesses for the circuits.
//!
//! ## Modules
//!
//! - `r1cs`: Contains the implementation and utilities for working with R1CS representations of
//! Circom circuits.
//! - `wasm_witness`: Provides functionalities for generating witnesses using WebAssembly (only
//! available for `wasm32` target).
//! - `witness`: Contains utilities for generating witnesses for Circom circuits.
//!
//! ## Structs
//!
//! - `CircomInput`: Represents the input structure for Circom circuits, including step inputs and
//! additional parameters.
//! - `CircuitJson`: Represents the JSON structure of a Circom circuit, including constraints,
//! number of inputs, outputs, and variables.
//! - `CircomCircuit`: Represents a Circom circuit, including its R1CS representation and optional
//! witness data.
use std::{
collections::{BTreeMap, HashMap},
env::current_dir,
Expand All @@ -20,28 +43,38 @@ pub mod r1cs;
#[cfg(target_arch = "wasm32")] pub mod wasm_witness;
pub mod witness;

/// Circom input
#[derive(Debug, Serialize, Deserialize)]
pub struct CircomInput {
/// Step inputs
pub step_in: Vec<String>,

/// Extra parameters
#[serde(flatten)]
pub extra: HashMap<String, Value>,
pub extra: HashMap<String, Value>,
}

/// Circuit JSON
#[derive(Serialize, Deserialize)]
pub struct CircuitJson {
/// Constraints
pub constraints: Vec<Vec<BTreeMap<String, String>>>,
/// Number of inputs
#[serde(rename = "nPubInputs")]
pub num_inputs: usize,
/// Number of outputs
#[serde(rename = "nOutputs")]
pub num_outputs: usize,
/// Number of variables
#[serde(rename = "nVars")]
pub num_variables: usize,
}

/// Circom circuit
#[derive(Clone)]
pub struct CircomCircuit {
/// R1CS
pub r1cs: Arc<R1CS>,
/// Witness
pub witness: Option<Vec<F<G1>>>,
}

Expand All @@ -52,8 +85,17 @@ impl Default for CircomCircuit {
}

impl CircomCircuit {
/// Return the arity of the circuit ie the number of public inputs
pub fn arity(&self) -> usize { self.r1cs.num_public_inputs }

/// Vanilla synthesize
///
/// This function synthesizes the circuit using the provided constraint system.
///
/// # Arguments
///
/// * `cs`: The constraint system to use for synthesis.
/// * `z`: The witness values to use for synthesis.
pub fn vanilla_synthesize<CS: ConstraintSystem<F<G1>>>(
&self,
cs: &mut CS,
Expand Down
77 changes: 73 additions & 4 deletions proofs/src/circom/r1cs.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,51 @@
//! # R1CS Module
//!
//! The `r1cs` module provides functionalities for handling Rank-1 Constraint System (R1CS)
//! representations of Circom circuits. It includes utilities for reading, parsing, and
//! managing R1CS data, which is essential for circuit synthesis and proof generation.
//!
//! ## Structs
//!
//! - `R1CS`: Represents the R1CS structure, including the number of inputs, outputs, variables, and
//! constraints.
//! - `Header`: Represents the header of an R1CS file, including field size and various counts.
//!
//! ## Type Definitions
//!
//! - `Constraint`: A type alias for a tuple representing a constraint in the R1CS, consisting of
//! vectors of pairs of indices and field elements.
//!
//! ## Functions
//!
//! - `read_field`: Reads a field element from a reader.
//! - `read_header`: Reads the header of an R1CS file from a reader.
//! - `read_constraint_vec`: Reads a vector of constraints from a reader.
//! - `read_constraints`: Reads all constraints from a reader based on the R1CS header.
use fs::OpenOptions;

use super::*;
// This was borrowed from `nova-scotia`. Big thank you for this middleware!
// some codes borrowed from https://github.com/poma/zkutil/blob/master/src/r1cs_reader.rs

/// Constraint type
pub type Constraint = (Vec<(usize, F<G1>)>, Vec<(usize, F<G1>)>, Vec<(usize, F<G1>)>);

/// R1CS type
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct R1CS {
/// Number of private inputs
pub num_private_inputs: usize,
/// Number of public inputs
pub num_public_inputs: usize,
/// Number of public outputs
pub num_public_outputs: usize,
/// Number of inputs
pub num_inputs: usize,
/// Number of auxiliary variables
pub num_aux: usize,
/// Number of variables
pub num_variables: usize,
/// Constraints
pub constraints: Vec<Constraint>,
}

Expand All @@ -33,16 +65,24 @@ impl Default for R1CS {
}
}

// R1CSFile's header
/// R1CSFile's header
#[derive(Debug, Default)]
pub struct Header {
/// Field size
pub field_size: u32,
/// Prime size
pub prime_size: Vec<u8>,
/// Number of wires
pub n_wires: u32,
/// Number of public outputs
pub n_pub_out: u32,
/// Number of public inputs
pub n_pub_in: u32,
/// Number of private inputs
pub n_prv_in: u32,
/// Number of labels
pub n_labels: u64,
/// Number of constraints
pub n_constraints: u32,
}

Expand All @@ -51,7 +91,7 @@ impl TryFrom<&R1CSType> for R1CS {

fn try_from(value: &R1CSType) -> Result<Self, Self::Error> {
match value {
R1CSType::File { path } => R1CS::try_from(path),
R1CSType::File(path) => R1CS::try_from(path),
R1CSType::Raw(bytes) => R1CS::try_from(&bytes[..]),
}
}
Expand All @@ -75,6 +115,7 @@ impl TryFrom<&PathBuf> for R1CS {
}
}

/// Reads an R1CS from a reader
fn from_reader<R: Read + Seek>(mut reader: R) -> Result<R1CS, ProofError> {
let mut magic = [0u8; 4];
reader.read_exact(&mut magic)?;
Expand Down Expand Up @@ -135,13 +176,12 @@ fn from_reader<R: Read + Seek>(mut reader: R) -> Result<R1CS, ProofError> {
})
}

/// Reads a field from a reader
fn read_field<R: Read>(mut reader: R) -> Result<F<G1>, ProofError> {
let mut repr = F::<G1>::ZERO.to_repr();
for digit in repr.as_mut().iter_mut() {
*digit = reader.read_u8()?;
}
// TODO(WJ 2024-11-05): there might be a better way to do this, but the constant time option type
// is weird `CTOption`
let fr = F::<G1>::from_repr(repr);
if fr.is_some().into() {
Ok(fr.unwrap())
Expand All @@ -150,6 +190,16 @@ fn read_field<R: Read>(mut reader: R) -> Result<F<G1>, ProofError> {
}
}

/// Reads a header from a reader
///
/// # Arguments
///
/// * `reader`: The reader to read the header from.
/// * `size`: The size of the header.
///
/// # Returns
///
/// The header.
fn read_header<R: Read>(mut reader: R, size: u64) -> Result<Header, ProofError> {
let field_size = reader.read_u32::<LittleEndian>()?;
let mut prime_size = vec![0u8; field_size as usize];
Expand All @@ -168,6 +218,15 @@ fn read_header<R: Read>(mut reader: R, size: u64) -> Result<Header, ProofError>
})
}

/// Reads a constraint vector from a reader
///
/// # Arguments
///
/// * `reader`: The reader to read the constraint vector from.
///
/// # Returns
///
/// The constraint vector.
fn read_constraint_vec<R: Read>(mut reader: R) -> Result<Vec<(usize, F<G1>)>, ProofError> {
let n_vec = reader.read_u32::<LittleEndian>()? as usize;
let mut vec = Vec::with_capacity(n_vec);
Expand All @@ -177,6 +236,16 @@ fn read_constraint_vec<R: Read>(mut reader: R) -> Result<Vec<(usize, F<G1>)>, Pr
Ok(vec)
}

/// Reads constraints from a reader
///
/// # Arguments
///
/// * `reader`: The reader to read the constraints from.
/// * `header`: The header of the R1CS.
///
/// # Returns
///
/// The constraints.
fn read_constraints<R: Read>(
mut reader: R,
header: &Header,
Expand Down
Loading

0 comments on commit f67a7f1

Please sign in to comment.