simple_composition/
simple_composition.rs1use curve25519_dalek::ristretto::RistrettoPoint;
4use curve25519_dalek::scalar::Scalar;
5use group::Group;
6use rand::rngs::OsRng;
7use sigma_proofs::{
8 composition::{ComposedRelation, ComposedWitness},
9 errors::Error,
10 LinearRelation,
11};
12
13type G = RistrettoPoint;
14type ProofResult<T> = Result<T, Error>;
15
16#[allow(non_snake_case)]
20fn create_relation(P1: G, P2: G, Q: G, H: G) -> ComposedRelation<G> {
21 let mut rel1 = LinearRelation::<G>::new();
23 let x1 = rel1.allocate_scalar();
24 let G1 = rel1.allocate_element();
25 let P1_var = rel1.allocate_eq(x1 * G1);
26 rel1.set_element(G1, G::generator());
27 rel1.set_element(P1_var, P1);
28
29 let mut rel2 = LinearRelation::<G>::new();
31 let x2 = rel2.allocate_scalar();
32 let G2 = rel2.allocate_element();
33 let H_var = rel2.allocate_element();
34 let P2_var = rel2.allocate_eq(x2 * G2);
35 let Q_var = rel2.allocate_eq(x2 * H_var);
36 rel2.set_element(G2, G::generator());
37 rel2.set_element(H_var, H);
38 rel2.set_element(P2_var, P2);
39 rel2.set_element(Q_var, Q);
40
41 ComposedRelation::or([rel1.canonical().unwrap(), rel2.canonical().unwrap()])
43}
44
45#[allow(non_snake_case)]
47fn prove(P1: G, x2: Scalar, H: G) -> ProofResult<Vec<u8>> {
48 let P2 = G::generator() * x2;
50 let Q = H * x2;
51
52 let instance = create_relation(P1, P2, Q, H);
53 let witness = ComposedWitness::Or(vec![
55 ComposedWitness::Simple(vec![Scalar::from(0u64)]),
56 ComposedWitness::Simple(vec![x2]),
57 ]);
58 let nizk = instance.into_nizk(b"or_proof_example");
59
60 nizk.prove_batchable(&witness, &mut OsRng)
61}
62
63#[allow(non_snake_case)]
65fn verify(P1: G, P2: G, Q: G, H: G, proof: &[u8]) -> ProofResult<()> {
66 let protocol = create_relation(P1, P2, Q, H);
67 let nizk = protocol.into_nizk(b"or_proof_example");
68
69 nizk.verify_batchable(proof)
70}
71
72#[allow(non_snake_case)]
73fn main() {
74 let x1 = Scalar::random(&mut OsRng);
76 let x2 = Scalar::random(&mut OsRng);
77 let H = G::random(&mut OsRng);
78
79 let P1 = G::generator() * x1; let P2 = G::generator() * x2; let Q = H * x2; println!("OR-proof example: Proving knowledge of x1 OR x2");
85 println!("(We only know x2, not x1)");
86
87 match prove(P1, x2, H) {
88 Ok(proof) => {
89 println!("Proof generated successfully");
90 println!("Proof (hex): {}", hex::encode(&proof));
91
92 match verify(P1, P2, Q, H, &proof) {
94 Ok(()) => println!("✓ Proof verified successfully!"),
95 Err(e) => println!("✗ Proof verification failed: {e:?}"),
96 }
97 }
98 Err(e) => println!("✗ Failed to generate proof: {e:?}"),
99 }
100}