cougr_core/zk/
commitment.rs1use soroban_sdk::{contracttype, Env};
9
10use super::crypto::{bn254_g1_add, bn254_g1_mul};
11use super::error::ZKError;
12use super::types::{G1Point, Scalar};
13
14#[contracttype]
20#[derive(Clone, Debug)]
21pub struct PedersenParams {
22 pub g: G1Point,
24 pub h: G1Point,
26}
27
28#[contracttype]
30#[derive(Clone, Debug)]
31pub struct PedersenCommitment {
32 pub point: G1Point,
34}
35
36pub fn pedersen_commit(
43 env: &Env,
44 params: &PedersenParams,
45 value: &Scalar,
46 blinding: &Scalar,
47) -> Result<PedersenCommitment, ZKError> {
48 let vg = bn254_g1_mul(env, ¶ms.g, value)?;
49 let rh = bn254_g1_mul(env, ¶ms.h, blinding)?;
50 let point = bn254_g1_add(env, &vg, &rh)?;
51 Ok(PedersenCommitment { point })
52}
53
54pub fn pedersen_verify(
58 env: &Env,
59 params: &PedersenParams,
60 commitment: &PedersenCommitment,
61 value: &Scalar,
62 blinding: &Scalar,
63) -> Result<bool, ZKError> {
64 let expected = pedersen_commit(env, params, value, blinding)?;
65 Ok(commitment.point.bytes == expected.point.bytes)
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use soroban_sdk::{BytesN, Env};
72
73 #[test]
74 fn test_pedersen_params_creation() {
75 let env = Env::default();
76 let params = PedersenParams {
77 g: G1Point {
78 bytes: BytesN::from_array(&env, &[0u8; 64]),
79 },
80 h: G1Point {
81 bytes: BytesN::from_array(&env, &[0u8; 64]),
82 },
83 };
84 assert_eq!(params.g.bytes.len(), 64);
85 assert_eq!(params.h.bytes.len(), 64);
86 }
87
88 #[test]
89 fn test_pedersen_commitment_type_creation() {
90 let env = Env::default();
91 let commitment = PedersenCommitment {
92 point: G1Point {
93 bytes: BytesN::from_array(&env, &[0u8; 64]),
94 },
95 };
96 assert_eq!(commitment.point.bytes.len(), 64);
97 }
98
99 #[test]
100 fn test_pedersen_same_commitment_equals() {
101 let env = Env::default();
102 let c1 = PedersenCommitment {
103 point: G1Point {
104 bytes: BytesN::from_array(&env, &[1u8; 64]),
105 },
106 };
107 let c2 = PedersenCommitment {
108 point: G1Point {
109 bytes: BytesN::from_array(&env, &[1u8; 64]),
110 },
111 };
112 assert_eq!(c1.point.bytes, c2.point.bytes);
113 }
114
115 #[test]
116 fn test_pedersen_different_commitments_differ() {
117 let env = Env::default();
118 let c1 = PedersenCommitment {
119 point: G1Point {
120 bytes: BytesN::from_array(&env, &[1u8; 64]),
121 },
122 };
123 let c2 = PedersenCommitment {
124 point: G1Point {
125 bytes: BytesN::from_array(&env, &[2u8; 64]),
126 },
127 };
128 assert_ne!(c1.point.bytes, c2.point.bytes);
129 }
130}