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:
parent
7af0999745
commit
a6d3514f2b
|
@ -527,11 +527,12 @@ impl Address {
|
||||||
merkle_root: Option<TapBranchHash>,
|
merkle_root: Option<TapBranchHash>,
|
||||||
network: Network
|
network: Network
|
||||||
) -> Address {
|
) -> Address {
|
||||||
|
let (output_key, _parity) = internal_key.tap_tweak(secp, merkle_root);
|
||||||
Address {
|
Address {
|
||||||
network: network,
|
network: network,
|
||||||
payload: Payload::WitnessProgram {
|
payload: Payload::WitnessProgram {
|
||||||
version: WitnessVersion::V1,
|
version: WitnessVersion::V1,
|
||||||
program: internal_key.tap_tweak(secp, merkle_root).into_inner().serialize().to_vec()
|
program: output_key.into_inner().serialize().to_vec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,10 @@ pub trait TapTweak {
|
||||||
/// * H is the hash function
|
/// * H is the hash function
|
||||||
/// * c is the commitment data
|
/// * c is the commitment data
|
||||||
/// * G is the generator point
|
/// * 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
|
/// Directly convert an UntweakedPublicKey to a TweakedPublicKey
|
||||||
///
|
///
|
||||||
|
@ -49,13 +52,13 @@ pub trait TapTweak {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TapTweak for UntweakedPublicKey {
|
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 tweak_value = TapTweakHash::from_key_and_tweak(self, merkle_root).into_inner();
|
||||||
let mut output_key = self.clone();
|
let mut output_key = self.clone();
|
||||||
let parity = output_key.tweak_add_assign(&secp, &tweak_value).expect("Tap tweak failed");
|
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));
|
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 {
|
fn dangerous_assume_tweaked(self) -> TweakedPublicKey {
|
||||||
|
|
|
@ -25,7 +25,7 @@ use core::cmp::Reverse;
|
||||||
use std::error;
|
use std::error;
|
||||||
|
|
||||||
use hashes::{sha256, sha256t, Hash, HashEngine};
|
use hashes::{sha256, sha256t, Hash, HashEngine};
|
||||||
use schnorr::{TweakedPublicKey, UntweakedPublicKey};
|
use schnorr::{TweakedPublicKey, UntweakedPublicKey, TapTweak};
|
||||||
use Script;
|
use Script;
|
||||||
|
|
||||||
use consensus::Encodable;
|
use consensus::Encodable;
|
||||||
|
@ -253,22 +253,12 @@ impl TaprootSpendInfo {
|
||||||
internal_key: UntweakedPublicKey,
|
internal_key: UntweakedPublicKey,
|
||||||
merkle_root: Option<TapBranchHash>,
|
merkle_root: Option<TapBranchHash>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let tweak = TapTweakHash::from_key_and_tweak(internal_key, merkle_root);
|
let (output_key, parity) = internal_key.tap_tweak(secp, 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");
|
|
||||||
Self {
|
Self {
|
||||||
internal_key: internal_key,
|
internal_key: internal_key,
|
||||||
merkle_root: merkle_root,
|
merkle_root: merkle_root,
|
||||||
output_key_parity: parity,
|
output_key_parity: parity,
|
||||||
output_key: TweakedPublicKey::dangerous_assume_tweaked(output_key),
|
output_key: output_key,
|
||||||
script_map: BTreeMap::new(),
|
script_map: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue