1use ark_ec::CurveGroup;
5use rand::thread_rng;
6use sha3::{Digest, Sha3_256};
7
8use crate::{
9 algebra::{CurvePoint, CurvePointResult, Scalar, ScalarResult},
10 fabric::ResultValue,
11};
12
13pub(crate) struct PedersenCommitment<C: CurveGroup> {
18 pub(crate) value: Scalar<C>,
20 pub(crate) blinder: Scalar<C>,
22 pub(crate) commitment: CurvePoint<C>,
24}
25
26impl<C: CurveGroup> PedersenCommitment<C> {
27 pub(crate) fn verify(&self) -> bool {
29 let generator = CurvePoint::generator();
30 let commitment = generator * self.value + generator * self.blinder;
31
32 commitment == self.commitment
33 }
34}
35
36pub(crate) struct PedersenCommitmentResult<C: CurveGroup> {
38 pub(crate) value: ScalarResult<C>,
40 pub(crate) blinder: Scalar<C>,
42 pub(crate) commitment: CurvePointResult<C>,
44}
45
46impl<C: CurveGroup> PedersenCommitmentResult<C> {
47 pub(crate) fn commit(value: ScalarResult<C>) -> PedersenCommitmentResult<C> {
49 let mut rng = thread_rng();
52 let blinder = Scalar::random(&mut rng);
53 let generator = CurvePoint::generator();
54 let commitment = generator * &value + generator * blinder;
55
56 PedersenCommitmentResult {
57 value,
58 blinder,
59 commitment,
60 }
61 }
62}
63
64pub(crate) struct HashCommitment<C: CurveGroup> {
73 pub(crate) value: CurvePoint<C>,
75 pub(crate) blinder: Scalar<C>,
77 pub(crate) commitment: Scalar<C>,
79}
80
81impl<C: CurveGroup> HashCommitment<C> {
82 pub(crate) fn verify(&self) -> bool {
84 let mut bytes = self.value.to_bytes();
86 bytes.append(&mut self.blinder.to_bytes_be());
87
88 let mut hasher = Sha3_256::new();
90 hasher.update(bytes);
91
92 let out_bytes = hasher.finalize();
93 let out = Scalar::from_be_bytes_mod_order(out_bytes.as_slice());
94
95 out == self.commitment
96 }
97}
98
99pub(crate) struct HashCommitmentResult<C: CurveGroup> {
101 pub(crate) value: CurvePointResult<C>,
103 pub(crate) blinder: Scalar<C>,
105 pub(crate) commitment: ScalarResult<C>,
107}
108
109impl<C: CurveGroup> HashCommitmentResult<C> {
110 pub(crate) fn commit(value: CurvePointResult<C>) -> HashCommitmentResult<C> {
112 let mut rng = thread_rng();
113 let blinder = Scalar::random(&mut rng);
114 let comm = value.fabric.new_gate_op(vec![value.id], move |mut args| {
115 let value: CurvePoint<C> = args.remove(0).into();
116
117 let mut bytes = value.to_bytes();
119 bytes.append(&mut blinder.to_bytes_be());
120
121 let mut hasher = Sha3_256::new();
123 hasher.update(bytes);
124
125 let out_bytes = hasher.finalize();
126 let out = Scalar::from_be_bytes_mod_order(out_bytes.as_slice());
127
128 ResultValue::Scalar(out)
129 });
130
131 HashCommitmentResult {
132 value,
133 blinder,
134 commitment: comm,
135 }
136 }
137}