|
1 | | -# sigma-rs: a(n updated) toolkit for Σ-protocols |
| 1 | +# sigma-rs |
2 | 2 |
|
| 3 | +A Rust library for building and composing Σ-protocols (Sigma protocols) for zero-knowledge proofs. |
3 | 4 |
|
4 | | -# WARNING |
| 5 | +## What is sigma-rs? |
5 | 6 |
|
6 | | -**THIS IMPLEMENTATION IS NOT YET READY FOR PRODUCTION USE** |
| 7 | +This library provides a flexible framework for creating zero-knowledge proofs for any statement expressible as a linear relation over group elements. Using the Fiat-Shamir transformation, these interactive protocols become non-interactive proofs suitable for real-world applications. |
7 | 8 |
|
8 | | -While I expect the 1.0 version to be largely unchanged from the current |
9 | | -code, for now there are no stability guarantees on the proofs, so they |
10 | | -should not yet be deployed. |
| 9 | +## Key Features |
11 | 10 |
|
12 | | -### Background |
| 11 | +- **Universal**: Express any linear relation as a Sigma protocol |
| 12 | +- **Composable**: Build complex proofs with AND/OR combinations |
| 13 | +- **Generic**: Works with any prime-order group implementing the `group` trait |
| 14 | +- **Secure**: Constant-time implementations prevent timing attacks |
| 15 | +- **Flexible**: Both high-level macros and low-level constraint API |
13 | 16 |
|
14 | | -This crate was originally created as part of [`dalek-cryptography`](https://github.com/dalek-cryptography). |
15 | | -It has been forked: |
16 | | -1. To bring the `zkp` crate up to date with `dalek-cryptography` dependencies. |
17 | | -2. To resolve bugs and incorporate changes to the fiat-shamir transform. |
18 | | -3. To make this effort compatible with the Σ-protocol standardization effort. |
| 17 | +## Quick Example |
19 | 18 |
|
20 | | -This crate has a toolkit for Schnorr-style zero-knowledge proofs over generic [`Group`](https://github.com/zkcrypto/group)s |
21 | | -It provides two levels of API: |
| 19 | +```rust |
| 20 | +use sigma_rs::{LinearRelation, Protocol, ProtocolWitness, NISigmaProtocol}; |
| 21 | +use sigma_rs::codec::ShakeCodec; |
| 22 | +use curve25519_dalek::RistrettoPoint as G; |
22 | 23 |
|
23 | | -* a higher-level, declarative API based around the `define_proof` macro, |
24 | | - which provides an embedded DSL for specifying proof statements in |
25 | | - Camenisch-Stadler-like notation: |
26 | | - ``` |
27 | | - define_proof! { |
28 | | - vrf_proof, // Name of the module for generated implementation |
29 | | - "VRF", // Label for the proof statement |
30 | | - (x), // Secret variables |
31 | | - (A, G, H), // Public variables unique to each proof |
32 | | - (B) : // Public variables common between proofs |
33 | | - A = (x * B), // Statements to prove |
34 | | - G = (x * H) |
35 | | - } |
36 | | - ``` |
37 | | - This expands into a module containing an implementation of proving, |
38 | | - verification, and batch verification. Proving uses constant-time |
39 | | - implementations, and the proofs have a derived implementation of |
40 | | - (memory-safe) serialization and deserialization via Serde. |
| 24 | +// Prove knowledge of (x, r) such that C = x·G + r·H (Pedersen commitment) |
| 25 | +let mut relation = LinearRelation::<G>::new(); |
41 | 26 |
|
42 | | -* a lower-level, imperative API inspired by [Bellman][bellman], which |
43 | | - provides a constraint system for Schnorr-style statements. This |
44 | | - allows programmable construction of proof statements at runtime. The |
45 | | - higher-level `define_proof` macro expands into an invocation of the |
46 | | - lower-level API. |
47 | | - The lower-level API is contained in the `toolbox` module. |
| 27 | +// Allocate variables |
| 28 | +let x = relation.allocate_scalar(); |
| 29 | +let r = relation.allocate_scalar(); |
| 30 | +let [G_var, H_var] = relation.allocate_elements(); |
48 | 31 |
|
49 | | -#### Auto-generated benchmarks |
| 32 | +// Define constraint: C = x·G + r·H |
| 33 | +let C = relation.allocate_eq(x * G_var + r * H_var); |
50 | 34 |
|
51 | | -The `define_proof` macro builds benchmarks for the generated proof |
52 | | -statements, but because these are generated in the client crate (where |
53 | | -the macro expansion happens), they need an extra step to be enabled. |
| 35 | +// Set public values and compute the commitment |
| 36 | +relation.set_elements([(G_var, G::generator()), (H_var, H)]); |
| 37 | +relation.compute_image(&[x_val, r_val]).unwrap(); |
54 | 38 |
|
55 | | -**To enable generated benchmarks in your crate, do the following**: |
| 39 | +// Create non-interactive proof |
| 40 | +let protocol = Protocol::from(relation); |
| 41 | +let nizk = NISigmaProtocol::<_, ShakeCodec<G>>::new(b"pedersen-proof", protocol); |
| 42 | +let proof = nizk.prove_batchable(&witness, &mut rng)?; |
| 43 | +``` |
56 | 44 |
|
57 | | -* Add a `bench` feature to your crate's `Cargo.toml`; |
58 | | -* Add `#[cfg_attr(feature = "bench", feature(test))]` to your crate's |
59 | | - `lib.rs` or `main.rs`, to enable Rust's nightly-only benchmark |
60 | | - feature. |
| 45 | +## Composition Example |
61 | 46 |
|
62 | | -## More information |
| 47 | +Prove complex statements with AND/OR logic: |
63 | 48 |
|
64 | | -We include runnable examples to demonstrate how to use the `sigma-rs` toolkit in [examples/](https://github.com/mmaker/sigma-rs/tree/main/examples). |
| 49 | +```rust |
| 50 | +// Prove: (I know x for A = x·G) OR (I know y,z for B = y·G AND C = z·H) |
| 51 | +let or_protocol = Protocol::Or(vec![ |
| 52 | + Protocol::from(dlog_relation), // First option |
| 53 | + Protocol::And(vec![ // Second option |
| 54 | + Protocol::from(relation_B), |
| 55 | + Protocol::from(relation_C), |
| 56 | + ]) |
| 57 | +]); |
| 58 | + |
| 59 | +// If we know the second option, create witness for index 1 |
| 60 | +let witness = ProtocolWitness::Or(1, vec![ |
| 61 | + ProtocolWitness::And(vec![ |
| 62 | + ProtocolWitness::Simple(vec![y]), |
| 63 | + ProtocolWitness::Simple(vec![z]), |
| 64 | + ]) |
| 65 | +]); |
| 66 | +``` |
| 67 | + |
| 68 | +## Examples |
| 69 | + |
| 70 | +See the [examples/](examples/) directory: |
| 71 | +- `schnorr.rs` - Discrete logarithm proof |
| 72 | +- `simple_composition.rs` - OR-proof composition |
| 73 | + |
| 74 | +## Status |
| 75 | + |
| 76 | +**⚠️ NOT YET READY FOR PRODUCTION USE** |
| 77 | + |
| 78 | +This library is under active development. While the API is stabilizing, there are no guarantees on proof compatibility between versions. |
| 79 | + |
| 80 | +## Background |
| 81 | + |
| 82 | +This crate continues the work from the original `zkp` toolkit in [`dalek-cryptography`](https://github.com/dalek-cryptography), modernized with updated dependencies and improved Fiat-Shamir transforms. It implements the general framework for Sigma protocols as described in [Maurer (2009)](https://doi.org/10.1007/978-3-642-02384-2_6). |
65 | 83 |
|
66 | 84 | ## Funding |
67 | 85 |
|
68 | 86 | This project is funded through [NGI0 Entrust](https://nlnet.nl/entrust), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program. Learn more at the [NLnet project page](https://nlnet.nl/project/sigmaprotocols). |
69 | 87 |
|
70 | 88 | [<img src="https://nlnet.nl/logo/banner.png" alt="NLnet foundation logo" width="20%" />](https://nlnet.nl) |
71 | | -[<img src="https://nlnet.nl/image/logos/NGI0_tag.svg" alt="NGI Zero Logo" width="20%" />](https://nlnet.nl/entrust) |
72 | | - |
73 | | -[bellman]: https://github.com/zkcrypto/bellman |
| 89 | +[<img src="https://nlnet.nl/image/logos/NGI0_tag.svg" alt="NGI Zero Logo" width="20%" />](https://nlnet.nl/entrust) |
0 commit comments