use blake2::{
Blake2b,
digest::consts::{U32, U64},
};
use borsh::BorshSerialize;
use tari_crypto::{
hash_domain,
ristretto::{RistrettoPublicKey, RistrettoSecretKey},
signatures::SchnorrSignature,
};
use tari_hashing::DomainSeparatedBorshHasher;
use tari_template_lib::types::Hash32;
hash_domain!(TariEngineHashDomain, "com.tari.ootle.engine", 0);
pub fn engine_hasher64(label: EngineHashDomainLabel) -> TariEngineHasher64 {
TariEngineHasher64::new_with_label(label.as_label())
}
pub fn substate_value_hasher32() -> TariHasher32 {
hasher32(EngineHashDomainLabel::SubstateValue)
}
pub fn hasher32(label: EngineHashDomainLabel) -> TariHasher32 {
TariHasher32::new_with_label(label.as_label())
}
pub fn template_hasher32() -> TariHasher32 {
hasher32(EngineHashDomainLabel::Template)
}
pub fn hash_template_code(code: &[u8]) -> Hash32 {
template_hasher32().chain(&code).result()
}
pub type EngineSchnorrSignature = SchnorrSignature<RistrettoPublicKey, RistrettoSecretKey, TariEngineHashDomain>;
pub struct TariHasher32 {
hasher: DomainSeparatedBorshHasher<TariEngineHashDomain, Blake2b<U32>>,
}
impl TariHasher32 {
pub fn new_with_label(label: &'static str) -> Self {
let hasher = DomainSeparatedBorshHasher::new_with_label(label);
Self { hasher }
}
pub fn update<T: BorshSerialize + ?Sized>(&mut self, data: &T) {
self.hasher.update_consensus_encode(data)
}
pub fn chain<T: BorshSerialize + ?Sized>(mut self, data: &T) -> Self {
self.update(data);
self
}
pub fn result(self) -> Hash32 {
self.hasher.finalize_into_array().into()
}
}
pub struct TariEngineHasher64 {
hasher: DomainSeparatedBorshHasher<TariEngineHashDomain, Blake2b<U64>>,
}
impl TariEngineHasher64 {
pub fn new_with_label(label: &'static str) -> Self {
let hasher = DomainSeparatedBorshHasher::new_with_label(label);
Self { hasher }
}
pub fn update<T: BorshSerialize + ?Sized>(&mut self, data: &T) {
self.hasher.update_consensus_encode(data)
}
pub fn chain<T: BorshSerialize + ?Sized>(mut self, data: &T) -> Self {
self.update(data);
self
}
pub fn result(self) -> [u8; 64] {
self.hasher.finalize().into()
}
}
#[derive(Debug)]
pub enum EngineHashDomainLabel {
Template,
SubstateAddress,
ConfidentialProof,
ConfidentialTransfer,
Transaction,
NonFungibleId,
UuidOutput,
Output,
EntityId,
ResourceAddress,
ComponentAddress,
TransactionReceipt,
FeeClaimAddress,
QuorumCertificate,
SubstateValue,
SubstateValuePart,
ViewableBalanceProof,
UtxoAddress,
ConfidentialOutputAddress,
StealthBalanceProof,
CovenantBalanceProof,
ValueProof,
Blob,
ConditionLeaf,
ConditionBranch,
}
impl EngineHashDomainLabel {
pub fn as_label(&self) -> &'static str {
match self {
Self::Template => "Template",
Self::SubstateAddress => "SubstateAddress",
Self::ConfidentialProof => "ConfidentialProof",
Self::ConfidentialTransfer => "ConfidentialTransfer",
Self::Transaction => "Transaction",
Self::NonFungibleId => "NonFungibleId",
Self::UuidOutput => "UuidOutput",
Self::Output => "Output",
Self::EntityId => "EntityId",
Self::ResourceAddress => "ResourceAddress",
Self::ComponentAddress => "ComponentAddress",
Self::TransactionReceipt => "TransactionReceipt",
Self::FeeClaimAddress => "FeeClaimAddress",
Self::QuorumCertificate => "QuorumCertificate",
Self::SubstateValue => "SubstateValue",
Self::SubstateValuePart => "SubstateValuePart",
Self::ViewableBalanceProof => "ViewableBalanceProof",
Self::UtxoAddress => "UtxoAddress",
Self::ConfidentialOutputAddress => "ConfidentialOutputAddress",
Self::StealthBalanceProof => "StealthBalanceProof",
Self::CovenantBalanceProof => "CovenantBalanceProof",
Self::ValueProof => "ValueProof",
Self::Blob => "Blob",
Self::ConditionLeaf => "ConditionLeaf",
Self::ConditionBranch => "ConditionBranch",
}
}
}