Skip to main content

schnorr/
schnorr.rs

1//! Example: Schnorr proof of knowledge.
2//!
3//! This example demonstrates how to prove knowledge of a discrete logarithm using `sigma-rs`.
4//!
5//! The prover convinces a verifier that it knows a secret $x$ such that: $$P = x \cdot G$$
6//!
7//! where $G$ is a generator of a prime-order group $\mathbb{G}$ and $P$ is a public group element.
8
9use curve25519_dalek::scalar::Scalar;
10use curve25519_dalek::RistrettoPoint;
11use group::Group;
12use rand::rngs::OsRng;
13
14use sigma_proofs::errors::Error;
15use sigma_proofs::LinearRelation;
16
17type ProofResult<T> = Result<T, Error>;
18
19/// Create a discrete logarithm relation for the given public key P
20#[allow(non_snake_case)]
21fn create_relation(P: RistrettoPoint) -> LinearRelation<RistrettoPoint> {
22    let mut relation = LinearRelation::new();
23
24    let x = relation.allocate_scalar();
25    let G = relation.allocate_element();
26    let P_var = relation.allocate_eq(x * G);
27    relation.set_element(G, RistrettoPoint::generator());
28    relation.set_element(P_var, P);
29
30    relation
31}
32
33/// Prove knowledge of the discrete logarithm: given witness x and public key P,
34/// generate a proof that P = x * G
35#[allow(non_snake_case)]
36fn prove(x: Scalar, P: RistrettoPoint) -> ProofResult<Vec<u8>> {
37    let nizk = create_relation(P).into_nizk(b"sigma-proofs-example");
38    nizk?.prove_batchable(&vec![x], &mut OsRng)
39}
40
41/// Verify a proof of knowledge of discrete logarithm for the given public key P
42#[allow(non_snake_case)]
43fn verify(P: RistrettoPoint, proof: &[u8]) -> ProofResult<()> {
44    let nizk = create_relation(P).into_nizk(b"sigma-proofs-example");
45    nizk?.verify_batchable(proof)
46}
47
48#[allow(non_snake_case)]
49fn main() {
50    let x = Scalar::random(&mut OsRng); // Private key (witness)
51    let P = RistrettoPoint::generator() * x; // Public key (statement)
52
53    println!("Generated new key pair:");
54    println!("Public key P: {:?}", hex::encode(P.compress().as_bytes()));
55
56    match prove(x, P) {
57        Ok(proof) => {
58            println!("Proof generated successfully:");
59            println!("Proof (hex): {}", hex::encode(&proof));
60
61            // Verify the proof
62            match verify(P, &proof) {
63                Ok(()) => println!("✓ Proof verified successfully!"),
64                Err(e) => println!("✗ Proof verification failed: {e:?}"),
65            }
66        }
67        Err(e) => println!("✗ Failed to generate proof: {e:?}"),
68    }
69}