//! spendable on-chain outputs which the user owns and is responsible for using just as any other
//! on-chain output which is theirs.
-use bitcoin::blockdata::transaction::{Transaction, TxOut};
+use bitcoin::blockdata::transaction::{Transaction, TxOut, SigHashType};
use bitcoin::blockdata::script::{Script, Builder};
use bitcoin::blockdata::opcodes;
use bitcoin::network::constants::Network;
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &accepted_data.remote_channel_pubkeys.funding_pubkey);
- let commitment_sighash = hash_to_message!(&bip143::SighashComponents::new(&commitment_tx).sighash_all(&commitment_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]);
+ let commitment_sighash = hash_to_message!(&bip143::SigHashCache::new(commitment_tx).signature_hash(0, &channel_funding_redeemscript, self.channel_value_satoshis, SigHashType::All)[..]);
let commitment_sig = secp_ctx.sign(&commitment_sighash, &self.funding_key);
let commitment_txid = commitment_tx.txid();
if let Some(_) = htlc.transaction_output_index {
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, feerate_per_kw, accepted_data.local_to_self_delay, htlc, &keys.a_delayed_payment_key, &keys.revocation_key);
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
- let htlc_sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]);
+ let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]);
let our_htlc_key = match chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key) {
Ok(s) => s,
Err(_) => return Err(()),
};
chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.local_to_self_delay(), &remote_delayedpubkey)
};
- let sighash_parts = bip143::SighashComponents::new(&justice_tx);
- let sighash = hash_to_message!(&sighash_parts.sighash_all(&justice_tx.input[input], &witness_script, amount)[..]);
+ let mut sighash_parts = bip143::SigHashCache::new(justice_tx);
+ let sighash = hash_to_message!(&sighash_parts.signature_hash(input, &witness_script, amount, SigHashType::All)[..]);
return Ok(secp_ctx.sign(&sighash, &revocation_key))
}
} else { return Err(()) }
} else { return Err(()) }
} else { return Err(()) };
- let sighash_parts = bip143::SighashComponents::new(&htlc_tx);
- let sighash = hash_to_message!(&sighash_parts.sighash_all(&htlc_tx.input[input], &witness_script, amount)[..]);
+ let mut sighash_parts = bip143::SigHashCache::new(htlc_tx);
+ let sighash = hash_to_message!(&sighash_parts.signature_hash(input, &witness_script, amount, SigHashType::All)[..]);
return Ok(secp_ctx.sign(&sighash, &htlc_key))
}
Err(())
let remote_channel_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_data.remote_channel_pubkeys.funding_pubkey);
- let sighash = hash_to_message!(&bip143::SighashComponents::new(closing_tx)
- .sighash_all(&closing_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]);
+ let sighash = hash_to_message!(&bip143::SigHashCache::new(closing_tx)
+ .signature_hash(0, &channel_funding_redeemscript, self.channel_value_satoshis, SigHashType::All)[..]);
Ok(secp_ctx.sign(&sighash, &self.funding_key))
}
/// ChannelKeys::sign_local_commitment() calls directly.
/// Channel value is amount locked in funding_outpoint.
pub fn get_local_sig<T: secp256k1::Signing>(&self, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1<T>) -> Signature {
- let sighash = hash_to_message!(&bip143::SighashComponents::new(&self.unsigned_tx)
- .sighash_all(&self.unsigned_tx.input[0], funding_redeemscript, channel_value_satoshis)[..]);
+ let sighash = hash_to_message!(&bip143::SigHashCache::new(&self.unsigned_tx)
+ .signature_hash(0, funding_redeemscript, channel_value_satoshis, SigHashType::All)[..]);
secp_ctx.sign(&sighash, funding_key)
}
let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc.0, &self.local_keys.a_htlc_key, &self.local_keys.b_htlc_key, &self.local_keys.revocation_key);
- let sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, this_htlc.0.amount_msat / 1000)[..]);
+ let sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, this_htlc.0.amount_msat / 1000, SigHashType::All)[..]);
ret.push(Some(secp_ctx.sign(&sighash, &our_htlc_key)));
} else {
ret.push(None);
let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw, logger).0;
- let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]);
+ let local_sighash = hash_to_message!(&bip143::SigHashCache::new(&local_initial_commitment_tx).signature_hash(0, &funding_script, self.channel_value_satoshis, SigHashType::All)[..]);
// They sign the "local" commitment transaction...
log_trace!(logger, "Checking funding_created tx signature {} by key {} against tx {} (sighash {}) with redeemscript {}", log_bytes!(sig.serialize_compact()[..]), log_bytes!(self.their_funding_pubkey().serialize()), encode::serialize_hex(&local_initial_commitment_tx), log_bytes!(local_sighash[..]), encode::serialize_hex(&funding_script));
let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw, logger).0;
- let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]);
+ let local_sighash = hash_to_message!(&bip143::SigHashCache::new(&local_initial_commitment_tx).signature_hash(0, &funding_script, self.channel_value_satoshis, SigHashType::All)[..]);
let their_funding_pubkey = &self.their_pubkeys.as_ref().unwrap().funding_pubkey;
(commitment_tx.0, commitment_tx.1, htlcs_cloned)
};
let local_commitment_txid = local_commitment_tx.0.txid();
- let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_commitment_tx.0).sighash_all(&local_commitment_tx.0.input[0], &funding_script, self.channel_value_satoshis)[..]);
+ let local_sighash = hash_to_message!(&bip143::SigHashCache::new(&local_commitment_tx.0).signature_hash(0, &funding_script, self.channel_value_satoshis, SigHashType::All)[..]);
log_trace!(logger, "Checking commitment tx signature {} by key {} against tx {} (sighash {}) with redeemscript {}", log_bytes!(msg.signature.serialize_compact()[..]), log_bytes!(self.their_funding_pubkey().serialize()), encode::serialize_hex(&local_commitment_tx.0), log_bytes!(local_sighash[..]), encode::serialize_hex(&funding_script));
if let Err(_) = self.secp_ctx.verify(&local_sighash, &msg.signature, &self.their_funding_pubkey()) {
return Err((None, ChannelError::Close("Invalid commitment tx signature from peer".to_owned())));
if let Some(_) = htlc.transaction_output_index {
let htlc_tx = self.build_htlc_transaction(&local_commitment_txid, &htlc, true, &local_keys, feerate_per_kw);
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &local_keys);
- let htlc_sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]);
+ let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]);
log_trace!(logger, "Checking HTLC tx signature {} by key {} against tx {} (sighash {}) with redeemscript {}", log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), log_bytes!(local_keys.b_htlc_key.serialize()), encode::serialize_hex(&htlc_tx), log_bytes!(htlc_sighash[..]), encode::serialize_hex(&htlc_redeemscript));
if let Err(_) = self.secp_ctx.verify(&htlc_sighash, &msg.htlc_signatures[idx], &local_keys.b_htlc_key) {
return Err((None, ChannelError::Close("Invalid HTLC tx signature from peer".to_owned())));
if used_total_fee != msg.fee_satoshis {
return Err(ChannelError::Close(format!("Remote sent us a closing_signed with a fee greater than the value they can claim. Fee in message: {}", msg.fee_satoshis)));
}
- let mut sighash = hash_to_message!(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]);
+ let mut sighash = hash_to_message!(&bip143::SigHashCache::new(&closing_tx).signature_hash(0, &funding_redeemscript, self.channel_value_satoshis, SigHashType::All)[..]);
let their_funding_pubkey = &self.their_pubkeys.as_ref().unwrap().funding_pubkey;
// The remote end may have decided to revoke their output due to inconsistent dust
// limits, so check for that case by re-checking the signature here.
closing_tx = self.build_closing_transaction(msg.fee_satoshis, true).0;
- sighash = hash_to_message!(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]);
+ sighash = hash_to_message!(&bip143::SigHashCache::new(&closing_tx).signature_hash(0, &funding_redeemscript, self.channel_value_satoshis, SigHashType::All)[..]);
secp_check!(self.secp_ctx.verify(&sighash, &msg.signature, self.their_funding_pubkey()), "Invalid closing tx signature from peer".to_owned());
},
};
use bitcoin::util::bip143;
use bitcoin::consensus::encode::serialize;
use bitcoin::blockdata::script::{Script, Builder};
- use bitcoin::blockdata::transaction::{Transaction, TxOut};
+ use bitcoin::blockdata::transaction::{Transaction, TxOut, SigHashType};
use bitcoin::blockdata::constants::genesis_block;
use bitcoin::blockdata::opcodes;
use bitcoin::network::constants::Network;
};
let redeemscript = chan.get_funding_redeemscript();
let their_signature = Signature::from_der(&hex::decode($their_sig_hex).unwrap()[..]).unwrap();
- let sighash = Message::from_slice(&bip143::SighashComponents::new(&unsigned_tx.0).sighash_all(&unsigned_tx.0.input[0], &redeemscript, chan.channel_value_satoshis)[..]).unwrap();
+ let sighash = Message::from_slice(&bip143::SigHashCache::new(&unsigned_tx.0).signature_hash(0, &redeemscript, chan.channel_value_satoshis, SigHashType::All)[..]).unwrap();
secp_ctx.verify(&sighash, &their_signature, chan.their_funding_pubkey()).unwrap();
let mut per_htlc = Vec::new();
let ref htlc = unsigned_tx.1[$htlc_idx];
let htlc_tx = chan.build_htlc_transaction(&unsigned_tx.0.txid(), &htlc, true, &keys, chan.feerate_per_kw);
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
- let htlc_sighash = Message::from_slice(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]).unwrap();
+ let htlc_sighash = Message::from_slice(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]).unwrap();
secp_ctx.verify(&htlc_sighash, &remote_signature, &keys.b_htlc_key).unwrap();
let mut preimage: Option<PaymentPreimage> = None;
let mut sum_actual_sigs = 0;
macro_rules! sign_input {
- ($sighash_parts: expr, $input: expr, $idx: expr, $amount: expr, $input_type: expr, $sum_actual_sigs: expr) => {
+ ($sighash_parts: expr, $idx: expr, $amount: expr, $input_type: expr, $sum_actual_sigs: expr) => {
let htlc = HTLCOutputInCommitment {
offered: if *$input_type == InputDescriptors::RevokedOfferedHTLC || *$input_type == InputDescriptors::OfferedHTLC { true } else { false },
amount_msat: 0,
cltv_expiry: 2 << 16,
payment_hash: PaymentHash([1; 32]),
- transaction_output_index: Some($idx),
+ transaction_output_index: Some($idx as u32),
};
let redeem_script = if *$input_type == InputDescriptors::RevokedOutput { chan_utils::get_revokeable_redeemscript(&pubkey, 256, &pubkey) } else { chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &pubkey, &pubkey, &pubkey) };
- let sighash = hash_to_message!(&$sighash_parts.sighash_all(&$input, &redeem_script, $amount)[..]);
+ let sighash = hash_to_message!(&$sighash_parts.signature_hash($idx, &redeem_script, $amount, SigHashType::All)[..]);
let sig = secp_ctx.sign(&sighash, &privkey);
- $input.witness.push(sig.serialize_der().to_vec());
- $input.witness[0].push(SigHashType::All as u8);
- sum_actual_sigs += $input.witness[0].len();
+ $sighash_parts.access_witness($idx).push(sig.serialize_der().to_vec());
+ $sighash_parts.access_witness($idx)[0].push(SigHashType::All as u8);
+ sum_actual_sigs += $sighash_parts.access_witness($idx)[0].len();
if *$input_type == InputDescriptors::RevokedOutput {
- $input.witness.push(vec!(1));
+ $sighash_parts.access_witness($idx).push(vec!(1));
} else if *$input_type == InputDescriptors::RevokedOfferedHTLC || *$input_type == InputDescriptors::RevokedReceivedHTLC {
- $input.witness.push(pubkey.clone().serialize().to_vec());
+ $sighash_parts.access_witness($idx).push(pubkey.clone().serialize().to_vec());
} else if *$input_type == InputDescriptors::ReceivedHTLC {
- $input.witness.push(vec![0]);
+ $sighash_parts.access_witness($idx).push(vec![0]);
} else {
- $input.witness.push(PaymentPreimage([1; 32]).0.to_vec());
+ $sighash_parts.access_witness($idx).push(PaymentPreimage([1; 32]).0.to_vec());
}
- $input.witness.push(redeem_script.into_bytes());
- println!("witness[0] {}", $input.witness[0].len());
- println!("witness[1] {}", $input.witness[1].len());
- println!("witness[2] {}", $input.witness[2].len());
+ $sighash_parts.access_witness($idx).push(redeem_script.into_bytes());
+ println!("witness[0] {}", $sighash_parts.access_witness($idx)[0].len());
+ println!("witness[1] {}", $sighash_parts.access_witness($idx)[1].len());
+ println!("witness[2] {}", $sighash_parts.access_witness($idx)[2].len());
}
}
value: 0,
});
let base_weight = claim_tx.get_weight();
- let sighash_parts = bip143::SighashComponents::new(&claim_tx);
let inputs_des = vec![InputDescriptors::RevokedOutput, InputDescriptors::RevokedOfferedHTLC, InputDescriptors::RevokedOfferedHTLC, InputDescriptors::RevokedReceivedHTLC];
- for (idx, inp) in claim_tx.input.iter_mut().zip(inputs_des.iter()).enumerate() {
- sign_input!(sighash_parts, inp.0, idx as u32, 0, inp.1, sum_actual_sigs);
+ {
+ let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
+ for (idx, inp) in inputs_des.iter().enumerate() {
+ sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
+ }
}
assert_eq!(base_weight + OnchainTxHandler::<InMemoryChannelKeys>::get_witnesses_weight(&inputs_des[..]), claim_tx.get_weight() + /* max_length_sig */ (73 * inputs_des.len() - sum_actual_sigs));
});
}
let base_weight = claim_tx.get_weight();
- let sighash_parts = bip143::SighashComponents::new(&claim_tx);
let inputs_des = vec![InputDescriptors::OfferedHTLC, InputDescriptors::ReceivedHTLC, InputDescriptors::ReceivedHTLC, InputDescriptors::ReceivedHTLC];
- for (idx, inp) in claim_tx.input.iter_mut().zip(inputs_des.iter()).enumerate() {
- sign_input!(sighash_parts, inp.0, idx as u32, 0, inp.1, sum_actual_sigs);
+ {
+ let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
+ for (idx, inp) in inputs_des.iter().enumerate() {
+ sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
+ }
}
assert_eq!(base_weight + OnchainTxHandler::<InMemoryChannelKeys>::get_witnesses_weight(&inputs_des[..]), claim_tx.get_weight() + /* max_length_sig */ (73 * inputs_des.len() - sum_actual_sigs));
witness: Vec::new(),
});
let base_weight = claim_tx.get_weight();
- let sighash_parts = bip143::SighashComponents::new(&claim_tx);
let inputs_des = vec![InputDescriptors::RevokedOutput];
- for (idx, inp) in claim_tx.input.iter_mut().zip(inputs_des.iter()).enumerate() {
- sign_input!(sighash_parts, inp.0, idx as u32, 0, inp.1, sum_actual_sigs);
+ {
+ let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
+ for (idx, inp) in inputs_des.iter().enumerate() {
+ sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
+ }
}
assert_eq!(base_weight + OnchainTxHandler::<InMemoryChannelKeys>::get_witnesses_weight(&inputs_des[..]), claim_tx.get_weight() + /* max_length_isg */ (73 * inputs_des.len() - sum_actual_sigs));
}
let keys = $keysinterface.derive_channel_keys($chan_value, key_derivation_params.0, key_derivation_params.1);
let remotepubkey = keys.pubkeys().payment_point;
let witness_script = Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: remotepubkey}, Network::Testnet).script_pubkey();
- let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap();
+ let sighash = Message::from_slice(&bip143::SigHashCache::new(&spend_tx).signature_hash(0, &witness_script, output.value, SigHashType::All)[..]).unwrap();
let remotesig = secp_ctx.sign(&sighash, &keys.inner.payment_key);
spend_tx.input[0].witness.push(remotesig.serialize_der().to_vec());
spend_tx.input[0].witness[0].push(SigHashType::All as u8);
let delayed_payment_pubkey = PublicKey::from_secret_key(&secp_ctx, &delayed_payment_key);
let witness_script = chan_utils::get_revokeable_redeemscript(remote_revocation_pubkey, *to_self_delay, &delayed_payment_pubkey);
- let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap();
+ let sighash = Message::from_slice(&bip143::SigHashCache::new(&spend_tx).signature_hash(0, &witness_script, output.value, SigHashType::All)[..]).unwrap();
let local_delayedsig = secp_ctx.sign(&sighash, &delayed_payment_key);
spend_tx.input[0].witness.push(local_delayedsig.serialize_der().to_vec());
spend_tx.input[0].witness[0].push(SigHashType::All as u8);
};
let pubkey = ExtendedPubKey::from_private(&secp_ctx, &secret).public_key;
let witness_script = Address::p2pkh(&pubkey, Network::Testnet).script_pubkey();
- let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap();
+ let sighash = Message::from_slice(&bip143::SigHashCache::new(&spend_tx).signature_hash(0, &witness_script, output.value, SigHashType::All)[..]).unwrap();
let sig = secp_ctx.sign(&sighash, &secret.private_key.key);
spend_tx.input[0].witness.push(sig.serialize_der().to_vec());
spend_tx.input[0].witness[0].push(SigHashType::All as u8);
use std::cmp;
use std::sync::{Mutex, Arc};
-use bitcoin::blockdata::transaction::Transaction;
+use bitcoin::blockdata::transaction::{Transaction, SigHashType};
use bitcoin::util::bip143;
use bitcoin::secp256k1;
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&this_htlc.0, &local_commitment_tx.local_keys);
- let sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, this_htlc.0.amount_msat / 1000)[..]);
+ let sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, this_htlc.0.amount_msat / 1000, SigHashType::All)[..]);
secp_ctx.verify(&sighash, this_htlc.1.as_ref().unwrap(), &local_commitment_tx.local_keys.b_htlc_key).unwrap();
}
}