MCPcopy Index your code
hub / github.com/chyanju/picus

github.com/chyanju/picus @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
4,363 symbols 22,287 edges 237 files 1,188 documented · 27%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README


Picus

Automated detection of under-constrained signals in zero-knowledge circuits

<a href="https://doi.org/10.1145/3591283"><img src="https://img.shields.io/badge/PLDI-2023-blue" alt="PLDI 2023"></a>
<a href="https://github.com/chyanju/picus/raw/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="MIT License"></a>
<a href="https://www.rust-lang.org/"><img src="https://img.shields.io/badge/rust-1.85%2B-orange" alt="Rust 1.85+"></a>

Picus is a security analysis tool for detecting under-constrained signals in zero-knowledge proof circuits. Given an R1CS constraint system, it verifies that all output signals are uniquely determined by the public inputs — or produces a concrete counter-example showing two distinct valid witnesses.

The techniques underlying Picus are described in the PLDI 2023 paper "Automated Detection of Under-Constrained Circuits in Zero-Knowledge Proofs" (see Citation).

Looking for the original PLDI 2023 research artifact? See the artifact branch.

Installation

Default builds are pure Rust: the in-tree native finite-field solver needs no external solver and no extra system dependencies. cvc5 / z3 are never compiled unless you opt in (see below).

# Install to PATH
cargo install --path crates/picus-cli

# Or build and run locally
cargo build --release
./target/release/picus check --r1cs circuit.r1cs

# Or via Docker
docker build -t picus .
docker run --rm -v $(pwd):/data picus check --r1cs /data/circuit.r1cs

The optional cvc5 and z3 backends are compiled only on explicit opt-in (--features cvc5 / z3) and carry extra build requirements (and, for cvc5, GPLv3 licensing) — see docs/building.md.

Usage

picus check --r1cs circuit.r1cs                   # verify uniqueness (native + ff)
picus check --r1cs circuit.r1cs --solver none     # propagation only, no solver
picus check --r1cs circuit.r1cs --lemmas all-bim  # tune propagation lemmas
picus check --r1cs circuit.r1cs --format json     # machine-readable output
picus check --r1cs circuit.r1cs --config my.toml  # load settings from a config file

picus info --r1cs circuit.r1cs --constraints      # inspect R1CS metadata

Configuration. No config is required — every setting has a built-in default. To customise, copy picus.default.toml (it documents every key), edit it, and pass it with --config <file>; or drop a ./picus.toml in the working directory and it is picked up automatically. Sources layer, with later winning: built-in defaults < config file < individual CLI flags. Full flag and configuration reference: docs/usage.md.

Use as a Rust Library

[dependencies]
# Tracks the main branch (the stable branch); default features = native
# solver only, no external build chain.
picus = { git = "https://github.com/chyanju/Picus", branch = "main" }

# To also build the cvc5 / z3 backends:
# picus = { git = "https://github.com/chyanju/Picus", branch = "main", features = ["cvc5"] }
use picus::{check_circuit, Config, CheckResult};

let result = check_circuit("circuit.r1cs", Config::default()).unwrap();
match result {
    CheckResult::Safe => println!("safe"),
    CheckResult::Unsafe { witness_1, witness_2 } => {
        // witness_1/witness_2: HashMap<String, BigUint>
        for (signal, value) in &witness_1 {
            println!("{} = {}", signal, value);
        }
    }
    CheckResult::Unknown => println!("unknown"),
}

See crates/picus/src/lib.rs for the full API, including check_r1cs_bytes(), check_r1cs(), PicusConfig::from_file(), and re-exported types.

Documentation

Usage CLI flags, configuration, result interpretation, solver differences, troubleshooting
Building cvc5 / z3 Optional external backends: build requirements and licensing
Architecture Crate structure, data flow, solver backends
Propagation Lemmas Deduction rules and their implementation
Changelog Version history

Citation

