@@ -1341,6 +1341,8 @@ mod tests {
13411341 secp256k1:: { All , SecretKey } ,
13421342 } ;
13431343
1344+ use std:: str:: FromStr ;
1345+
13441346 use super :: * ;
13451347 use crate :: address:: script_pubkey:: ScriptExt as _;
13461348 use crate :: bip32:: ChildNumber ;
@@ -2237,6 +2239,49 @@ mod tests {
22372239 assert ! ( !rtt. proprietary. is_empty( ) ) ;
22382240 }
22392241
2242+ // Deserialize MuSig2 PSBT participant keys according to BIP-373
2243+ #[ test]
2244+ fn serialize_and_deserialize_musig2_participants ( ) {
2245+ // XXX: Does not cover PSBT_IN_MUSIG2_PUB_NONCE, PSBT_IN_MUSIG2_PARTIAL_SIG (yet)
2246+
2247+ let expected_in_agg_pk = secp256k1:: PublicKey :: from_str ( "021401301810a46a4e3f39e4603ec228ed301d9f2079767fda758dee7224b32e00" ) . unwrap ( ) ;
2248+ let expected_in_pubkeys = vec ! [
2249+ secp256k1:: PublicKey :: from_str( "02bebd7a1cef20283444b96e9ce78137e951ce48705390933896311a9abc75736a" ) . unwrap( ) ,
2250+ secp256k1:: PublicKey :: from_str( "0355212dff7b3d7e8126687a62fd0435a3fb4de56d9af9ae23a1c9ca05b349c8e2" ) . unwrap( ) ,
2251+ ] ;
2252+
2253+ let expected_out_agg_pk = secp256k1:: PublicKey :: from_str ( "0364934a64831bd917a2667b886671650846f021e1c025e4b2bb65e49ab3e7cba5" ) . unwrap ( ) ;
2254+
2255+ let expected_out_pubkeys = vec ! [
2256+ secp256k1:: PublicKey :: from_str( "02841d69a8b80ae23a8090e6f3765540ea5efd8c287b1307c983a6e2a3a171b525" ) . unwrap( ) ,
2257+ secp256k1:: PublicKey :: from_str( "02bad833849a98cdfb0a0749609ddccab16ad54485ecc67f828df4bdc4f2b90d4c" ) . unwrap( ) ,
2258+ ] ;
2259+
2260+ const PSBT_HEX : & str = "70736274ff01005e02000000017b42be5ea467afe0d0571dc4a91bef97ff9605a590c0b8d5892323946414d1810000000000ffffffff01f0b9f50500000000225120bc7e18f55e2c7a28d78cadac1bc72c248372375d269bafe6b315bc40505d07e5000000000001012b00e1f50500000000225120de564ebf8ff7bd9bb41bd88264c04b1713ebb9dc8df36319091d2eabb16cda6221161401301810a46a4e3f39e4603ec228ed301d9f2079767fda758dee7224b32e000500eb4cbe62211655212dff7b3d7e8126687a62fd0435a3fb4de56d9af9ae23a1c9ca05b349c8e20500755abbf92116bebd7a1cef20283444b96e9ce78137e951ce48705390933896311a9abc75736a05002a33dfd90117201401301810a46a4e3f39e4603ec228ed301d9f2079767fda758dee7224b32e00221a021401301810a46a4e3f39e4603ec228ed301d9f2079767fda758dee7224b32e004202bebd7a1cef20283444b96e9ce78137e951ce48705390933896311a9abc75736a0355212dff7b3d7e8126687a62fd0435a3fb4de56d9af9ae23a1c9ca05b349c8e20001052064934a64831bd917a2667b886671650846f021e1c025e4b2bb65e49ab3e7cba5210764934a64831bd917a2667b886671650846f021e1c025e4b2bb65e49ab3e7cba50500fa4c6afa22080364934a64831bd917a2667b886671650846f021e1c025e4b2bb65e49ab3e7cba54202841d69a8b80ae23a8090e6f3765540ea5efd8c287b1307c983a6e2a3a171b52502bad833849a98cdfb0a0749609ddccab16ad54485ecc67f828df4bdc4f2b90d4c00" ;
2261+
2262+ let psbt = hex_psbt ( PSBT_HEX ) . unwrap ( ) ;
2263+
2264+ assert_eq ! ( psbt. inputs[ 0 ] . musig2_participant_pubkeys. len( ) , 1 ) ;
2265+ assert_eq ! (
2266+ psbt. inputs[ 0 ] . musig2_participant_pubkeys. iter( ) . next( ) . unwrap( ) ,
2267+ ( & expected_in_agg_pk, & expected_in_pubkeys)
2268+ ) ;
2269+
2270+ assert_eq ! ( psbt. outputs[ 0 ] . musig2_participant_pubkeys. len( ) , 1 ) ;
2271+ assert_eq ! (
2272+ psbt. outputs[ 0 ] . musig2_participant_pubkeys. iter( ) . next( ) . unwrap( ) ,
2273+ ( & expected_out_agg_pk, & expected_out_pubkeys)
2274+ ) ;
2275+
2276+ // Check round trip de/serialization
2277+ assert_eq ! ( psbt. serialize_hex( ) , PSBT_HEX ) ;
2278+
2279+ const PSBT_TRUNCATED_MUSIG_PARTICIPANTS_HEX : & str = "70736274ff01005e0200000001f034711ce319b1db76ce73440f2cb64a7e3a02e75c936b8d8a4958a024ea8d870000000000ffffffff01f0b9f50500000000225120bc7e18f55e2c7a28d78cadac1bc72c248372375d269bafe6b315bc40505d07e5000000000001012b00e1f50500000000225120de564ebf8ff7bd9bb41bd88264c04b1713ebb9dc8df36319091d2eabb16cda6221161401301810a46a4e3f39e4603ec228ed301d9f2079767fda758dee7224b32e000500eb4cbe62211655212dff7b3d7e8126687a62fd0435a3fb4de56d9af9ae23a1c9ca05b349c8e20500755abbf92116bebd7a1cef20283444b96e9ce78137e951ce48705390933896311a9abc75736a05002a33dfd90117201401301810a46a4e3f39e4603ec228ed301d9f2079767fda758dee7224b32e00221a021401301810a46a4e3f39e4603ec228ed301d9f2079767fda758dee7224b32e002a02bebd7a1cef20283444b96e9ce78137e951ce48705390933896311a9abc75736a0355212dff7b3d7e810001052064934a64831bd917a2667b886671650846f021e1c025e4b2bb65e49ab3e7cba5210764934a64831bd917a2667b886671650846f021e1c025e4b2bb65e49ab3e7cba50500fa4c6afa22080364934a64831bd917a2667b886671650846f021e1c025e4b2bb65e49ab3e7cba52a02841d69a8b80ae23a8090e6f3765540ea5efd8c287b1307c983a6e2a3a171b52502bad833849a98cdfb00" ;
2280+
2281+ hex_psbt ( PSBT_TRUNCATED_MUSIG_PARTICIPANTS_HEX )
2282+ . expect_err ( "Deserializing PSBT with truncated musig participants should error" ) ;
2283+ }
2284+
22402285 // PSBTs taken from BIP 174 test vectors.
22412286 #[ test]
22422287 fn combine_psbts ( ) {
0 commit comments