Skip to content

Commit

Permalink
fix: implement hashing api for dan layer (see issue #4392) (#4427)
Browse files Browse the repository at this point in the history
Description
--- Add tari hashing api for DAN layer.

Motivation and Context
--- Tackle issue #4392.

How Has This Been Tested?
--- Existing unit tests.
  • Loading branch information
jorgeantonio21 authored Aug 10, 2022
1 parent 4c68408 commit f7c5e77
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 16 deletions.
42 changes: 42 additions & 0 deletions dan_layer/core/src/models/hashing.rs
Original file line number Diff line number Diff line change
@@ -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<D: Digest + LengthExtensionAttackResistant>(
label: &'static str,
) -> DomainSeparatedHasher<D, DanLayerCoreModelsDomain> {
DomainSeparatedHasher::<D, DanLayerCoreModelsDomain>::new_with_label(label)
}
7 changes: 4 additions & 3 deletions dan_layer/core/src/models/hot_stuff_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -200,7 +201,7 @@ impl<TPayload: Payload> HotStuffMessage<TPayload> {
}

pub fn create_signature_challenge(&self) -> Vec<u8> {
let mut b = Blake256::new()
let mut b = dan_layer_models_hasher::<Blake256>(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 {
Expand All @@ -209,7 +210,7 @@ impl<TPayload: Payload> HotStuffMessage<TPayload> {
b = b.chain(node_hash.as_bytes());
} else {
}
b.finalize().to_vec()
b.finalize().as_ref().to_vec()
}

pub fn view_number(&self) -> ViewId {
Expand Down
2 changes: 2 additions & 0 deletions dan_layer/core/src/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
19 changes: 13 additions & 6 deletions dan_layer/core/src/models/tari_dan_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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::<Blake256>(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()
}
}

Expand Down
41 changes: 41 additions & 0 deletions dan_layer/core/src/templates/hashing.rs
Original file line number Diff line number Diff line change
@@ -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<D: Digest + LengthExtensionAttackResistant>(
label: &'static str,
) -> DomainSeparatedHasher<D, DanLayerCoreTemplatesDomain> {
DomainSeparatedHasher::<D, DanLayerCoreTemplatesDomain>::new_with_label(label)
}
1 change: 1 addition & 0 deletions dan_layer/core/src/templates/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
8 changes: 6 additions & 2 deletions dan_layer/core/src/templates/tip004_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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";
Expand Down Expand Up @@ -95,7 +95,11 @@ fn mint<TUnitOfWork: StateDbUnitOfWork>(args: &[u8], state_db: &mut TUnitOfWork)
}

fn hash_of(s: &str) -> Vec<u8> {
Blake256::new().chain(s).finalize().to_vec()
dan_layer_templates_hasher::<Blake256>(TIP004_TEMPLATE_LABEL)
.chain(s)
.finalize()
.as_ref()
.to_vec()
}

fn balance_of<TUnitOfWork: StateDbUnitOfWorkReader>(
Expand Down
41 changes: 41 additions & 0 deletions dan_layer/engine/src/instructions/hashing.rs
Original file line number Diff line number Diff line change
@@ -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<D: Digest + LengthExtensionAttackResistant>(
label: &'static str,
) -> DomainSeparatedHasher<D, DanLayerEngineInstructionsDomain> {
DomainSeparatedHasher::<D, DanLayerEngineInstructionsDomain>::new_with_label(label)
}
17 changes: 12 additions & 5 deletions dan_layer/engine/src/instructions/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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::<Blake256>(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()
}
}

Expand Down
1 change: 1 addition & 0 deletions dan_layer/engine/src/instructions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2022 The Tari Project
// SPDX-License-Identifier: BSD-3-Clause

mod hashing;
mod instruction;

pub use instruction::Instruction;

0 comments on commit f7c5e77

Please sign in to comment.