Skip to content

Commit

Permalink
Use BLAKE2b 256-bit hashes for selectors (#680)
Browse files Browse the repository at this point in the history
* use BLAKE2b 256-bit hashes for selectors

Before this PR we accidentally used BLAKE2b 512-bit hashing.
Using 256-bit versions is important for smart contracts so that smart contracts can compute selector hashes on their own through the built-in contracts-pallet hash support which includes BLAKE2b 256-bit but not 512-bit.

* apply rustfmt
  • Loading branch information
Robbepop authored Feb 4, 2021
1 parent a50bf6d commit e22a0fe
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 13 deletions.
4 changes: 2 additions & 2 deletions crates/lang/ir/src/ir/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ impl TryFrom<syn::NestedMeta> for AttributeFrag {
];
return Ok(AttributeFrag {
ast: meta,
arg: AttributeArg::Selector(Selector::new(
arg: AttributeArg::Selector(Selector::from_bytes(
selector_bytes,
)),
})
Expand Down Expand Up @@ -1069,7 +1069,7 @@ mod tests {
#[ink(selector = "0xDEADBEEF")]
},
Ok(test::Attribute::Ink(vec![AttributeArg::Selector(
Selector::new([0xDE, 0xAD, 0xBE, 0xEF]),
Selector::from_bytes([0xDE, 0xAD, 0xBE, 0xEF]),
)])),
);
}
Expand Down
24 changes: 24 additions & 0 deletions crates/lang/ir/src/ir/blake2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2018-2021 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Computes the BLAKE2b 256-bit hash for the given input and stores it in output.
pub fn blake2b_256(input: &[u8], output: &mut [u8]) {
use ::blake2::digest::{
Update as _,
VariableOutput as _,
};
let mut blake2 = blake2::VarBlake2b::new_keyed(&[], 32);
blake2.update(input);
blake2.finalize_variable(|result| output.copy_from_slice(result));
}
10 changes: 3 additions & 7 deletions crates/lang/ir/src/ir/item_impl/callable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,7 @@ where
}
}
};
let hash = <blake2::Blake2b as blake2::Digest>::digest(&joined);
ir::Selector::new([hash[0], hash[1], hash[2], hash[3]])
ir::Selector::new(&joined)
}

/// Ensures that common invariants of externally callable ink! entities are met.
Expand Down Expand Up @@ -521,11 +520,8 @@ mod tests {
impl ExpectedSelector {
pub fn expected_selector(self) -> ir::Selector {
match self {
Self::Raw(raw_selector) => ir::Selector::new(raw_selector),
Self::Blake2(blake2_input) => {
let hash = <blake2::Blake2b as blake2::Digest>::digest(&blake2_input);
ir::Selector::new([hash[0], hash[1], hash[2], hash[3]])
}
Self::Raw(raw_selector) => ir::Selector::from_bytes(raw_selector),
Self::Blake2(blake2_input) => ir::Selector::new(&blake2_input),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/lang/ir/src/ir/item_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ mod tests {
}
}
},
"encountered ink! messages with overlapping selectors (= [EA, 48, 09, 33])\n\
"encountered ink! messages with overlapping selectors (= [04, C4, 94, 46])\n\
hint: use #[ink(selector = \"0x...\")] on the callable or \
#[ink(namespace = \"...\")] on the implementation block to \
disambiguate overlapping selectors.",
Expand Down
1 change: 1 addition & 0 deletions crates/lang/ir/src/ir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#![allow(dead_code)]

mod attrs;
mod blake2;
mod chain_extension;
mod config;
mod contract;
Expand Down
15 changes: 12 additions & 3 deletions crates/lang/ir/src/ir/selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use super::blake2::blake2b_256;

/// A function selector.
///
/// # Note
Expand All @@ -23,11 +25,18 @@ pub struct Selector {
}

impl Selector {
/// Creates a new selector from the given bytes.
pub fn new(bytes: [u8; 4]) -> Self {
/// Creates a new selector from the given raw bytes.
pub fn from_bytes(bytes: [u8; 4]) -> Self {
Self { bytes }
}

/// Computes the BLAKE-2 256-bit based selector from the given input bytes.
pub fn new(input: &[u8]) -> Self {
let mut output = [0; 32];
blake2b_256(input, &mut output);
Self::from_bytes([output[0], output[1], output[2], output[3]])
}

/// Returns the underlying four bytes.
pub fn as_bytes(&self) -> &[u8; 4] {
&self.bytes
Expand All @@ -41,6 +50,6 @@ impl Selector {

impl From<[u8; 4]> for Selector {
fn from(bytes: [u8; 4]) -> Self {
Self::new(bytes)
Self::from_bytes(bytes)
}
}

0 comments on commit e22a0fe

Please sign in to comment.