Skip to content
WeiqiNsPublic

About

Zero-knowledge proofs on encrypted and secret-shared data: a generic fully linear PCP engine.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

Fully Linear PCPs in Rust (RustFLPCP)

CI codecov

RustFLPCP lets a client prove its input is valid, such as a one-hot vote or a vector with a bounded norm, to a verifier that only computes linear functions of the input and the proof. The check therefore works on data the verifier cannot read: inner-product functional encryption (IPFE) ciphertexts or secret shares. It implements the fully linear PCPs of Boneh et al. (CRYPTO 2019) as a generic engine and is the proof layer of PEAR (PoPETs 2025): write a validity circuit once and get a prover, explicit linear queries, and a decision procedure over any arkworks FFT field. For a 1,024-entry one-hot vector, proving takes about 1.5 ms, building a query about 0.6 ms, and checking the proof against it about 0.12 ms on one CPU core (cargo bench --bench flp).

use ark_bls12_381::Fr;
use rand::rngs::OsRng;
use rust_flpcp::{Flp, OneHot};

let rng = &mut OsRng;
let flp = Flp::<Fr, _>::new(OneHot { len: 4 })?;
let vector = flp.prove(&[0u64, 0, 1, 0].map(Fr::from), rng)?;

let query = flp.query(rng);
let answers: Vec<Fr> = query
    .linear_queries()
    .iter()
    .map(|linear| {
        let inner: Fr = linear.coeffs.iter().zip(&vector).map(|(c, v)| *c * v).sum();
        inner + linear.constant
    })
    .collect();
assert!(flp.decide(&query, &answers));

Under IPFE each coeffs is a function key and the verifier sees only the answers; flp.verify(&query, &vector) is the plaintext shortcut. This is examples/quickstart.rs.

Circuits

Circuit Accepts
Range { len, bounds } every value in bounds (Range::binary(len) for bits)
BitRange { len, bounds } every value in bounds, via bit decompositions (for wide ranges)
OneHot { len } exactly one value is 1, the rest 0
Membership { len, values } every value is one of values
NormBound { len, input_bits, norm_bits, square_chunk } values below 2^input_bits, sum of squares below 2^norm_bits
SignedNormBound { .. } the same for signed values, as in federated-learning clipping
MeanVariance { len, input_bits } values below 2^input_bits, each claimed y equals x^2, for private mean and variance

Circuits with auxiliary bits build their input with encode. Run cargo run --example costs for each circuit's vector length and query count.

Writing a circuit

Implement Circuit<F>: input_len, gadgets, and an eval generic over W: Wire<F> that returns outputs which must all be zero for a valid input. Wires only support affine operations; every multiplication goes through calls.call(GadgetId(i), inputs) on a gadget (RangeProduct, SetProduct, Square, ParallelSum, or your own Gadget<F>). The same eval builds both the proof and the queries. Flp::new runs each gadget's check_params, so a RangeProduct or SetProduct constant too large for the field is rejected. ParallelSum proves only a sum, so never use it to batch zero checks.

Security notes

  • Pass a cryptographically secure generator (rand 0.8, such as OsRng); test_rng() is for tests only.
  • The Query holds the verifier's secret randomness: keep it from the prover. Never answer one vector under two different queries, which reveals a linear function of the input. Reusing one query across many provers, as PEAR does, is covered by the reusable soundness and zero-knowledge proofs in the PEAR paper.
  • A cheating proof passes with probability about its polynomial degree over the field size.

Using it

[dependencies]
rust_flpcp = { git = "https://github.com/WeiqiNs/RustFLPCP" }
ark-bls12-381 = { version = "0.6", default-features = false, features = ["scalar_field"] }
rand = "0.8"

Any arkworks FFT field works in place of BLS12-381's scalar field. rand stays on 0.8 because arkworks 0.6 takes rand 0.8 generators. The parallel feature enables arkworks' multithreaded FFTs.

Build and test

cargo test --all
cargo clippy --all --all-targets -- -D warnings
cargo llvm-cov --all --fail-uncovered-lines 0
cargo bench --bench flp

About

Zero-knowledge proofs on encrypted and secret-shared data: a generic fully linear PCP engine.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages