1use crate::{
2 error::Result, BitcoinByteArray, BitcoinDataType, ByteArray, DataType, FixedByteArray,
3 Function, Op,
4};
5
6use serde_derive::{Deserialize, Serialize};
7use sha1::Digest;
8use std::borrow::Cow;
9use std::fmt::{Debug, Display};
10use std::sync::Arc;
11
12pub trait Hashed: Display + Debug + Sized + Eq + PartialEq {
13 fn as_slice(&self) -> &[u8];
14 fn from_slice(hash: &[u8]) -> Result<Self>;
15 fn from_byte_array(hash: ByteArray) -> Result<Self>;
16 fn function() -> Function;
17 fn digest_slice(msg: &[u8]) -> Arc<[u8]>;
18 fn digest(msg: impl Into<ByteArray>) -> Self {
19 let msg = msg.into();
20 let hash = Self::digest_slice(&msg);
21 Self::from_byte_array(msg.apply_function(hash, Self::function()))
22 .expect("Self::digest_slice produced invalid slice")
23 }
24 fn named(self, name: impl Into<Cow<'static, str>>) -> Self;
25 fn from_hex_le(s: &str) -> Result<Self> {
26 Self::from_slice(&hex::decode(s)?.iter().cloned().rev().collect::<Vec<_>>())
27 }
28 fn from_hex_be(s: &str) -> Result<Self> {
29 Self::from_slice(&hex::decode(s)?)
30 }
31 fn from_slice_le(hash_le: &[u8]) -> Result<Self> {
32 Self::from_slice(&hash_le.iter().cloned().rev().collect::<Vec<_>>())
33 }
34 fn to_vec_le(&self) -> Vec<u8> {
35 self.as_slice().iter().cloned().rev().collect()
36 }
37 fn to_hex_le(&self) -> String {
38 hex::encode(self.to_vec_le())
39 }
40 fn to_hex_be(&self) -> String {
41 hex::encode(self.as_slice())
42 }
43 fn as_byte_array(&self) -> &ByteArray;
44 fn into_byte_array(self) -> ByteArray;
45 fn concat(self, other: impl Into<ByteArray>) -> ByteArray {
46 self.into_byte_array().concat(other)
47 }
48}
49
50#[derive(Clone, Eq, PartialEq, Default, Hash, Deserialize, Serialize)]
51pub struct Sha1(FixedByteArray<[u8; 20]>);
52#[derive(Clone, Eq, PartialEq, Default, Hash, Deserialize, Serialize)]
53pub struct Ripemd160(FixedByteArray<[u8; 20]>);
54#[derive(Clone, Eq, PartialEq, Default, Hash, Deserialize, Serialize)]
55pub struct Sha256(FixedByteArray<[u8; 32]>);
56#[derive(Clone, Eq, PartialEq, Default, Hash, Deserialize, Serialize)]
57pub struct Sha256d(FixedByteArray<[u8; 32]>);
58#[derive(Clone, Eq, PartialEq, Default, Hash, Deserialize, Serialize)]
59pub struct Hash160(FixedByteArray<[u8; 20]>);
60
61impl Sha1 {
62 pub fn new(hash: [u8; 20]) -> Self {
63 Sha1(FixedByteArray::new_unnamed(hash))
64 }
65}
66impl Ripemd160 {
67 pub fn new(hash: [u8; 20]) -> Self {
68 Ripemd160(FixedByteArray::new_unnamed(hash))
69 }
70}
71impl Sha256 {
72 pub fn new(hash: [u8; 32]) -> Self {
73 Sha256(FixedByteArray::new_unnamed(hash))
74 }
75}
76impl Sha256d {
77 pub fn new(hash: [u8; 32]) -> Self {
78 Sha256d(FixedByteArray::new_unnamed(hash))
79 }
80}
81impl Hash160 {
82 pub fn new(hash: [u8; 20]) -> Self {
83 Hash160(FixedByteArray::new_unnamed(hash))
84 }
85}
86
87impl Debug for Sha1 {
88 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
89 write!(fmt, "Sha1({})", self.to_hex_le())
90 }
91}
92impl Debug for Ripemd160 {
93 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
94 write!(fmt, "Ripemd160({})", self.to_hex_le())
95 }
96}
97impl Debug for Sha256 {
98 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
99 write!(fmt, "Sha256({})", self.to_hex_le())
100 }
101}
102impl Debug for Sha256d {
103 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
104 write!(fmt, "Sha256d({})", self.to_hex_le())
105 }
106}
107impl Debug for Hash160 {
108 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
109 write!(fmt, "Hash160({})", self.to_hex_le())
110 }
111}
112
113impl Display for Sha1 {
114 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
115 write!(fmt, "{}", self.to_hex_le())
116 }
117}
118impl Display for Ripemd160 {
119 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
120 write!(fmt, "{}", self.to_hex_le())
121 }
122}
123impl Display for Sha256 {
124 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
125 write!(fmt, "{}", self.to_hex_le())
126 }
127}
128impl Display for Sha256d {
129 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
130 write!(fmt, "{}", self.to_hex_le())
131 }
132}
133impl Display for Hash160 {
134 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
135 write!(fmt, "{}", self.to_hex_le())
136 }
137}
138
139impl Hashed for Sha1 {
140 fn function() -> Function {
141 Function::Sha1
142 }
143 fn digest_slice(msg: &[u8]) -> Arc<[u8]> {
144 sha1::Sha1::digest(msg).as_slice().into()
145 }
146 fn as_slice(&self) -> &[u8] {
147 self.0.as_ref()
148 }
149 fn from_slice(hash: &[u8]) -> Result<Self> {
150 Ok(Sha1(FixedByteArray::from_slice_unnamed(hash)?))
151 }
152 fn from_byte_array(hash: ByteArray) -> Result<Self> {
153 Ok(Sha1(FixedByteArray::from_byte_array(hash)?))
154 }
155 fn named(self, name: impl Into<Cow<'static, str>>) -> Self {
156 Sha1(self.0.named(name))
157 }
158 fn as_byte_array(&self) -> &ByteArray {
159 self.0.as_byte_array()
160 }
161 fn into_byte_array(self) -> ByteArray {
162 self.0.into_byte_array()
163 }
164}
165
166impl Hashed for Ripemd160 {
167 fn function() -> Function {
168 Function::Ripemd160
169 }
170 fn digest_slice(msg: &[u8]) -> Arc<[u8]> {
171 ripemd160::Ripemd160::digest(msg).as_slice().into()
172 }
173 fn as_slice(&self) -> &[u8] {
174 self.0.as_ref()
175 }
176 fn from_slice(hash: &[u8]) -> Result<Self> {
177 Ok(Ripemd160(FixedByteArray::from_slice_unnamed(hash)?))
178 }
179 fn from_byte_array(hash: ByteArray) -> Result<Self> {
180 Ok(Ripemd160(FixedByteArray::from_byte_array(hash)?))
181 }
182 fn named(self, name: impl Into<Cow<'static, str>>) -> Self {
183 Ripemd160(self.0.named(name))
184 }
185 fn as_byte_array(&self) -> &ByteArray {
186 self.0.as_byte_array()
187 }
188 fn into_byte_array(self) -> ByteArray {
189 self.0.into_byte_array()
190 }
191}
192
193impl Hashed for Sha256 {
194 fn function() -> Function {
195 Function::Sha256
196 }
197 fn digest_slice(msg: &[u8]) -> Arc<[u8]> {
198 sha2::Sha256::digest(msg).as_slice().into()
199 }
200 fn as_slice(&self) -> &[u8] {
201 self.0.as_ref()
202 }
203 fn from_slice(hash: &[u8]) -> Result<Self> {
204 Ok(Sha256(FixedByteArray::from_slice_unnamed(hash)?))
205 }
206 fn from_byte_array(hash: ByteArray) -> Result<Self> {
207 Ok(Sha256(FixedByteArray::from_byte_array(hash)?))
208 }
209 fn named(self, name: impl Into<Cow<'static, str>>) -> Self {
210 Sha256(self.0.named(name))
211 }
212 fn as_byte_array(&self) -> &ByteArray {
213 self.0.as_byte_array()
214 }
215 fn into_byte_array(self) -> ByteArray {
216 self.0.into_byte_array()
217 }
218}
219
220impl Hashed for Sha256d {
221 fn function() -> Function {
222 Function::Hash256
223 }
224 fn digest_slice(msg: &[u8]) -> Arc<[u8]> {
225 sha2::Sha256::digest(sha2::Sha256::digest(msg).as_slice())
226 .as_slice()
227 .into()
228 }
229 fn as_slice(&self) -> &[u8] {
230 self.0.as_ref()
231 }
232 fn from_slice(hash: &[u8]) -> Result<Self> {
233 Ok(Sha256d(FixedByteArray::from_slice_unnamed(hash)?))
234 }
235 fn from_byte_array(hash: ByteArray) -> Result<Self> {
236 Ok(Sha256d(FixedByteArray::from_byte_array(hash)?))
237 }
238 fn named(self, name: impl Into<Cow<'static, str>>) -> Self {
239 Sha256d(self.0.named(name))
240 }
241 fn as_byte_array(&self) -> &ByteArray {
242 self.0.as_byte_array()
243 }
244 fn into_byte_array(self) -> ByteArray {
245 self.0.into_byte_array()
246 }
247}
248
249impl Hashed for Hash160 {
250 fn function() -> Function {
251 Function::Hash160
252 }
253 fn digest_slice(msg: &[u8]) -> Arc<[u8]> {
254 ripemd160::Ripemd160::digest(sha2::Sha256::digest(msg).as_slice())
255 .as_slice()
256 .into()
257 }
258 fn as_slice(&self) -> &[u8] {
259 self.0.as_ref()
260 }
261 fn from_slice(hash: &[u8]) -> Result<Self> {
262 Ok(Hash160(FixedByteArray::from_slice_unnamed(hash)?))
263 }
264 fn from_byte_array(hash: ByteArray) -> Result<Self> {
265 Ok(Hash160(FixedByteArray::from_byte_array(hash)?))
266 }
267 fn named(self, name: impl Into<Cow<'static, str>>) -> Self {
268 Hash160(self.0.named(name))
269 }
270 fn as_byte_array(&self) -> &ByteArray {
271 self.0.as_byte_array()
272 }
273 fn into_byte_array(self) -> ByteArray {
274 self.0.into_byte_array()
275 }
276}
277
278impl BitcoinDataType for Sha1 {
279 type Type = BitcoinByteArray;
280 fn to_data(&self) -> Self::Type {
281 BitcoinByteArray(self.as_byte_array().clone())
282 }
283 fn to_pushop(&self) -> Op {
284 self.as_byte_array().clone().into()
285 }
286 fn to_data_type(&self) -> DataType {
287 DataType::ByteArray(Some(self.0.len()))
288 }
289}
290
291impl BitcoinDataType for Ripemd160 {
292 type Type = BitcoinByteArray;
293 fn to_data(&self) -> Self::Type {
294 BitcoinByteArray(self.as_byte_array().clone())
295 }
296 fn to_pushop(&self) -> Op {
297 self.as_byte_array().clone().into()
298 }
299 fn to_data_type(&self) -> DataType {
300 DataType::ByteArray(Some(self.0.len()))
301 }
302}
303
304impl BitcoinDataType for Sha256 {
305 type Type = BitcoinByteArray;
306 fn to_data(&self) -> Self::Type {
307 BitcoinByteArray(self.as_byte_array().clone())
308 }
309 fn to_pushop(&self) -> Op {
310 self.as_byte_array().clone().into()
311 }
312 fn to_data_type(&self) -> DataType {
313 DataType::ByteArray(Some(self.0.len()))
314 }
315}
316
317impl BitcoinDataType for Sha256d {
318 type Type = BitcoinByteArray;
319 fn to_data(&self) -> Self::Type {
320 BitcoinByteArray(self.as_byte_array().clone())
321 }
322 fn to_pushop(&self) -> Op {
323 self.as_byte_array().clone().into()
324 }
325 fn to_data_type(&self) -> DataType {
326 DataType::ByteArray(Some(self.0.len()))
327 }
328}
329
330impl BitcoinDataType for Hash160 {
331 type Type = BitcoinByteArray;
332 fn to_data(&self) -> Self::Type {
333 BitcoinByteArray(self.as_byte_array().clone())
334 }
335 fn to_pushop(&self) -> Op {
336 self.as_byte_array().clone().into()
337 }
338 fn to_data_type(&self) -> DataType {
339 DataType::ByteArray(Some(self.0.len()))
340 }
341}
342
343impl From<Sha1> for ByteArray {
344 fn from(hash: Sha1) -> Self {
345 hash.into_byte_array()
346 }
347}
348impl From<Ripemd160> for ByteArray {
349 fn from(hash: Ripemd160) -> Self {
350 hash.into_byte_array()
351 }
352}
353impl From<Sha256> for ByteArray {
354 fn from(hash: Sha256) -> Self {
355 hash.into_byte_array()
356 }
357}
358impl From<Sha256d> for ByteArray {
359 fn from(hash: Sha256d) -> Self {
360 hash.into_byte_array()
361 }
362}
363impl From<Hash160> for ByteArray {
364 fn from(hash: Hash160) -> Self {
365 hash.into_byte_array()
366 }
367}
368
369#[cfg(test)]
370mod tests {
371 use super::{Hash160, Hashed, Result, Ripemd160, Sha1, Sha256, Sha256d};
372 use crate::error::ErrorKind;
373 use hex_literal::hex;
374
375 #[test]
376 fn test_sha1_slice() -> Result<()> {
377 const EMPTY_SHA1: [u8; 20] = hex!("da39a3ee5e6b4b0d3255bfef95601890afd80709");
378 assert_eq!(Sha1::digest(b"").as_slice(), EMPTY_SHA1);
379 assert_eq!(Sha1::digest(b""), Sha1::from_slice(&EMPTY_SHA1)?);
380 assert_eq!(
381 ErrorKind::InvalidSize(20, 2).to_string(),
382 Sha1::from_slice(&[0, 0]).unwrap_err().kind().to_string(),
383 );
384 Ok(())
385 }
386
387 #[test]
388 fn test_sha1_hex_be() -> Result<()> {
389 const EMPTY_SHA1: &str = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
390 assert_eq!(Sha1::digest(b"").to_hex_be(), EMPTY_SHA1);
391 assert_eq!(Sha1::digest(b""), Sha1::from_hex_be(EMPTY_SHA1)?);
392 Ok(())
393 }
394
395 #[test]
396 fn test_sha1_hex_le() -> Result<()> {
397 const EMPTY_SHA1_LE: &str = "0907d8af90186095efbf55320d4b6b5eeea339da";
398 assert_eq!(Sha1::digest(b"").to_hex_le(), EMPTY_SHA1_LE);
399 assert_eq!(Sha1::digest(b""), Sha1::from_hex_le(EMPTY_SHA1_LE)?);
400 Ok(())
401 }
402
403 #[test]
404 fn test_ripemd160_slice() -> Result<()> {
405 const EMPTY_RIPEMD: [u8; 20] = hex!("9c1185a5c5e9fc54612808977ee8f548b2258d31");
406 assert_eq!(Ripemd160::digest(b"").as_slice(), EMPTY_RIPEMD);
407 assert_eq!(
408 Ripemd160::digest(b""),
409 Ripemd160::from_slice(&EMPTY_RIPEMD)?
410 );
411 assert_eq!(
412 ErrorKind::InvalidSize(20, 2).to_string(),
413 Ripemd160::from_slice(&[0, 0])
414 .unwrap_err()
415 .kind()
416 .to_string(),
417 );
418 Ok(())
419 }
420
421 #[test]
422 fn test_ripemd160_hex_be() -> Result<()> {
423 const EMPTY_RIPEMD: &str = "9c1185a5c5e9fc54612808977ee8f548b2258d31";
424 assert_eq!(Ripemd160::digest(b"").to_hex_be(), EMPTY_RIPEMD);
425 assert_eq!(
426 Ripemd160::digest(b""),
427 Ripemd160::from_hex_be(EMPTY_RIPEMD)?
428 );
429 Ok(())
430 }
431
432 #[test]
433 fn test_ripemd160_hex_le() -> Result<()> {
434 const EMPTY_RIPEMD_LE: &str = "318d25b248f5e87e9708286154fce9c5a585119c";
435 assert_eq!(Ripemd160::digest(b"").to_hex_le(), EMPTY_RIPEMD_LE);
436 assert_eq!(
437 Ripemd160::digest(b""),
438 Ripemd160::from_hex_le(EMPTY_RIPEMD_LE)?
439 );
440 Ok(())
441 }
442
443 #[test]
444 fn test_sha256_slice() -> Result<()> {
445 const EMPTY_SHA256: [u8; 32] =
446 hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
447 assert_eq!(Sha256::digest(b"").as_slice(), EMPTY_SHA256);
448 assert_eq!(Sha256::digest(b""), Sha256::from_slice(&EMPTY_SHA256)?);
449 assert_eq!(
450 ErrorKind::InvalidSize(32, 2).to_string(),
451 Sha256::from_slice(&[0, 0]).unwrap_err().kind().to_string(),
452 );
453 Ok(())
454 }
455
456 #[test]
457 fn test_sha256_hex_be() -> Result<()> {
458 const EMPTY_SHA256: &str =
459 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
460 assert_eq!(Sha256::digest(b"").to_hex_be(), EMPTY_SHA256);
461 assert_eq!(Sha256::digest(b""), Sha256::from_hex_be(EMPTY_SHA256)?);
462 Ok(())
463 }
464
465 #[test]
466 fn test_sha256_hex_le() -> Result<()> {
467 const EMPTY_SHA256_LE: &str =
468 "55b852781b9995a44c939b64e441ae2724b96f99c8f4fb9a141cfc9842c4b0e3";
469 assert_eq!(Sha256::digest(b"").to_hex_le(), EMPTY_SHA256_LE);
470 assert_eq!(Sha256::digest(b""), Sha256::from_hex_le(EMPTY_SHA256_LE)?);
471 Ok(())
472 }
473
474 #[test]
475 fn test_sha256d_slice() -> Result<()> {
476 const EMPTY_SHA256D: [u8; 32] =
477 hex!("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456");
478 assert_eq!(Sha256d::digest(b"").as_slice(), EMPTY_SHA256D);
479 assert_eq!(Sha256d::digest(b""), Sha256d::from_slice(&EMPTY_SHA256D)?);
480 assert_eq!(
481 ErrorKind::InvalidSize(32, 2).to_string(),
482 Sha256d::from_slice(&[0, 0]).unwrap_err().kind().to_string(),
483 );
484 Ok(())
485 }
486
487 #[test]
488 fn test_sha256d_hex_be() -> Result<()> {
489 const EMPTY_SHA256D: &str =
490 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456";
491 assert_eq!(Sha256d::digest(b"").to_hex_be(), EMPTY_SHA256D);
492 assert_eq!(Sha256d::digest(b""), Sha256d::from_hex_be(EMPTY_SHA256D)?);
493 Ok(())
494 }
495
496 #[test]
497 fn test_sha256d_hex_le() -> Result<()> {
498 const EMPTY_SHA256D_LE: &str =
499 "56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d";
500 assert_eq!(Sha256d::digest(b"").to_hex_le(), EMPTY_SHA256D_LE);
501 assert_eq!(
502 Sha256d::digest(b""),
503 Sha256d::from_hex_le(EMPTY_SHA256D_LE)?
504 );
505 Ok(())
506 }
507
508 #[test]
509 fn test_hash160_slice() -> Result<()> {
510 const EMPTY_HASH160: [u8; 20] = hex!("b472a266d0bd89c13706a4132ccfb16f7c3b9fcb");
511 assert_eq!(Hash160::digest(b"").as_slice(), EMPTY_HASH160);
512 assert_eq!(Hash160::digest(b""), Hash160::from_slice(&EMPTY_HASH160)?);
513 assert_eq!(
514 ErrorKind::InvalidSize(20, 2).to_string(),
515 Hash160::from_slice(&[0, 0]).unwrap_err().kind().to_string(),
516 );
517 Ok(())
518 }
519
520 #[test]
521 fn test_hash160_hex_be() -> Result<()> {
522 const EMPTY_HASH160: &str = "b472a266d0bd89c13706a4132ccfb16f7c3b9fcb";
523 assert_eq!(Hash160::digest(b"").to_hex_be(), EMPTY_HASH160);
524 assert_eq!(Hash160::digest(b""), Hash160::from_hex_be(EMPTY_HASH160)?);
525 Ok(())
526 }
527
528 #[test]
529 fn test_hash160_hex_le() -> Result<()> {
530 const EMPTY_HASH160_LE: &str = "cb9f3b7c6fb1cf2c13a40637c189bdd066a272b4";
531 assert_eq!(Hash160::digest(b"").to_hex_le(), EMPTY_HASH160_LE);
532 assert_eq!(
533 Hash160::digest(b""),
534 Hash160::from_hex_le(EMPTY_HASH160_LE)?
535 );
536 Ok(())
537 }
538}