@@ -116,7 +116,6 @@ pub mod psbt;
116116
117117mod util;
118118
119- use std:: io:: Write ;
120119use std:: str:: FromStr ;
121120use std:: { error, fmt, hash, str} ;
122121
@@ -134,58 +133,43 @@ pub use descriptor::pretaproot::{traits::PreTaprootDescriptorTrait, PreTaprootDe
134133
135134///Public key trait which can be converted to Hash type
136135pub trait MiniscriptKey : Clone + Eq + Ord + fmt:: Debug + fmt:: Display + hash:: Hash {
137- /// Check if the publicKey is uncompressed. The default
138- /// implementation returns false
136+ /// Returns true if the pubkey is uncompressed. Defaults to `false`.
139137 fn is_uncompressed ( & self ) -> bool {
140138 false
141139 }
142140
143- /// Check if the publicKey is x-only. The default
144- /// implementation returns false
145- //
141+ /// Returns true if the pubkey is an x-only pubkey. Defaults to `false`.
146142 // This is required to know what in DescriptorPublicKey to know whether the inner
147143 // key in allowed in descriptor context
148144 fn is_x_only_key ( & self ) -> bool {
149145 false
150146 }
151147
152- /// The associated Hash type with the publicKey
148+ /// The associated [` Hash`] type for this pubkey.
153149 type Hash : Clone + Eq + Ord + fmt:: Display + fmt:: Debug + hash:: Hash ;
154150
155- /// Converts an object to PublicHash
151+ /// Converts this key to the associated pubkey hash.
156152 fn to_pubkeyhash ( & self ) -> Self :: Hash ;
157153}
158154
159155impl MiniscriptKey for bitcoin:: secp256k1:: PublicKey {
160- /// `is_uncompressed` always returns `false`
161- fn is_uncompressed ( & self ) -> bool {
162- false
163- }
164-
165156 type Hash = hash160:: Hash ;
166157
167158 fn to_pubkeyhash ( & self ) -> Self :: Hash {
168- let mut engine = hash160:: Hash :: engine ( ) ;
169- engine
170- . write_all ( & self . serialize ( ) )
171- . expect ( "engines don't error" ) ;
172- hash160:: Hash :: from_engine ( engine)
159+ hash160:: Hash :: hash ( & self . serialize ( ) )
173160 }
174161}
175162
176163impl MiniscriptKey for bitcoin:: PublicKey {
177- /// `is_uncompressed` returns true only for
178- /// bitcoin::Publickey type if the underlying key is uncompressed.
164+ /// Returns the compressed-ness of the underlying secp256k1 key.
179165 fn is_uncompressed ( & self ) -> bool {
180166 !self . compressed
181167 }
182168
183169 type Hash = hash160:: Hash ;
184170
185171 fn to_pubkeyhash ( & self ) -> Self :: Hash {
186- let mut engine = hash160:: Hash :: engine ( ) ;
187- self . write_into ( & mut engine) . expect ( "engines don't error" ) ;
188- hash160:: Hash :: from_engine ( engine)
172+ hash160:: Hash :: hash ( & self . to_bytes ( ) )
189173 }
190174}
191175
@@ -794,3 +778,58 @@ fn hex_script(s: &str) -> bitcoin::Script {
794778 let v: Vec < u8 > = bitcoin:: hashes:: hex:: FromHex :: from_hex ( s) . unwrap ( ) ;
795779 bitcoin:: Script :: from ( v)
796780}
781+
782+ #[ cfg( test) ]
783+ mod tests {
784+ use super :: * ;
785+
786+ #[ test]
787+ fn regression_bitcoin_key_hash ( ) {
788+ use bitcoin:: PublicKey ;
789+
790+ // Uncompressed key.
791+ let pk = PublicKey :: from_str (
792+ "042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133"
793+ ) . unwrap ( ) ;
794+
795+ let want = hash160:: Hash :: from_str ( "ac2e7daf42d2c97418fd9f78af2de552bb9c6a7a" ) . unwrap ( ) ;
796+ let got = pk. to_pubkeyhash ( ) ;
797+ assert_eq ! ( got, want)
798+ }
799+
800+ #[ test]
801+ fn regression_secp256k1_key_hash ( ) {
802+ use bitcoin:: secp256k1:: PublicKey ;
803+
804+ // Compressed key.
805+ let pk = PublicKey :: from_str (
806+ "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af" ,
807+ )
808+ . unwrap ( ) ;
809+
810+ let want = hash160:: Hash :: from_str ( "9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4" ) . unwrap ( ) ;
811+ let got = pk. to_pubkeyhash ( ) ;
812+ assert_eq ! ( got, want)
813+ }
814+
815+ #[ test]
816+ fn regression_xonly_key_hash ( ) {
817+ use bitcoin:: secp256k1:: XOnlyPublicKey ;
818+
819+ let pk = XOnlyPublicKey :: from_str (
820+ "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115" ,
821+ )
822+ . unwrap ( ) ;
823+
824+ let want = hash160:: Hash :: from_str ( "eb8ac65f971ae688a94aeabf223506865e7e08f2" ) . unwrap ( ) ;
825+ let got = pk. to_pubkeyhash ( ) ;
826+ assert_eq ! ( got, want)
827+ }
828+
829+ #[ test]
830+ fn regression_string_key_hash ( ) {
831+ let pk = String :: from ( "some-key-hash-string" ) ;
832+ let hash = pk. to_pubkeyhash ( ) ;
833+ assert_eq ! ( hash, pk)
834+ }
835+ }
0 commit comments