Skip to content

Commit e53ca8a

Browse files
committed
use bitcoin_hashes 1.0 throughout the codebase
This is a fairly big commit but it's mostly mechanical and it didn't seem super helpful to pull it out into multiple commits. The bulk of the prepatory work was done in #278.
1 parent 3baff6a commit e53ca8a

18 files changed

Lines changed: 185 additions & 163 deletions

elementsd-tests/src/pset.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use crate::{setup, Call};
88

99
use bitcoin::{self, Address, Amount};
1010
use elements::encode::serialize;
11-
use elements::hashes::Hash;
1211
use elements::hex::DisplayHex as _;
1312
use elements::pset::PartiallySignedTransaction;
1413
use elements::{AssetId, ContractHash};

elementsd-tests/src/taproot.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use bitcoin::Amount;
1010
use elements::hex;
1111
use elements::confidential::{AssetBlindingFactor, ValueBlindingFactor};
1212
use elements::encode::{deserialize, serialize_hex};
13-
use elements::hashes::Hash;
1413
use elements::script::Builder;
1514
use elements::secp256k1_zkp;
1615
use elements::sighash::{self, SighashCache};
@@ -215,7 +214,7 @@ fn taproot_spend_test(
215214
);
216215
let tweak = secp256k1_zkp::Scalar::from_be_bytes(tweak.to_byte_array()).expect("hash value greater than curve order");
217216
let sig = secp.sign_schnorr(
218-
&secp256k1_zkp::Message::from_digest_slice(&sighash_msg[..]).unwrap(),
217+
&secp256k1_zkp::Message::from_digest(sighash_msg.to_byte_array()),
219218
&output_keypair.add_xonly_tweak(secp, &tweak).unwrap(),
220219
);
221220

