Skip to content

Commit

Permalink
Add ripemd family of hashes (#226)
Browse files Browse the repository at this point in the history
* add ripemd family of hashes

* revert accidental core2 dep change

* rustfmt

* add ripemd tests
- removes it from default features,
- adds a simple helper function for writing new tests (generating multihashes out of band)

* rustfmt

* fix clippy warnings

* CI i stg just let me make a PR, rustfmt

* move util to examples
  • Loading branch information
mriise authored Aug 10, 2022
1 parent 1100d98 commit f805963
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 12 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ sha1 = ["digest", "sha-1"]
sha2 = ["digest", "sha-2"]
sha3 = ["digest", "sha-3"]
strobe = ["strobe-rs"]
ripemd = ["ripemd-rs"]

[dependencies]
parity-scale-codec = { version = "3.0.0", default-features = false, features = ["derive"], optional = true }
Expand All @@ -51,6 +52,7 @@ sha-1 = { version = "0.10.0", default-features = false, optional = true }
sha-2 = { version = "0.10.0", default-features = false, optional = true, package = "sha2" }
sha-3 = { version = "0.10.0", default-features = false, optional = true, package = "sha3" }
strobe-rs = { version = "0.7.0", default-features = false, optional = true }
ripemd-rs = { package = "ripemd", version = "0.1.1", optional = true}

core2 = { version = "0.4.0", default-features = false }

Expand Down
24 changes: 24 additions & 0 deletions examples/manual_mh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use multihash::{Code, MultihashDigest};

/// prefix/multihash generating tool to aid when adding new tests
fn prefix_util() {
use unsigned_varint::encode;
// change these as needed
let empty = Code::Sha2_256.wrap(&[]).unwrap().to_bytes();
let hash = "7c8357577f51d4f0a8d393aa1aaafb28863d9421";

// encode things
let len = (hash.len() / 2) as u64; // always hex so len bytes is always half
let mut buf = encode::u64_buffer();
let len = encode::u64(len, &mut buf);

let code_hex = hex::encode(&empty[..1]); // change if longer/shorter prefix
let len_hex = hex::encode(len);
println!("prefix hex: code: {}, len: {}", code_hex, len_hex);

println!("{}{}{}", code_hex, len_hex, hash);
}

fn main() {
prefix_util()
}
34 changes: 22 additions & 12 deletions src/hasher_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ pub mod blake3 {
}

#[cfg(feature = "digest")]
macro_rules! derive_hasher_sha {
macro_rules! derive_rustcrypto_hasher {
($module:ty, $name:ident, $size:expr) => {
/// Multihash hasher.
#[derive(Debug)]
Expand Down Expand Up @@ -200,30 +200,40 @@ macro_rules! derive_hasher_sha {
pub mod sha1 {
use super::*;

derive_hasher_sha!(::sha1::Sha1, Sha1, 20);
derive_rustcrypto_hasher!(::sha1::Sha1, Sha1, 20);
}

#[cfg(feature = "sha2")]
pub mod sha2 {
use super::*;

derive_hasher_sha!(sha_2::Sha256, Sha2_256, 32);
derive_hasher_sha!(sha_2::Sha512, Sha2_512, 64);
derive_rustcrypto_hasher!(sha_2::Sha256, Sha2_256, 32);
derive_rustcrypto_hasher!(sha_2::Sha512, Sha2_512, 64);
}

#[cfg(feature = "sha3")]
pub mod sha3 {
use super::*;

derive_hasher_sha!(sha_3::Sha3_224, Sha3_224, 28);
derive_hasher_sha!(sha_3::Sha3_256, Sha3_256, 32);
derive_hasher_sha!(sha_3::Sha3_384, Sha3_384, 48);
derive_hasher_sha!(sha_3::Sha3_512, Sha3_512, 64);
derive_rustcrypto_hasher!(sha_3::Sha3_224, Sha3_224, 28);
derive_rustcrypto_hasher!(sha_3::Sha3_256, Sha3_256, 32);
derive_rustcrypto_hasher!(sha_3::Sha3_384, Sha3_384, 48);
derive_rustcrypto_hasher!(sha_3::Sha3_512, Sha3_512, 64);

derive_hasher_sha!(sha_3::Keccak224, Keccak224, 28);
derive_hasher_sha!(sha_3::Keccak256, Keccak256, 32);
derive_hasher_sha!(sha_3::Keccak384, Keccak384, 48);
derive_hasher_sha!(sha_3::Keccak512, Keccak512, 64);
derive_rustcrypto_hasher!(sha_3::Keccak224, Keccak224, 28);
derive_rustcrypto_hasher!(sha_3::Keccak256, Keccak256, 32);
derive_rustcrypto_hasher!(sha_3::Keccak384, Keccak384, 48);
derive_rustcrypto_hasher!(sha_3::Keccak512, Keccak512, 64);
}

#[cfg(feature = "ripemd")]
pub mod ripemd {

use super::*;

derive_rustcrypto_hasher!(ripemd_rs::Ripemd160, Ripemd160, 20);
derive_rustcrypto_hasher!(ripemd_rs::Ripemd256, Ripemd256, 32);
derive_rustcrypto_hasher!(ripemd_rs::Ripemd320, Ripemd320, 40);
}

pub mod identity {
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ pub use crate::hasher_impl::blake2s::{Blake2s128, Blake2s256, Blake2sHasher};
#[cfg(feature = "blake3")]
pub use crate::hasher_impl::blake3::{Blake3Hasher, Blake3_256};
pub use crate::hasher_impl::identity::{Identity256, IdentityHasher};
#[cfg(feature = "ripemd")]
pub use crate::hasher_impl::ripemd::{Ripemd160, Ripemd256, Ripemd320};
#[cfg(feature = "sha1")]
pub use crate::hasher_impl::sha1::Sha1;
#[cfg(feature = "sha2")]
Expand Down
12 changes: 12 additions & 0 deletions src/multihash_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ pub enum Code {
#[cfg(feature = "blake3")]
#[mh(code = 0x1e, hasher = crate::Blake3_256)]
Blake3_256,
/// RIPEMD-160 (20-byte hash size)
#[cfg(feature = "ripemd")]
#[mh(code = 0x1053, hasher = crate::Ripemd160)]
Ripemd160,
/// RIPEMD-256 (32-byte hash size)
#[cfg(feature = "ripemd")]
#[mh(code = 0x1054, hasher = crate::Ripemd256)]
Ripemd256,
/// RIPEMD-320 (40-byte hash size)
#[cfg(feature = "ripemd")]
#[mh(code = 0x1055, hasher = crate::Ripemd320)]
Ripemd320,

// The following hashes are not cryptographically secure hashes and are not enabled by default
/// Identity hash (max. 64 bytes)
Expand Down
50 changes: 50 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ use multihash::{
Sha2_512, Sha3_224, Sha3_256, Sha3_384, Sha3_512, Strobe256, Strobe512,
};

#[cfg(feature = "ripemd")]
use multihash::{Ripemd160, Ripemd256, Ripemd320};

#[derive(Clone, Copy, Debug, Eq, Multihash, PartialEq)]
#[mh(alloc_size = 64)]
pub enum Code {
Expand Down Expand Up @@ -47,6 +50,15 @@ pub enum Code {
Strobe256,
#[mh(code = 0x3312e8, hasher = Strobe512)]
Strobe512,
#[cfg(feature = "ripemd")]
#[mh(code = 0x1053, hasher = Ripemd160)]
Ripemd160,
#[cfg(feature = "ripemd")]
#[mh(code = 0x1054, hasher = Ripemd256)]
Ripemd256,
#[cfg(feature = "ripemd")]
#[mh(code = 0x1055, hasher = Ripemd320)]
Ripemd320,
}

macro_rules! assert_encode {
Expand Down Expand Up @@ -97,6 +109,13 @@ fn multihash_encode() {
Blake2s128, Code::Blake2s128, b"hello world", "d0e4021037deae0226c30da2ab424a7b8ee14e83";
Blake3_256, Code::Blake3_256, b"hello world", "1e20d74981efa70a0c880b8d8c1985d075dbcbf679b99a5f9914e5aaf96b831a9e24";
}

#[cfg(feature = "ripemd")]
assert_encode! {
Ripemd160, Code::Ripemd160, b"hello world", "d3201498c615784ccb5fe5936fbc0cbe9dfdb408d92f0f";
Ripemd256, Code::Ripemd256, b"hello world", "d420200d375cf9d9ee95a3bb15f757c81e93bb0ad963edf69dc4d12264031814608e37";
Ripemd320, Code::Ripemd320, b"hello world", "d520280e12fe7d075f8e319e07c106917eddb0135e9a10aefb50a8a07ccb0582ff1fa27b95ed5af57fd5c6";
}
}

macro_rules! assert_decode {
Expand Down Expand Up @@ -134,6 +153,12 @@ fn assert_decode() {
Code::Blake2s128, "d0e4021037deae0226c30da2ab424a7b8ee14e83";
Code::Blake3_256, "1e20d74981efa70a0c880b8d8c1985d075dbcbf679b99a5f9914e5aaf96b831a9e24";
}
#[cfg(feature = "ripemd")]
assert_decode! {
Code::Ripemd160, "d3201498c615784ccb5fe5936fbc0cbe9dfdb408d92f0f";
Code::Ripemd256, "d420200d375cf9d9ee95a3bb15f757c81e93bb0ad963edf69dc4d12264031814608e37";
Code::Ripemd320, "d520280e12fe7d075f8e319e07c106917eddb0135e9a10aefb50a8a07ccb0582ff1fa27b95ed5af57fd5c6";
}
}

macro_rules! assert_roundtrip {
Expand Down Expand Up @@ -191,6 +216,13 @@ fn assert_roundtrip() {
Code::Blake2s256, Blake2s256;
Code::Blake3_256, Blake3_256;
);

#[cfg(feature = "ripemd")]
assert_roundtrip! {
Code::Ripemd160, Ripemd160;
Code::Ripemd256, Ripemd256;
Code::Ripemd320, Ripemd320;
}
}

/// Testing the public interface of `Multihash` and coversions to it
Expand Down Expand Up @@ -300,6 +332,24 @@ fn test_multihash_methods() {
"1e20",
"d74981efa70a0c880b8d8c1985d075dbcbf679b99a5f9914e5aaf96b831a9e24",
);
#[cfg(feature = "ripemd")]
{
multihash_methods::<Ripemd160>(
Code::Ripemd160,
"d32014",
"98c615784ccb5fe5936fbc0cbe9dfdb408d92f0f",
);
multihash_methods::<Ripemd256>(
Code::Ripemd256,
"d42020",
"0d375cf9d9ee95a3bb15f757c81e93bb0ad963edf69dc4d12264031814608e37",
);
multihash_methods::<Ripemd320>(
Code::Ripemd320,
"d52028",
"0e12fe7d075f8e319e07c106917eddb0135e9a10aefb50a8a07ccb0582ff1fa27b95ed5af57fd5c6",
);
}
}

#[test]
Expand Down

0 comments on commit f805963

Please sign in to comment.