@@ -128,7 +128,7 @@ use core::{fmt, hash, str};
128128use std:: error;
129129
130130use bitcoin:: blockdata:: { opcodes, script} ;
131- use bitcoin:: hashes:: { hash160, sha256, Hash } ;
131+ use bitcoin:: hashes:: { hash160, ripemd160 , sha256, Hash } ;
132132
133133pub use crate :: descriptor:: { Descriptor , DescriptorPublicKey } ;
134134pub use crate :: interpreter:: Interpreter ;
@@ -165,6 +165,13 @@ pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Ha
165165 /// The associated [`hash256::Hash`] for this [`MiniscriptKey`],
166166 /// used in the hash256 fragment.
167167 type Hash256 : Clone + Eq + Ord + fmt:: Display + fmt:: Debug + hash:: Hash ;
168+ /// The associated [`ripedmd160::Hash`] for this [`MiniscriptKey`] type.
169+ /// used in the ripemd160 fragment
170+ type Ripemd160 : Clone + Eq + Ord + fmt:: Display + fmt:: Debug + hash:: Hash ;
171+
172+ /// The associated [`hash160::Hash`] for this [`MiniscriptKey`] type.
173+ /// used in the hash160 fragment
174+ type Hash160 : Clone + Eq + Ord + fmt:: Display + fmt:: Debug + hash:: Hash ;
168175
169176 /// Converts this key to the associated pubkey hash.
170177 fn to_pubkeyhash ( & self ) -> Self :: RawPkHash ;
@@ -174,6 +181,8 @@ impl MiniscriptKey for bitcoin::secp256k1::PublicKey {
174181 type RawPkHash = hash160:: Hash ;
175182 type Sha256 = sha256:: Hash ;
176183 type Hash256 = hash256:: Hash ;
184+ type Ripemd160 = ripemd160:: Hash ;
185+ type Hash160 = hash160:: Hash ;
177186
178187 fn to_pubkeyhash ( & self ) -> Self :: RawPkHash {
179188 hash160:: Hash :: hash ( & self . serialize ( ) )
@@ -189,6 +198,8 @@ impl MiniscriptKey for bitcoin::PublicKey {
189198 type RawPkHash = hash160:: Hash ;
190199 type Sha256 = sha256:: Hash ;
191200 type Hash256 = hash256:: Hash ;
201+ type Ripemd160 = ripemd160:: Hash ;
202+ type Hash160 = hash160:: Hash ;
192203
193204 fn to_pubkeyhash ( & self ) -> Self :: RawPkHash {
194205 hash160:: Hash :: hash ( & self . to_bytes ( ) )
@@ -199,6 +210,8 @@ impl MiniscriptKey for bitcoin::secp256k1::XOnlyPublicKey {
199210 type RawPkHash = hash160:: Hash ;
200211 type Sha256 = sha256:: Hash ;
201212 type Hash256 = hash256:: Hash ;
213+ type Ripemd160 = ripemd160:: Hash ;
214+ type Hash160 = hash160:: Hash ;
202215
203216 fn to_pubkeyhash ( & self ) -> Self :: RawPkHash {
204217 hash160:: Hash :: hash ( & self . serialize ( ) )
@@ -213,6 +226,8 @@ impl MiniscriptKey for String {
213226 type RawPkHash = String ;
214227 type Sha256 = String ; // specify hashes as string
215228 type Hash256 = String ;
229+ type Ripemd160 = String ;
230+ type Hash160 = String ;
216231
217232 fn to_pubkeyhash ( & self ) -> Self :: RawPkHash {
218233 ( & self ) . to_string ( )
@@ -243,6 +258,12 @@ pub trait ToPublicKey: MiniscriptKey {
243258
244259 /// Converts the generic associated [`MiniscriptKey::Hash256`] to [`hash256::Hash`]
245260 fn to_hash256 ( hash : & <Self as MiniscriptKey >:: Hash256 ) -> hash256:: Hash ;
261+
262+ /// Converts the generic associated [`MiniscriptKey::Ripemd160`] to [`ripemd160::Hash`]
263+ fn to_ripemd160 ( hash : & <Self as MiniscriptKey >:: Ripemd160 ) -> ripemd160:: Hash ;
264+
265+ /// Converts the generic associated [`MiniscriptKey::Hash160`] to [`hash160::Hash`]
266+ fn to_hash160 ( hash : & <Self as MiniscriptKey >:: Hash160 ) -> hash160:: Hash ;
246267}
247268
248269impl ToPublicKey for bitcoin:: PublicKey {
@@ -261,6 +282,14 @@ impl ToPublicKey for bitcoin::PublicKey {
261282 fn to_hash256 ( hash : & hash256:: Hash ) -> hash256:: Hash {
262283 * hash
263284 }
285+
286+ fn to_ripemd160 ( hash : & ripemd160:: Hash ) -> ripemd160:: Hash {
287+ * hash
288+ }
289+
290+ fn to_hash160 ( hash : & hash160:: Hash ) -> hash160:: Hash {
291+ * hash
292+ }
264293}
265294
266295impl ToPublicKey for bitcoin:: secp256k1:: PublicKey {
@@ -279,6 +308,14 @@ impl ToPublicKey for bitcoin::secp256k1::PublicKey {
279308 fn to_hash256 ( hash : & hash256:: Hash ) -> hash256:: Hash {
280309 * hash
281310 }
311+
312+ fn to_ripemd160 ( hash : & ripemd160:: Hash ) -> ripemd160:: Hash {
313+ * hash
314+ }
315+
316+ fn to_hash160 ( hash : & hash160:: Hash ) -> hash160:: Hash {
317+ * hash
318+ }
282319}
283320
284321impl ToPublicKey for bitcoin:: secp256k1:: XOnlyPublicKey {
@@ -306,6 +343,14 @@ impl ToPublicKey for bitcoin::secp256k1::XOnlyPublicKey {
306343 fn to_hash256 ( hash : & hash256:: Hash ) -> hash256:: Hash {
307344 * hash
308345 }
346+
347+ fn to_ripemd160 ( hash : & ripemd160:: Hash ) -> ripemd160:: Hash {
348+ * hash
349+ }
350+
351+ fn to_hash160 ( hash : & hash160:: Hash ) -> hash160:: Hash {
352+ * hash
353+ }
309354}
310355
311356/// Dummy key which de/serializes to the empty string; useful sometimes for testing
@@ -327,6 +372,8 @@ impl MiniscriptKey for DummyKey {
327372 type RawPkHash = DummyKeyHash ;
328373 type Sha256 = DummySha256Hash ;
329374 type Hash256 = DummyHash256 ;
375+ type Ripemd160 = DummyRipemd160Hash ;
376+ type Hash160 = DummyHash160Hash ;
330377
331378 fn to_pubkeyhash ( & self ) -> Self :: RawPkHash {
332379 DummyKeyHash
@@ -366,6 +413,14 @@ impl ToPublicKey for DummyKey {
366413 hash256:: Hash :: from_str ( "50863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352" )
367414 . unwrap ( )
368415 }
416+
417+ fn to_ripemd160 ( _: & DummyRipemd160Hash ) -> ripemd160:: Hash {
418+ ripemd160:: Hash :: from_str ( "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31" ) . unwrap ( )
419+ }
420+
421+ fn to_hash160 ( _: & DummyHash160Hash ) -> hash160:: Hash {
422+ hash160:: Hash :: from_str ( "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31" ) . unwrap ( )
423+ }
369424}
370425
371426/// Dummy keyhash which de/serializes to the empty string; useful sometimes for testing
@@ -437,19 +492,72 @@ impl str::FromStr for DummyHash256 {
437492 }
438493}
439494
495+ /// Dummy keyhash which de/serializes to the empty string; useful for testing
496+ #[ derive( Copy , Clone , PartialOrd , Ord , PartialEq , Eq , Debug ) ]
497+ pub struct DummyRipemd160Hash ;
498+
499+ impl str:: FromStr for DummyRipemd160Hash {
500+ type Err = & ' static str ;
501+ fn from_str ( x : & str ) -> Result < DummyRipemd160Hash , & ' static str > {
502+ if x. is_empty ( ) {
503+ Ok ( DummyRipemd160Hash )
504+ } else {
505+ Err ( "non empty dummy hash" )
506+ }
507+ }
508+ }
509+
440510impl fmt:: Display for DummyHash256 {
441511 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
442512 f. write_str ( "" )
443513 }
444514}
515+ impl fmt:: Display for DummyRipemd160Hash {
516+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
517+ f. write_str ( "" )
518+ }
519+ }
445520
446521impl hash:: Hash for DummyHash256 {
447522 fn hash < H : hash:: Hasher > ( & self , state : & mut H ) {
448523 "DummySha256Hash" . hash ( state) ;
449524 }
450525}
451526
452- /// Provides the conversion information required in [`TranslatePk`]
527+ impl hash:: Hash for DummyRipemd160Hash {
528+ fn hash < H : hash:: Hasher > ( & self , state : & mut H ) {
529+ "DummyRipemd160Hash" . hash ( state) ;
530+ }
531+ }
532+
533+ /// Dummy keyhash which de/serializes to the empty string; useful for testing
534+ #[ derive( Copy , Clone , PartialOrd , Ord , PartialEq , Eq , Debug ) ]
535+ pub struct DummyHash160Hash ;
536+
537+ impl str:: FromStr for DummyHash160Hash {
538+ type Err = & ' static str ;
539+ fn from_str ( x : & str ) -> Result < DummyHash160Hash , & ' static str > {
540+ if x. is_empty ( ) {
541+ Ok ( DummyHash160Hash )
542+ } else {
543+ Err ( "non empty dummy hash" )
544+ }
545+ }
546+ }
547+
548+ impl fmt:: Display for DummyHash160Hash {
549+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
550+ f. write_str ( "" )
551+ }
552+ }
553+
554+ impl hash:: Hash for DummyHash160Hash {
555+ fn hash < H : hash:: Hasher > ( & self , state : & mut H ) {
556+ "DummyHash160Hash" . hash ( state) ;
557+ }
558+ }
559+ /// Describes an object that can translate various keys and hashes from one key to the type
560+ /// associated with the other key. Used by the [`TranslatePk`] trait to do the actual translations.
453561pub trait Translator < P , Q , E >
454562where
455563 P : MiniscriptKey ,
@@ -466,6 +574,12 @@ where
466574
467575 /// Provides the translation from P::Hash256 -> Q::Hash256
468576 fn hash256 ( & mut self , hash256 : & P :: Hash256 ) -> Result < Q :: Hash256 , E > ;
577+
578+ /// Translates ripemd160 hashes from P::Ripemd160 -> Q::Ripemd160
579+ fn ripemd160 ( & mut self , ripemd160 : & P :: Ripemd160 ) -> Result < Q :: Ripemd160 , E > ;
580+
581+ /// Translates hash160 hashes from P::Hash160 -> Q::Hash160
582+ fn hash160 ( & mut self , hash160 : & P :: Hash160 ) -> Result < Q :: Hash160 , E > ;
469583}
470584
471585/// Provides the conversion information required in [`TranslatePk`].
@@ -487,7 +601,12 @@ impl<P, Q, E, T> Translator<P, Q, E> for T
487601where
488602 T : PkTranslator < P , Q , E > ,
489603 P : MiniscriptKey ,
490- Q : MiniscriptKey < Sha256 = P :: Sha256 , Hash256 = P :: Hash256 > ,
604+ Q : MiniscriptKey <
605+ Sha256 = P :: Sha256 ,
606+ Hash256 = P :: Hash256 ,
607+ Ripemd160 = P :: Ripemd160 ,
608+ Hash160 = P :: Hash160 ,
609+ > ,
491610{
492611 fn pk ( & mut self , pk : & P ) -> Result < Q , E > {
493612 <Self as PkTranslator < P , Q , E > >:: pk ( self , pk)
@@ -507,6 +626,17 @@ where
507626 fn hash256 ( & mut self , hash256 : & <P as MiniscriptKey >:: Hash256 ) -> Result < <Q >:: Hash256 , E > {
508627 Ok ( hash256. clone ( ) )
509628 }
629+
630+ fn ripemd160 (
631+ & mut self ,
632+ ripemd160 : & <P as MiniscriptKey >:: Ripemd160 ,
633+ ) -> Result < <Q >:: Ripemd160 , E > {
634+ Ok ( ripemd160. clone ( ) )
635+ }
636+
637+ fn hash160 ( & mut self , hash160 : & <P as MiniscriptKey >:: Hash160 ) -> Result < <Q >:: Hash160 , E > {
638+ Ok ( hash160. clone ( ) )
639+ }
510640}
511641
512642/// Converts a descriptor using abstract keys to one using specific keys. Uses translator `t` to do
0 commit comments