1use soroban_sdk::{Bytes, BytesN, Env};
2
3use super::commitment::{pedersen_commit, pedersen_verify, PedersenCommitment, PedersenParams};
4use super::error::ZKError;
5use super::groth16::verify_groth16;
6use super::merkle::proof::{verify_inclusion, OnChainMerkleProof};
7use super::types::{Groth16Proof, Scalar, VerificationKey};
8
9pub trait CommitmentScheme {
16 type Parameters;
17 type Value;
18 type Opening;
19 type Commitment;
20
21 fn commit(
22 &self,
23 env: &Env,
24 params: &Self::Parameters,
25 value: &Self::Value,
26 opening: &Self::Opening,
27 ) -> Result<Self::Commitment, ZKError>;
28
29 fn verify(
30 &self,
31 env: &Env,
32 params: &Self::Parameters,
33 commitment: &Self::Commitment,
34 value: &Self::Value,
35 opening: &Self::Opening,
36 ) -> Result<bool, ZKError>;
37}
38
39pub trait MerkleProofVerifier {
45 type Proof;
46 type Root;
47
48 fn verify(
49 &self,
50 env: &Env,
51 proof: &Self::Proof,
52 expected_root: &Self::Root,
53 ) -> Result<bool, ZKError>;
54}
55
56pub trait HiddenStateCodec {
61 type State;
62
63 fn encode(&self, env: &Env, state: &Self::State) -> Result<Bytes, ZKError>;
64 fn decode(&self, env: &Env, encoded: &Bytes) -> Result<Self::State, ZKError>;
65}
66
67pub trait ProofVerifier {
74 type VerificationKey;
75 type Proof;
76 type PublicInput;
77
78 fn verify(
79 &self,
80 env: &Env,
81 verification_key: &Self::VerificationKey,
82 proof: &Self::Proof,
83 public_inputs: &[Self::PublicInput],
84 ) -> Result<bool, ZKError>;
85}
86
87#[derive(Clone, Copy, Debug, Default)]
89pub struct PedersenCommitmentScheme;
90
91impl CommitmentScheme for PedersenCommitmentScheme {
92 type Parameters = PedersenParams;
93 type Value = Scalar;
94 type Opening = Scalar;
95 type Commitment = PedersenCommitment;
96
97 fn commit(
98 &self,
99 env: &Env,
100 params: &Self::Parameters,
101 value: &Self::Value,
102 opening: &Self::Opening,
103 ) -> Result<Self::Commitment, ZKError> {
104 pedersen_commit(env, params, value, opening)
105 }
106
107 fn verify(
108 &self,
109 env: &Env,
110 params: &Self::Parameters,
111 commitment: &Self::Commitment,
112 value: &Self::Value,
113 opening: &Self::Opening,
114 ) -> Result<bool, ZKError> {
115 pedersen_verify(env, params, commitment, value, opening)
116 }
117}
118
119#[derive(Clone, Copy, Debug, Default)]
121pub struct Sha256MerkleProofVerifier;
122
123impl MerkleProofVerifier for Sha256MerkleProofVerifier {
124 type Proof = OnChainMerkleProof;
125 type Root = BytesN<32>;
126
127 fn verify(
128 &self,
129 env: &Env,
130 proof: &Self::Proof,
131 expected_root: &Self::Root,
132 ) -> Result<bool, ZKError> {
133 verify_inclusion(env, proof, expected_root)
134 }
135}
136
137#[derive(Clone, Copy, Debug, Default)]
142pub struct Bytes32HiddenStateCodec;
143
144impl HiddenStateCodec for Bytes32HiddenStateCodec {
145 type State = BytesN<32>;
146
147 fn encode(&self, env: &Env, state: &Self::State) -> Result<Bytes, ZKError> {
148 Ok(Bytes::from_slice(env, &state.to_array()))
149 }
150
151 fn decode(&self, env: &Env, encoded: &Bytes) -> Result<Self::State, ZKError> {
152 if encoded.len() != 32 {
153 return Err(ZKError::InvalidInput);
154 }
155
156 let mut bytes = [0u8; 32];
157 for i in 0..32u32 {
158 bytes[i as usize] = encoded.get(i).ok_or(ZKError::InvalidInput)?;
159 }
160 Ok(BytesN::from_array(env, &bytes))
161 }
162}
163
164#[derive(Clone, Copy, Debug, Default)]
170pub struct Groth16ProofVerifier;
171
172impl ProofVerifier for Groth16ProofVerifier {
173 type VerificationKey = VerificationKey;
174 type Proof = Groth16Proof;
175 type PublicInput = Scalar;
176
177 fn verify(
178 &self,
179 env: &Env,
180 verification_key: &Self::VerificationKey,
181 proof: &Self::Proof,
182 public_inputs: &[Self::PublicInput],
183 ) -> Result<bool, ZKError> {
184 verify_groth16(env, verification_key, proof, public_inputs)
185 }
186}
187
188#[cfg(test)]
189mod tests {
190 use super::*;
191 use soroban_sdk::{BytesN, Env, Vec};
192
193 #[test]
194 fn test_bytes32_hidden_state_codec_roundtrip() {
195 let env = Env::default();
196 let codec = Bytes32HiddenStateCodec;
197 let state = BytesN::from_array(&env, &[0xAB; 32]);
198
199 let encoded = codec.encode(&env, &state).unwrap();
200 let decoded = codec.decode(&env, &encoded).unwrap();
201
202 assert_eq!(decoded, state);
203 }
204
205 #[test]
206 fn test_bytes32_hidden_state_codec_rejects_wrong_length() {
207 let env = Env::default();
208 let codec = Bytes32HiddenStateCodec;
209 let encoded = Bytes::from_slice(&env, &[1, 2, 3]);
210
211 let result = codec.decode(&env, &encoded);
212 assert_eq!(result, Err(ZKError::InvalidInput));
213 }
214
215 #[test]
216 fn test_sha256_merkle_verifier_rejects_malformed_proof() {
217 let env = Env::default();
218 let verifier = Sha256MerkleProofVerifier;
219 let proof = OnChainMerkleProof {
220 siblings: Vec::new(&env),
221 path_bits: 0,
222 leaf: BytesN::from_array(&env, &[1u8; 32]),
223 leaf_index: 0,
224 depth: 1,
225 };
226 let root = BytesN::from_array(&env, &[0u8; 32]);
227
228 let result = verifier.verify(&env, &proof, &root);
229 assert_eq!(result, Err(ZKError::InvalidProofLength));
230 }
231}