diem_crypto/
hash.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8//! This module defines traits and implementations of
9//! [cryptographic hash functions](https://en.wikipedia.org/wiki/Cryptographic_hash_function)
10//! for the Diem project.
11//!
12//! It is designed to help authors protect against two types of real world
13//! attacks:
14//!
15//! 1. **Semantic Ambiguity**: imagine that Alice has a private key and is using
16//!    two different applications, X and Y. X asks Alice to sign a message
17//! saying    "I am Alice". Alice accepts to sign this message in the context of
18//! X. However,    unbeknownst to Alice, in application Y, messages beginning
19//! with the letter "I"    represent transfers. " am " represents a transfer of
20//! 500 coins and "Alice"    can be interpreted as a destination address. When
21//! Alice signed the message she    needed to be aware of how other applications
22//! might interpret that message.
23//!
24//! 2. **Format Ambiguity**: imagine a program that hashes a pair of strings. To
25//!    hash the strings `a` and `b` it hashes `a + "||" + b`. The pair of
26//!    strings `a="foo||", b = "bar"` and `a="foo", b = "||bar"` result in the
27//!    same input to the hash function and therefore the same hash. This creates
28//!    a collision.
29//!
30//! Regarding (1), this library makes it easy for Diem developers to create as
31//! many new "hashable" Rust types as needed so that each Rust type hashed and
32//! signed in Diem has a unique meaning, that is, unambiguously captures the
33//! intent of a signer.
34//!
35//! Regarding (2), this library provides the `CryptoHasher` abstraction to
36//! easily manage cryptographic seeds for hashing. Hashing seeds aim to ensure
37//! that the hashes of values of a given type `MyNewStruct` never collide with
38//! hashes of values from another type.
39//!
40//! Finally, to prevent format ambiguity within a same type `MyNewStruct` and
41//! facilitate protocol specifications, we use [Binary Canonical Serialization (BCS)](https://docs.rs/bcs/)
42//! as the recommended solution to write Rust values into a hasher.
43//!
44//! # Quick Start
45//!
46//! To obtain a `hash()` method for any new type `MyNewStruct`, it is (strongly)
47//! recommended to use the derive macros of `serde` and `diem_crypto_derive` as
48//! follows:
49//!
50//! ```
51//! use diem_crypto::hash::CryptoHash;
52//! use diem_crypto_derive::{BCSCryptoHash, CryptoHasher};
53//! use serde::{Deserialize, Serialize};
54//! #[derive(Serialize, Deserialize, CryptoHasher, BCSCryptoHash)]
55//! struct MyNewStruct {/* ... */}
56//!
57//! let value = MyNewStruct { /*...*/ };
58//! value.hash();
59//! ```
60//!
61//! Under the hood, this will generate a new implementation `MyNewStructHasher`
62//! for the trait `CryptoHasher` and implement the trait `CryptoHash` for
63//! `MyNewStruct` using BCS.
64//!
65//! # Implementing New Hashers
66//!
67//! The trait `CryptoHasher` captures the notion of a pre-seeded hash function,
68//! aka a "hasher". New implementations can be defined in two ways.
69//!
70//! ## Derive macro (recommended)
71//!
72//! For any new structure `MyNewStruct` that needs to be hashed, it is
73//! recommended to simply use the derive macro [`CryptoHasher`](https://doc.rust-lang.org/reference/procedural-macros.html).
74//!
75//! ```
76//! use diem_crypto_derive::CryptoHasher;
77//! use serde::Deserialize;
78//! #[derive(Deserialize, CryptoHasher)]
79//! #[serde(rename = "OptionalCustomSerdeName")]
80//! struct MyNewStruct {/* ... */}
81//! ```
82//!
83//! The macro `CryptoHasher` will define a hasher automatically called
84//! `MyNewStructHasher`, and derive a salt using the name of the type as seen by
85//! the Serde library. In the example above, this name was changed using the
86//! Serde parameter `rename`: the salt will be based on the value
87//! `OptionalCustomSerdeName` instead of the default name `MyNewStruct`.
88//!
89//! ## Customized hashers
90//!
91//! **IMPORTANT:** Do NOT use this for new code unless you know what you are
92//! doing.
93//!
94//! This library also provides a few customized hashers defined in the code as
95//! follows:
96//!
97//! ```
98//! # // To get around that there's no way to doc-test a non-exported macro:
99//! # macro_rules! define_hasher { ($e:expr) => () }
100//! define_hasher! { (MyNewDataHasher, MY_NEW_DATA_HASHER, MY_NEW_DATA_SEED,
101//! b"MyUniqueSaltString") }
102//! ```
103//!
104//! # Using a hasher directly
105//!
106//! **IMPORTANT:** Do NOT use this for new code unless you know what you are
107//! doing.
108//! ```
109//! use diem_crypto::hash::{CryptoHasher, TestOnlyHasher};
110//!
111//! let mut hasher = TestOnlyHasher::default();
112//! hasher.update("Test message".as_bytes());
113//! let hash_value = hasher.finish();
114//! ```
115#![allow(clippy::integer_arithmetic)]
116use bytes::Bytes;
117use cfx_types::U256;
118use hex::FromHex;
119use mirai_annotations::*;
120use once_cell::sync::{Lazy, OnceCell};
121#[cfg(any(test, feature = "fuzzing"))]
122use proptest_derive::Arbitrary;
123use rand::{rngs::OsRng, Rng};
124use serde::{de, ser};
125use std::{
126    self,
127    convert::{AsRef, TryFrom},
128    fmt,
129    str::FromStr,
130};
131use tiny_keccak::{Hasher, Sha3};
132
133/// A prefix used to begin the salt of every diem hashable structure. The salt
134/// consists in this global prefix, concatenated with the specified
135/// serialization name of the struct.
136pub(crate) const DIEM_HASH_PREFIX: &[u8] = b"DIEM::";
137
138/// Output value of our hash function. Intentionally opaque for safety and
139/// modularity.
140#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
141#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
142pub struct HashValue {
143    hash: [u8; HashValue::LENGTH],
144}
145
146impl HashValue {
147    /// The length of the hash in bytes.
148    pub const LENGTH: usize = 32;
149    /// The length of the hash in bits.
150    pub const LENGTH_IN_BITS: usize = Self::LENGTH * 8;
151
152    /// Create a new [`HashValue`] from a byte array.
153    pub fn new(hash: [u8; HashValue::LENGTH]) -> Self { HashValue { hash } }
154
155    /// Create from a slice (e.g. retrieved from storage).
156    pub fn from_slice<T: AsRef<[u8]>>(
157        bytes: T,
158    ) -> Result<Self, HashValueParseError> {
159        <[u8; Self::LENGTH]>::try_from(bytes.as_ref())
160            .map_err(|_| HashValueParseError)
161            .map(Self::new)
162    }
163
164    /// Dumps into a vector.
165    pub fn to_vec(&self) -> Vec<u8> { self.hash.to_vec() }
166
167    /// Creates a zero-initialized instance.
168    pub const fn zero() -> Self {
169        HashValue {
170            hash: [0; HashValue::LENGTH],
171        }
172    }
173
174    /// Create a cryptographically random instance.
175    pub fn random() -> Self {
176        let mut rng = OsRng;
177        let hash: [u8; HashValue::LENGTH] = rng.gen();
178        HashValue { hash }
179    }
180
181    /// Creates a random instance with given rng. Useful in unit tests.
182    pub fn random_with_rng<R: Rng>(rng: &mut R) -> Self {
183        let hash: [u8; HashValue::LENGTH] = rng.gen();
184        HashValue { hash }
185    }
186
187    /// Convenience function that computes a `HashValue` internally equal to
188    /// the sha3_256 of a byte buffer. It will handle hasher creation, data
189    /// feeding and finalization.
190    ///
191    /// Note this will not result in the `<T as CryptoHash>::hash()` for any
192    /// reasonable struct T, as this computes a sha3 without any ornaments.
193    pub fn sha3_256_of(buffer: &[u8]) -> Self {
194        let mut sha3 = Sha3::v256();
195        sha3.update(buffer);
196        HashValue::from_keccak(sha3)
197    }
198
199    #[cfg(test)]
200    #[allow(missing_docs)]
201    pub fn from_iter_sha3<'a, I>(buffers: I) -> Self
202    where I: IntoIterator<Item = &'a [u8]> {
203        let mut sha3 = Sha3::v256();
204        for buffer in buffers {
205            sha3.update(buffer);
206        }
207        HashValue::from_keccak(sha3)
208    }
209
210    fn as_ref_mut(&mut self) -> &mut [u8] { &mut self.hash[..] }
211
212    fn from_keccak(state: Sha3) -> Self {
213        let mut hash = Self::zero();
214        state.finalize(hash.as_ref_mut());
215        hash
216    }
217
218    /// Returns a `HashValueBitIterator` over all the bits that represent this
219    /// `HashValue`.
220    pub fn iter_bits(&self) -> HashValueBitIterator<'_> {
221        HashValueBitIterator::new(self)
222    }
223
224    /// Constructs a `HashValue` from an iterator of bits.
225    pub fn from_bit_iter(
226        iter: impl ExactSizeIterator<Item = bool>,
227    ) -> Result<Self, HashValueParseError> {
228        if iter.len() != Self::LENGTH_IN_BITS {
229            return Err(HashValueParseError);
230        }
231
232        let mut buf = [0; Self::LENGTH];
233        for (i, bit) in iter.enumerate() {
234            if bit {
235                buf[i / 8] |= 1 << (7 - i % 8);
236            }
237        }
238        Ok(Self::new(buf))
239    }
240
241    /// Returns the length of common prefix of `self` and `other` in bits.
242    pub fn common_prefix_bits_len(&self, other: HashValue) -> usize {
243        self.iter_bits()
244            .zip(other.iter_bits())
245            .take_while(|(x, y)| x == y)
246            .count()
247    }
248
249    /// Full hex representation of a given hash value.
250    pub fn to_hex(&self) -> String { format!("{:x}", self) }
251
252    /// Parse a given hex string to a hash value.
253    pub fn from_hex<T: AsRef<[u8]>>(
254        hex: T,
255    ) -> Result<Self, HashValueParseError> {
256        <[u8; Self::LENGTH]>::from_hex(hex)
257            .map_err(|_| HashValueParseError)
258            .map(Self::new)
259    }
260
261    /// Convert a hash to big int (U256).
262    pub fn to_u256(&self) -> U256 { U256::from_big_endian(self.as_ref()) }
263}
264
265impl ser::Serialize for HashValue {
266    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
267    where S: ser::Serializer {
268        if serializer.is_human_readable() {
269            serializer.serialize_str(&self.to_hex())
270        } else {
271            // In order to preserve the Serde data model and help analysis
272            // tools, make sure to wrap our value in a container
273            // with the same name as the original type.
274            serializer.serialize_newtype_struct(
275                "HashValue",
276                serde_bytes::Bytes::new(&self.hash[..]),
277            )
278        }
279    }
280}
281
282impl<'de> de::Deserialize<'de> for HashValue {
283    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
284    where D: de::Deserializer<'de> {
285        if deserializer.is_human_readable() {
286            let encoded_hash = <String>::deserialize(deserializer)?;
287            HashValue::from_hex(encoded_hash.as_str())
288                .map_err(<D::Error as ::serde::de::Error>::custom)
289        } else {
290            // See comment in serialize.
291            #[derive(::serde::Deserialize)]
292            #[serde(rename = "HashValue")]
293            struct Value<'a>(&'a [u8]);
294
295            let value = Value::deserialize(deserializer)?;
296            Self::from_slice(value.0)
297                .map_err(<D::Error as ::serde::de::Error>::custom)
298        }
299    }
300}
301
302impl Default for HashValue {
303    fn default() -> Self { HashValue::zero() }
304}
305
306impl AsRef<[u8; HashValue::LENGTH]> for HashValue {
307    fn as_ref(&self) -> &[u8; HashValue::LENGTH] { &self.hash }
308}
309
310impl std::ops::Deref for HashValue {
311    type Target = [u8; Self::LENGTH];
312
313    fn deref(&self) -> &Self::Target { &self.hash }
314}
315
316impl std::ops::Index<usize> for HashValue {
317    type Output = u8;
318
319    fn index(&self, s: usize) -> &u8 { self.hash.index(s) }
320}
321
322impl fmt::Binary for HashValue {
323    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
324        for byte in &self.hash {
325            write!(f, "{:08b}", byte)?;
326        }
327        Ok(())
328    }
329}
330
331impl fmt::LowerHex for HashValue {
332    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
333        for byte in &self.hash {
334            write!(f, "{:02x}", byte)?;
335        }
336        Ok(())
337    }
338}
339
340impl fmt::Debug for HashValue {
341    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
342        write!(f, "HashValue(")?;
343        <Self as fmt::LowerHex>::fmt(self, f)?;
344        write!(f, ")")?;
345        Ok(())
346    }
347}
348
349/// Will print shortened (4 bytes) hash
350impl fmt::Display for HashValue {
351    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
352        for byte in self.hash.iter().take(4) {
353            write!(f, "{:02x}", byte)?;
354        }
355        Ok(())
356    }
357}
358
359impl From<HashValue> for Bytes {
360    fn from(value: HashValue) -> Bytes {
361        Bytes::copy_from_slice(value.hash.as_ref())
362    }
363}
364
365impl FromStr for HashValue {
366    type Err = HashValueParseError;
367
368    fn from_str(s: &str) -> Result<Self, HashValueParseError> {
369        HashValue::from_hex(s)
370    }
371}
372
373/// Parse error when attempting to construct a HashValue
374#[derive(Clone, Copy, Debug)]
375pub struct HashValueParseError;
376
377impl fmt::Display for HashValueParseError {
378    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
379        write!(f, "unable to parse HashValue")
380    }
381}
382
383impl std::error::Error for HashValueParseError {}
384
385/// An iterator over `HashValue` that generates one bit for each iteration.
386pub struct HashValueBitIterator<'a> {
387    /// The reference to the bytes that represent the `HashValue`.
388    hash_bytes: &'a [u8],
389    pos: std::ops::Range<usize>,
390    /* invariant hash_bytes.len() == HashValue::LENGTH;
391     * invariant pos.end == hash_bytes.len() * 8; */
392}
393
394impl<'a> HashValueBitIterator<'a> {
395    /// Constructs a new `HashValueBitIterator` using given `HashValue`.
396    fn new(hash_value: &'a HashValue) -> Self {
397        HashValueBitIterator {
398            hash_bytes: hash_value.as_ref(),
399            pos: (0..HashValue::LENGTH_IN_BITS),
400        }
401    }
402
403    /// Returns the `index`-th bit in the bytes.
404    fn get_bit(&self, index: usize) -> bool {
405        assume!(index < self.pos.end); // assumed precondition
406        assume!(self.hash_bytes.len() == HashValue::LENGTH); // invariant
407        assume!(self.pos.end == self.hash_bytes.len() * 8); // invariant
408        let pos = index / 8;
409        let bit = 7 - index % 8;
410        (self.hash_bytes[pos] >> bit) & 1 != 0
411    }
412}
413
414impl<'a> std::iter::Iterator for HashValueBitIterator<'a> {
415    type Item = bool;
416
417    fn next(&mut self) -> Option<Self::Item> {
418        self.pos.next().map(|x| self.get_bit(x))
419    }
420
421    fn size_hint(&self) -> (usize, Option<usize>) { self.pos.size_hint() }
422}
423
424impl<'a> std::iter::DoubleEndedIterator for HashValueBitIterator<'a> {
425    fn next_back(&mut self) -> Option<Self::Item> {
426        self.pos.next_back().map(|x| self.get_bit(x))
427    }
428}
429
430impl<'a> std::iter::ExactSizeIterator for HashValueBitIterator<'a> {}
431
432/// A type that can be cryptographically hashed to produce a `HashValue`.
433///
434/// In most cases, this trait should not be implemented manually but rather
435/// derived using the macros `serde::Serialize`, `CryptoHasher`, and
436/// `BCSCryptoHash`.
437pub trait CryptoHash {
438    /// The associated `Hasher` type which comes with a unique salt for this
439    /// type.
440    type Hasher: CryptoHasher;
441
442    /// Hashes the object and produces a `HashValue`.
443    fn hash(&self) -> HashValue;
444}
445
446/// A trait for representing the state of a cryptographic hasher.
447pub trait CryptoHasher: Default + std::io::Write {
448    /// the seed used to initialize hashing `Self` before the serialization
449    /// bytes of the actual value
450    fn seed() -> &'static [u8; 32];
451
452    /// Write bytes into the hasher.
453    fn update(&mut self, bytes: &[u8]);
454
455    /// Finish constructing the [`HashValue`].
456    fn finish(self) -> HashValue;
457}
458
459/// The default hasher underlying generated implementations of `CryptoHasher`.
460#[doc(hidden)]
461#[derive(Clone)]
462pub struct DefaultHasher {
463    state: Sha3,
464}
465
466impl DefaultHasher {
467    #[doc(hidden)]
468    /// This function does not return a HashValue in the sense of our usual
469    /// hashes, but a construction of initial bytes that are fed into any hash
470    /// provided we're passed  a (bcs) serialization name as argument.
471    pub fn prefixed_hash(buffer: &[u8]) -> [u8; HashValue::LENGTH] {
472        // The salt is initial material we prefix to actual value bytes for
473        // domain separation. Its length is variable.
474        let salt: Vec<u8> = [DIEM_HASH_PREFIX, buffer].concat();
475        // The seed is a fixed-length hash of the salt, thereby preventing
476        // suffix attacks on the domain separation bytes.
477        HashValue::sha3_256_of(&salt[..]).hash
478    }
479
480    #[doc(hidden)]
481    pub fn new(typename: &[u8]) -> Self {
482        let mut state = Sha3::v256();
483        if !typename.is_empty() {
484            state.update(&Self::prefixed_hash(typename));
485        }
486        DefaultHasher { state }
487    }
488
489    #[doc(hidden)]
490    pub fn update(&mut self, bytes: &[u8]) { self.state.update(bytes); }
491
492    #[doc(hidden)]
493    pub fn finish(self) -> HashValue {
494        let mut hasher = HashValue::default();
495        self.state.finalize(hasher.as_ref_mut());
496        hasher
497    }
498}
499
500impl fmt::Debug for DefaultHasher {
501    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
502        write!(f, "DefaultHasher: state = Sha3")
503    }
504}
505
506macro_rules! define_hasher {
507    (
508        $(#[$attr:meta])*
509        ($hasher_type: ident, $hasher_name: ident, $seed_name: ident, $salt: expr)
510    ) => {
511
512        #[derive(Clone, Debug)]
513        $(#[$attr])*
514        pub struct $hasher_type(DefaultHasher);
515
516        impl $hasher_type {
517            fn new() -> Self {
518                $hasher_type(DefaultHasher::new($salt))
519            }
520        }
521
522        static $hasher_name: Lazy<$hasher_type> = Lazy::new(|| { $hasher_type::new() });
523        static $seed_name: OnceCell<[u8; 32]> = OnceCell::new();
524
525        impl Default for $hasher_type {
526            fn default() -> Self {
527                $hasher_name.clone()
528            }
529        }
530
531        impl CryptoHasher for $hasher_type {
532            fn seed() -> &'static [u8;32] {
533                $seed_name.get_or_init(|| {
534                    DefaultHasher::prefixed_hash($salt)
535                })
536            }
537
538            fn update(&mut self, bytes: &[u8]) {
539                self.0.update(bytes);
540            }
541
542            fn finish(self) -> HashValue {
543                self.0.finish()
544            }
545        }
546
547        impl std::io::Write for $hasher_type {
548            fn write(&mut self, bytes: &[u8]) -> std::io::Result<usize> {
549                self.0.update(bytes);
550                Ok(bytes.len())
551            }
552            fn flush(&mut self) -> std::io::Result<()> {
553                Ok(())
554            }
555        }
556    };
557}
558
559define_hasher! {
560    /// The hasher used to compute the hash of an internal node in the transaction accumulator.
561    (
562        TransactionAccumulatorHasher,
563        TRANSACTION_ACCUMULATOR_HASHER,
564        TRANSACTION_ACCUMULATOR_SEED,
565        b"TransactionAccumulator"
566    )
567}
568
569define_hasher! {
570    /// The hasher used to compute the hash of an internal node in the event accumulator.
571    (
572        EventAccumulatorHasher,
573        EVENT_ACCUMULATOR_HASHER,
574        EVENT_ACCUMULATOR_SEED,
575        b"EventAccumulator"
576    )
577}
578
579define_hasher! {
580    /// The hasher used to compute the hash of an internal node in the Sparse Merkle Tree.
581    (
582        SparseMerkleInternalHasher,
583        SPARSE_MERKLE_INTERNAL_HASHER,
584        SPARSE_MERKLE_INTERNAL_SEED,
585        b"SparseMerkleInternal"
586    )
587}
588
589define_hasher! {
590    /// The hasher used to compute the hash of an internal node in the transaction accumulator.
591    (
592        VoteProposalHasher,
593        VOTE_PROPOSAL_HASHER,
594        VOTE_PROPOSAL_SEED,
595        b"VoteProposalHasher"
596    )
597}
598
599define_hasher! {
600    /// The hasher used only for testing. It doesn't have a salt.
601    (TestOnlyHasher, TEST_ONLY_HASHER, TEST_ONLY_SEED, b"")
602}
603
604fn create_literal_hash(word: &str) -> HashValue {
605    let mut s = word.as_bytes().to_vec();
606    assert!(s.len() <= HashValue::LENGTH);
607    s.resize(HashValue::LENGTH, 0);
608    HashValue::from_slice(&s).expect("Cannot fail")
609}
610
611/// Placeholder hash of `Accumulator`.
612pub static ACCUMULATOR_PLACEHOLDER_HASH: Lazy<HashValue> =
613    Lazy::new(|| create_literal_hash("ACCUMULATOR_PLACEHOLDER_HASH"));
614
615/// Placeholder hash of `SparseMerkleTree`.
616pub static SPARSE_MERKLE_PLACEHOLDER_HASH: Lazy<HashValue> =
617    Lazy::new(|| create_literal_hash("SPARSE_MERKLE_PLACEHOLDER_HASH"));
618
619/// Block id reserved as the id of parent block of the genesis block.
620pub static PRE_GENESIS_BLOCK_ID: Lazy<HashValue> =
621    Lazy::new(|| create_literal_hash("PRE_GENESIS_BLOCK_ID"));
622
623/// Genesis block id is used as a parent of the very first block executed by the
624/// executor.
625pub static GENESIS_BLOCK_ID: Lazy<HashValue> = Lazy::new(|| {
626    // This maintains the invariant that block.id() == block.hash(), for
627    // the genesis block and allows us to (de/)serialize it consistently
628    HashValue::new([
629        0x5e, 0x10, 0xba, 0xd4, 0x5b, 0x35, 0xed, 0x92, 0x9c, 0xd6, 0xd2, 0xc7,
630        0x09, 0x8b, 0x13, 0x5d, 0x02, 0xdd, 0x25, 0x9a, 0xe8, 0x8a, 0x8d, 0x09,
631        0xf4, 0xeb, 0x5f, 0xba, 0xe9, 0xa6, 0xf6, 0xe4,
632    ])
633});
634
635/// Provides a test_only_hash() method that can be used in tests on types that
636/// implement `serde::Serialize`.
637///
638/// # Example
639/// ```
640/// use diem_crypto::hash::TestOnlyHash;
641///
642/// b"hello world".test_only_hash();
643/// ```
644pub trait TestOnlyHash {
645    /// Generates a hash used only for tests.
646    fn test_only_hash(&self) -> HashValue;
647}
648
649impl<T: ser::Serialize + ?Sized> TestOnlyHash for T {
650    fn test_only_hash(&self) -> HashValue {
651        let bytes = bcs::to_bytes(self).expect("serialize failed during hash.");
652        let mut hasher = TestOnlyHasher::default();
653        hasher.update(&bytes);
654        hasher.finish()
655    }
656}