To cite the software itself, use the "Cite this repository" button in the GitHub sidebar — it is generated from CITATION.cff and provides ready-made APA and BibTeX entries pinned to a released version.

To cite the research behind Picus, use the PLDI 2023 paper:

@article{pailoor2023automated,
  author = {Pailoor, Shankara and Chen, Yanju and Wang, Franklyn and Rodr\'{i}guez, Clara and Van Geffen, Jacob and Morton, Jason and Chu, Michael and Gu, Brian and Feng, Yu and Dillig, Isil},
  title = {Automated Detection of Under-Constrained Circuits in Zero-Knowledge Proofs},
  year = {2023},
  volume = {7},
  number = {PLDI},
  journal = {Proc. ACM Program. Lang.},
  articleno = {165},
  doi = {10.1145/3591283}
}

License

MIT

Extension points exported contracts — how you extend this code

PropagationLemma (Interface)
Plugin interface for a single propagation lemma. [6 implementers]
crates/picus-analysis/src/propagation/lemma.rs
Theory (Interface)
Theory plug-in interface. [5 implementers]
crates/picus-solver/src/cdclt/theory.rs
SolverBackend (Interface)
Trait for solver backends. Backends consume a [`PolyIR`] snapshot whose `target_signal` and `known_signals` reflect the [4 …
crates/picus-smt/src/backends/mod.rs
Provenance (Interface)
Per-row bookkeeping threaded through the reduction. Each time a row is reduced by a pivot row, the pivot's provenance is [3 …
crates/picus-core/src/ff/linalg.rs
GbAlgorithm (Interface)
Pluggable Groebner-basis algorithm. Every public GB entry point (`compute_gb_with_order` and its traced sibling) routes [3 …
crates/picus-solver/src/gb/ideal/engine.rs
MonomialRepr (Interface)
Operations on a monomial `x_0^{e_0} ... x_{n-1}^{e_{n-1}}` that the engine relies on. Implementations must agree bit-for [2 …
crates/picus-core/src/ff/repr.rs
CriterionPair (Interface)
What the GM / B criteria need from an S-pair, independent of the monomial representation. [2 implementers]
crates/picus-solver/src/ff/spair_criteria.rs
PolyRepr (Interface)
Representation-agnostic interface implemented by both the dense [`super::polynomial::DensePoly`] and the sparse [`super: [2 …
crates/picus-core/src/ff/repr.rs

Core symbols most depended-on inside this repo

iter
called by 842
crates/picus-core/src/poly.rs
clone
called by 732
crates/picus-core/src/ff/field.rs
map
called by 702
crates/picus-core/src/ff/field.rs
var
called by 659
crates/picus-solver/src/sat/lit.rs
field
called by 452
crates/picus-core/src/poly.rs
sub
called by 431
crates/picus-solver/src/ff/univariate.rs
len
called by 409
crates/picus-solver/src/sat/clause.rs
var
called by 339
crates/picus-solver/src/frontend/encoder/constraint_system.rs

Shape

Function 2,886
Method 1,194
Class 199
Enum 74
Interface 10

Languages

Rust100%

Modules by API surface

crates/picus-solver/src/smt2/tests.rs124 symbols
crates/cvc5-ff/src/term_manager.rs89 symbols
crates/cvc5-ff/src/solver.rs89 symbols
crates/picus-solver/src/cdclt/orchestrator_tests.rs85 symbols
crates/picus-core/src/ff/polynomial/tests.rs84 symbols
crates/picus-solver/tests/cdclt_vs_dnf_parity.rs80 symbols
crates/cvc5-ff/src/term.rs76 symbols
crates/picus-solver/src/sat/solver_tests.rs73 symbols
crates/cvc5-ff/src/sort.rs72 symbols
crates/picus-solver/src/ff/buchberger/tests.rs69 symbols
crates/picus-core/src/ff/field.rs66 symbols
crates/picus-analysis/src/propagation/basis2/compconstant_tests.rs66 symbols

For agents

$ claude mcp add picus \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact