Add BIP-373 PSBT_{IN,OUT}_MUSIG2_PARTICIPANT_PUBKEYS serialization and deserialization
This commit is contained in:
parent
ecf4b2bcee
commit
3e8e6d9aa1
|
@ -59,6 +59,8 @@ const PSBT_IN_TAP_BIP32_DERIVATION: u64 = 0x16;
|
||||||
const PSBT_IN_TAP_INTERNAL_KEY: u64 = 0x17;
|
const PSBT_IN_TAP_INTERNAL_KEY: u64 = 0x17;
|
||||||
/// Type: Taproot Merkle Root PSBT_IN_TAP_MERKLE_ROOT = 0x18
|
/// Type: Taproot Merkle Root PSBT_IN_TAP_MERKLE_ROOT = 0x18
|
||||||
const PSBT_IN_TAP_MERKLE_ROOT: u64 = 0x18;
|
const PSBT_IN_TAP_MERKLE_ROOT: u64 = 0x18;
|
||||||
|
/// Type: MuSig2 Public Keys Participating in Aggregate Input PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1a
|
||||||
|
const PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS: u64 = 0x1a;
|
||||||
/// Type: Proprietary Use Type PSBT_IN_PROPRIETARY = 0xFC
|
/// Type: Proprietary Use Type PSBT_IN_PROPRIETARY = 0xFC
|
||||||
const PSBT_IN_PROPRIETARY: u64 = 0xFC;
|
const PSBT_IN_PROPRIETARY: u64 = 0xFC;
|
||||||
|
|
||||||
|
@ -113,6 +115,8 @@ pub struct Input {
|
||||||
pub tap_internal_key: Option<XOnlyPublicKey>,
|
pub tap_internal_key: Option<XOnlyPublicKey>,
|
||||||
/// Taproot Merkle root.
|
/// Taproot Merkle root.
|
||||||
pub tap_merkle_root: Option<TapNodeHash>,
|
pub tap_merkle_root: Option<TapNodeHash>,
|
||||||
|
/// Mapping from MuSig2 aggregate keys to the participant keys from which they were aggregated.
|
||||||
|
pub musig2_participant_pubkeys: BTreeMap<secp256k1::PublicKey, Vec<secp256k1::PublicKey>>,
|
||||||
/// Proprietary key-value pairs for this input.
|
/// Proprietary key-value pairs for this input.
|
||||||
pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
|
pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
|
||||||
/// Unknown key-value pairs for this input.
|
/// Unknown key-value pairs for this input.
|
||||||
|
@ -352,6 +356,11 @@ impl Input {
|
||||||
self.tap_merkle_root <= <raw_key: _>|< raw_value: TapNodeHash>
|
self.tap_merkle_root <= <raw_key: _>|< raw_value: TapNodeHash>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS => {
|
||||||
|
impl_psbt_insert_pair! {
|
||||||
|
self.musig2_participant_pubkeys <= <raw_key: secp256k1::PublicKey>|< raw_value: Vec<secp256k1::PublicKey> >
|
||||||
|
}
|
||||||
|
}
|
||||||
PSBT_IN_PROPRIETARY => {
|
PSBT_IN_PROPRIETARY => {
|
||||||
let key = raw::ProprietaryKey::try_from(raw_key.clone())?;
|
let key = raw::ProprietaryKey::try_from(raw_key.clone())?;
|
||||||
match self.proprietary.entry(key) {
|
match self.proprietary.entry(key) {
|
||||||
|
@ -390,6 +399,7 @@ impl Input {
|
||||||
self.tap_script_sigs.extend(other.tap_script_sigs);
|
self.tap_script_sigs.extend(other.tap_script_sigs);
|
||||||
self.tap_scripts.extend(other.tap_scripts);
|
self.tap_scripts.extend(other.tap_scripts);
|
||||||
self.tap_key_origins.extend(other.tap_key_origins);
|
self.tap_key_origins.extend(other.tap_key_origins);
|
||||||
|
self.musig2_participant_pubkeys.extend(other.musig2_participant_pubkeys);
|
||||||
self.proprietary.extend(other.proprietary);
|
self.proprietary.extend(other.proprietary);
|
||||||
self.unknown.extend(other.unknown);
|
self.unknown.extend(other.unknown);
|
||||||
|
|
||||||
|
@ -482,6 +492,11 @@ impl Map for Input {
|
||||||
impl_psbt_get_pair! {
|
impl_psbt_get_pair! {
|
||||||
rv.push(self.tap_merkle_root, PSBT_IN_TAP_MERKLE_ROOT)
|
rv.push(self.tap_merkle_root, PSBT_IN_TAP_MERKLE_ROOT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_psbt_get_pair! {
|
||||||
|
rv.push_map(self.musig2_participant_pubkeys, PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS)
|
||||||
|
}
|
||||||
|
|
||||||
for (key, value) in self.proprietary.iter() {
|
for (key, value) in self.proprietary.iter() {
|
||||||
rv.push(raw::Pair { key: key.to_key(), value: value.clone() });
|
rv.push(raw::Pair { key: key.to_key(), value: value.clone() });
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ const PSBT_OUT_TAP_INTERNAL_KEY: u64 = 0x05;
|
||||||
const PSBT_OUT_TAP_TREE: u64 = 0x06;
|
const PSBT_OUT_TAP_TREE: u64 = 0x06;
|
||||||
/// Type: Taproot Key BIP 32 Derivation Path PSBT_OUT_TAP_BIP32_DERIVATION = 0x07
|
/// Type: Taproot Key BIP 32 Derivation Path PSBT_OUT_TAP_BIP32_DERIVATION = 0x07
|
||||||
const PSBT_OUT_TAP_BIP32_DERIVATION: u64 = 0x07;
|
const PSBT_OUT_TAP_BIP32_DERIVATION: u64 = 0x07;
|
||||||
|
/// Type: MuSig2 Public Keys Participating in Aggregate Output PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS = 0x08
|
||||||
|
const PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS: u64 = 0x08;
|
||||||
/// Type: Proprietary Use Type PSBT_IN_PROPRIETARY = 0xFC
|
/// Type: Proprietary Use Type PSBT_IN_PROPRIETARY = 0xFC
|
||||||
const PSBT_OUT_PROPRIETARY: u64 = 0xFC;
|
const PSBT_OUT_PROPRIETARY: u64 = 0xFC;
|
||||||
|
|
||||||
|
@ -40,6 +42,8 @@ pub struct Output {
|
||||||
pub tap_tree: Option<TapTree>,
|
pub tap_tree: Option<TapTree>,
|
||||||
/// Map of tap root x only keys to origin info and leaf hashes contained in it.
|
/// Map of tap root x only keys to origin info and leaf hashes contained in it.
|
||||||
pub tap_key_origins: BTreeMap<XOnlyPublicKey, (Vec<TapLeafHash>, KeySource)>,
|
pub tap_key_origins: BTreeMap<XOnlyPublicKey, (Vec<TapLeafHash>, KeySource)>,
|
||||||
|
/// Mapping from MuSig2 aggregate keys to the participant keys from which they were aggregated.
|
||||||
|
pub musig2_participant_pubkeys: BTreeMap<secp256k1::PublicKey, Vec<secp256k1::PublicKey>>,
|
||||||
/// Proprietary key-value pairs for this output.
|
/// Proprietary key-value pairs for this output.
|
||||||
pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
|
pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
|
||||||
/// Unknown key-value pairs for this output.
|
/// Unknown key-value pairs for this output.
|
||||||
|
@ -90,6 +94,11 @@ impl Output {
|
||||||
self.tap_key_origins <= <raw_key: XOnlyPublicKey>|< raw_value: (Vec<TapLeafHash>, KeySource)>
|
self.tap_key_origins <= <raw_key: XOnlyPublicKey>|< raw_value: (Vec<TapLeafHash>, KeySource)>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS => {
|
||||||
|
impl_psbt_insert_pair! {
|
||||||
|
self.musig2_participant_pubkeys <= <raw_key: secp256k1::PublicKey>|< raw_value: Vec<secp256k1::PublicKey> >
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => match self.unknown.entry(raw_key) {
|
_ => match self.unknown.entry(raw_key) {
|
||||||
btree_map::Entry::Vacant(empty_key) => {
|
btree_map::Entry::Vacant(empty_key) => {
|
||||||
empty_key.insert(raw_value);
|
empty_key.insert(raw_value);
|
||||||
|
@ -107,6 +116,7 @@ impl Output {
|
||||||
self.proprietary.extend(other.proprietary);
|
self.proprietary.extend(other.proprietary);
|
||||||
self.unknown.extend(other.unknown);
|
self.unknown.extend(other.unknown);
|
||||||
self.tap_key_origins.extend(other.tap_key_origins);
|
self.tap_key_origins.extend(other.tap_key_origins);
|
||||||
|
self.musig2_participant_pubkeys.extend(other.musig2_participant_pubkeys);
|
||||||
|
|
||||||
combine!(redeem_script, self, other);
|
combine!(redeem_script, self, other);
|
||||||
combine!(witness_script, self, other);
|
combine!(witness_script, self, other);
|
||||||
|
@ -143,6 +153,10 @@ impl Map for Output {
|
||||||
rv.push_map(self.tap_key_origins, PSBT_OUT_TAP_BIP32_DERIVATION)
|
rv.push_map(self.tap_key_origins, PSBT_OUT_TAP_BIP32_DERIVATION)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_psbt_get_pair! {
|
||||||
|
rv.push_map(self.musig2_participant_pubkeys, PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS)
|
||||||
|
}
|
||||||
|
|
||||||
for (key, value) in self.proprietary.iter() {
|
for (key, value) in self.proprietary.iter() {
|
||||||
rv.push(raw::Pair { key: key.to_key(), value: value.clone() });
|
rv.push(raw::Pair { key: key.to_key(), value: value.clone() });
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,28 @@ impl Deserialize for secp256k1::PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Serialize for Vec<secp256k1::PublicKey> {
|
||||||
|
fn serialize(&self) -> Vec<u8> {
|
||||||
|
let mut result: Vec<u8> = Vec::with_capacity(secp256k1::constants::PUBLIC_KEY_SIZE * self.len());
|
||||||
|
|
||||||
|
for pubkey in self.iter() {
|
||||||
|
result.extend(Serialize::serialize(pubkey));
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deserialize for Vec<secp256k1::PublicKey> {
|
||||||
|
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
|
bytes.chunks(secp256k1::constants::PUBLIC_KEY_SIZE)
|
||||||
|
.map(|pubkey_bytes| {
|
||||||
|
secp256k1::PublicKey::deserialize(pubkey_bytes)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Serialize for ecdsa::Signature {
|
impl Serialize for ecdsa::Signature {
|
||||||
fn serialize(&self) -> Vec<u8> { self.to_vec() }
|
fn serialize(&self) -> Vec<u8> { self.to_vec() }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue