use crate::commitment::{Commitment, CommitmentOpening};
use mpz_core::{
commit::{Decommitment, HashCommit, Nonce},
hash::Hash,
};
use mpz_garble_core::{encoding_state, encoding_state::Full, EncodedValue};
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Serialize, Deserialize)]
pub struct Blake3Commitment {
hash: Hash,
nonce: Nonce,
}
opaque_debug::implement!(Blake3Commitment);
impl Blake3Commitment {
pub fn new(encodings: &[EncodedValue<encoding_state::Active>]) -> Self {
let (decommitment, hash) = encodings.hash_commit();
Self {
hash,
nonce: *decommitment.nonce(),
}
}
pub fn hash(&self) -> &Hash {
&self.hash
}
pub fn nonce(&self) -> &Nonce {
&self.nonce
}
pub fn open(&self, data: Vec<u8>) -> Blake3Opening {
Blake3Opening::new(data, self.nonce)
}
}
impl From<Blake3Commitment> for Commitment {
fn from(value: Blake3Commitment) -> Self {
Self::Blake3(value)
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct Blake3Opening {
data: Vec<u8>,
nonce: Nonce,
}
impl Blake3Opening {
pub(crate) fn new(data: Vec<u8>, nonce: Nonce) -> Self {
Self { data, nonce }
}
pub fn recover(&self, encodings: &[EncodedValue<Full>]) -> Blake3Commitment {
assert_eq!(
encodings.len(),
self.data.len(),
"encodings and data must have the same length"
);
let encodings = encodings
.iter()
.zip(&self.data)
.map(|(encoding, data)| encoding.select(*data).expect("encoding is for a u8"))
.collect::<Vec<_>>();
let hash = Decommitment::new_with_nonce(encodings, self.nonce).commit();
Blake3Commitment {
hash,
nonce: self.nonce,
}
}
pub fn data(&self) -> &[u8] {
&self.data
}
pub fn into_data(self) -> Vec<u8> {
self.data
}
}
impl From<Blake3Opening> for CommitmentOpening {
fn from(value: Blake3Opening) -> Self {
Self::Blake3(value)
}
}