@@ -25,7 +25,7 @@ use core::cmp::Reverse;
25
25
use std:: error;
26
26
27
27
use hashes:: { sha256, sha256t, Hash , HashEngine } ;
28
- use schnorr;
28
+ use schnorr:: { TweakedPublicKey , UntweakedPublicKey , TapTweak } ;
29
29
use Script ;
30
30
31
31
use consensus:: Encodable ;
@@ -101,7 +101,7 @@ impl TapTweakHash {
101
101
/// Create a new BIP341 [`TapTweakHash`] from key and tweak
102
102
/// Produces H_taptweak(P||R) where P is internal key and R is the merkle root
103
103
pub fn from_key_and_tweak (
104
- internal_key : schnorr :: PublicKey ,
104
+ internal_key : UntweakedPublicKey ,
105
105
merkle_root : Option < TapBranchHash > ,
106
106
) -> TapTweakHash {
107
107
let mut eng = TapTweakHash :: engine ( ) ;
@@ -171,13 +171,13 @@ type ScriptMerkleProofMap = BTreeMap<(Script, LeafVersion), BTreeSet<TaprootMerk
171
171
#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
172
172
pub struct TaprootSpendInfo {
173
173
/// The BIP341 internal key.
174
- internal_key : schnorr :: PublicKey ,
174
+ internal_key : UntweakedPublicKey ,
175
175
/// The Merkle root of the script tree (None if there are no scripts)
176
176
merkle_root : Option < TapBranchHash > ,
177
177
/// The sign final output pubkey as per BIP 341
178
178
output_key_parity : bool ,
179
179
/// The tweaked output key
180
- output_key : schnorr :: PublicKey ,
180
+ output_key : TweakedPublicKey ,
181
181
/// Map from (script, leaf_version) to (sets of) [`TaprootMerkleBranch`].
182
182
/// More than one control block for a given script is only possible if it
183
183
/// appears in multiple branches of the tree. In all cases, keeping one should
@@ -207,7 +207,7 @@ impl TaprootSpendInfo {
207
207
/// 2^32.
208
208
pub fn with_huffman_tree < C , I > (
209
209
secp : & Secp256k1 < C > ,
210
- internal_key : schnorr :: PublicKey ,
210
+ internal_key : UntweakedPublicKey ,
211
211
script_weights : I ,
212
212
) -> Result < Self , TaprootBuilderError >
213
213
where
@@ -253,20 +253,10 @@ impl TaprootSpendInfo {
253
253
///
254
254
pub fn new_key_spend < C : secp256k1:: Verification > (
255
255
secp : & Secp256k1 < C > ,
256
- internal_key : schnorr :: PublicKey ,
256
+ internal_key : UntweakedPublicKey ,
257
257
merkle_root : Option < TapBranchHash > ,
258
258
) -> Self {
259
- let tweak = TapTweakHash :: from_key_and_tweak ( internal_key, merkle_root) ;
260
- let mut output_key = internal_key;
261
- // # Panics:
262
- //
263
- // This would return Err if the merkle root hash is the negation of the secret
264
- // key corresponding to the internal key.
265
- // Because the tweak is derived as specified in BIP341 (hash output of a function),
266
- // this is unlikely to occur (1/2^128) in real life usage, it is safe to unwrap this
267
- let parity = output_key
268
- . tweak_add_assign ( & secp, & tweak)
269
- . expect ( "TapTweakHash::from_key_and_tweak is broken" ) ;
259
+ let ( output_key, parity) = internal_key. tap_tweak ( secp, merkle_root) ;
270
260
Self {
271
261
internal_key : internal_key,
272
262
merkle_root : merkle_root,
@@ -282,7 +272,7 @@ impl TaprootSpendInfo {
282
272
}
283
273
284
274
/// Obtain the internal key
285
- pub fn internal_key ( & self ) -> schnorr :: PublicKey {
275
+ pub fn internal_key ( & self ) -> UntweakedPublicKey {
286
276
self . internal_key
287
277
}
288
278
@@ -293,7 +283,7 @@ impl TaprootSpendInfo {
293
283
294
284
/// Output key(the key used in script pubkey) from Spend data. See also
295
285
/// [`TaprootSpendInfo::output_key_parity`]
296
- pub fn output_key ( & self ) -> schnorr :: PublicKey {
286
+ pub fn output_key ( & self ) -> TweakedPublicKey {
297
287
self . output_key
298
288
}
299
289
@@ -305,7 +295,7 @@ impl TaprootSpendInfo {
305
295
// Internal function to compute [`TaprootSpendInfo`] from NodeInfo
306
296
fn from_node_info < C : secp256k1:: Verification > (
307
297
secp : & Secp256k1 < C > ,
308
- internal_key : schnorr :: PublicKey ,
298
+ internal_key : UntweakedPublicKey ,
309
299
node : NodeInfo ,
310
300
) -> TaprootSpendInfo {
311
301
// Create as if it is a key spend path with the given merkle root
@@ -433,7 +423,7 @@ impl TaprootBuilder {
433
423
pub fn finalize < C : secp256k1:: Verification > (
434
424
mut self ,
435
425
secp : & Secp256k1 < C > ,
436
- internal_key : schnorr :: PublicKey ,
426
+ internal_key : UntweakedPublicKey ,
437
427
) -> Result < TaprootSpendInfo , TaprootBuilderError > {
438
428
if self . branch . len ( ) > 1 {
439
429
return Err ( TaprootBuilderError :: IncompleteTree ) ;
@@ -655,7 +645,7 @@ pub struct ControlBlock {
655
645
/// The parity of the output key (NOT THE INTERNAL KEY WHICH IS ALWAYS XONLY)
656
646
pub output_key_parity : bool ,
657
647
/// The internal key
658
- pub internal_key : schnorr :: PublicKey ,
648
+ pub internal_key : UntweakedPublicKey ,
659
649
/// The merkle proof of a script associated with this leaf
660
650
pub merkle_branch : TaprootMerkleBranch ,
661
651
}
@@ -677,7 +667,7 @@ impl ControlBlock {
677
667
}
678
668
let output_key_parity = ( sl[ 0 ] & 1 ) == 1 ;
679
669
let leaf_version = LeafVersion :: from_u8 ( sl[ 0 ] & TAPROOT_LEAF_MASK ) ?;
680
- let internal_key = schnorr :: PublicKey :: from_slice ( & sl[ 1 ..TAPROOT_CONTROL_BASE_SIZE ] )
670
+ let internal_key = UntweakedPublicKey :: from_slice ( & sl[ 1 ..TAPROOT_CONTROL_BASE_SIZE ] )
681
671
. map_err ( TaprootError :: InvalidInternalKey ) ?;
682
672
let merkle_branch = TaprootMerkleBranch :: from_slice ( & sl[ TAPROOT_CONTROL_BASE_SIZE ..] ) ?;
683
673
Ok ( ControlBlock {
@@ -722,7 +712,7 @@ impl ControlBlock {
722
712
pub fn verify_taproot_commitment < C : secp256k1:: Verification > (
723
713
& self ,
724
714
secp : & Secp256k1 < C > ,
725
- output_key : & schnorr :: PublicKey ,
715
+ output_key : & TweakedPublicKey ,
726
716
script : & Script ,
727
717
) -> bool {
728
718
// compute the script hash
@@ -746,7 +736,7 @@ impl ControlBlock {
746
736
let tweak = TapTweakHash :: from_key_and_tweak ( self . internal_key , Some ( curr_hash) ) ;
747
737
self . internal_key . tweak_add_check (
748
738
secp,
749
- output_key,
739
+ output_key. as_inner ( ) ,
750
740
self . output_key_parity ,
751
741
tweak. into_inner ( ) ,
752
742
)
@@ -903,6 +893,7 @@ mod test {
903
893
use hashes:: { sha256, Hash , HashEngine } ;
904
894
use secp256k1:: VerifyOnly ;
905
895
use core:: str:: FromStr ;
896
+ use schnorr;
906
897
907
898
fn tag_engine ( tag_name : & str ) -> sha256:: HashEngine {
908
899
let mut engine = sha256:: Hash :: engine ( ) ;
@@ -987,6 +978,7 @@ mod test {
987
978
988
979
fn _verify_tap_commitments ( secp : & Secp256k1 < VerifyOnly > , out_spk_hex : & str , script_hex : & str , control_block_hex : & str ) {
989
980
let out_pk = schnorr:: PublicKey :: from_str ( & out_spk_hex[ 4 ..] ) . unwrap ( ) ;
981
+ let out_pk = TweakedPublicKey :: dangerous_assume_tweaked ( out_pk) ;
990
982
let script = Script :: from_hex ( script_hex) . unwrap ( ) ;
991
983
let control_block = ControlBlock :: from_slice ( & Vec :: < u8 > :: from_hex ( control_block_hex) . unwrap ( ) ) . unwrap ( ) ;
992
984
assert_eq ! ( control_block_hex, control_block. serialize( ) . to_hex( ) ) ;
@@ -1028,7 +1020,7 @@ mod test {
1028
1020
#[ test]
1029
1021
fn build_huffman_tree ( ) {
1030
1022
let secp = Secp256k1 :: verification_only ( ) ;
1031
- let internal_key = schnorr :: PublicKey :: from_str ( "93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51" ) . unwrap ( ) ;
1023
+ let internal_key = UntweakedPublicKey :: from_str ( "93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51" ) . unwrap ( ) ;
1032
1024
1033
1025
let script_weights = vec ! [
1034
1026
( 10 , Script :: from_hex( "51" ) . unwrap( ) ) , // semantics of script don't matter for this test
@@ -1078,7 +1070,7 @@ mod test {
1078
1070
#[ test]
1079
1071
fn taptree_builder ( ) {
1080
1072
let secp = Secp256k1 :: verification_only ( ) ;
1081
- let internal_key = schnorr :: PublicKey :: from_str ( "93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51" ) . unwrap ( ) ;
1073
+ let internal_key = UntweakedPublicKey :: from_str ( "93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51" ) . unwrap ( ) ;
1082
1074
1083
1075
let builder = TaprootBuilder :: new ( ) ;
1084
1076
// Create a tree as shown below
0 commit comments