From 808a86e4329a196b139adfd274a25c1be481f73a Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 6 Oct 2023 17:21:00 +0200 Subject: [PATCH] primitives: move TaprootPk and OutputPk from bp-std --- dbc/src/tapret/xonlypk.rs | 9 ++-- primitives/src/lib.rs | 5 +- primitives/src/stl.rs | 11 +++-- primitives/src/taproot.rs | 96 ++++++++++++++++++++++++++++++--------- src/stl.rs | 2 +- 5 files changed, 89 insertions(+), 34 deletions(-) diff --git a/dbc/src/tapret/xonlypk.rs b/dbc/src/tapret/xonlypk.rs index 5ac25b69..8c12e285 100644 --- a/dbc/src/tapret/xonlypk.rs +++ b/dbc/src/tapret/xonlypk.rs @@ -19,9 +19,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use bc::{InternalPk, TapBranchHash, TapLeafHash, TapNodeHash, TapScript}; +use bc::{InternalPk, OutputPk, TapBranchHash, TapLeafHash, TapNodeHash, TapScript}; use commit_verify::{mpc, CommitVerify, ConvolveCommit, ConvolveCommitProof}; -use secp256k1::XOnlyPublicKey; use super::{Lnpbp12, TapretNodePartner, TapretPathProof, TapretProof}; use crate::tapret::tapscript::TapretCommitment; @@ -46,20 +45,20 @@ pub enum TapretKeyError { impl ConvolveCommitProof for TapretProof { type Suppl = TapretPathProof; - fn restore_original(&self, _: &XOnlyPublicKey) -> InternalPk { self.internal_pk } + fn restore_original(&self, _: &OutputPk) -> InternalPk { self.internal_pk } fn extract_supplement(&self) -> &Self::Suppl { &self.path_proof } } impl ConvolveCommit for InternalPk { - type Commitment = XOnlyPublicKey; + type Commitment = OutputPk; type CommitError = TapretKeyError; fn convolve_commit( &self, supplement: &TapretPathProof, msg: &mpc::Commitment, - ) -> Result<(XOnlyPublicKey, TapretProof), Self::CommitError> { + ) -> Result<(OutputPk, TapretProof), Self::CommitError> { let tapret_commitment = TapretCommitment::with(*msg, supplement.nonce); let script_commitment = TapScript::commit(&tapret_commitment); diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index e568ec51..9bb67a66 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -77,8 +77,9 @@ pub use segwit::{SegwitError, Witness, WitnessProgram, WitnessScript, WitnessVer pub use sigtypes::{Bip340Sig, LegacySig, SigError, SighashFlag, SighashType}; pub use taproot::{ ControlBlock, FutureLeafVer, InternalPk, IntoTapHash, InvalidLeafVer, InvalidParityValue, - InvalidPubkey, LeafScript, LeafVer, Parity, TapBranchHash, TapCode, TapLeafHash, TapMerklePath, - TapNodeHash, TapScript, TAPROOT_ANNEX_PREFIX, TAPROOT_LEAF_MASK, TAPROOT_LEAF_TAPSCRIPT, + InvalidPubkey, LeafScript, LeafVer, OutputPk, Parity, TapBranchHash, TapCode, TapLeafHash, + TapMerklePath, TapNodeHash, TapScript, TaprootPk, TAPROOT_ANNEX_PREFIX, TAPROOT_LEAF_MASK, + TAPROOT_LEAF_TAPSCRIPT, }; pub use tx::{ LockTime, Outpoint, OutpointParseError, Sats, SeqNo, Tx, TxIn, TxOut, TxParseError, TxVer, diff --git a/primitives/src/stl.rs b/primitives/src/stl.rs index 81134e9b..17a6c76a 100644 --- a/primitives/src/stl.rs +++ b/primitives/src/stl.rs @@ -23,9 +23,10 @@ use strict_types::{CompileError, LibBuilder, TypeLib}; use crate::{ - Bip340Sig, BlockHeader, ByteStr, Chain, ControlBlock, FutureLeafVer, LeafScript, LegacySig, - OpCode, RedeemScript, TapCode, TapLeafHash, TapNodeHash, TapScript, Tx, VBytes, VarInt, - WeightUnits, WitnessProgram, WitnessScript, WitnessVer, Wtxid, LIB_NAME_BITCOIN, + Bip340Sig, BlockHeader, ByteStr, Chain, ControlBlock, FutureLeafVer, InternalPk, LeafScript, + LegacySig, OpCode, OutputPk, RedeemScript, TapCode, TapLeafHash, TapNodeHash, TapScript, Tx, + VBytes, VarInt, WeightUnits, WitnessProgram, WitnessScript, WitnessVer, Wtxid, + LIB_NAME_BITCOIN, }; #[deprecated(since = "0.10.8", note = "use LIB_ID_BP_TX instead")] @@ -34,7 +35,7 @@ pub const LIB_ID_BITCOIN: &str = pub const LIB_ID_BP_TX: &str = "urn:ubideco:stl:6GgF7biXPVNcus2FfQj2pQuRzau11rXApMQLfCZhojgi#money-pardon-parody"; pub const LIB_ID_BP_CONSENSUS: &str = - "urn:ubideco:stl:A6tfQFthqmb39wR5sWvrfgf3oiAyazm8rh7ff35ruioi#russian-emerald-extra"; + "urn:ubideco:stl:A9EKnosv2TJAJvQvRgCDLUpajnfSjS7oRiuogFs1S8Nq#chapter-henry-unit"; #[deprecated(since = "0.10.8", note = "use _bp_tx_stl instead")] fn _bitcoin_stl() -> Result { _bp_tx_stl() } @@ -57,6 +58,8 @@ fn _bp_consensus_stl() -> Result { .transpile::() .transpile::() .transpile::() + .transpile::() + .transpile::() .transpile::() .transpile::() .transpile::() diff --git a/primitives/src/taproot.rs b/primitives/src/taproot.rs index 7ab9eeda..ad2eb300 100644 --- a/primitives/src/taproot.rs +++ b/primitives/src/taproot.rs @@ -69,9 +69,9 @@ pub struct InvalidPubkey; derive(Serialize, Deserialize), serde(crate = "serde_crate", transparent) )] -pub struct InternalPk(XOnlyPublicKey); +pub struct TaprootPk(XOnlyPublicKey); -impl InternalPk { +impl TaprootPk { pub fn from_byte_array(data: [u8; 32]) -> Result { XOnlyPublicKey::from_slice(data.as_ref()) .map(Self) @@ -79,8 +79,54 @@ impl InternalPk { } pub fn to_byte_array(&self) -> [u8; 32] { self.0.serialize() } +} + +impl From for [u8; 32] { + fn from(pk: TaprootPk) -> [u8; 32] { pk.to_byte_array() } +} + +impl StrictEncode for TaprootPk { + fn strict_encode(&self, writer: W) -> io::Result { + let bytes = Bytes32::from(self.0.serialize()); + writer.write_newtype::(&bytes) + } +} + +impl StrictDecode for TaprootPk { + fn strict_decode(reader: &mut impl TypedRead) -> Result { + reader.read_tuple(|r| { + let bytes: Bytes32 = r.read_field()?; + XOnlyPublicKey::from_slice(bytes.as_slice()) + .map(Self) + .map_err(|_| { + DecodeError::DataIntegrityError(format!( + "invalid x-only public key value '{bytes:x}'" + )) + }) + }) + } +} + +#[derive(Wrapper, WrapperMut, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] +#[wrapper(Deref, LowerHex, Display, FromStr)] +#[wrapper_mut(DerefMut)] +#[derive(StrictType, StrictEncode, StrictDecode, StrictDumb)] +#[strict_type(lib = LIB_NAME_BITCOIN, dumb = Self(strict_dumb!()))] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", transparent) +)] +pub struct InternalPk(TaprootPk); - pub fn to_output_key(&self, merkle_root: Option) -> XOnlyPublicKey { +impl InternalPk { + pub fn from_byte_array(data: [u8; 32]) -> Result { + TaprootPk::from_byte_array(data).map(Self) + } + + pub fn to_byte_array(&self) -> [u8; 32] { self.0.to_byte_array() } + + pub fn to_output_key(&self, merkle_root: Option) -> OutputPk { let mut engine = Sha256::from_tag(MIDSTATE_TAPTWEAK); // always hash the key engine.input_raw(&self.0.serialize()); @@ -99,30 +145,36 @@ impl InternalPk { tweaked_parity, tweak )); - output_key + OutputPk(TaprootPk(output_key)) } } -impl StrictEncode for InternalPk { - fn strict_encode(&self, writer: W) -> io::Result { - let bytes = Bytes32::from(self.0.serialize()); - writer.write_newtype::(&bytes) - } +impl From for [u8; 32] { + fn from(pk: InternalPk) -> [u8; 32] { pk.to_byte_array() } } -impl StrictDecode for InternalPk { - fn strict_decode(reader: &mut impl TypedRead) -> Result { - reader.read_tuple(|r| { - let bytes: Bytes32 = r.read_field()?; - XOnlyPublicKey::from_slice(bytes.as_slice()) - .map(Self) - .map_err(|_| { - DecodeError::DataIntegrityError(format!( - "invalid x-only public key value '{bytes:x}'" - )) - }) - }) +#[derive(Wrapper, WrapperMut, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] +#[wrapper(Deref, LowerHex, Display, FromStr)] +#[wrapper_mut(DerefMut)] +#[derive(StrictType, StrictEncode, StrictDecode, StrictDumb)] +#[strict_type(lib = LIB_NAME_BITCOIN, dumb = Self(strict_dumb!()))] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", transparent) +)] +pub struct OutputPk(TaprootPk); + +impl OutputPk { + pub fn from_byte_array(data: [u8; 32]) -> Result { + TaprootPk::from_byte_array(data).map(Self) } + + pub fn to_byte_array(&self) -> [u8; 32] { self.0.to_byte_array() } +} + +impl From for [u8; 32] { + fn from(pk: OutputPk) -> [u8; 32] { pk.to_byte_array() } } pub trait IntoTapHash { @@ -506,7 +558,7 @@ impl ScriptPubkey { Self::p2tr_tweaked(output_key) } - pub fn p2tr_tweaked(output_key: XOnlyPublicKey) -> Self { + pub fn p2tr_tweaked(output_key: OutputPk) -> Self { // output key is 32 bytes long, so it's safe to use // `new_witness_program_unchecked` (Segwitv1) Self::with_witness_program_unchecked(WitnessVer::V1, &output_key.serialize()) diff --git a/src/stl.rs b/src/stl.rs index 005f26b9..9745480b 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -30,7 +30,7 @@ use strict_types::{CompileError, LibBuilder, TypeLib}; /// Strict types id for the library providing data types from [`dbc`] and /// [`seals`] crates. pub const LIB_ID_BPCORE: &str = - "urn:ubideco:stl:2YsxMW6xygK2FxFSbbBLqmzaUSytmLHHNF9DRio5zNr2#sultan-data-copy"; + "urn:ubideco:stl:5cbnbTwuKKKpRqh9WJejEKXcWahnHc3jgwBeJCNr48cL#gyro-minute-maestro"; fn _bp_core_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_BPCORE), tiny_bset! {