diff --git a/dan_layer/core/src/models/hashing.rs b/dan_layer/core/src/models/hashing.rs new file mode 100644 index 0000000000..7b30efefdd --- /dev/null +++ b/dan_layer/core/src/models/hashing.rs @@ -0,0 +1,42 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use digest::Digest; +use tari_crypto::{ + hash_domain, + hashing::{DomainSeparatedHasher, LengthExtensionAttackResistant}, +}; + +hash_domain!( + DanLayerCoreModelsDomain, + "com.tari.tari_project.dan_layer.core.models", + 1 +); + +pub(crate) const HOT_STUFF_MESSAGE_LABEL: &str = "hot_stuff_message"; +pub(crate) const TARI_DAN_PAYLOAD_LABEL: &str = "tari_dan_payload"; + +pub(crate) fn dan_layer_models_hasher( + label: &'static str, +) -> DomainSeparatedHasher { + DomainSeparatedHasher::::new_with_label(label) +} diff --git a/dan_layer/core/src/models/hot_stuff_message.rs b/dan_layer/core/src/models/hot_stuff_message.rs index 784658a62d..5ee81adce8 100644 --- a/dan_layer/core/src/models/hot_stuff_message.rs +++ b/dan_layer/core/src/models/hot_stuff_message.rs @@ -20,12 +20,13 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use digest::Digest; use tari_common_types::types::FixedHash; use tari_core::transactions::transaction_components::SignerSignature; use tari_crypto::hash::blake2::Blake256; +use super::HOT_STUFF_MESSAGE_LABEL; use crate::models::{ + dan_layer_models_hasher, HotStuffMessageType, HotStuffTreeNode, Payload, @@ -200,7 +201,7 @@ impl HotStuffMessage { } pub fn create_signature_challenge(&self) -> Vec { - let mut b = Blake256::new() + let mut b = dan_layer_models_hasher::(HOT_STUFF_MESSAGE_LABEL) .chain(&[self.message_type.as_u8()]) .chain(self.view_number.as_u64().to_le_bytes()); if let Some(ref node) = self.node { @@ -209,7 +210,7 @@ impl HotStuffMessage { b = b.chain(node_hash.as_bytes()); } else { } - b.finalize().to_vec() + b.finalize().as_ref().to_vec() } pub fn view_number(&self) -> ViewId { diff --git a/dan_layer/core/src/models/mod.rs b/dan_layer/core/src/models/mod.rs index 70d346b560..852a81b949 100644 --- a/dan_layer/core/src/models/mod.rs +++ b/dan_layer/core/src/models/mod.rs @@ -28,6 +28,7 @@ mod base_layer_output; mod committee; pub mod domain_events; mod error; +mod hashing; mod hot_stuff_message; mod hot_stuff_tree_node; mod instruction_set; @@ -46,6 +47,7 @@ pub use base_layer_metadata::BaseLayerMetadata; pub use base_layer_output::{BaseLayerOutput, CheckpointOutput, CommitteeOutput}; pub use committee::Committee; pub use error::ModelError; +pub(crate) use hashing::{dan_layer_models_hasher, HOT_STUFF_MESSAGE_LABEL}; pub use hot_stuff_message::HotStuffMessage; pub use hot_stuff_tree_node::HotStuffTreeNode; pub use instruction_set::InstructionSet; diff --git a/dan_layer/core/src/models/tari_dan_payload.rs b/dan_layer/core/src/models/tari_dan_payload.rs index 40df6810ec..c4567c4702 100644 --- a/dan_layer/core/src/models/tari_dan_payload.rs +++ b/dan_layer/core/src/models/tari_dan_payload.rs @@ -22,11 +22,11 @@ use std::fmt::Debug; -use digest::Digest; use tari_common_types::types::FixedHash; use tari_crypto::hash::blake2::Blake256; use tari_dan_engine::instructions::Instruction; +use super::{dan_layer_models_hasher, hashing::TARI_DAN_PAYLOAD_LABEL}; use crate::models::{ConsensusHash, InstructionSet, Payload}; #[derive(Debug, Clone)] @@ -56,12 +56,19 @@ impl TariDanPayload { } fn calculate_hash(&self) -> FixedHash { - let result = Blake256::new().chain(self.instruction_set.consensus_hash()); - if let Some(ref ck) = self.checkpoint { - result.chain(ck.consensus_hash()).finalize().into() + let result = + dan_layer_models_hasher::(TARI_DAN_PAYLOAD_LABEL).chain(self.instruction_set.consensus_hash()); + + let mut out = [0u8; 32]; + + let result = if let Some(ref ck) = self.checkpoint { + result.chain(ck.consensus_hash()).finalize() } else { - result.finalize().into() - } + result.finalize() + }; + + out.copy_from_slice(result.as_ref()); + out.into() } } diff --git a/dan_layer/core/src/templates/hashing.rs b/dan_layer/core/src/templates/hashing.rs new file mode 100644 index 0000000000..abe1b7a535 --- /dev/null +++ b/dan_layer/core/src/templates/hashing.rs @@ -0,0 +1,41 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use digest::Digest; +use tari_crypto::{ + hash_domain, + hashing::{DomainSeparatedHasher, LengthExtensionAttackResistant}, +}; + +hash_domain!( + DanLayerCoreTemplatesDomain, + "com.tari.tari_project.dan_layer.core.templates", + 1 +); + +pub(crate) const TIP004_TEMPLATE_LABEL: &str = "tip004_template"; + +pub(crate) fn dan_layer_templates_hasher( + label: &'static str, +) -> DomainSeparatedHasher { + DomainSeparatedHasher::::new_with_label(label) +} diff --git a/dan_layer/core/src/templates/mod.rs b/dan_layer/core/src/templates/mod.rs index 5a94462230..66b350a3e1 100644 --- a/dan_layer/core/src/templates/mod.rs +++ b/dan_layer/core/src/templates/mod.rs @@ -20,6 +20,7 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +pub mod hashing; pub mod tip002_template; pub mod tip004_template; pub mod tip721_template; diff --git a/dan_layer/core/src/templates/tip004_template.rs b/dan_layer/core/src/templates/tip004_template.rs index 17d1d5f4cd..4f14661fa2 100644 --- a/dan_layer/core/src/templates/tip004_template.rs +++ b/dan_layer/core/src/templates/tip004_template.rs @@ -20,7 +20,6 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use digest::Digest; use log::*; use prost::Message; use tari_core::transactions::transaction_components::TemplateParameter; @@ -29,6 +28,7 @@ use tari_dan_common_types::proto::tips::tip004; use tari_dan_engine::state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}; use tari_utilities::hex::Hex; +use super::hashing::{dan_layer_templates_hasher, TIP004_TEMPLATE_LABEL}; use crate::{models::InstructionSet, DigitalAssetError}; const LOG_TARGET: &str = "tari::dan_layer::core::templates::tip004_template"; @@ -95,7 +95,11 @@ fn mint(args: &[u8], state_db: &mut TUnitOfWork) } fn hash_of(s: &str) -> Vec { - Blake256::new().chain(s).finalize().to_vec() + dan_layer_templates_hasher::(TIP004_TEMPLATE_LABEL) + .chain(s) + .finalize() + .as_ref() + .to_vec() } fn balance_of( diff --git a/dan_layer/engine/src/instructions/hashing.rs b/dan_layer/engine/src/instructions/hashing.rs new file mode 100644 index 0000000000..2602d3ddc5 --- /dev/null +++ b/dan_layer/engine/src/instructions/hashing.rs @@ -0,0 +1,41 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use digest::Digest; +use tari_crypto::{ + hash_domain, + hashing::{DomainSeparatedHasher, LengthExtensionAttackResistant}, +}; + +hash_domain!( + DanLayerEngineInstructionsDomain, + "com.tari.tari_project.dan_layer.engine.instructions", + 1 +); + +pub(crate) const INSTRUCTION_LABEL: &str = "instruction"; + +pub(crate) fn dan_layer_engine_instructions( + label: &'static str, +) -> DomainSeparatedHasher { + DomainSeparatedHasher::::new_with_label(label) +} diff --git a/dan_layer/engine/src/instructions/instruction.rs b/dan_layer/engine/src/instructions/instruction.rs index dd1a632ed2..4e71c7f2cd 100644 --- a/dan_layer/engine/src/instructions/instruction.rs +++ b/dan_layer/engine/src/instructions/instruction.rs @@ -3,12 +3,13 @@ use std::fmt::{Display, Formatter}; -use digest::Digest; use tari_common_types::types::{FixedHash, PublicKey}; use tari_crypto::hash::blake2::Blake256; use tari_dan_common_types::TemplateId; use tari_utilities::hex::Hex; +use super::hashing::{dan_layer_engine_instructions, INSTRUCTION_LABEL}; + #[derive(Clone, Debug)] pub struct Instruction { template_id: TemplateId, @@ -79,10 +80,16 @@ impl Instruction { } pub fn calculate_hash(&self) -> FixedHash { - let b = Blake256::new().chain(self.method.as_bytes()).chain(&self.args); - // b.chain(self.from.as_bytes()) - // .chain(com_sig_to_bytes(&self.signature)) - b.finalize().into() + // Blake256 has 32-byte output + let b = dan_layer_engine_instructions::(INSTRUCTION_LABEL) + .chain(self.method.as_bytes()) + .chain(&self.args) + .finalize(); + + let mut out = [0u8; 32]; + out.copy_from_slice(b.as_ref()); + + out.into() } } diff --git a/dan_layer/engine/src/instructions/mod.rs b/dan_layer/engine/src/instructions/mod.rs index e7dc0b50e9..614a8ed58b 100644 --- a/dan_layer/engine/src/instructions/mod.rs +++ b/dan_layer/engine/src/instructions/mod.rs @@ -1,6 +1,7 @@ // Copyright 2022 The Tari Project // SPDX-License-Identifier: BSD-3-Clause +mod hashing; mod instruction; pub use instruction::Instruction;