use rand::thread_rng;
use sha3::{Digest, Sha3_256};
use crate::{
algebra::{
scalar::{Scalar, ScalarResult},
stark_curve::{StarkPoint, StarkPointResult},
},
fabric::ResultValue,
};
pub(crate) struct PedersenCommitment {
pub(crate) value: Scalar,
pub(crate) blinder: Scalar,
pub(crate) commitment: StarkPoint,
}
impl PedersenCommitment {
pub(crate) fn verify(&self) -> bool {
let generator = StarkPoint::generator();
let commitment = generator * self.value + generator * self.blinder;
commitment == self.commitment
}
}
pub(crate) struct PedersenCommitmentResult {
pub(crate) value: ScalarResult,
pub(crate) blinder: Scalar,
pub(crate) commitment: StarkPointResult,
}
impl PedersenCommitmentResult {
pub(crate) fn commit(value: ScalarResult) -> PedersenCommitmentResult {
let mut rng = thread_rng();
let blinder = Scalar::random(&mut rng);
let generator = StarkPoint::generator();
let commitment = generator * &value + generator * blinder;
PedersenCommitmentResult {
value,
blinder,
commitment,
}
}
}
pub(crate) struct HashCommitment {
pub(crate) value: StarkPoint,
pub(crate) blinder: Scalar,
pub(crate) commitment: Scalar,
}
impl HashCommitment {
pub(crate) fn verify(&self) -> bool {
let mut bytes = self.value.to_bytes();
bytes.append(&mut self.blinder.to_bytes_be());
let mut hasher = Sha3_256::new();
hasher.update(bytes);
let out_bytes = hasher.finalize();
let out = Scalar::from_be_bytes_mod_order(out_bytes.as_slice());
out == self.commitment
}
}
pub(crate) struct HashCommitmentResult {
pub(crate) value: StarkPointResult,
pub(crate) blinder: Scalar,
pub(crate) commitment: ScalarResult,
}
impl HashCommitmentResult {
pub(crate) fn commit(value: StarkPointResult) -> HashCommitmentResult {
let mut rng = thread_rng();
let blinder = Scalar::random(&mut rng);
let comm = value.fabric.new_gate_op(vec![value.id], move |mut args| {
let value: StarkPoint = args.remove(0).into();
let mut bytes = value.to_bytes();
bytes.append(&mut blinder.to_bytes_be());
let mut hasher = Sha3_256::new();
hasher.update(bytes);
let out_bytes = hasher.finalize();
let out = Scalar::from_be_bytes_mod_order(out_bytes.as_slice());
ResultValue::Scalar(out)
});
HashCommitmentResult {
value,
blinder,
commitment: comm,
}
}
}