diff --git a/config/Cargo.toml b/config/Cargo.toml index 87d34483e..1ce441310 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -25,7 +25,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -tendermint = { version = "0.28.0", default-features = false, features = ["rust-crypto"], path = "../tendermint" } +tendermint = { version = "0.28.0", default-features = false, path = "../tendermint" } flex-error = { version = "0.4.4", default-features = false } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/light-client-js/Cargo.toml b/light-client-js/Cargo.toml index c87cce77f..bedfe1132 100644 --- a/light-client-js/Cargo.toml +++ b/light-client-js/Cargo.toml @@ -23,7 +23,7 @@ default = ["console_error_panic_hook"] serde = { version = "1.0", default-features = false, features = [ "derive" ] } serde_json = { version = "1.0", default-features = false } tendermint = { version = "0.28.0", default-features = false, path = "../tendermint" } -tendermint-light-client-verifier = { version = "0.28.0", features = ["rust-crypto"], default-features = false, path = "../light-client-verifier" } +tendermint-light-client-verifier = { version = "0.28.0", default-features = false, path = "../light-client-verifier" } wasm-bindgen = { version = "0.2.63", default-features = false, features = [ "serde-serialize" ] } serde-wasm-bindgen = { version = "0.4.5", default-features = false } diff --git a/light-client-js/src/lib.rs b/light-client-js/src/lib.rs index 8b96295ba..9cb6ecc84 100644 --- a/light-client-js/src/lib.rs +++ b/light-client-js/src/lib.rs @@ -15,6 +15,9 @@ use std::time::Duration; use serde::{Deserialize, Serialize}; use tendermint::Time; +// TODO: Use Web Crypto API for cryptographic routines. +// https://github.com/informalsystems/tendermint-rs/issues/1241 +use tendermint_light_client_verifier::ProdVerifier; use tendermint_light_client_verifier::{ options::Options, types::{LightBlock, TrustThreshold}, @@ -22,10 +25,6 @@ use tendermint_light_client_verifier::{ }; use wasm_bindgen::{prelude::*, JsValue}; -// TODO: Use Web Crypto API for cryptographic routines. -// https://github.com/informalsystems/tendermint-rs/issues/1241 -use tendermint_light_client_verifier::ProdVerifier; - /// Check whether a given untrusted block can be trusted. #[wasm_bindgen] pub fn verify(untrusted: JsValue, trusted: JsValue, options: JsValue, now: JsValue) -> JsValue { diff --git a/light-client-verifier/Cargo.toml b/light-client-verifier/Cargo.toml index bde6fd9cb..e14787938 100644 --- a/light-client-verifier/Cargo.toml +++ b/light-client-verifier/Cargo.toml @@ -23,8 +23,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [features] -default = ["rust-crypto", "flex-error/std", "flex-error/eyre_tracer"] -rust-crypto = ["tendermint/rust-crypto"] +default = ["flex-error/std", "flex-error/eyre_tracer"] [dependencies] tendermint = { version = "0.28.0", path = "../tendermint", default-features = false } diff --git a/light-client-verifier/src/lib.rs b/light-client-verifier/src/lib.rs index 79bac7865..ce413cefd 100644 --- a/light-client-verifier/src/lib.rs +++ b/light-client-verifier/src/lib.rs @@ -11,7 +11,4 @@ pub mod predicates; pub mod types; mod verifier; -pub use verifier::{PredicateVerifier, Verdict, Verifier}; - -#[cfg(feature = "rust-crypto")] -pub use verifier::ProdVerifier; +pub use verifier::{PredicateVerifier, ProdVerifier, Verdict, Verifier}; diff --git a/light-client-verifier/src/operations/voting_power.rs b/light-client-verifier/src/operations/voting_power.rs index 442db0510..afb7ee305 100644 --- a/light-client-verifier/src/operations/voting_power.rs +++ b/light-client-verifier/src/operations/voting_power.rs @@ -146,7 +146,7 @@ impl VotingPowerCalculator for ProdVotingPowerCalculator { // Check vote is valid let sign_bytes = signed_vote.sign_bytes(); if validator - .verify_signature(&sign_bytes, signed_vote.signature()) + .verify(&sign_bytes, signed_vote.signature()) .is_err() { return Err(VerificationError::invalid_signature( diff --git a/light-client-verifier/src/predicates.rs b/light-client-verifier/src/predicates.rs index ea437769b..ca2823876 100644 --- a/light-client-verifier/src/predicates.rs +++ b/light-client-verifier/src/predicates.rs @@ -3,7 +3,12 @@ use core::time::Duration; use tendermint::{ - block::Height, chain::Id as ChainId, crypto::Sha256, hash::Hash, merkle::MerkleHash, + block::Height, + chain::Id as ChainId, + crypto::{Sha256, SignatureVerifier}, + hash::Hash, + merkle::MerkleHash, + PublicKey, }; use crate::{ @@ -15,13 +20,12 @@ use crate::{ /// Production predicates, using the default implementation /// of the `VerificationPredicates` trait. -#[cfg(feature = "rust-crypto")] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct ProdPredicates; -#[cfg(feature = "rust-crypto")] impl VerificationPredicates for ProdPredicates { - type Sha256 = tendermint::crypto::default::Sha256; + type Hasher = Sha256; + type SignatureVerifier = PublicKey; } /// Defines the various predicates used to validate and verify light blocks. @@ -32,7 +36,8 @@ impl VerificationPredicates for ProdPredicates { /// have to re-define every predicate. pub trait VerificationPredicates: Send + Sync { /// The implementation of SHA256 digest - type Sha256: MerkleHash + Sha256 + Default; + type Hasher: MerkleHash + Default; + type SignatureVerifier: SignatureVerifier; /// Compare the provided validator_set_hash against the hash produced from hashing the validator /// set. @@ -41,7 +46,7 @@ pub trait VerificationPredicates: Send + Sync { validators: &ValidatorSet, header_validators_hash: Hash, ) -> Result<(), VerificationError> { - let validators_hash = validators.hash_with::(); + let validators_hash = validators.hash_with::(); if header_validators_hash == validators_hash { Ok(()) } else { @@ -58,7 +63,7 @@ pub trait VerificationPredicates: Send + Sync { next_validators: &ValidatorSet, header_next_validators_hash: Hash, ) -> Result<(), VerificationError> { - let next_validators_hash = next_validators.hash_with::(); + let next_validators_hash = next_validators.hash_with::(); if header_next_validators_hash == next_validators_hash { Ok(()) } else { @@ -75,7 +80,7 @@ pub trait VerificationPredicates: Send + Sync { header: &Header, commit_hash: Hash, ) -> Result<(), VerificationError> { - let header_hash = header.hash_with::(); + let header_hash = header.hash_with::(); if header_hash == commit_hash { Ok(()) } else { @@ -226,7 +231,7 @@ pub trait VerificationPredicates: Send + Sync { } } -#[cfg(all(test, feature = "rust-crypto"))] +#[cfg(test)] mod tests { use core::{convert::TryInto, time::Duration}; diff --git a/light-client-verifier/src/verifier.rs b/light-client-verifier/src/verifier.rs index 6bddabe7f..481365ad8 100644 --- a/light-client-verifier/src/verifier.rs +++ b/light-client-verifier/src/verifier.rs @@ -4,18 +4,15 @@ use serde::{Deserialize, Serialize}; use crate::{ errors::{ErrorExt, VerificationError, VerificationErrorDetail}, - operations::{voting_power::VotingPowerTally, CommitValidator, VotingPowerCalculator}, + operations::{ + voting_power::VotingPowerTally, CommitValidator, ProdCommitValidator, + ProdVotingPowerCalculator, VotingPowerCalculator, + }, options::Options, - predicates::VerificationPredicates, + predicates::{ProdPredicates, VerificationPredicates}, types::{Time, TrustedBlockState, UntrustedBlockState}, }; -#[cfg(feature = "rust-crypto")] -use crate::{ - operations::{ProdCommitValidator, ProdVotingPowerCalculator}, - predicates::ProdPredicates, -}; - /// Represents the result of the verification performed by the /// verifier component. #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] @@ -267,7 +264,6 @@ where } } -#[cfg(feature = "rust-crypto")] /// The default production implementation of the [`PredicateVerifier`]. pub type ProdVerifier = PredicateVerifier; diff --git a/light-client/Cargo.toml b/light-client/Cargo.toml index eb0b033ac..95378a976 100644 --- a/light-client/Cargo.toml +++ b/light-client/Cargo.toml @@ -26,13 +26,12 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = ["rpc-client", "flex-error/std", "flex-error/eyre_tracer"] -rpc-client = ["tokio", "rust-crypto", "tendermint-rpc/http-client"] -rust-crypto = ["tendermint/rust-crypto", "tendermint-light-client-verifier/rust-crypto"] +rpc-client = ["tokio", "tendermint-rpc/http-client"] secp256k1 = ["tendermint/secp256k1", "tendermint-rpc/secp256k1"] lightstore-sled = ["sled"] -unstable = ["rust-crypto"] +unstable = [] # Enable to execute long-running model-based tests -mbt = ["rust-crypto"] +mbt = [] [dependencies] tendermint = { version = "0.28.0", path = "../tendermint", default-features = false } diff --git a/light-client/src/builder/light_client.rs b/light-client/src/builder/light_client.rs index 6a0ac3290..c7fca6795 100644 --- a/light-client/src/builder/light_client.rs +++ b/light-client/src/builder/light_client.rs @@ -1,7 +1,11 @@ //! DSL for building a light client [`Instance`] -use tendermint::{block::Height, crypto::Sha256, merkle::MerkleHash, Hash}; - +use tendermint::{ + block::Height, + crypto::{Sha256, SignatureVerifier}, + merkle::MerkleHash, + Hash, PublicKey, +}; #[cfg(feature = "rpc-client")] use { crate::components::clock::SystemClock, @@ -39,26 +43,27 @@ pub struct HasTrustedState; /// Builder for a light client [`Instance`] #[must_use] -pub struct LightClientBuilder { +pub struct LightClientBuilder { peer_id: PeerId, options: Options, io: Box, clock: Box, verifier: Box, scheduler: Box, - predicates: Box>, + predicates: Box>, light_store: Box, #[allow(dead_code)] state: State, } -impl LightClientBuilder +impl LightClientBuilder where - H: MerkleHash + Sha256 + Default, + H: MerkleHash + Default, + S: SignatureVerifier, { /// Private method to move from one state to another - fn with_state(self, state: Next) -> LightClientBuilder { + fn with_state(self, state: Next) -> LightClientBuilder { LightClientBuilder { peer_id: self.peer_id, options: self.options, @@ -73,8 +78,7 @@ where } } -#[cfg(feature = "rpc-client")] -impl LightClientBuilder { +impl LightClientBuilder { /// Initialize a builder for a production (non-mock) light client. pub fn prod( peer_id: PeerId, @@ -96,9 +100,10 @@ impl LightClientBuilder { } } -impl LightClientBuilder +impl LightClientBuilder where - H: MerkleHash + Sha256 + Default, + H: MerkleHash + Default, + S: SignatureVerifier, { /// Initialize a builder for a custom light client, by providing all dependencies upfront. // TODO: redesign this, it's a builder API! @@ -111,7 +116,7 @@ where clock: Box, verifier: Box, scheduler: Box, - predicates: Box>, + predicates: Box>, ) -> Self { Self { peer_id, @@ -130,7 +135,7 @@ where fn trust_light_block( mut self, trusted_state: LightBlock, - ) -> Result, Error> { + ) -> Result, Error> { self.validate(&trusted_state)?; // TODO(liamsi, romac): it is unclear if this should be Trusted or only Verified @@ -141,7 +146,7 @@ where /// Keep using the latest verified or trusted block in the light store. /// Such a block must exists otherwise this will fail. - pub fn trust_from_store(self) -> Result, Error> { + pub fn trust_from_store(self) -> Result, Error> { let trusted_state = self .light_store .highest_trusted_or_verified() @@ -155,7 +160,7 @@ where self, trusted_height: Height, trusted_hash: Hash, - ) -> Result, Error> { + ) -> Result, Error> { let trusted_state = self .io .fetch_light_block(AtHeight::At(trusted_height)) @@ -207,9 +212,10 @@ where } } -impl LightClientBuilder +impl LightClientBuilder where - H: MerkleHash + Sha256 + Default, + H: MerkleHash + Default, + S: SignatureVerifier, { /// Build the light client [`Instance`]. #[must_use] diff --git a/light-client/src/fork_detector.rs b/light-client/src/fork_detector.rs index 1bde5c70c..856eef653 100644 --- a/light-client/src/fork_detector.rs +++ b/light-client/src/fork_detector.rs @@ -68,8 +68,7 @@ pub struct ProvidedForkDetector { _crypto: PhantomData, } -#[cfg(feature = "rust-crypto")] -pub type ProdForkDetector = ProvidedForkDetector; +pub type ProdForkDetector = ProvidedForkDetector; impl ProvidedForkDetector { /// Construct a new fork detector that will use the given header hasher. @@ -88,8 +87,9 @@ impl Default for ProvidedForkDetector { impl ForkDetector for ProvidedForkDetector where - // Sync + Send have to be added only because of forbid(unsafe_code) - H: MerkleHash + Sha256 + Default + Sync + Send, + // Sync + Send have to be added only because of + // forbid(unsafe_code) + H: MerkleHash + Default + Sync + Send, { /// Perform fork detection. See the documentation `ProdForkDetector` for details. fn detect_forks( diff --git a/light-client/src/supervisor.rs b/light-client/src/supervisor.rs index 50dd7f401..dbd9e82df 100644 --- a/light-client/src/supervisor.rs +++ b/light-client/src/supervisor.rs @@ -421,7 +421,7 @@ impl Handle for SupervisorHandle { } } -#[cfg(all(test, feature = "rust-crypto"))] +#[cfg(test)] mod tests { use core::{ convert::{Into, TryFrom}, diff --git a/light-client/src/tests.rs b/light-client/src/tests.rs index 26c9df702..1bde29063 100644 --- a/light-client/src/tests.rs +++ b/light-client/src/tests.rs @@ -1,9 +1,6 @@ //! Utilities and datatypes for use in tests. -use std::collections::HashMap; - -#[cfg(feature = "rust-crypto")] -use std::time::Duration; +use std::{collections::HashMap, time::Duration}; use contracts::contract_trait; use serde::{Deserialize, Serialize}; @@ -24,14 +21,12 @@ use crate::{ evidence::EvidenceReporter, light_client::LightClient, state::State, - verifier::types::{ - Height, LightBlock, PeerId, SignedHeader, Time, TrustThreshold, ValidatorSet, + verifier::{ + types::{Height, LightBlock, PeerId, SignedHeader, Time, TrustThreshold, ValidatorSet}, + Verdict, Verifier, }, }; -#[cfg(feature = "rust-crypto")] -use crate::verifier::{Verdict, Verifier}; - #[derive(Deserialize, Clone, Debug)] pub struct TestCases { pub batch_name: String, @@ -148,7 +143,6 @@ impl MockEvidenceReporter { } } -#[cfg(feature = "rust-crypto")] pub fn verify_single( trusted_block: LightBlock, input: LightBlock, diff --git a/light-client/tests/supervisor.rs b/light-client/tests/supervisor.rs index 293ed9be1..3726cb237 100644 --- a/light-client/tests/supervisor.rs +++ b/light-client/tests/supervisor.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "rust-crypto")] - use std::{collections::HashMap, time::Duration}; use tendermint_light_client::{ diff --git a/rpc/src/endpoint/block_results.rs b/rpc/src/endpoint/block_results.rs index 75f5de739..a753358ee 100644 --- a/rpc/src/endpoint/block_results.rs +++ b/rpc/src/endpoint/block_results.rs @@ -3,8 +3,7 @@ use serde::{Deserialize, Serialize}; use tendermint::{abci, block, consensus, validator}; -use crate::prelude::*; -use crate::serializers; +use crate::{prelude::*, serializers}; /// Get ABCI results at a given height. #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] diff --git a/rpc/src/serializers/tx_hash_base64.rs b/rpc/src/serializers/tx_hash_base64.rs index feded9a5c..9c986a958 100644 --- a/rpc/src/serializers/tx_hash_base64.rs +++ b/rpc/src/serializers/tx_hash_base64.rs @@ -2,9 +2,9 @@ use serde::{Deserialize, Deserializer, Serializer}; use subtle_encoding::base64; +use tendermint::{hash::Algorithm, Hash}; use crate::prelude::*; -use tendermint::{hash::Algorithm, Hash}; /// Deserialize a base64-encoded string into an abci::transaction::Hash pub fn deserialize<'de, D>(deserializer: D) -> Result diff --git a/tendermint/Cargo.toml b/tendermint/Cargo.toml index 5369460a1..3dcbe8451 100644 --- a/tendermint/Cargo.toml +++ b/tendermint/Cargo.toml @@ -50,16 +50,15 @@ tendermint-proto = { version = "0.28.0", default-features = false, path = "../pr time = { version = "0.3", default-features = false, features = ["macros", "parsing"] } zeroize = { version = "1.1", default-features = false, features = ["zeroize_derive", "alloc"] } flex-error = { version = "0.4.4", default-features = false } -sha2 = { version = "0.10", optional = true, default-features = false } +sha2 = { version = "0.10", default-features = false } k256 = { version = "0.11", optional = true, default-features = false, features = ["ecdsa"] } ripemd = { version = "0.1.3", optional = true, default-features = false } [features] -default = ["std", "rust-crypto"] +default = ["std"] std = ["flex-error/std", "flex-error/eyre_tracer", "clock"] clock = ["time/std"] secp256k1 = ["k256", "ripemd"] -rust-crypto = ["sha2"] [dev-dependencies] k256 = { version = "0.11", default-features = false, features = ["ecdsa"] } diff --git a/tendermint/src/abci/event.rs b/tendermint/src/abci/event.rs index 8b69ba2ff..3b852b12c 100644 --- a/tendermint/src/abci/event.rs +++ b/tendermint/src/abci/event.rs @@ -1,7 +1,6 @@ use serde::{Deserialize, Serialize}; -use crate::prelude::*; -use crate::serializers::bytes::base64string; +use crate::{prelude::*, serializers::bytes::base64string}; /// An event that occurred while processing a request. /// diff --git a/tendermint/src/abci/response/check_tx.rs b/tendermint/src/abci/response/check_tx.rs index 3c730d2cf..53ba17276 100644 --- a/tendermint/src/abci/response/check_tx.rs +++ b/tendermint/src/abci/response/check_tx.rs @@ -2,8 +2,7 @@ use bytes::Bytes; use serde::{Deserialize, Serialize}; use super::super::{Code, Event}; -use crate::prelude::*; -use crate::serializers; +use crate::{prelude::*, serializers}; #[doc = include_str!("../doc/response-checktx.md")] #[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)] diff --git a/tendermint/src/abci/response/deliver_tx.rs b/tendermint/src/abci/response/deliver_tx.rs index 864461adf..1a034b6ec 100644 --- a/tendermint/src/abci/response/deliver_tx.rs +++ b/tendermint/src/abci/response/deliver_tx.rs @@ -2,8 +2,7 @@ use bytes::Bytes; use serde::{Deserialize, Serialize}; use super::super::{Code, Event}; -use crate::prelude::*; -use crate::serializers; +use crate::{prelude::*, serializers}; #[doc = include_str!("../doc/response-delivertx.md")] #[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)] diff --git a/tendermint/src/abci/response/info.rs b/tendermint/src/abci/response/info.rs index b19705599..4d4136e8a 100644 --- a/tendermint/src/abci/response/info.rs +++ b/tendermint/src/abci/response/info.rs @@ -1,9 +1,9 @@ -use crate::{block, prelude::*, AppHash, Error}; use core::convert::TryFrom; -use tendermint_proto::abci as pb; -use tendermint_proto::Protobuf; use serde::{Deserialize, Serialize}; +use tendermint_proto::{abci as pb, Protobuf}; + +use crate::{block, prelude::*, AppHash, Error}; #[doc = include_str!("../doc/response-info.md")] #[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)] diff --git a/tendermint/src/abci/response/init_chain.rs b/tendermint/src/abci/response/init_chain.rs index 0dc360c0b..6d5668b4f 100644 --- a/tendermint/src/abci/response/init_chain.rs +++ b/tendermint/src/abci/response/init_chain.rs @@ -1,6 +1,4 @@ -use crate::AppHash; - -use crate::{consensus, prelude::*, validator}; +use crate::{consensus, prelude::*, validator, AppHash}; #[doc = include_str!("../doc/response-initchain.md")] #[derive(Clone, PartialEq, Eq, Debug, Default)] diff --git a/tendermint/src/abci/response/set_option.rs b/tendermint/src/abci/response/set_option.rs index 028eafde5..6e216cdb8 100644 --- a/tendermint/src/abci/response/set_option.rs +++ b/tendermint/src/abci/response/set_option.rs @@ -1,5 +1,4 @@ -use crate::abci::Code; -use crate::prelude::*; +use crate::{abci::Code, prelude::*}; #[doc = include_str!("../doc/response-setoption.md")] #[derive(Clone, PartialEq, Eq, Debug)] diff --git a/tendermint/src/account.rs b/tendermint/src/account.rs index 6ce369a59..3691f0935 100644 --- a/tendermint/src/account.rs +++ b/tendermint/src/account.rs @@ -81,21 +81,20 @@ impl Debug for Id { } } -#[cfg(feature = "rust-crypto")] mod key_conversions { + use digest::Digest; + use sha2::Sha256; + use super::{Id, LENGTH}; - use crate::crypto::default::Sha256; #[cfg(feature = "secp256k1")] use crate::public_key::Secp256k1; use crate::public_key::{Ed25519, PublicKey}; - use digest::Digest; // RIPEMD160(SHA256(pk)) #[cfg(feature = "secp256k1")] impl From for Id { fn from(pk: Secp256k1) -> Id { use ripemd::Ripemd160; - let sha_digest = Sha256::digest(pk.to_bytes()); let ripemd_digest = Ripemd160::digest(&sha_digest[..]); let mut bytes = [0u8; LENGTH]; diff --git a/tendermint/src/block/header.rs b/tendermint/src/block/header.rs index ad747134b..837562674 100644 --- a/tendermint/src/block/header.rs +++ b/tendermint/src/block/header.rs @@ -8,11 +8,8 @@ use tendermint_proto::{ }; use crate::{ - account, block, chain, - crypto::Sha256, - merkle::{self, MerkleHash}, - prelude::*, - AppHash, Error, Hash, Time, + account, block, chain, crypto::Sha256, merkle::MerkleHash, prelude::*, AppHash, Error, Hash, + Time, }; /// Block `Header` values contain metadata about the block and about the @@ -168,15 +165,14 @@ impl From
for RawHeader { impl Header { /// Computes the hash of this header. - #[cfg(feature = "rust-crypto")] pub fn hash(&self) -> Hash { - self.hash_with::() + self.hash_with::() } /// Hash this header with a Merkle hasher provided by a crypto provider. pub fn hash_with(&self) -> Hash where - H: MerkleHash + Sha256 + Default, + H: MerkleHash + Default, { // Note that if there is an encoding problem this will // panic (as the golang code would): @@ -206,7 +202,7 @@ impl Header { self.proposer_address.encode_vec().unwrap(), ]; - Hash::Sha256(merkle::simple_hash_from_byte_vectors::(&fields_bytes)) + Hash::Sha256(H::hash_byte_vectors(&mut H::default(), &fields_bytes)) } } @@ -254,23 +250,20 @@ mod tests { test_serialization_roundtrip::
(json_data); } - #[cfg(feature = "rust-crypto")] - mod crypto { - use super::*; - use crate::{hash::Algorithm, Hash}; - - #[test] - fn header_hashing() { - let expected_hash = Hash::from_hex_upper( - Algorithm::Sha256, - "F30A71F2409FB15AACAEDB6CC122DFA2525BEE9CAE521721B06BFDCA291B8D56", - ) - .unwrap(); - let header: Header = serde_json::from_str(include_str!( - "../../tests/support/serialization/block/header_with_known_hash.json" - )) - .unwrap(); - assert_eq!(expected_hash, header.hash()); - } + use super::*; + use crate::{hash::Algorithm, Hash}; + + #[test] + fn header_hashing() { + let expected_hash = Hash::from_hex_upper( + Algorithm::Sha256, + "F30A71F2409FB15AACAEDB6CC122DFA2525BEE9CAE521721B06BFDCA291B8D56", + ) + .unwrap(); + let header: Header = serde_json::from_str(include_str!( + "../../tests/support/serialization/block/header_with_known_hash.json" + )) + .unwrap(); + assert_eq!(expected_hash, header.hash()); } } diff --git a/tendermint/src/crypto.rs b/tendermint/src/crypto.rs index ef578e1b4..8d968ba50 100644 --- a/tendermint/src/crypto.rs +++ b/tendermint/src/crypto.rs @@ -7,8 +7,34 @@ //! The abstract framework enabling this extensibility is provided by the //! `digest` and `signature` crates. -pub mod sha256; -pub use sha256::Sha256; +use crate::{Error, Signature}; +/// Length of a SHA256 hash in bytes. +pub const HASH_SIZE: usize = 32; -#[cfg(feature = "rust-crypto")] -pub mod default; +/// An interface to allow digesting arbitrary byte slices. +/// +/// This trait provides the most general possible interface that can be +/// implemented by host functions in popular on-chain smart contract +/// environments. As such, in can only do one-piece slice digests. +pub trait Hasher: Send + Sync { + fn digest(data: impl AsRef<[u8]>) -> [u8; HASH_SIZE]; +} + +/// The default implementation of the [`Hasher`][Hashertrait] trait. +/// +/// [Hashertrait]: super::Hasher +pub use sha2::Sha256; + +/// A SHA256 digest implementation. +impl Hasher for Sha256 { + fn digest(data: impl AsRef<[u8]>) -> [u8; HASH_SIZE] { + let mut hash_bytes = [0u8; HASH_SIZE]; + hash_bytes.copy_from_slice(&data.as_ref()); + hash_bytes + } +} + +/// An interface to allow verifying signatures. +pub trait SignatureVerifier: Send + Sync { + fn verify(&self, sign_bytes: &[u8], signature: &Signature) -> Result<(), Error>; +} diff --git a/tendermint/src/crypto/default.rs b/tendermint/src/crypto/default.rs deleted file mode 100644 index 81ba318f1..000000000 --- a/tendermint/src/crypto/default.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! Pure Rust implementations of the cryptographic traits. -//! -//! Most applications using this crate should use these implementations. -//! Alternative implementations can be useful on targets like wasm and -//! on-chain environments, where code size is at a premium and a faster -//! platform-native cryptographic API is available. - -use super::sha256::HASH_SIZE; -use digest::Digest; - -/// The default implementation of the [`Sha256`][sha256trait] trait. -/// -/// [sha256trait]: super::Sha256 -pub use sha2::Sha256; - -impl super::Sha256 for Sha256 { - fn digest(data: impl AsRef<[u8]>) -> [u8; HASH_SIZE] { - let digest = ::digest(data); - // copy the GenericArray out - let mut hash = [0u8; HASH_SIZE]; - hash.copy_from_slice(&digest); - hash - } -} - -/// Types implementing the ECDSA algorithm using the Secp256k1 elliptic curve. -#[cfg(feature = "secp256k1")] -pub mod ecdsa_secp256k1 { - pub use k256::ecdsa::{Signature, SigningKey, VerifyingKey}; -} diff --git a/tendermint/src/crypto/sha256.rs b/tendermint/src/crypto/sha256.rs deleted file mode 100644 index e4e2a4357..000000000 --- a/tendermint/src/crypto/sha256.rs +++ /dev/null @@ -1,11 +0,0 @@ -/// Length of a SHA256 hash in bytes. -pub const HASH_SIZE: usize = 32; - -/// A SHA256 digest implementation. -/// -/// This trait provides the most general possible interface that can be -/// implemented by host functions in popular on-chain smart contract -/// environments. As such, in can only do one-piece slice digests. -pub trait Sha256 { - fn digest(data: impl AsRef<[u8]>) -> [u8; HASH_SIZE]; -} diff --git a/tendermint/src/merkle.rs b/tendermint/src/merkle.rs index 44611189e..d66a0e3df 100644 --- a/tendermint/src/merkle.rs +++ b/tendermint/src/merkle.rs @@ -1,35 +1,18 @@ //! Merkle tree used in Tendermint networks pub mod proof; - -pub use proof::Proof; - -use core::marker::PhantomData; - use digest::{consts::U32, Digest, FixedOutputReset}; - -use crate::crypto::Sha256; -use crate::prelude::*; +pub use proof::Proof; /// Size of Merkle root hash -pub use crate::crypto::sha256::HASH_SIZE; +pub use crate::crypto::HASH_SIZE; +use crate::{crypto::Hasher, prelude::*}; /// Hash is the output of the cryptographic digest function pub type Hash = [u8; HASH_SIZE]; -/// Compute a simple Merkle root from vectors of arbitrary byte vectors. -/// The leaves of the tree are the bytes of the given byte vectors in -/// the given order. -pub fn simple_hash_from_byte_vectors(byte_vecs: &[Vec]) -> Hash -where - H: MerkleHash + Default, -{ - let mut hasher = H::default(); - hasher.hash_byte_vectors(byte_vecs) -} - /// Implementation of Merkle tree hashing for Tendermint. -pub trait MerkleHash { +pub trait MerkleHash: Hasher { // tmhash({}) // Pre and post-conditions: the hasher is in the reset state // before and after calling this function. @@ -63,21 +46,15 @@ pub trait MerkleHash { } } -// A helper to copy GenericArray into the human-friendly Hash type. -fn copy_to_hash(output: impl AsRef<[u8]>) -> Hash { - let mut hash_bytes = [0u8; HASH_SIZE]; - hash_bytes.copy_from_slice(output.as_ref()); - hash_bytes -} - +/// A Blanket implementation of MerkleHash for any Digest impl MerkleHash for H where - H: Digest + FixedOutputReset, + H: Digest + FixedOutputReset + Hasher, { fn empty_hash(&mut self) -> Hash { // Get the output of an empty digest state. let digest = self.finalize_reset(); - copy_to_hash(digest) + ::digest(digest) } fn leaf_hash(&mut self, bytes: &[u8]) -> Hash { @@ -87,8 +64,7 @@ where // Finalize the digest, reset the hasher state. let digest = self.finalize_reset(); - - copy_to_hash(digest) + ::digest(digest) } fn inner_hash(&mut self, left: Hash, right: Hash) -> Hash { @@ -99,53 +75,15 @@ where // Finalize the digest, reset the hasher state let digest = self.finalize_reset(); - - copy_to_hash(digest) - } -} - -/// A wrapper for platform-provided host functions which can't do incremental -/// hashing. One unfortunate example of such platform is Polkadot. -pub struct NonIncremental(PhantomData); - -impl Default for NonIncremental { - fn default() -> Self { - Self(Default::default()) + ::digest(digest) } } - -impl MerkleHash for NonIncremental { - fn empty_hash(&mut self) -> Hash { - let digest = H::digest([]); - copy_to_hash(digest) - } - - fn leaf_hash(&mut self, bytes: &[u8]) -> Hash { - // This is why non-incremental digest APIs are daft. - let mut buf = Vec::with_capacity(1 + bytes.len()); - buf.push(0); - buf.extend_from_slice(bytes); - let digest = H::digest(buf); - copy_to_hash(digest) - } - - fn inner_hash(&mut self, left: Hash, right: Hash) -> Hash { - // This is why non-incremental digest APIs are daft. - let mut buf = [0u8; 1 + HASH_SIZE * 2]; - buf[0] = 1; - buf[1..HASH_SIZE + 1].copy_from_slice(&left); - buf[HASH_SIZE + 1..].copy_from_slice(&right); - let digest = H::digest(buf); - copy_to_hash(digest) - } -} - -#[cfg(all(test, feature = "rust-crypto"))] +#[cfg(test)] mod tests { - use sha2::Sha256; use subtle_encoding::hex; - use super::*; // TODO: use non-subtle ? + use super::*; + use crate::crypto::Sha256; // TODO: use non-subtle ? #[test] fn test_rfc6962_empty_tree() { @@ -154,7 +92,7 @@ mod tests { let empty_tree_root = &hex::decode(empty_tree_root_hex).unwrap(); let empty_tree: Vec> = vec![vec![]; 0]; - let root = simple_hash_from_byte_vectors::(&empty_tree); + let root = Sha256::default().hash_byte_vectors(&empty_tree); assert_eq!(empty_tree_root, &root); } @@ -165,7 +103,7 @@ mod tests { let empty_leaf_root = &hex::decode(empty_leaf_root_hex).unwrap(); let one_empty_leaf: Vec> = vec![vec![]; 1]; - let root = simple_hash_from_byte_vectors::(&one_empty_leaf); + let root = Sha256::default().hash_byte_vectors(&one_empty_leaf); assert_eq!(empty_leaf_root, &root); } @@ -177,7 +115,7 @@ mod tests { let leaf_root = &hex::decode(leaf_root_hex).unwrap(); let leaf_tree: Vec> = vec![leaf_string.as_bytes().to_vec(); 1]; - let root = simple_hash_from_byte_vectors::(&leaf_tree); + let root = Sha256::default().hash_byte_vectors(&leaf_tree); assert_eq!(leaf_root, &root); } @@ -188,22 +126,7 @@ mod tests { let right = b"N456".to_vec(); let node_hash = &hex::decode(node_hash_hex).unwrap(); - let hash = simple_hash_from_byte_vectors::(&[left, right]); + let hash = Sha256::default().hash_byte_vectors(&[left, right]); assert_eq!(node_hash, &hash); } - - mod non_incremental { - use super::*; - - #[test] - fn test_rfc6962_tree_of_2() { - let node_hash_hex = "dc9a0536ff2e196d5a628a5bf377ab247bbddf83342be39699461c1e766e6646"; - let left = b"N123".to_vec(); - let right = b"N456".to_vec(); - - let node_hash = &hex::decode(node_hash_hex).unwrap(); - let hash = simple_hash_from_byte_vectors::>(&[left, right]); - assert_eq!(node_hash, &hash); - } - } } diff --git a/tendermint/src/node/id.rs b/tendermint/src/node/id.rs index 45117134f..24f2463ea 100644 --- a/tendermint/src/node/id.rs +++ b/tendermint/src/node/id.rs @@ -58,13 +58,15 @@ impl Debug for Id { } } -#[cfg(feature = "rust-crypto")] mod key_conversions { - use super::{Id, LENGTH}; - use crate::crypto::default::Sha256; - use crate::public_key::{Ed25519, PublicKey}; - use crate::Error; use digest::Digest; + use sha2::Sha256; + + use super::{Id, LENGTH}; + use crate::{ + public_key::{Ed25519, PublicKey}, + Error, + }; impl From for Id { fn from(pk: Ed25519) -> Id { diff --git a/tendermint/src/public_key.rs b/tendermint/src/public_key.rs index 5b39e5040..8c7907a80 100644 --- a/tendermint/src/public_key.rs +++ b/tendermint/src/public_key.rs @@ -1,9 +1,8 @@ //! Public keys used in Tendermint networks -pub use ed25519_dalek::PublicKey as Ed25519; +pub use ed25519_dalek::{PublicKey as Ed25519, Verifier}; #[cfg(feature = "secp256k1")] -pub use k256::ecdsa::VerifyingKey as Secp256k1; - +pub use k256::ecdsa::{VerifyingKey as Secp256k1, VerifyingKey}; mod pub_key_request; mod pub_key_response; use core::{cmp::Ordering, convert::TryFrom, fmt, ops::Deref, str::FromStr}; @@ -12,14 +11,13 @@ pub use pub_key_request::PubKeyRequest; pub use pub_key_response::PubKeyResponse; use serde::{de, ser, Deserialize, Deserializer, Serialize}; use serde_json::Value; -use signature::Verifier as _; use subtle_encoding::{base64, bech32, hex}; use tendermint_proto::{ crypto::{public_key::Sum, PublicKey as RawPublicKey}, Protobuf, }; -use crate::{error::Error, prelude::*, signature::Signature}; +use crate::{crypto::SignatureVerifier, error::Error, prelude::*, Signature}; // Note:On the golang side this is generic in the sense that it could everything that implements // github.com/tendermint/tendermint/crypto.PubKey @@ -192,39 +190,6 @@ impl PublicKey { } } - /// Verify the given [`Signature`] using this public key - pub fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), Error> { - match self { - PublicKey::Ed25519(pk) => { - match ed25519_dalek::Signature::try_from(signature.as_bytes()) { - Ok(sig) => pk.verify(msg, &sig).map_err(|_| { - Error::signature_invalid( - "Ed25519 signature verification failed".to_string(), - ) - }), - Err(e) => Err(Error::signature_invalid(format!( - "invalid Ed25519 signature: {}", - e - ))), - } - }, - #[cfg(feature = "secp256k1")] - PublicKey::Secp256k1(pk) => { - match k256::ecdsa::Signature::try_from(signature.as_bytes()) { - Ok(sig) => pk.verify(msg, &sig).map_err(|_| { - Error::signature_invalid( - "Secp256k1 signature verification failed".to_string(), - ) - }), - Err(e) => Err(Error::signature_invalid(format!( - "invalid Secp256k1 signature: {}", - e - ))), - } - }, - } - } - /// Serialize this key as a byte vector. pub fn to_bytes(self) -> Vec { match self { @@ -258,6 +223,41 @@ impl PublicKey { } } +impl SignatureVerifier for PublicKey { + /// Verify the given [`Signature`] using this public key + fn verify(&self, sign_bytes: &[u8], signature: &Signature) -> Result<(), Error> { + match self { + PublicKey::Ed25519(pk) => { + match ed25519_dalek::Signature::try_from(signature.as_bytes()) { + Ok(sig) => pk.verify(sign_bytes, &sig).map_err(|_| { + Error::signature_invalid( + "Ed25519 signature verification failed".to_string(), + ) + }), + Err(e) => Err(Error::signature_invalid(format!( + "invalid Ed25519 signature: {}", + e + ))), + } + }, + #[cfg(feature = "secp256k1")] + PublicKey::Secp256k1(pk) => { + match k256::ecdsa::Signature::try_from(signature.as_bytes()) { + Ok(sig) => pk.verify(sign_bytes, &sig).map_err(|_| { + Error::signature_invalid( + "Secp256k1 signature verification failed".to_string(), + ) + }), + Err(e) => Err(Error::signature_invalid(format!( + "invalid Secp256k1 signature: {}", + e + ))), + } + }, + } + } +} + impl From for PublicKey { fn from(pk: Ed25519) -> PublicKey { PublicKey::Ed25519(pk) @@ -440,13 +440,13 @@ where #[cfg(test)] mod tests { - use core::convert::TryFrom; - use subtle_encoding::hex; use tendermint_proto::Protobuf; - use super::{PublicKey, Signature, TendermintKey}; - use crate::{prelude::*, public_key::PubKeyResponse}; + use super::{PublicKey, TendermintKey}; + use crate::{ + crypto::SignatureVerifier, prelude::*, public_key::PubKeyResponse, signature::Signature, + }; const EXAMPLE_CONSENSUS_KEY: &str = "4A25C6640A1F72B9C975338294EF51B6D1C33158BB6ECBA69FBC3FB5A33C9DCE"; diff --git a/tendermint/src/tx/proof.rs b/tendermint/src/tx/proof.rs index 7d8abfa7a..5190308bd 100644 --- a/tendermint/src/tx/proof.rs +++ b/tendermint/src/tx/proof.rs @@ -1,6 +1,5 @@ use serde::{Deserialize, Serialize}; -use tendermint_proto::types::TxProof as RawTxProof; -use tendermint_proto::Protobuf; +use tendermint_proto::{types::TxProof as RawTxProof, Protobuf}; use crate::{merkle, prelude::*, Error, Hash}; diff --git a/tendermint/src/validator.rs b/tendermint/src/validator.rs index 60eb79c37..2ef535684 100644 --- a/tendermint/src/validator.rs +++ b/tendermint/src/validator.rs @@ -2,6 +2,9 @@ use core::convert::{TryFrom, TryInto}; +pub use ed25519_dalek::PublicKey as Ed25519; +#[cfg(feature = "secp256k1")] +pub use k256::ecdsa::VerifyingKey as Secp256k1; use serde::{Deserialize, Serialize}; use tendermint_proto::{ abci::ValidatorUpdate as RawValidatorUpdate, @@ -13,13 +16,8 @@ use tendermint_proto::{ }; use crate::{ - account, - crypto::Sha256, - hash::Hash, - merkle::{self, MerkleHash}, - prelude::*, - public_key::deserialize_public_key, - vote, Error, PublicKey, Signature, + account, crypto::SignatureVerifier, hash::Hash, merkle::MerkleHash, prelude::*, + public_key::deserialize_public_key, vote, Error, PublicKey, Signature, }; /// Validator set contains a vector of validators @@ -140,15 +138,14 @@ impl Set { } /// Compute the hash of this validator set. - #[cfg(feature = "rust-crypto")] pub fn hash(&self) -> Hash { - self.hash_with::() + self.hash_with::() } /// Hash this header with a SHA256 hasher provided by a crypto provider. pub fn hash_with(&self) -> Hash where - H: MerkleHash + Sha256 + Default, + H: MerkleHash + Default, { let validator_bytes: Vec> = self .validators() @@ -156,7 +153,7 @@ impl Set { .map(|validator| validator.hash_bytes()) .collect(); - Hash::Sha256(merkle::simple_hash_from_byte_vectors::(&validator_bytes)) + Hash::Sha256(H::hash_byte_vectors(&mut H::default(), &validator_bytes)) } } @@ -212,18 +209,6 @@ impl From for RawValidator { } impl Info { - /// Return the voting power of the validator. - pub fn power(&self) -> u64 { - self.power.value() - } - - /// Verify the given signature against the given sign_bytes using the validators - /// public key. - pub fn verify_signature(&self, sign_bytes: &[u8], signature: &Signature) -> Result<(), Error> { - self.pub_key.verify(sign_bytes, signature) - } - - #[cfg(feature = "rust-crypto")] /// Create a new validator. pub fn new(pk: PublicKey, vp: vote::Power) -> Info { Info { @@ -234,6 +219,26 @@ impl Info { proposer_priority: ProposerPriority::default(), } } + + /// Return the voting power of the validator. + pub fn power(&self) -> u64 { + self.power.value() + } + + pub fn verify(&self, sign_bytes: &[u8], signature: &Signature) -> Result<(), Error> { + Self::verify_with::(&self.pub_key, sign_bytes, signature) + } + + pub fn verify_with( + pub_key: &S, + sign_bytes: &[u8], + signature: &Signature, + ) -> Result<(), Error> + where + S: SignatureVerifier, + { + S::verify(&pub_key, sign_bytes, signature) + } } /// SimpleValidator is the form of the validator used for computing the Merkle tree. @@ -367,7 +372,6 @@ impl TryFrom for Update { mod tests { use super::*; - #[cfg(feature = "rust-crypto")] mod crypto { use super::*; @@ -387,27 +391,29 @@ mod tests { // "strings" // ) // func testValSet() { - // pk1 := ed25519.GenPrivKeyFromSecret([]byte{4, 211, 14, 157, 10, 0, 205, 9, 10, 116, 207, - // 161, 4, 211, 190, 37, 108, 88, 202, 168, 63, 135, 0, 141, 53, 55, 254, 57, 40, 184, 20, - // 242}) pk2 := ed25519.GenPrivKeyFromSecret([]byte{99, 231, 126, 151, 159, 236, 2, - // 229, 33, 44, 200, 248, 147, 176, 13, 127, 105, 76, 49, 83, 25, 101, 44, 57, 20, 215, 166, - // 188, 134, 94, 56, 165}) pk3 := ed25519.GenPrivKeyFromSecret([]byte{54, 253, 151, - // 16, 182, 114, 125, 12, 74, 101, 54, 253, 174, 153, 121, 74, 145, 180, 111, 16, 214, 48, + // pk1 := ed25519.GenPrivKeyFromSecret([]byte{4, 211, 14, 157, 10, 0, 205, 9, 10, 116, + // 207, 161, 4, 211, 190, 37, 108, 88, 202, 168, 63, 135, 0, 141, 53, 55, + // 254, 57, 40, 184, 20, 242}) pk2 := + // ed25519.GenPrivKeyFromSecret([]byte{99, 231, 126, 151, 159, 236, 2, + // 229, 33, 44, 200, 248, 147, 176, 13, 127, 105, 76, 49, 83, 25, 101, 44, 57, 20, 215, + // 166, 188, 134, 94, 56, 165}) pk3 := + // ed25519.GenPrivKeyFromSecret([]byte{54, 253, 151, 16, 182, 114, 125, 12, + // 74, 101, 54, 253, 174, 153, 121, 74, 145, 180, 111, 16, 214, 48, // 193, 109, 104, 134, 55, 162, 151, 16, 182, 114}) not_in_set := - // ed25519.GenPrivKeyFromSecret([]byte{121, 74, 145, 180, 111, 16, 214, 48, 193, 109, 35, - // 68, 19, 27, 173, 69, 92, 204, 127, 218, 234, 81, 232, 75, 204, 199, 48, 163, 55, 132, - // 231, 147}) fmt.Println("pk1: ", strings.Join(strings.Split(fmt.Sprintf("%v", - // pk1.PubKey().Bytes()), " "), ", ")) fmt.Println("pk2:", - // strings.Join(strings.Split(fmt.Sprintf("%v", pk2.PubKey().Bytes()), " "), ", ")) - // fmt.Println("pk3: ", strings.Join(strings.Split(fmt.Sprintf("%v", pk3.PubKey().Bytes()), - // " "), ", ")) fmt.Println("not_in_set: ", - // strings.Join(strings.Split(fmt.Sprintf("%v", not_in_set.PubKey().Bytes()), " "), ", ")) - // v1 := types.NewValidator(pk1.PubKey(), 148151478422287875) - // v2 := types.NewValidator(pk2.PubKey(), 158095448483785107) - // v3 := types.NewValidator(pk3.PubKey(), 770561664770006272) - // set := types.NewValidatorSet([]*types.Validator{v1, v2, v3}) - // fmt.Println("Hash:", strings.Join(strings.Split(fmt.Sprintf("%v", set.Hash()), " "), ", - // ")) } + // ed25519.GenPrivKeyFromSecret([]byte{121, 74, 145, 180, 111, 16, 214, 48, 193, 109, + // 35, 68, 19, 27, 173, 69, 92, 204, 127, 218, 234, 81, 232, 75, 204, 199, + // 48, 163, 55, 132, 231, 147}) fmt.Println("pk1: ", + // strings.Join(strings.Split(fmt.Sprintf("%v", pk1.PubKey().Bytes()), " "), + // ", ")) fmt.Println("pk2:", strings.Join(strings.Split(fmt.Sprintf("%v", + // pk2.PubKey().Bytes()), " "), ", ")) fmt.Println("pk3: ", + // strings.Join(strings.Split(fmt.Sprintf("%v", pk3.PubKey().Bytes()), " "), + // ", ")) fmt.Println("not_in_set: ", strings.Join(strings.Split(fmt. + // Sprintf("%v", not_in_set.PubKey().Bytes()), " "), ", ")) v1 := types. + // NewValidator(pk1.PubKey(), 148151478422287875) v2 := types. + // NewValidator(pk2.PubKey(), 158095448483785107) v3 := types. + // NewValidator(pk3.PubKey(), 770561664770006272) set := types. + // NewValidatorSet([]*types.Validator{v1, v2, v3}) fmt.Println("Hash:", + // strings.Join(strings.Split(fmt.Sprintf("%v", set.Hash()), " "), ", ")) } let v1 = make_validator( vec![ 48, 163, 55, 132, 231, 147, 230, 163, 56, 158, 127, 218, 179, 139, 212, 103, diff --git a/tendermint/tests/alt_crypto.rs b/tendermint/tests/alt_crypto.rs index 462525e60..05f322154 100644 --- a/tendermint/tests/alt_crypto.rs +++ b/tendermint/tests/alt_crypto.rs @@ -1,12 +1,10 @@ //! An imitation of alternative cryptographic function implementations //! for a chain environment that provides its own cryptographic API. -use tendermint::crypto::{sha256::HASH_SIZE, Sha256}; - use digest::Digest; -use signature::{self, DigestSigner, DigestVerifier, Signature, Signer, Verifier}; - use k256::ecdsa::{SigningKey, VerifyingKey}; +use signature::{self, DigestSigner, DigestVerifier, Signature, Signer, Verifier}; +use tendermint::crypto::{Hasher, Sha256, HASH_SIZE}; #[derive(Debug, Default)] struct SubstrateSha256(sha2::Sha256); @@ -68,18 +66,21 @@ impl Verifier for SubstrateSignatureVerifier { } } -impl Sha256 for SubstrateSha256 { +impl Hasher for SubstrateSha256 { fn digest(data: impl AsRef<[u8]>) -> [u8; HASH_SIZE] { - ::digest(data) + let digest = ::digest(data); + let mut hash_bytes = [0u8; HASH_SIZE]; + hash_bytes.copy_from_slice(&digest); + hash_bytes } } mod tests { - use super::{SubstrateSha256, SubstrateSignatureVerifier, SubstrateSigner}; use signature::{Signature, Signer, Verifier}; - use tendermint::crypto::Sha256; - use subtle_encoding::hex; + use tendermint::crypto::Hasher; + + use super::{SubstrateSha256, SubstrateSignatureVerifier, SubstrateSigner}; #[test] fn sha256_can_hash() {