// SPDX-License-Identifier: CC0-1.0 //! PSBT serialization. //! //! Defines traits used for (de)serializing PSBT values into/from raw //! bytes from/as PSBT key-value pairs. //! use crate::prelude::*; use crate::io; use crate::blockdata::script::Script; use crate::blockdata::witness::Witness; use crate::blockdata::transaction::{Transaction, TxOut}; use crate::consensus::encode::{self, serialize, Decodable, Encodable, deserialize_partial}; use secp256k1::{self, XOnlyPublicKey}; use crate::bip32::{ChildNumber, Fingerprint, KeySource}; use crate::hashes::{hash160, ripemd160, sha256, sha256d, Hash}; use crate::crypto::{ecdsa, schnorr}; use crate::psbt; use crate::util::taproot::{TapBranchHash, TapLeafHash, ControlBlock, LeafVersion}; use crate::crypto::key::PublicKey; use super::map::{TapTree, PsbtSighashType}; use crate::util::taproot::TaprootBuilder; /// A trait for serializing a value as raw data for insertion into PSBT /// key-value pairs. pub trait Serialize { /// Serialize a value as raw data. fn serialize(&self) -> Vec; } /// A trait for deserializing a value from raw data in PSBT key-value pairs. pub trait Deserialize: Sized { /// Deserialize a value from raw data. fn deserialize(bytes: &[u8]) -> Result; } impl_psbt_de_serialize!(Transaction); impl_psbt_de_serialize!(TxOut); impl_psbt_de_serialize!(Witness); impl_psbt_hash_de_serialize!(ripemd160::Hash); impl_psbt_hash_de_serialize!(sha256::Hash); impl_psbt_hash_de_serialize!(TapLeafHash); impl_psbt_hash_de_serialize!(TapBranchHash); impl_psbt_hash_de_serialize!(hash160::Hash); impl_psbt_hash_de_serialize!(sha256d::Hash); // taproot impl_psbt_de_serialize!(Vec); impl Serialize for Script { fn serialize(&self) -> Vec { self.to_bytes() } } impl Deserialize for Script { fn deserialize(bytes: &[u8]) -> Result { Ok(Self::from(bytes.to_vec())) } } impl Serialize for PublicKey { fn serialize(&self) -> Vec { let mut buf = Vec::new(); self.write_into(&mut buf).expect("vecs don't error"); buf } } impl Deserialize for PublicKey { fn deserialize(bytes: &[u8]) -> Result { PublicKey::from_slice(bytes) .map_err(|_| encode::Error::ParseFailed("invalid public key")) } } impl Serialize for secp256k1::PublicKey { fn serialize(&self) -> Vec { self.serialize().to_vec() } } impl Deserialize for secp256k1::PublicKey { fn deserialize(bytes: &[u8]) -> Result { secp256k1::PublicKey::from_slice(bytes) .map_err(|_| encode::Error::ParseFailed("invalid public key")) } } impl Serialize for ecdsa::Signature { fn serialize(&self) -> Vec { self.to_vec() } } impl Deserialize for ecdsa::Signature { fn deserialize(bytes: &[u8]) -> Result { // NB: Since BIP-174 says "the signature as would be pushed to the stack from // a scriptSig or witness" we should ideally use a consensus deserialization and do // not error on a non-standard values. However, // // 1) the current implementation of from_u32_consensus(`flag`) does not preserve // the sighash byte `flag` mapping all unknown values to EcdsaSighashType::All or // EcdsaSighashType::AllPlusAnyOneCanPay. Therefore, break the invariant // EcdsaSig::from_slice(&sl[..]).to_vec = sl. // // 2) This would cause to have invalid signatures because the sighash message // also has a field sighash_u32 (See BIP141). For example, when signing with non-standard // 0x05, the sighash message would have the last field as 0x05u32 while, the verification // would use check the signature assuming sighash_u32 as `0x01`. ecdsa::Signature::from_slice(bytes) .map_err(|e| match e { ecdsa::Error::EmptySignature => { encode::Error::ParseFailed("Empty partial signature data") } ecdsa::Error::NonStandardSighashType(flag) => { encode::Error::from(psbt::Error::NonStandardSighashType(flag)) } ecdsa::Error::Secp256k1(..) => { encode::Error::ParseFailed("Invalid Ecdsa signature") } ecdsa::Error::HexEncoding(..) => { unreachable!("Decoding from slice, not hex") } }) } } impl Serialize for KeySource { fn serialize(&self) -> Vec { let mut rv: Vec = Vec::with_capacity(key_source_len(self)); rv.append(&mut self.0.to_bytes().to_vec()); for cnum in self.1.into_iter() { rv.append(&mut serialize(&u32::from(*cnum))) } rv } } impl Deserialize for KeySource { fn deserialize(bytes: &[u8]) -> Result { if bytes.len() < 4 { return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into()) } let fprint: Fingerprint = Fingerprint::from(&bytes[0..4]); let mut dpath: Vec = Default::default(); let mut d = &bytes[4..]; while !d.is_empty() { match u32::consensus_decode(&mut d) { Ok(index) => dpath.push(index.into()), Err(e) => return Err(e), } } Ok((fprint, dpath.into())) } } // partial sigs impl Serialize for Vec { fn serialize(&self) -> Vec { self.clone() } } impl Deserialize for Vec { fn deserialize(bytes: &[u8]) -> Result { Ok(bytes.to_vec()) } } impl Serialize for PsbtSighashType { fn serialize(&self) -> Vec { serialize(&self.to_u32()) } } impl Deserialize for PsbtSighashType { fn deserialize(bytes: &[u8]) -> Result { let raw: u32 = encode::deserialize(bytes)?; Ok(PsbtSighashType { inner: raw }) } } // Taproot related ser/deser impl Serialize for XOnlyPublicKey { fn serialize(&self) -> Vec { XOnlyPublicKey::serialize(self).to_vec() } } impl Deserialize for XOnlyPublicKey { fn deserialize(bytes: &[u8]) -> Result { XOnlyPublicKey::from_slice(bytes) .map_err(|_| encode::Error::ParseFailed("Invalid xonly public key")) } } impl Serialize for schnorr::Signature { fn serialize(&self) -> Vec { self.to_vec() } } impl Deserialize for schnorr::Signature { fn deserialize(bytes: &[u8]) -> Result { schnorr::Signature::from_slice(bytes) .map_err(|e| match e { schnorr::Error::InvalidSighashType(flag) => { encode::Error::from(psbt::Error::NonStandardSighashType(flag as u32)) } schnorr::Error::InvalidSignatureSize(_) => { encode::Error::ParseFailed("Invalid Schnorr signature length") } schnorr::Error::Secp256k1(..) => { encode::Error::ParseFailed("Invalid Schnorr signature") } }) } } impl Serialize for (XOnlyPublicKey, TapLeafHash) { fn serialize(&self) -> Vec { let ser_pk = self.0.serialize(); let mut buf = Vec::with_capacity(ser_pk.len() + self.1.as_ref().len()); buf.extend(&ser_pk); buf.extend(self.1.as_ref()); buf } } impl Deserialize for (XOnlyPublicKey, TapLeafHash) { fn deserialize(bytes: &[u8]) -> Result { if bytes.len() < 32 { return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into()) } let a: XOnlyPublicKey = Deserialize::deserialize(&bytes[..32])?; let b: TapLeafHash = Deserialize::deserialize(&bytes[32..])?; Ok((a, b)) } } impl Serialize for ControlBlock { fn serialize(&self) -> Vec { ControlBlock::serialize(self) } } impl Deserialize for ControlBlock { fn deserialize(bytes: &[u8]) -> Result { Self::from_slice(bytes) .map_err(|_| encode::Error::ParseFailed("Invalid control block")) } } // Versioned Script impl Serialize for (Script, LeafVersion) { fn serialize(&self) -> Vec { let mut buf = Vec::with_capacity(self.0.len() + 1); buf.extend(self.0.as_bytes()); buf.push(self.1.to_consensus()); buf } } impl Deserialize for (Script, LeafVersion) { fn deserialize(bytes: &[u8]) -> Result { if bytes.is_empty() { return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into()) } // The last byte is LeafVersion. let script = Script::deserialize(&bytes[..bytes.len() - 1])?; let leaf_ver = LeafVersion::from_consensus(bytes[bytes.len() - 1]) .map_err(|_| encode::Error::ParseFailed("invalid leaf version"))?; Ok((script, leaf_ver)) } } impl Serialize for (Vec, KeySource) { fn serialize(&self) -> Vec { let mut buf = Vec::with_capacity( 32 * self.0.len() + key_source_len(&self.1)); self.0.consensus_encode(&mut buf).expect("Vecs don't error allocation"); // TODO: Add support for writing into a writer for key-source buf.extend(self.1.serialize()); buf } } impl Deserialize for (Vec, KeySource) { fn deserialize(bytes: &[u8]) -> Result { let (leafhash_vec, consumed) = deserialize_partial::>(bytes)?; let key_source = KeySource::deserialize(&bytes[consumed..])?; Ok((leafhash_vec, key_source)) } } impl Serialize for TapTree { fn serialize(&self) -> Vec { match (self.0.branch().len(), self.0.branch().last()) { (1, Some(Some(root))) => { let mut buf = Vec::new(); for leaf_info in root.leaves.iter() { // # Cast Safety: // // TaprootMerkleBranch can only have len atmost 128(TAPROOT_CONTROL_MAX_NODE_COUNT). // safe to cast from usize to u8 buf.push(leaf_info.merkle_branch().as_inner().len() as u8); buf.push(leaf_info.leaf_version().to_consensus()); leaf_info.script().consensus_encode(&mut buf).expect("Vecs dont err"); } buf } // This should be unreachable as we Taptree is already finalized _ => unreachable!(), } } } impl Deserialize for TapTree { fn deserialize(bytes: &[u8]) -> Result { let mut builder = TaprootBuilder::new(); let mut bytes_iter = bytes.iter(); while let Some(depth) = bytes_iter.next() { let version = bytes_iter.next().ok_or(encode::Error::ParseFailed("Invalid Taproot Builder"))?; let (script, consumed) = deserialize_partial::