pub mod blake3;
mod builder;
use std::collections::HashMap;
use bimap::BiMap;
use mpz_core::hash::Hash;
use mpz_garble_core::{encoding_state::Full, EncodedValue};
use serde::{Deserialize, Serialize};
use utils::range::RangeSet;
use crate::{
merkle::{MerkleRoot, MerkleTree},
Direction,
};
pub use builder::{TranscriptCommitmentBuilder, TranscriptCommitmentBuilderError};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct CommitmentId(u32);
impl CommitmentId {
pub(crate) fn new(id: u32) -> Self {
Self(id)
}
pub(crate) fn to_inner(self) -> u32 {
self.0
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct CommitmentInfo {
pub(crate) kind: CommitmentKind,
pub(crate) ranges: RangeSet<usize>,
pub(crate) direction: Direction,
}
impl CommitmentInfo {
pub(crate) fn new(kind: CommitmentKind, ranges: RangeSet<usize>, direction: Direction) -> Self {
Self {
kind,
ranges,
direction,
}
}
pub fn kind(&self) -> CommitmentKind {
self.kind
}
pub fn ranges(&self) -> &RangeSet<usize> {
&self.ranges
}
pub fn direction(&self) -> &Direction {
&self.direction
}
}
#[derive(Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub enum Commitment {
Blake3(blake3::Blake3Commitment),
}
impl Commitment {
pub fn hash(&self) -> Hash {
match self {
Commitment::Blake3(commitment) => *commitment.hash(),
}
}
pub fn kind(&self) -> CommitmentKind {
match self {
Commitment::Blake3(_) => CommitmentKind::Blake3,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum CommitmentKind {
Blake3,
}
#[derive(Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub enum CommitmentOpening {
Blake3(blake3::Blake3Opening),
}
impl CommitmentOpening {
pub fn kind(&self) -> CommitmentKind {
match self {
CommitmentOpening::Blake3(_) => CommitmentKind::Blake3,
}
}
pub fn recover(&self, encodings: &[EncodedValue<Full>]) -> Commitment {
match self {
CommitmentOpening::Blake3(opening) => opening.recover(encodings).into(),
}
}
pub fn data(&self) -> &[u8] {
match self {
CommitmentOpening::Blake3(opening) => opening.data(),
}
}
pub fn into_data(self) -> Vec<u8> {
match self {
CommitmentOpening::Blake3(opening) => opening.into_data(),
}
}
}
#[derive(Clone, Serialize, Deserialize)]
pub struct TranscriptCommitments {
merkle_tree: MerkleTree,
commitments: HashMap<CommitmentId, Commitment>,
commitment_info: BiMap<CommitmentId, CommitmentInfo>,
}
opaque_debug::implement!(TranscriptCommitments);
impl TranscriptCommitments {
pub fn merkle_tree(&self) -> &MerkleTree {
&self.merkle_tree
}
pub fn merkle_root(&self) -> MerkleRoot {
self.merkle_tree.root()
}
pub fn get(&self, id: &CommitmentId) -> Option<&Commitment> {
self.commitments.get(id)
}
pub fn get_id_by_info(
&self,
kind: CommitmentKind,
ranges: &RangeSet<usize>,
direction: Direction,
) -> Option<CommitmentId> {
self.commitment_info
.get_by_right(&CommitmentInfo::new(kind, ranges.clone(), direction))
.copied()
}
pub fn get_info(&self, id: &CommitmentId) -> Option<&CommitmentInfo> {
self.commitment_info.get_by_left(id)
}
}