Skip to content

Commit e2e8e77

Browse files
committed
Merge #434: Add Hash256 associated type
905c5dc Rename Pk::Hash to Pk::RawPkHash (sanket1729) 5d36f9b Add Hash256 associated type (sanket1729) e22b081 Add Hash256 type (sanket1729) Pull request description: - Implement a new hash type that does not display/FromStr with `DISPLAY_BACKWARD`. Should we make this type upstream in bitcoin-hashes? - Remove the PkTranslator trait as it was causing conflicting implementations downstream. - Replace the above with more macros :( ACKs for top commit: apoelstra: ACK 905c5dc Tree-SHA512: c65027ce30a917e96d9403fcc75dae3089ec4f0ffa169fdfda8b559aa33345dfff2cf89ed49a26376de23d5acc31cbdaeb00dc31f9a000b89c18b25e58e938d4
2 parents c6835f7 + 905c5dc commit e2e8e77

28 files changed

+386
-166
lines changed

examples/taproot.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use bitcoin::util::address::WitnessVersion;
66
use bitcoin::Network;
77
use miniscript::descriptor::DescriptorType;
88
use miniscript::policy::Concrete;
9-
use miniscript::{Descriptor, Miniscript, Tap, TranslatePk, Translator};
9+
use miniscript::{hash256, Descriptor, Miniscript, Tap, TranslatePk, Translator};
1010
use secp256k1::{rand, KeyPair};
1111

1212
// Refer to https://github.com/sanket1729/adv_btc_workshop/blob/master/workshop.md#creating-a-taproot-descriptor
@@ -28,6 +28,10 @@ impl Translator<String, bitcoin::XOnlyPublicKey, ()> for StrPkTranslator {
2828
fn sha256(&mut self, _sha256: &String) -> Result<sha256::Hash, ()> {
2929
unreachable!("Policy does not contain any sha256 fragment");
3030
}
31+
32+
fn hash256(&mut self, _sha256: &String) -> Result<hash256::Hash, ()> {
33+
unreachable!("Policy does not contain any hash256 fragment");
34+
}
3135
}
3236

3337
fn main() {

src/descriptor/bare.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Bare<Pk> {
167167
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
168168
where
169169
Pk: 'a,
170-
Pk::Hash: 'a,
170+
Pk::RawPkHash: 'a,
171171
{
172172
self.ms.for_each_key(pred)
173173
}
@@ -329,7 +329,7 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Pkh<Pk> {
329329
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
330330
where
331331
Pk: 'a,
332-
Pk::Hash: 'a,
332+
Pk::RawPkHash: 'a,
333333
{
334334
pred(&self.pk)
335335
}

src/descriptor/key.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use bitcoin::util::bip32;
1010
use bitcoin::{self, XOnlyPublicKey, XpubIdentifier};
1111

1212
use crate::prelude::*;
13-
use crate::{MiniscriptKey, ToPublicKey};
13+
use crate::{hash256, MiniscriptKey, ToPublicKey};
1414

1515
/// The descriptor pubkey, either a single pubkey or an xpub.
1616
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)]
@@ -736,8 +736,9 @@ impl<K: InnerXKey> DescriptorXKey<K> {
736736

737737
impl MiniscriptKey for DescriptorPublicKey {
738738
// This allows us to be able to derive public keys even for PkH s
739-
type Hash = Self;
740-
type Sha256 = bitcoin::hashes::sha256::Hash;
739+
type RawPkHash = Self;
740+
type Sha256 = sha256::Hash;
741+
type Hash256 = hash256::Hash;
741742

742743
fn is_uncompressed(&self) -> bool {
743744
match self {
@@ -802,8 +803,9 @@ impl fmt::Display for DerivedDescriptorKey {
802803

803804
impl MiniscriptKey for DerivedDescriptorKey {
804805
// This allows us to be able to derive public keys even for PkH s
805-
type Hash = Self;
806-
type Sha256 = bitcoin::hashes::sha256::Hash;
806+
type RawPkHash = Self;
807+
type Sha256 = sha256::Hash;
808+
type Hash256 = hash256::Hash;
807809

808810
fn is_uncompressed(&self) -> bool {
809811
self.key.is_uncompressed()
@@ -831,6 +833,10 @@ impl ToPublicKey for DerivedDescriptorKey {
831833
fn to_sha256(hash: &sha256::Hash) -> sha256::Hash {
832834
*hash
833835
}
836+
837+
fn to_hash256(hash: &hash256::Hash) -> hash256::Hash {
838+
*hash
839+
}
834840
}
835841

836842
#[cfg(test)]

src/descriptor/mod.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ use self::checksum::verify_checksum;
3737
use crate::miniscript::{Legacy, Miniscript, Segwitv0};
3838
use crate::prelude::*;
3939
use crate::{
40-
expression, miniscript, BareCtx, Error, ForEachKey, MiniscriptKey, PkTranslator, Satisfier,
41-
ToPublicKey, TranslatePk, Translator,
40+
expression, hash256, miniscript, BareCtx, Error, ForEachKey, MiniscriptKey, PkTranslator,
41+
Satisfier, ToPublicKey, TranslatePk, Translator,
4242
};
4343

4444
mod bare;
@@ -498,7 +498,7 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Descriptor<Pk> {
498498
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
499499
where
500500
Pk: 'a,
501-
Pk::Hash: 'a,
501+
Pk::RawPkHash: 'a,
502502
{
503503
match *self {
504504
Descriptor::Bare(ref bare) => bare.for_each_key(pred),
@@ -646,6 +646,12 @@ impl Descriptor<DescriptorPublicKey> {
646646
sha256::Hash::from_str(sha256).map_err(|e| Error::Unexpected(e.to_string()))?;
647647
Ok(hash)
648648
}
649+
650+
fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, Error> {
651+
let hash = hash256::Hash::from_str(hash256)
652+
.map_err(|e| Error::Unexpected(e.to_string()))?;
653+
Ok(hash)
654+
}
649655
}
650656

651657
let descriptor = Descriptor::<String>::from_str(s)?;
@@ -672,6 +678,10 @@ impl Descriptor<DescriptorPublicKey> {
672678
fn sha256(&mut self, sha256: &sha256::Hash) -> Result<String, ()> {
673679
Ok(sha256.to_string())
674680
}
681+
682+
fn hash256(&mut self, hash256: &hash256::Hash) -> Result<String, ()> {
683+
Ok(hash256.to_string())
684+
}
675685
}
676686

677687
fn key_to_string(pk: &DescriptorPublicKey, key_map: &KeyMap) -> Result<String, ()> {

src/descriptor/segwitv0.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wsh<Pk> {
249249
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
250250
where
251251
Pk: 'a,
252-
Pk::Hash: 'a,
252+
Pk::RawPkHash: 'a,
253253
{
254254
match self.inner {
255255
WshInner::SortedMulti(ref smv) => smv.for_each_key(pred),
@@ -442,7 +442,7 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wpkh<Pk> {
442442
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
443443
where
444444
Pk: 'a,
445-
Pk::Hash: 'a,
445+
Pk::RawPkHash: 'a,
446446
{
447447
pred(&self.pk)
448448
}

src/descriptor/sh.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Sh<Pk> {
380380
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
381381
where
382382
Pk: 'a,
383-
Pk::Hash: 'a,
383+
Pk::RawPkHash: 'a,
384384
{
385385
match self.inner {
386386
ShInner::Wsh(ref wsh) => wsh.for_each_key(pred),

src/descriptor/sortedmulti.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for SortedMultiVec<Pk
115115
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
116116
where
117117
Pk: 'a,
118-
Pk::Hash: 'a,
118+
Pk::RawPkHash: 'a,
119119
{
120120
self.pks.iter().all(|key| pred(key))
121121
}

src/descriptor/tr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Tr<Pk> {
581581
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
582582
where
583583
Pk: 'a,
584-
Pk::Hash: 'a,
584+
Pk::RawPkHash: 'a,
585585
{
586586
let script_keys_res = self
587587
.iter_scripts()

src/interpreter/mod.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ use core::fmt;
2323
use core::str::FromStr;
2424

2525
use bitcoin::blockdata::witness::Witness;
26-
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};
26+
use bitcoin::hashes::{hash160, ripemd160, sha256};
2727
use bitcoin::util::{sighash, taproot};
2828
use bitcoin::{self, secp256k1, TxOut};
2929

3030
use crate::miniscript::context::NoChecks;
3131
use crate::miniscript::ScriptContext;
3232
use crate::prelude::*;
33-
use crate::{Descriptor, Miniscript, Terminal, ToPublicKey};
33+
use crate::{hash256, Descriptor, Miniscript, Terminal, ToPublicKey};
3434

3535
mod error;
3636
mod inner;
@@ -148,10 +148,11 @@ impl TypedHash160 {
148148
}
149149

150150
impl MiniscriptKey for BitcoinKey {
151-
type Hash = TypedHash160;
152-
type Sha256 = bitcoin::hashes::sha256::Hash;
151+
type RawPkHash = TypedHash160;
152+
type Sha256 = sha256::Hash;
153+
type Hash256 = hash256::Hash;
153154

154-
fn to_pubkeyhash(&self) -> Self::Hash {
155+
fn to_pubkeyhash(&self) -> Self::RawPkHash {
155156
match self {
156157
BitcoinKey::Fullkey(pk) => TypedHash160::FullKey(pk.to_pubkeyhash()),
157158
BitcoinKey::XOnlyPublicKey(pk) => TypedHash160::XonlyKey(pk.to_pubkeyhash()),
@@ -454,7 +455,7 @@ pub enum HashLockType {
454455
///SHA 256 hashlock
455456
Sha256(sha256::Hash),
456457
///Hash 256 hashlock
457-
Hash256(sha256d::Hash),
458+
Hash256(hash256::Hash),
458459
///Hash160 hashlock
459460
Hash160(hash160::Hash),
460461
///Ripemd160 hashlock
@@ -1040,7 +1041,7 @@ fn verify_sersig<'txin>(
10401041
mod tests {
10411042

10421043
use bitcoin;
1043-
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
1044+
use bitcoin::hashes::{hash160, ripemd160, sha256, Hash};
10441045
use bitcoin::secp256k1::{self, Secp256k1};
10451046

10461047
use super::inner::ToNoChecks;
@@ -1156,11 +1157,8 @@ mod tests {
11561157
let preimage = [0xab as u8; 32];
11571158
let sha256_hash = sha256::Hash::hash(&preimage);
11581159
let sha256 = no_checks_ms(&format!("sha256({})", sha256_hash));
1159-
let sha256d_hash_rev = sha256d::Hash::hash(&preimage);
1160-
let mut sha256d_hash_bytes = sha256d_hash_rev.clone().into_inner();
1161-
sha256d_hash_bytes.reverse();
1162-
let sha256d_hash = sha256d::Hash::from_inner(sha256d_hash_bytes);
1163-
let hash256 = no_checks_ms(&format!("hash256({})", sha256d_hash));
1160+
let hash256_hash = hash256::Hash::hash(&preimage);
1161+
let hash256 = no_checks_ms(&format!("hash256({})", hash256_hash));
11641162
let hash160_hash = hash160::Hash::hash(&preimage);
11651163
let hash160 = no_checks_ms(&format!("hash160({})", hash160_hash));
11661164
let ripemd160_hash = ripemd160::Hash::hash(&preimage);
@@ -1242,7 +1240,7 @@ mod tests {
12421240
assert_eq!(
12431241
sha256d_satisfied.unwrap(),
12441242
vec![SatisfiedConstraint::HashLock {
1245-
hash: HashLockType::Hash256(sha256d_hash_rev),
1243+
hash: HashLockType::Hash256(hash256_hash),
12461244
preimage: preimage,
12471245
}]
12481246
);

src/interpreter/stack.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
1717
use bitcoin;
1818
use bitcoin::blockdata::{opcodes, script};
19-
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
19+
use bitcoin::hashes::{hash160, ripemd160, sha256, Hash};
2020

2121
use super::error::PkEvalErrInner;
2222
use super::{
2323
verify_sersig, BitcoinKey, Error, HashLockType, KeySigPair, SatisfiedConstraint, TypedHash160,
2424
};
25+
use crate::hash256;
2526
use crate::prelude::*;
2627

2728
/// Definition of Stack Element of the Stack used for interpretation of Miniscript.
@@ -288,13 +289,13 @@ impl<'txin> Stack<'txin> {
288289
/// `SIZE 32 EQUALVERIFY HASH256 h EQUAL`
289290
pub(super) fn evaluate_hash256(
290291
&mut self,
291-
hash: &sha256d::Hash,
292+
hash: &hash256::Hash,
292293
) -> Option<Result<SatisfiedConstraint, Error>> {
293294
if let Some(Element::Push(preimage)) = self.pop() {
294295
if preimage.len() != 32 {
295296
return Some(Err(Error::HashPreimageLengthMismatch));
296297
}
297-
if sha256d::Hash::hash(preimage) == *hash {
298+
if hash256::Hash::hash(preimage) == *hash {
298299
self.push(Element::Satisfied);
299300
Some(Ok(SatisfiedConstraint::HashLock {
300301
hash: HashLockType::Hash256(*hash),

0 commit comments

Comments
 (0)