1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use std::io::{self, Error, ErrorKind};
use ripemd::{Digest, Ripemd160};
use sha3::Keccak256;
#[cfg(all(not(windows)))]
use ring::digest::{digest, SHA256};
#[cfg(all(not(windows)))]
pub const SHA256_OUTPUT_LEN: usize = ring::digest::SHA256_OUTPUT_LEN;
#[cfg(all(windows))]
pub const SHA256_OUTPUT_LEN: usize = 32;
#[cfg(all(not(windows)))]
pub fn sha256(d: impl AsRef<[u8]>) -> Vec<u8> {
digest(&SHA256, d.as_ref()).as_ref().into()
}
#[cfg(all(windows))]
pub fn sha256(b: impl AsRef<[u8]>) -> Vec<u8> {
panic!("unimplemented")
}
pub fn sha256_ripemd160<B>(b: B) -> io::Result<Vec<u8>>
where
B: AsRef<[u8]>,
{
let digest_sha256 = sha256(b);
let sha256_ripemd160 = Ripemd160::digest(&digest_sha256);
if sha256_ripemd160.len() != 20 {
return Err(Error::new(
ErrorKind::InvalidData,
format!(
"ripemd160 of sha256 must be 20-byte, got {}",
sha256_ripemd160.len()
),
));
}
Ok(sha256_ripemd160.to_vec())
}
#[test]
fn test_sha256_ripemd160() {
let d = sha256_ripemd160(&<Vec<u8>>::from([
0x3d, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
]))
.unwrap();
assert_eq!(d.len(), 20);
}
pub fn keccak256(b: impl AsRef<[u8]>) -> primitive_types::H256 {
primitive_types::H256::from_slice(&Keccak256::digest(b.as_ref()))
}
#[test]
fn test_keccak256() {
let d = keccak256(&<Vec<u8>>::from([
0x3d, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
]));
assert_eq!(d.0.len(), 32);
}