sigma_protocols/protocols/
pedersen.rs1use curve25519_dalek::ristretto::RistrettoPoint;
7use curve25519_dalek::scalar::Scalar;
8
9use crate::error::{Error, Result};
10use crate::sigma::{MultiScalarResponse, PointCommitment, ScalarChallenge, SigmaProtocol};
11use crate::utils::{random_scalar, scalar_from_state};
12
13#[derive(Clone, Debug)]
17pub struct PedersenStatement {
18 pub g: RistrettoPoint,
19 pub h: RistrettoPoint,
20 pub commitment: RistrettoPoint,
21}
22
23#[derive(Clone, Debug)]
27pub struct PedersenWitness {
28 pub value: Scalar,
29 pub randomness: Scalar,
30}
31
32pub struct PedersenProof;
36
37impl SigmaProtocol for PedersenProof {
38 type Statement = PedersenStatement;
39 type Witness = PedersenWitness;
40 type Commitment = PointCommitment;
41 type Challenge = ScalarChallenge;
42 type Response = MultiScalarResponse;
43
44 fn prover_commit(
45 statement: &Self::Statement,
46 _witness: &Self::Witness,
47 ) -> (Self::Commitment, Vec<u8>) {
48 let r_v = random_scalar();
49 let r_r = random_scalar();
50 let commitment = r_v * statement.g + r_r * statement.h;
51
52 let mut state = Vec::with_capacity(64);
53 state.extend_from_slice(&r_v.to_bytes());
54 state.extend_from_slice(&r_r.to_bytes());
55
56 (PointCommitment(commitment), state)
57 }
58
59 fn prover_response(
60 _statement: &Self::Statement,
61 witness: &Self::Witness,
62 state: &[u8],
63 challenge: &Self::Challenge,
64 ) -> Result<Self::Response> {
65 if state.len() != 64 {
66 return Err(Error::InvalidProof);
67 }
68
69 let r_v = scalar_from_state(&state[0..32])?;
70 let r_r = scalar_from_state(&state[32..64])?;
71
72 let s_v = r_v + challenge.0 * witness.value;
73 let s_r = r_r + challenge.0 * witness.randomness;
74
75 Ok(MultiScalarResponse(vec![s_v, s_r]))
76 }
77
78 fn verifier(
79 statement: &Self::Statement,
80 commitment: &Self::Commitment,
81 challenge: &Self::Challenge,
82 response: &Self::Response,
83 ) -> Result<()> {
84 if response.0.len() != 2 {
85 return Err(Error::InvalidResponse);
86 }
87
88 let s_v = response.0[0];
89 let s_r = response.0[1];
90
91 let lhs = s_v * statement.g + s_r * statement.h;
92
93 let rhs = commitment.0 + challenge.0 * statement.commitment;
94
95 if lhs == rhs {
96 Ok(())
97 } else {
98 Err(Error::InvalidProof)
99 }
100 }
101}