You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Verify the holder provided valid witnesses and uses SIGHASH_ALL
LDK checks the following:
* Each input spends an output that is one of P2WPKH, P2WSH, or P2TR.
These were already checked by LDK when the inputs to be contributed
were provided.
* All signatures use the `SIGHASH_ALL` sighash type.
* P2WPKH and P2TR key path spends are valid (verifies signatures)
NOTE:
* When checking P2WSH spends, LDK tries to decode 70-72 byte witness
elements as ECDSA signatures with a sighash flag. If the internal
DER-decoding fails, then LDK just assumes it wasn't a signature and
carries with checks. If the element can be decoded as an ECDSA
signature, the the sighash flag must be `SIGHASH_ALL`.
* When checking P2TR script-path spends, LDK assumes all elements of
exactly 65 bytes with the last byte matching any valid sighash flag
byte are schnorr signatures and checks that the sighash type is
`SIGHASH_ALL`. If the last byte is not any valid sighash flag, the
element is assumed not to be a signature and is ignored. Elements of
64 bytes are not checked because if they were schnorr signatures then
they would implicitly be `SIGHASH_DEFAULT` which is an alias of
`SIGHASH_ALL`.
'inputs: for ((input_idx, input), witness) in script_pubkeys.zip(witnesses) {
7608
+
let prev_output = input.prev_output();
7609
+
let script_pubkey = &prev_output.script_pubkey;
7610
+
7611
+
// P2WPKH
7612
+
if script_pubkey.is_p2wpkh() {
7613
+
if witness.len() != 2 {
7614
+
return Err(APIError::APIMisuseError {
7615
+
err: format!(
7616
+
"The witness for input at index {input_idx} does not have the correct number of elements for a P2WPKH spend. Expected 2 got {}",
7617
+
witness.len()
7618
+
),
7619
+
});
7620
+
}
7621
+
let sighash = cache
7622
+
.p2wpkh_signature_hash(
7623
+
input_idx,
7624
+
script_pubkey,
7625
+
prev_output.value,
7626
+
EcdsaSighashType::All,
7627
+
)
7628
+
.expect("Transaction is ready for signing");
7629
+
let msg = Message::from_digest_slice(&sighash[..]).unwrap();
7630
+
let pubkey = PublicKey::from_slice(&witness[1]).map_err(|_| APIError::APIMisuseError { err: format!("The witness for input at index {input_idx} contains an invalid ECDSA public key") })?;
7631
+
let sig = bitcoin::ecdsa::Signature::from_slice(&witness[0]).map_err(|_| APIError::APIMisuseError { err: format!("The witness for input at index {input_idx} contains an invalid signature") })?;
_ => return Err(APIError::APIMisuseError { err: format!("The scriptPubKey of the previous output for input at index {input_idx} for a P2TR key path spend has an invalid public key") }),
let sig = bitcoin::taproot::Signature::from_slice(&witness[0]).map_err(|_| APIError::APIMisuseError { err: format!("The witness for input at index {input_idx} for a P2TR key path spend has an invalid signature") })?;
0 commit comments