# zkp: a toolkit for Schnorr proofs

About two years ago, I made a proof-of-concept library called `zkp`

, which used Rust macros to auto-generate an implementation of proving and verification for a class of Schnorr-style discrete logarithm proof statements. However, this approach had a number of limitations and wasn’t suitable for use in real applications. Today, I published a new and completely rewritten version of the library, which is now available on crates.io.

The new implementation contains a lower-level, Bellman-inspired programmable constraint system API, which allows imperative specification of proof statements, as well as a higher-level macro, which allows declarative specification of proof statements using a DSL that resembles mathematical notation:

`define_proof! {`

vrf_proof, // Name of the module for generated implementation

"VRF", // Label for the proof statement

(x), // Secret variables

(A, G, H), // Public variables unique to each proof

(B) : // Public variables common between proofs

A = (x * B), // Statements to prove

G = (x * H)

}

This macro expands into a module containing an implementation of proving, verification, batch verification, and benchmarks for the proof statement. Proving uses constant-time implementations, and the proofs have a derived implementation of (memory-safe) serialization and deserialization via Serde.

The repository’s `tests`

directory contains examples of how to use both the higher-level and lower-level APIs:

- a specification of an “anonymous credential presentation with 10 hidden attributes” proof from CMZ’13. Thanks to the choice of group, as well as the backend optimization work I did,
**the generated implementation performs verification between 20 to 40 times faster**than the benchmark numbers reported in that paper. - A transcript-based signature and VRF construction with an auto-generated implementation. This includes an example of using the online interactive composition described in the Merlin blog post to provide chained signatures between two counterparties.
- An example of using the lower-level constraint system API manually.

# Using the API

To experiment with the API, add the crates to `Cargo.toml`

:

`[dependencies]`

curve25519-dalek = "1"

zkp = "0.6"

then add the crates to `lib.rs`

(or `main.rs`

):

`#[macro_use]`

extern crate zkp;

extern crate curve25519_dalek;

The documentation on the new API can be found on doc.dalek.rs or on docs.rs. After generating an implementation with the `define_proof`

macro, the documentation on how to use the generated code will appear in your crates’ documentation. Here’s an example of one way to use it:

# What’s next

I’m hoping to streamline the API a little bit and release 1.0 soon. If this toolkit seems like it would be useful to you, please try out the API and leave comments on the issue tracker!