Skip to content

Commit

Permalink
Merge #591: PSBT BIP32 keys using to Secp256k1 keys instead of bitcoi…
Browse files Browse the repository at this point in the history
…n ECDSA

a6e8f58 PSBT BIP32 keys moved to Secp256k1 from bitcoin ECDSA (Dr Maxim Orlovsky)

Pull request description:

  Fourth step in implementation of Schnorr key support after #588. This PR is a follow-up to non-API breaking #589 and API-breaking #590, which must be reviewed and merged first. ~~(The current PR includes all commits from #589 and #590, which should be reviewed there. The only commit specific to this PR is b8105e9)~~

  UPDATE: All related PRs are merged now and this PR is ready for the review

  PR description:
  While PSBT BIP174 does not specify whether uncompressed keys are supported in BIP32-related fields, from BIP32 it follows that it is impossible to use uncompressed keys within the extended keys.  This PR fixes this situation and is a companion to BIP174 PR clarifying key serialization: bitcoin/bips#1100

ACKs for top commit:
  apoelstra:
    ACK a6e8f58
  sanket1729:
    ACK a6e8f58. Not sure which order to merge since there are many ready PRs which that would break each other.

Tree-SHA512: 198ba646bbce1949b255a54a97957d952acdad8b7f9580be123116c0f44d773e6d90e0cac0d5993ec9a6b3328aa43aced0908522817861585877c50008fec835
  • Loading branch information
