Merge rust-bitcoin/rust-bitcoin#591: PSBT BIP32 keys using to Secp256k1 keys instead of bitcoin ECDSA

a6e8f581db 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 b8105e95dc8651626b783403ca060f7d32d21144)~~

  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: https://github.com/bitcoin/bips/pull/1100

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

Tree-SHA512: 198ba646bbce1949b255a54a97957d952acdad8b7f9580be123116c0f44d773e6d90e0cac0d5993ec9a6b3328aa43aced0908522817861585877c50008fec835
This commit is contained in:
sanket1729 2022-01-11 12:42:15 +05:30
commit e4d5039a86
No known key found for this signature in database
GPG Key ID: 648FFB183E0870A2
5 changed files with 21 additions and 33 deletions

View File

@ -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)

View File

@ -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;
@ -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>,
@ -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>,
@ -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 => {
@ -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 => {
@ -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! {

View File

@ -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;
@ -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
@ -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())?) {
@ -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! {

View File

@ -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;
@ -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()
};
@ -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(),
@ -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()

View File

@ -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;
@ -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"))
}
}