@@ -239,7 +238,7 @@ fn taproot_spend_test(
239238
.unwrap();
240239

241240
let sig = secp.sign_schnorr(
242-
&secp256k1_zkp::Message::from_digest_slice(&sighash_msg[..]).unwrap(),
241+
&secp256k1_zkp::Message::from_digest(sighash_msg.to_byte_array()),
243242
&test_data.leaf1_keypair,
244243
);
245244

src/address.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@
1515
//! # Addresses
1616
//!
1717
18-
use std::convert::TryFrom as _;
18+
use std::convert::{TryFrom as _, TryInto as _};
1919
use std::error;
2020
use std::fmt;
2121
use std::fmt::Write as _;
2222
use std::str::FromStr;
2323

2424
use bech32::{Bech32, Bech32m, ByteIterExt, Fe32, Fe32IterExt, Hrp};
2525
use crate::blech32::{Blech32, Blech32m};
26-
use crate::hashes::Hash;
2726
use bitcoin::base58;
27+
use bitcoin::hashes::Hash as _;
2828
use bitcoin::PublicKey;
2929
use internals::array::ArrayExt as _;
3030
use internals::slice::SliceExt;
@@ -329,12 +329,12 @@ impl Address {
329329
) -> Address {
330330
let ws = script::Builder::new()
331331
.push_int(0)
332-
.push_slice(&WScriptHash::hash(&script[..])[..])
332+
.push_slice(WScriptHash::hash_script(script).as_ref())
333333
.into_script();
334334

335335
Address {
336336
params,
337-
payload: Payload::ScriptHash(ScriptHash::hash(&ws[..])),
337+
payload: Payload::ScriptHash(ScriptHash::hash_script(&ws)),
338338
blinding_pubkey: blinder,
339339
}
340340
}
@@ -386,9 +386,9 @@ impl Address {
386386
) -> Option<Address> {
387387
Some(Address {
388388
payload: if script.is_p2pkh() {
389-
Payload::PubkeyHash(Hash::from_slice(&script.as_bytes()[3..23]).unwrap())
389+
Payload::PubkeyHash(PubkeyHash::from_byte_array(script.as_bytes()[3..23].try_into().unwrap()))
390390
} else if script.is_p2sh() {
391-
Payload::ScriptHash(Hash::from_slice(&script.as_bytes()[2..22]).unwrap())
391+
Payload::ScriptHash(ScriptHash::from_byte_array(script.as_bytes()[2..22].try_into().unwrap()))
392392
} else if script.is_v0_p2wpkh() {
393393
Payload::WitnessProgram {
394394
version: Fe32::Q,
@@ -418,12 +418,12 @@ impl Address {
418418
Payload::PubkeyHash(ref hash) => script::Builder::new()
419419
.push_opcode(opcodes::all::OP_DUP)
420420
.push_opcode(opcodes::all::OP_HASH160)
421-
.push_slice(&hash[..])
421+
.push_slice(hash.as_ref())
422422
.push_opcode(opcodes::all::OP_EQUALVERIFY)
423423
.push_opcode(opcodes::all::OP_CHECKSIG),
424424
Payload::ScriptHash(ref hash) => script::Builder::new()
425425
.push_opcode(opcodes::all::OP_HASH160)
426-
.push_slice(&hash[..])
426+
.push_slice(hash.as_byte_array())
427427
.push_opcode(opcodes::all::OP_EQUAL),
428428
Payload::WitnessProgram {
429429
version: witver,
@@ -566,12 +566,12 @@ impl fmt::Display for Address {
566566
prefixed[0] = self.params.blinded_prefix;
567567
prefixed[1] = self.params.p2pkh_prefix;
568568
prefixed[2..35].copy_from_slice(&blinder.serialize());
569-
prefixed[35..].copy_from_slice(&hash[..]);
569+
prefixed[35..].copy_from_slice(hash.as_ref());
570570
base58::encode_check_to_fmt(fmt, &prefixed[..])
571571
} else {
572572
let mut prefixed = [0; 21];
573573
prefixed[0] = self.params.p2pkh_prefix;
574-
prefixed[1..].copy_from_slice(&hash[..]);
574+
prefixed[1..].copy_from_slice(hash.as_ref());
575575
base58::encode_check_to_fmt(fmt, &prefixed[..])
576576
}
577577
}
@@ -581,12 +581,12 @@ impl fmt::Display for Address {
581581
prefixed[0] = self.params.blinded_prefix;
582582
prefixed[1] = self.params.p2sh_prefix;
583583
prefixed[2..35].copy_from_slice(&blinder.serialize());
584-
prefixed[35..].copy_from_slice(&hash[..]);
584+
prefixed[35..].copy_from_slice(hash.as_byte_array());
585585
base58::encode_check_to_fmt(fmt, &prefixed[..])
586586
} else {
587587
let mut prefixed = [0; 21];
588588
prefixed[0] = self.params.p2sh_prefix;
589-
prefixed[1..].copy_from_slice(&hash[..]);
589+
prefixed[1..].copy_from_slice(hash.as_byte_array());
590590
base58::encode_check_to_fmt(fmt, &prefixed[..])
591591
}
592592
}
@@ -937,7 +937,7 @@ mod test {
937937
"93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51",
938938
)
939939
.unwrap();
940-
let tap_node_hash = TapNodeHash::all_zeros();
940+
let tap_node_hash = TapNodeHash::from_byte_array([0; 32]);
941941

942942
let mut expected = IntoIterator::into_iter([
943943
"2dszRCFv8Ub4ytKo1Q1vXXGgSx7mekNDwSJ",

src/block.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::io;
2121
#[cfg(feature = "serde")] use std::fmt;
2222

2323
use crate::dynafed;
24-
use crate::hashes::Hash;
24+
use crate::hashes::{HashEngine as _, sha256d};
2525
use crate::Transaction;
2626
use crate::encode::{self, serialize, Decodable, Encodable, VarInt};
2727
use crate::{BlockHash, Script, TxMerkleNode};
@@ -235,7 +235,7 @@ impl BlockHeader {
235235
};
236236

237237
// Everything except the signblock witness goes into the hash
238-
let mut enc = BlockHash::engine();
238+
let mut enc = sha256d::Hash::engine();
239239
version.consensus_encode(&mut enc).unwrap();
240240
self.prev_blockhash.consensus_encode(&mut enc).unwrap();
241241
self.merkle_root.consensus_encode(&mut enc).unwrap();
@@ -250,7 +250,7 @@ impl BlockHeader {
250250
proposed.consensus_encode(&mut enc).unwrap();
251251
},
252252
}
253-
BlockHash::from_engine(enc)
253+
BlockHash(enc.finalize())
254254
}
255255

256256
/// Returns true if this is a block with dynamic federations enabled.

src/confidential.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
//! Structures representing Pedersen commitments of various types
1818
//!
1919
20-
use crate::hashes::{sha256d, Hash};
20+
use crate::hashes::sha256d;
2121
use secp256k1_zkp::{self, CommitmentSecrets, Generator, PedersenCommitment,
2222
PublicKey, Secp256k1, SecretKey, Signing, Tweak, ZERO_TWEAK,
2323
compute_adaptive_blinding_factor,

src/dynafed.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
2323
use serde::ser::{SerializeSeq, SerializeStruct};
2424

2525
use crate::encode::{self, Encodable, Decodable};
26-
use crate::hashes::{Hash, sha256d};
26+
use crate::hashes::sha256d;
2727
use crate::Script;
2828

2929
impl_sha256_midstate_wrapper! {
@@ -149,7 +149,7 @@ impl FullParams {
149149
let compact_root = crate::fast_merkle_root::fast_merkle_root(&leaves[..]);
150150

151151
let leaves = [
152-
compact_root.to_byte_array(),
152+
compact_root.to_parts().0,
153153
self.extra_root().to_byte_array(),
154154
];
155155
ParamsRoot::from_midstate(crate::fast_merkle_root::fast_merkle_root(&leaves[..]))
@@ -364,7 +364,7 @@ impl Params {
364364
serialize_hash(self.signblockscript().unwrap()).to_byte_array(),
365365
serialize_hash(&self.signblock_witness_limit().unwrap()).to_byte_array(),
366366
];
367-
let compact_root = crate::fast_merkle_root::fast_merkle_root(&leaves[..]);
367+
let compact_root = ElidedRoot::from_midstate(crate::fast_merkle_root::fast_merkle_root(&leaves[..]));
368368

369369
let leaves = [
370370
compact_root.to_byte_array(),
@@ -718,8 +718,8 @@ mod tests {
718718
signblock_witness: vec![],
719719
},
720720
version: Default::default(),
721-
prev_blockhash: BlockHash::all_zeros(),
722-
merkle_root: TxMerkleNode::all_zeros(),
721+
prev_blockhash: BlockHash::GENESIS_PREVIOUS_BLOCK_HASH,
722+
merkle_root: TxMerkleNode::from_byte_array([0; 32]),
723723
time: Default::default(),
724724
height: Default::default(),
725725
};

src/encode.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,16 +298,14 @@ impl Decodable for bitcoin::ScriptBuf {
298298
}
299299
}
300300

301-
impl Encodable for bitcoin::hashes::sha256d::Hash {
301+
impl Encodable for hashes::sha256d::Hash {
302302
fn consensus_encode<W: io::Write>(&self, mut w: W) -> Result<usize, Error> {
303303
self.as_byte_array().consensus_encode(&mut w)
304304
}
305305
}
306-
impl Decodable for bitcoin::hashes::sha256d::Hash {
306+
impl Decodable for hashes::sha256d::Hash {
307307
fn consensus_decode<D: io::Read>(d: D) -> Result<Self, Error> {
308-
Ok(Self::from_byte_array(
309-
<<Self as Hash>::Bytes>::consensus_decode(d)?,
310-
))
308+
Ok(Self::from_byte_array(<[u8; 32]>::consensus_decode(d)?))
311309
}
312310
}
313311

src/fast_merkle_root.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
1313
//
1414

15-
use crate::hashes::{sha256, Hash, HashEngine};
15+
use crate::hashes::{sha256, HashEngine};
1616

1717
/// Calculate a single sha256 midstate hash of the given left and right leaves.
1818
#[inline]
1919
fn sha256midstate(left: &[u8], right: &[u8]) -> sha256::Midstate {
2020
let mut engine = sha256::Hash::engine();
2121
engine.input(left);
2222
engine.input(right);
23-
engine.midstate()
23+
engine.midstate().expect("hashing exactly 64 bytes")
2424
}
2525

2626
/// Compute the Merkle root of the give hashes using mid-state only.
@@ -45,14 +45,14 @@ pub fn fast_merkle_root(leaves: &[[u8; 32]]) -> sha256::Midstate {
4545
let mut inner: [sha256::Midstate; 32] = Default::default();
4646
let mut count: u32 = 0;
4747
while (count as usize) < leaves.len() {
48-
let mut temp_hash = sha256::Midstate::from_byte_array(leaves[count as usize]);
48+
let mut temp_hash = sha256::Midstate::new(leaves[count as usize], 64);
4949
count += 1;
5050
// For each of the lower bits in count that are 0, do 1 step. Each
5151
// corresponds to an inner value that existed before processing the
5252
// current leaf, and each needs a hash to combine it.
5353
let mut level = 0;
5454
while count & (1u32 << level) == 0 {
55-
temp_hash = sha256midstate(&inner[level][..], &temp_hash[..]);
55+
temp_hash = sha256midstate(inner[level].as_parts().0, temp_hash.as_parts().0);
5656
level += 1;
5757
}
5858
// Store the resulting hash at inner position level.
@@ -81,7 +81,7 @@ pub fn fast_merkle_root(leaves: &[[u8; 32]]) -> sha256::Midstate {
8181
count += 1 << level;
8282
level += 1;
8383
while count & (1u32 << level) == 0 {
84-
result_hash = sha256midstate(&inner[level][..], &result_hash[..]);
84+
result_hash = sha256midstate(inner[level].as_parts().0, result_hash.as_parts().0);
8585
level += 1;
8686
}
8787
}
@@ -92,11 +92,15 @@ pub fn fast_merkle_root(leaves: &[[u8; 32]]) -> sha256::Midstate {
9292
#[cfg(test)]
9393
mod tests {
9494
use super::fast_merkle_root;
95-
use crate::hashes::sha256;
96-
use std::str::FromStr;
9795

9896
#[test]
9997
fn test_fast_merkle_root() {
98+
fn decode_hex(hex: &str) -> [u8; 32] {
99+
let mut ret = hex::decode_to_array(hex).unwrap();
100+
ret.reverse();
101+
ret
102+
}
103+
100104
// unit test vectors from Elements Core
101105
let test_leaves = [
102106
"b66b041650db0f297b53f8d93c0e8706925bf3323f8c59c14a6fac37bfdcd06f",
@@ -116,9 +120,9 @@ mod tests {
116120
let mut leaves = vec![];
117121
for i in 0..4 {
118122
let root = fast_merkle_root(&leaves);
119-
assert_eq!(root, FromStr::from_str(test_roots[i]).unwrap(), "root #{}", i);
120-
leaves.push(sha256::Midstate::from_str(test_leaves[i]).unwrap().to_byte_array());
123+
assert_eq!(root.to_parts().0, decode_hex(test_roots[i]), "root #{i}");
124+
leaves.push(decode_hex(test_leaves[i]));
121125
}
122-
assert_eq!(fast_merkle_root(&leaves), FromStr::from_str(test_roots[4]).unwrap());
126+
assert_eq!(fast_merkle_root(&leaves).to_parts().0, decode_hex(test_roots[4]));
123127
}
124128
}

src/hash_types.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//! to avoid mixing data of the same hash format (like `SHA256d`) but of different meaning
1919
//! (transaction id, block hash etc).
2020
21-
use crate::hashes::{hash160, hash_newtype, sha256, sha256d, Hash};
21+
use crate::hashes::{hash160, sha256, sha256d};
2222

2323
// Re-export bitcoin's pubkeyhash types. We already re-export bitcoin's `PublicKey` type.
2424
pub use bitcoin::{PubkeyHash, WPubkeyHash};
@@ -30,7 +30,7 @@ macro_rules! impl_hashencode {
3030
&self,
3131
w: W,
3232
) -> Result<usize, crate::encode::Error> {
33-
self.0.consensus_encode(w)
33+
self.as_byte_array().consensus_encode(w)
3434
}
3535
}
3636

@@ -44,32 +44,53 @@ macro_rules! impl_hashencode {
4444
};
4545
}
4646

47-
hash_newtype! {
47+
hashes::hash_newtype! {
4848
/// An elements transaction ID
49-
pub struct Txid(sha256d::Hash);
49+
pub struct Txid(pub(crate) sha256d::Hash);
5050
/// An elements witness transaction ID
51-
pub struct Wtxid(sha256d::Hash);
51+
pub struct Wtxid(pub(crate) sha256d::Hash);
5252
/// An elements blockhash
53-
pub struct BlockHash(sha256d::Hash);
53+
pub struct BlockHash(pub(crate) sha256d::Hash);
5454

5555
/// "Hash of the transaction according to the signature algorithm"
56-
pub struct Sighash(sha256d::Hash);
56+
pub struct Sighash(pub(crate) sha256d::Hash);
5757

5858
/// A hash of Bitcoin Script bytecode.
59-
pub struct ScriptHash(hash160::Hash);
59+
pub struct ScriptHash(pub(crate) hash160::Hash);
6060
/// SegWit version of a Bitcoin Script bytecode hash.
61-
pub struct WScriptHash(sha256::Hash);
61+
pub struct WScriptHash(pub(crate) sha256::Hash);
6262

6363
/// A hash of the Merkle tree branch or root for transactions
6464
pub struct TxMerkleNode(sha256d::Hash);
6565
}
6666

67+
68+
hashes::impl_hex_for_newtype!(Txid, Wtxid, BlockHash, ScriptHash, WScriptHash, TxMerkleNode);
69+
#[cfg(feature = "serde")]
70+
hashes::impl_serde_for_newtype!(Txid, Wtxid, BlockHash, ScriptHash, WScriptHash, TxMerkleNode);
71+
// We do not implement serde or display/fromstr for 'Sighash'. In general it's dangerous
72+
// to deserialize sighashes; they must be the output of a cryptographic hash function.
73+
hashes::impl_debug_only_for_newtype!(Sighash);
74+
6775
impl_hashencode!(Txid);
6876
impl_hashencode!(Wtxid);
6977
impl_hashencode!(Sighash);
7078
impl_hashencode!(BlockHash);
7179
impl_hashencode!(TxMerkleNode);
7280

81+
impl BlockHash {
82+
/// Dummy hash used as the previous blockhash of the genesis block.
83+
pub const GENESIS_PREVIOUS_BLOCK_HASH: Self = Self::from_byte_array([0; 32]);
84+
}
85+
86+
impl Txid {
87+
/// The `Txid` used in a coinbase prevout.
88+
///
89+
/// This is used as the "txid" of the dummy input of a coinbase transaction. This is not a real
90+
/// TXID and should not be used in any other contexts.
91+
pub const COINBASE_PREVOUT: Self = Self::from_byte_array([0; 32]);
92+
}
93+
7394
impl ScriptHash {
7495
/// Computes the `ScriptHash` of a script.
7596
pub fn hash_script(s: &crate::Script) -> Self {

src/internal_macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ macro_rules! impl_sha256_midstate_wrapper {
422422

423423
/// (Private) convert a sha256 midstate to an object.
424424
fn from_midstate(value: crate::hashes::sha256::Midstate) -> Self {
425-
Self(value.to_byte_array())
425+
Self(value.to_parts().0)
426426
}
427427
}
428428

0 commit comments

Comments
 (0)