sanket1729 committed Jan 11, 2022
2 parents 0e2e559 + a6e8f58 commit e4d5039
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 33 deletions.
4 changes: 2 additions & 2 deletions src/blockdata/script.rs
Expand Up @@ -1038,10 +1038,10 @@ mod test {
let pubkey = PublicKey::from_str("0234e6a79c5359c613762d537e0e19d86c77c1666d8c9ab050f23acd198e97f93e").unwrap();
assert!(Script::new_p2pk(&pubkey).is_p2pk());

let pubkey_hash = PubkeyHash::hash(&pubkey.serialize());
let pubkey_hash = PubkeyHash::hash(&pubkey.key.serialize());
assert!(Script::new_p2pkh(&pubkey_hash).is_p2pkh());

let wpubkey_hash = WPubkeyHash::hash(&pubkey.serialize());
let wpubkey_hash = WPubkeyHash::hash(&pubkey.key.serialize());
assert!(Script::new_v0_wpkh(&wpubkey_hash).is_v0_p2wpkh());

let script = Builder::new().push_opcode(opcodes::all::OP_NUMEQUAL)
Expand Down
14 changes: 7 additions & 7 deletions src/util/psbt/map/input.rs
Expand Up @@ -16,13 +16,13 @@ use prelude::*;

use ::{EcdsaSig, io};

use secp256k1;
use blockdata::script::Script;
use blockdata::transaction::{EcdsaSigHashType, Transaction, TxOut};
use consensus::encode;
use hashes::{self, hash160, ripemd160, sha256, sha256d};
use secp256k1::XOnlyPublicKey;
use util::bip32::KeySource;
use hashes::{self, hash160, ripemd160, sha256, sha256d};
use util::ecdsa::PublicKey;
use util::psbt;
use util::psbt::map::Map;
use util::psbt::raw;
Expand Down Expand Up @@ -88,7 +88,7 @@ pub struct Input {
pub witness_utxo: Option<TxOut>,
/// A map from public keys to their corresponding signature as would be
/// pushed to the stack from a scriptSig or witness for a non-taproot inputs.
pub partial_sigs: BTreeMap<PublicKey, EcdsaSig>,
pub partial_sigs: BTreeMap<secp256k1::PublicKey, EcdsaSig>,
/// The sighash type to be used for this input. Signatures for this input
/// must use the sighash type.
pub sighash_type: Option<EcdsaSigHashType>,
Expand All @@ -99,7 +99,7 @@ pub struct Input {
/// A map from public keys needed to sign this input to their corresponding
/// master key fingerprints and derivation paths.
#[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq"))]
pub bip32_derivation: BTreeMap<PublicKey, KeySource>,
pub bip32_derivation: BTreeMap<secp256k1::PublicKey, KeySource>,
/// The finalized, fully-constructed scriptSig with signatures and any other
/// scripts necessary for this input to pass validation.
pub final_script_sig: Option<Script>,
Expand Down Expand Up @@ -162,7 +162,7 @@ impl Map for Input {
}
PSBT_IN_PARTIAL_SIG => {
impl_psbt_insert_pair! {
self.partial_sigs <= <raw_key: PublicKey>|<raw_value: EcdsaSig>
self.partial_sigs <= <raw_key: secp256k1::PublicKey>|<raw_value: EcdsaSig>
}
}
PSBT_IN_SIGHASH_TYPE => {
Expand All @@ -182,7 +182,7 @@ impl Map for Input {
}
PSBT_IN_BIP32_DERIVATION => {
impl_psbt_insert_pair! {
self.bip32_derivation <= <raw_key: PublicKey>|<raw_value: KeySource>
self.bip32_derivation <= <raw_key: secp256k1::PublicKey>|<raw_value: KeySource>
}
}
PSBT_IN_FINAL_SCRIPTSIG => {
Expand Down Expand Up @@ -282,7 +282,7 @@ impl Map for Input {
}

impl_psbt_get_pair! {
rv.push(self.bip32_derivation as <PSBT_IN_BIP32_DERIVATION, PublicKey>|<KeySource>)
rv.push(self.bip32_derivation as <PSBT_IN_BIP32_DERIVATION, secp256k1::PublicKey>|<KeySource>)
}

impl_psbt_get_pair! {
Expand Down
8 changes: 4 additions & 4 deletions src/util/psbt/map/output.rs
Expand Up @@ -20,7 +20,7 @@ use blockdata::script::Script;
use consensus::encode;
use secp256k1::XOnlyPublicKey;
use util::bip32::KeySource;
use util::ecdsa::PublicKey;
use secp256k1;
use util::psbt;
use util::psbt::map::Map;
use util::psbt::raw;
Expand Down Expand Up @@ -57,7 +57,7 @@ pub struct Output {
/// A map from public keys needed to spend this output to their
/// corresponding master key fingerprints and derivation paths.
#[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq"))]
pub bip32_derivation: BTreeMap<PublicKey, KeySource>,
pub bip32_derivation: BTreeMap<secp256k1::PublicKey, KeySource>,
/// The internal pubkey
pub tap_internal_key: Option<XOnlyPublicKey>,
/// Taproot Output tree
Expand Down Expand Up @@ -139,7 +139,7 @@ impl Map for Output {
}
PSBT_OUT_BIP32_DERIVATION => {
impl_psbt_insert_pair! {
self.bip32_derivation <= <raw_key: PublicKey>|<raw_value: KeySource>
self.bip32_derivation <= <raw_key: secp256k1::PublicKey>|<raw_value: KeySource>
}
}
PSBT_OUT_PROPRIETARY => match self.proprietary.entry(raw::ProprietaryKey::from_key(raw_key.clone())?) {
Expand Down Expand Up @@ -186,7 +186,7 @@ impl Map for Output {
}

impl_psbt_get_pair! {
rv.push(self.bip32_derivation as <PSBT_OUT_BIP32_DERIVATION, PublicKey>|<KeySource>)
rv.push(self.bip32_derivation as <PSBT_OUT_BIP32_DERIVATION, secp256k1::PublicKey>|<KeySource>)
}

impl_psbt_get_pair! {
Expand Down
16 changes: 3 additions & 13 deletions src/util/psbt/mod.rs
Expand Up @@ -256,7 +256,6 @@ mod tests {
use network::constants::Network::Bitcoin;
use consensus::encode::{deserialize, serialize, serialize_hex};
use util::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, Fingerprint, KeySource};
use util::ecdsa;
use util::psbt::map::{Output, Input};
use util::psbt::raw;

Expand Down Expand Up @@ -321,10 +320,7 @@ mod tests {
witness_script: Some(hex_script!(
"a9143545e6e33b832c47050f24d3eeb93c9c03948bc787"
)),
bip32_derivation: hd_keypaths.into_iter().map(|(key, src)| (ecdsa::PublicKey {
compressed: true,
key,
}, src)).collect(),
bip32_derivation: hd_keypaths,
..Default::default()
};

Expand Down Expand Up @@ -481,10 +477,7 @@ mod tests {
"0339880dc92394b7355e3d0439fa283c31de7590812ea011c4245c0674a685e883".parse().unwrap(),
"304402204f67e2afb76142d44fae58a2495d33a3419daa26cd0db8d04f3452b63289ac0f022010762a9fb67e94cc5cad9026f6dc99ff7f070f4278d30fbc7d0c869dd38c7fe701".parse().unwrap(),
)].into_iter().collect(),
bip32_derivation: keypaths.clone().into_iter().map(|(key, src)| (ecdsa::PublicKey {
compressed: true,
key,
}, src)).collect(),
bip32_derivation: keypaths.clone(),
final_script_witness: Some(vec![vec![1, 3], vec![5]]),
ripemd160_preimages: vec![(ripemd160::Hash::hash(&[]), vec![1, 2])].into_iter().collect(),
sha256_preimages: vec![(sha256::Hash::hash(&[]), vec![1, 2])].into_iter().collect(),
Expand All @@ -495,10 +488,7 @@ mod tests {
..Default::default()
}],
outputs: vec![Output {
bip32_derivation: keypaths.into_iter().map(|(key, src)| (ecdsa::PublicKey {
compressed: true,
key,
}, src)).collect(),
bip32_derivation: keypaths,
proprietary: proprietary.clone(),
unknown: unknown.clone(),
..Default::default()
Expand Down
12 changes: 5 additions & 7 deletions src/util/psbt/serialize.rs
Expand Up @@ -28,7 +28,7 @@ use consensus::encode::{self, serialize, Decodable, Encodable, deserialize_parti
use secp256k1::{self, XOnlyPublicKey};
use util::bip32::{ChildNumber, Fingerprint, KeySource};
use hashes::{hash160, ripemd160, sha256, sha256d, Hash};
use util::ecdsa::{PublicKey, EcdsaSig};
use util::ecdsa::EcdsaSig;
use util::psbt;
use util::taproot::{TapBranchHash, TapLeafHash, ControlBlock, LeafVersion};
use schnorr;
Expand Down Expand Up @@ -74,17 +74,15 @@ impl Deserialize for Script {
}
}

impl Serialize for PublicKey {
impl Serialize for secp256k1::PublicKey {
fn serialize(&self) -> Vec<u8> {
let mut buf = Vec::new();
self.write_into(&mut buf).expect("vecs don't error");
buf
self.serialize().to_vec()
}
}

impl Deserialize for PublicKey {
impl Deserialize for secp256k1::PublicKey {
fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error> {
PublicKey::from_slice(bytes)
secp256k1::PublicKey::from_slice(bytes)
.map_err(|_| encode::Error::ParseFailed("invalid public key"))
}
}
Expand Down

0 comments on commit e4d5039

Please sign in to comment.