Return parity when doing tap_tweak

Currently we calculate the parity during `tap_tweak` but do not return
it, this means others must re-do work done inside `tap_tweak` in order
to calculate the parity. We can just return the parity along with the
tweaked key.
This commit is contained in:
Tobin Harding 2021-12-02 14:43:38 +11:00
parent 7af0999745
commit a6d3514f2b
3 changed files with 11 additions and 17 deletions

View File

@ -527,11 +527,12 @@ impl Address {
merkle_root: Option<TapBranchHash>,
network: Network
) -> Address {
let (output_key, _parity) = internal_key.tap_tweak(secp, merkle_root);
Address {
network: network,
payload: Payload::WitnessProgram {
version: WitnessVersion::V1,
program: internal_key.tap_tweak(secp, merkle_root).into_inner().serialize().to_vec()
program: output_key.into_inner().serialize().to_vec()
}
}
}

View File

@ -39,7 +39,10 @@ pub trait TapTweak {
/// * H is the hash function
/// * c is the commitment data
/// * G is the generator point
fn tap_tweak<C: Verification>(self, secp: &Secp256k1<C>, merkle_root: Option<TapBranchHash>) -> TweakedPublicKey;
///
/// # Returns
/// The tweaked key and its parity.
fn tap_tweak<C: Verification>(self, secp: &Secp256k1<C>, merkle_root: Option<TapBranchHash>) -> (TweakedPublicKey, bool);
/// Directly convert an UntweakedPublicKey to a TweakedPublicKey
///
@ -49,13 +52,13 @@ pub trait TapTweak {
}
impl TapTweak for UntweakedPublicKey {
fn tap_tweak<C: Verification>(self, secp: &Secp256k1<C>, merkle_root: Option<TapBranchHash>) -> TweakedPublicKey {
fn tap_tweak<C: Verification>(self, secp: &Secp256k1<C>, merkle_root: Option<TapBranchHash>) -> (TweakedPublicKey, bool) {
let tweak_value = TapTweakHash::from_key_and_tweak(self, merkle_root).into_inner();
let mut output_key = self.clone();
let parity = output_key.tweak_add_assign(&secp, &tweak_value).expect("Tap tweak failed");
debug_assert!(self.tweak_add_check(&secp, &output_key, parity, tweak_value));
TweakedPublicKey(output_key)
(TweakedPublicKey(output_key), parity)
}
fn dangerous_assume_tweaked(self) -> TweakedPublicKey {

View File

@ -25,7 +25,7 @@ use core::cmp::Reverse;
use std::error;
use hashes::{sha256, sha256t, Hash, HashEngine};
use schnorr::{TweakedPublicKey, UntweakedPublicKey};
use schnorr::{TweakedPublicKey, UntweakedPublicKey, TapTweak};
use Script;
use consensus::Encodable;
@ -253,22 +253,12 @@ impl TaprootSpendInfo {
internal_key: UntweakedPublicKey,
merkle_root: Option<TapBranchHash>,
) -> Self {
let tweak = TapTweakHash::from_key_and_tweak(internal_key, merkle_root);
let mut output_key = internal_key;
// # Panics:
//
// This would return Err if the merkle root hash is the negation of the secret
// key corresponding to the internal key.
// Because the tweak is derived as specified in BIP341 (hash output of a function),
// this is unlikely to occur (1/2^128) in real life usage, it is safe to unwrap this
let parity = output_key
.tweak_add_assign(&secp, &tweak)
.expect("TapTweakHash::from_key_and_tweak is broken");
let (output_key, parity) = internal_key.tap_tweak(secp, merkle_root);
Self {
internal_key: internal_key,
merkle_root: merkle_root,
output_key_parity: parity,
output_key: TweakedPublicKey::dangerous_assume_tweaked(output_key),
output_key: output_key,
script_map: BTreeMap::new(),
}
}