sigma_protocols/protocols/
dleq.rs1use curve25519_dalek::ristretto::RistrettoPoint;
7use curve25519_dalek::scalar::Scalar;
8
9use crate::error::{Error, Result};
10use crate::sigma::{MultiPointCommitment, ScalarChallenge, ScalarResponse, SigmaProtocol};
11use crate::utils::{random_scalar, scalar_from_state};
12
13#[derive(Clone, Debug)]
17pub struct DLEQStatement {
18 pub g: RistrettoPoint,
19 pub h: RistrettoPoint,
20 pub x: RistrettoPoint,
21 pub y: RistrettoPoint,
22}
23
24#[derive(Clone, Debug)]
26pub struct DLEQWitness {
27 pub alpha: Scalar,
28}
29
30pub struct DLEQProof;
34
35impl SigmaProtocol for DLEQProof {
36 type Statement = DLEQStatement;
37 type Witness = DLEQWitness;
38 type Commitment = MultiPointCommitment;
39 type Challenge = ScalarChallenge;
40 type Response = ScalarResponse;
41
42 fn prover_commit(
43 statement: &Self::Statement,
44 _witness: &Self::Witness,
45 ) -> (Self::Commitment, Vec<u8>) {
46 let r = random_scalar();
47 let a = r * statement.g;
48 let b = r * statement.h;
49 (MultiPointCommitment(vec![a, b]), r.to_bytes().to_vec())
50 }
51
52 fn prover_response(
53 _statement: &Self::Statement,
54 witness: &Self::Witness,
55 state: &[u8],
56 challenge: &Self::Challenge,
57 ) -> Result<Self::Response> {
58 let r = scalar_from_state(state)?;
59 let response = r + challenge.0 * witness.alpha;
60 Ok(ScalarResponse(response))
61 }
62
63 fn verifier(
64 statement: &Self::Statement,
65 commitment: &Self::Commitment,
66 challenge: &Self::Challenge,
67 response: &Self::Response,
68 ) -> Result<()> {
69 if commitment.0.len() != 2 {
70 return Err(Error::InvalidCommitment);
71 }
72
73 let a = commitment.0[0];
74 let b = commitment.0[1];
75
76 let lhs_g = response.0 * statement.g;
77 let rhs_g = a + challenge.0 * statement.x;
78
79 let lhs_h = response.0 * statement.h;
80 let rhs_h = b + challenge.0 * statement.y;
81
82 if lhs_g == rhs_g && lhs_h == rhs_h {
83 Ok(())
84 } else {
85 Err(Error::InvalidProof)
86 }
87 }
88}