@@ -1195,3 +1195,338 @@ impl Session {
11951195 /// Get a mut pointer to the inner Session
11961196 pub fn as_mut_ptr ( & mut self ) -> * mut ffi:: MusigSession { & mut self . 0 }
11971197}
1198+
1199+ #[ cfg( test) ]
1200+ mod tests {
1201+ use super :: * ;
1202+ #[ cfg( feature = "std" ) ]
1203+ #[ cfg( feature = "rand" ) ]
1204+ use crate :: { Message , PublicKey , Secp256k1 , SecretKey } ;
1205+
1206+ #[ test]
1207+ #[ cfg( feature = "std" ) ]
1208+ #[ cfg( feature = "rand" ) ]
1209+ fn session_secret_rand ( ) {
1210+ let mut rng = rand:: rng ( ) ;
1211+ let session_secrand = SessionSecretRand :: from_rng ( & mut rng) ;
1212+ let session_secrand1 = SessionSecretRand :: from_rng ( & mut rng) ;
1213+ assert_ne ! ( session_secrand. to_byte_array( ) , [ 0 ; 32 ] ) ; // with overwhelming probability
1214+ assert_ne ! ( session_secrand, session_secrand1) ; // with overwhelming probability
1215+ }
1216+
1217+ #[ test]
1218+ fn session_secret_no_rand ( ) {
1219+ let custom_bytes = [ 42u8 ; 32 ] ;
1220+ let session_secrand = SessionSecretRand :: assume_unique_per_nonce_gen ( custom_bytes) ;
1221+ assert_eq ! ( session_secrand. to_byte_array( ) , custom_bytes) ;
1222+ assert_eq ! ( session_secrand. as_byte_array( ) , & custom_bytes) ;
1223+ }
1224+
1225+ #[ test]
1226+ #[ should_panic( expected = "session secrets may not be all zero" ) ]
1227+ fn session_secret_rand_zero_panic ( ) {
1228+ let zero_bytes = [ 0u8 ; 32 ] ;
1229+ let _session_secrand = SessionSecretRand :: assume_unique_per_nonce_gen ( zero_bytes) ;
1230+ }
1231+
1232+ #[ test]
1233+ #[ cfg( not( secp256k1_fuzz) ) ]
1234+ #[ cfg( feature = "std" ) ]
1235+ #[ cfg( feature = "rand" ) ]
1236+ fn key_agg_cache ( ) {
1237+ let secp = Secp256k1 :: new ( ) ;
1238+ let mut rng = rand:: rng ( ) ;
1239+
1240+ let ( _seckey1, pubkey1) = secp. generate_keypair ( & mut rng) ;
1241+ let seckey2 = SecretKey :: new ( & mut rng) ;
1242+ let pubkey2 = PublicKey :: from_secret_key ( & secp, & seckey2) ;
1243+
1244+ let pubkeys = [ & pubkey1, & pubkey2] ;
1245+ let key_agg_cache = KeyAggCache :: new ( & secp, & pubkeys) ;
1246+ let agg_pk = key_agg_cache. agg_pk ( ) ;
1247+
1248+ // Test agg_pk_full
1249+ let agg_pk_full = key_agg_cache. agg_pk_full ( ) ;
1250+ assert_eq ! ( agg_pk_full. x_only_public_key( ) . 0 , agg_pk) ;
1251+ }
1252+
1253+ #[ test]
1254+ #[ cfg( not( secp256k1_fuzz) ) ]
1255+ #[ cfg( feature = "std" ) ]
1256+ #[ cfg( feature = "rand" ) ]
1257+ fn key_agg_cache_tweaking ( ) {
1258+ let secp = Secp256k1 :: new ( ) ;
1259+ let mut rng = rand:: rng ( ) ;
1260+
1261+ let ( _seckey1, pubkey1) = secp. generate_keypair ( & mut rng) ;
1262+ let seckey2 = SecretKey :: new ( & mut rng) ;
1263+ let pubkey2 = PublicKey :: from_secret_key ( & secp, & seckey2) ;
1264+
1265+ let mut key_agg_cache = KeyAggCache :: new ( & secp, & [ & pubkey1, & pubkey2] ) ;
1266+ let key_agg_cache1 = KeyAggCache :: new ( & secp, & [ & pubkey2, & pubkey1] ) ;
1267+ let key_agg_cache2 = KeyAggCache :: new ( & secp, & [ & pubkey1, & pubkey1] ) ;
1268+ let key_agg_cache3 = KeyAggCache :: new ( & secp, & [ & pubkey1, & pubkey1, & pubkey2] ) ;
1269+ assert_ne ! ( key_agg_cache, key_agg_cache1) ; // swapped keys DOES mean not equal
1270+ assert_ne ! ( key_agg_cache, key_agg_cache2) ; // missing keys
1271+ assert_ne ! ( key_agg_cache, key_agg_cache3) ; // repeated key
1272+ let original_agg_pk = key_agg_cache. agg_pk ( ) ;
1273+ assert_ne ! ( key_agg_cache. agg_pk( ) , key_agg_cache1. agg_pk( ) ) ; // swapped keys DOES mean not equal
1274+ assert_ne ! ( key_agg_cache. agg_pk( ) , key_agg_cache2. agg_pk( ) ) ; // missing keys
1275+ assert_ne ! ( key_agg_cache. agg_pk( ) , key_agg_cache3. agg_pk( ) ) ; // repeated key
1276+
1277+ // Test EC tweaking
1278+ let plain_tweak: [ u8 ; 32 ] = * b"this could be a BIP32 tweak....\0 " ;
1279+ let plain_tweak = Scalar :: from_be_bytes ( plain_tweak) . unwrap ( ) ;
1280+ let tweaked_key = key_agg_cache. pubkey_ec_tweak_add ( & secp, & plain_tweak) . unwrap ( ) ;
1281+ assert_ne ! ( key_agg_cache. agg_pk( ) , original_agg_pk) ;
1282+ assert_eq ! ( key_agg_cache. agg_pk( ) , tweaked_key. x_only_public_key( ) . 0 ) ;
1283+
1284+ // Test xonly tweaking
1285+ let xonly_tweak: [ u8 ; 32 ] = * b"this could be a Taproot tweak..\0 " ;
1286+ let xonly_tweak = Scalar :: from_be_bytes ( xonly_tweak) . unwrap ( ) ;
1287+ let tweaked_agg_pk = key_agg_cache. pubkey_xonly_tweak_add ( & secp, & xonly_tweak) . unwrap ( ) ;
1288+ assert_eq ! ( key_agg_cache. agg_pk( ) , tweaked_agg_pk. x_only_public_key( ) . 0 ) ;
1289+ }
1290+
1291+ #[ test]
1292+ #[ cfg( feature = "std" ) ]
1293+ #[ cfg( feature = "rand" ) ]
1294+ #[ should_panic( expected = "Cannot aggregate an empty slice of pubkeys" ) ]
1295+ fn key_agg_cache_empty_panic ( ) {
1296+ let secp = Secp256k1 :: new ( ) ;
1297+ let _ = KeyAggCache :: new ( & secp, & [ ] ) ;
1298+ }
1299+
1300+ #[ test]
1301+ #[ cfg( feature = "std" ) ]
1302+ #[ cfg( feature = "rand" ) ]
1303+ fn nonce_generation ( ) {
1304+ let secp = Secp256k1 :: new ( ) ;
1305+ let mut rng = rand:: rng ( ) ;
1306+
1307+ let ( _seckey1, pubkey1) = secp. generate_keypair ( & mut rng) ;
1308+ let seckey2 = SecretKey :: new ( & mut rng) ;
1309+ let pubkey2 = PublicKey :: from_secret_key ( & secp, & seckey2) ;
1310+
1311+ let key_agg_cache = KeyAggCache :: new ( & secp, & [ & pubkey1, & pubkey2] ) ;
1312+
1313+ let msg_bytes: [ u8 ; 32 ] = * b"this_could_be_the_hash_of_a_msg!" ;
1314+ let msg = Message :: from_digest_slice ( & msg_bytes) . unwrap ( ) ;
1315+
1316+ // Test nonce generation with KeyAggCache
1317+ let session_secrand1 = SessionSecretRand :: from_rng ( & mut rng) ;
1318+ let ( _sec_nonce1, pub_nonce1) =
1319+ key_agg_cache. nonce_gen ( & secp, session_secrand1, pubkey1, msg, None ) ;
1320+
1321+ // Test direct nonce generation
1322+ let session_secrand2 = SessionSecretRand :: from_rng ( & mut rng) ;
1323+ let extra_rand = Some ( [ 42u8 ; 32 ] ) ;
1324+ let ( _sec_nonce2, _pub_nonce2) = new_nonce_pair (
1325+ & secp,
1326+ session_secrand2,
1327+ Some ( & key_agg_cache) ,
1328+ Some ( seckey2) ,
1329+ pubkey2,
1330+ Some ( msg) ,
1331+ extra_rand,
1332+ ) ;
1333+
1334+ // Test PublicNonce serialization/deserialization
1335+ let serialized_nonce = pub_nonce1. serialize ( ) ;
1336+ let deserialized_nonce = PublicNonce :: from_byte_array ( & serialized_nonce) . unwrap ( ) ;
1337+ assert_eq ! ( pub_nonce1. serialize( ) , deserialized_nonce. serialize( ) ) ;
1338+ }
1339+
1340+ #[ test]
1341+ #[ cfg( feature = "std" ) ]
1342+ #[ cfg( feature = "rand" ) ]
1343+ fn aggregated_nonce ( ) {
1344+ let secp = Secp256k1 :: new ( ) ;
1345+ let mut rng = rand:: rng ( ) ;
1346+
1347+ let ( _seckey1, pubkey1) = secp. generate_keypair ( & mut rng) ;
1348+ let seckey2 = SecretKey :: new ( & mut rng) ;
1349+ let pubkey2 = PublicKey :: from_secret_key ( & secp, & seckey2) ;
1350+
1351+ let key_agg_cache = KeyAggCache :: new ( & secp, & [ & pubkey1, & pubkey2] ) ;
1352+
1353+ let msg_bytes: [ u8 ; 32 ] = * b"this_could_be_the_hash_of_a_msg!" ;
1354+ let msg = Message :: from_digest_slice ( & msg_bytes) . unwrap ( ) ;
1355+
1356+ let session_secrand1 = SessionSecretRand :: from_rng ( & mut rng) ;
1357+ let ( _, pub_nonce1) = key_agg_cache. nonce_gen ( & secp, session_secrand1, pubkey1, msg, None ) ;
1358+
1359+ let session_secrand2 = SessionSecretRand :: from_rng ( & mut rng) ;
1360+ let ( _, pub_nonce2) = key_agg_cache. nonce_gen ( & secp, session_secrand2, pubkey2, msg, None ) ;
1361+
1362+ // Test AggregatedNonce creation
1363+ let agg_nonce = AggregatedNonce :: new ( & secp, & [ & pub_nonce1, & pub_nonce2] ) ;
1364+ let agg_nonce1 = AggregatedNonce :: new ( & secp, & [ & pub_nonce2, & pub_nonce1] ) ;
1365+ let agg_nonce2 = AggregatedNonce :: new ( & secp, & [ & pub_nonce2, & pub_nonce2] ) ;
1366+ let agg_nonce3 = AggregatedNonce :: new ( & secp, & [ & pub_nonce2, & pub_nonce2] ) ;
1367+ assert_eq ! ( agg_nonce, agg_nonce1) ; // swapped nonces
1368+ assert_ne ! ( agg_nonce, agg_nonce2) ; // repeated/different nonces
1369+ assert_ne ! ( agg_nonce, agg_nonce3) ; // repeated nonce but still both nonces present
1370+
1371+ // Test AggregatedNonce serialization/deserialization
1372+ let serialized_agg_nonce = agg_nonce. serialize ( ) ;
1373+ let deserialized_agg_nonce =
1374+ AggregatedNonce :: from_byte_array ( & serialized_agg_nonce) . unwrap ( ) ;
1375+ assert_eq ! ( agg_nonce. serialize( ) , deserialized_agg_nonce. serialize( ) ) ;
1376+ }
1377+
1378+ #[ test]
1379+ #[ cfg( feature = "std" ) ]
1380+ #[ cfg( feature = "rand" ) ]
1381+ #[ should_panic( expected = "Cannot aggregate an empty slice of nonces" ) ]
1382+ fn aggregated_nonce_empty_panic ( ) {
1383+ let secp = Secp256k1 :: new ( ) ;
1384+ let empty_nonces: Vec < & PublicNonce > = vec ! [ ] ;
1385+ let _agg_nonce = AggregatedNonce :: new ( & secp, & empty_nonces) ;
1386+ }
1387+
1388+ #[ test]
1389+ #[ cfg( not( secp256k1_fuzz) ) ]
1390+ #[ cfg( feature = "std" ) ]
1391+ #[ cfg( feature = "rand" ) ]
1392+ fn session_and_partial_signing ( ) {
1393+ let secp = Secp256k1 :: new ( ) ;
1394+ let mut rng = rand:: rng ( ) ;
1395+
1396+ let ( seckey1, pubkey1) = secp. generate_keypair ( & mut rng) ;
1397+ let seckey2 = SecretKey :: new ( & mut rng) ;
1398+ let pubkey2 = PublicKey :: from_secret_key ( & secp, & seckey2) ;
1399+
1400+ let pubkeys = [ & pubkey1, & pubkey2] ;
1401+ let key_agg_cache = KeyAggCache :: new ( & secp, & pubkeys) ;
1402+
1403+ let msg_bytes: [ u8 ; 32 ] = * b"this_could_be_the_hash_of_a_msg!" ;
1404+ let msg = Message :: from_digest_slice ( & msg_bytes) . unwrap ( ) ;
1405+
1406+ let session_secrand1 = SessionSecretRand :: from_rng ( & mut rng) ;
1407+ let ( sec_nonce1, pub_nonce1) =
1408+ key_agg_cache. nonce_gen ( & secp, session_secrand1, pubkey1, msg, None ) ;
1409+
1410+ let session_secrand2 = SessionSecretRand :: from_rng ( & mut rng) ;
1411+ let ( sec_nonce2, pub_nonce2) =
1412+ key_agg_cache. nonce_gen ( & secp, session_secrand2, pubkey2, msg, None ) ;
1413+
1414+ let nonces = [ & pub_nonce1, & pub_nonce2] ;
1415+ let agg_nonce = AggregatedNonce :: new ( & secp, & nonces) ;
1416+
1417+ // Test Session creation
1418+ let session = Session :: new ( & secp, & key_agg_cache, agg_nonce, msg) ;
1419+
1420+ // Test partial signing
1421+ let keypair1 = Keypair :: from_secret_key ( & secp, & seckey1) ;
1422+ let partial_sign1 = session. partial_sign ( & secp, sec_nonce1, & keypair1, & key_agg_cache) ;
1423+
1424+ let keypair2 = Keypair :: from_secret_key ( & secp, & seckey2) ;
1425+ let partial_sign2 = session. partial_sign ( & secp, sec_nonce2, & keypair2, & key_agg_cache) ;
1426+
1427+ // Test partial signature verification
1428+ assert ! ( session. partial_verify( & secp, & key_agg_cache, partial_sign1, pub_nonce1, pubkey1) ) ;
1429+ assert ! ( session. partial_verify( & secp, & key_agg_cache, partial_sign2, pub_nonce2, pubkey2) ) ;
1430+ // Test that they are invalid if you switch keys
1431+ assert ! ( !session. partial_verify( & secp, & key_agg_cache, partial_sign2, pub_nonce2, pubkey1) ) ;
1432+ assert ! ( !session. partial_verify( & secp, & key_agg_cache, partial_sign2, pub_nonce1, pubkey2) ) ;
1433+ assert ! ( !session. partial_verify( & secp, & key_agg_cache, partial_sign2, pub_nonce1, pubkey1) ) ;
1434+
1435+ // Test PartialSignature serialization/deserialization
1436+ let serialized_partial_sig = partial_sign1. serialize ( ) ;
1437+ let deserialized_partial_sig =
1438+ PartialSignature :: from_byte_array ( & serialized_partial_sig) . unwrap ( ) ;
1439+ assert_eq ! ( partial_sign1. serialize( ) , deserialized_partial_sig. serialize( ) ) ;
1440+ }
1441+
1442+ #[ test]
1443+ #[ cfg( not( secp256k1_fuzz) ) ]
1444+ #[ cfg( feature = "std" ) ]
1445+ #[ cfg( feature = "rand" ) ]
1446+ fn signature_aggregation_and_verification ( ) {
1447+ let secp = Secp256k1 :: new ( ) ;
1448+ let mut rng = rand:: rng ( ) ;
1449+
1450+ let ( seckey1, pubkey1) = secp. generate_keypair ( & mut rng) ;
1451+ let seckey2 = SecretKey :: new ( & mut rng) ;
1452+ let pubkey2 = PublicKey :: from_secret_key ( & secp, & seckey2) ;
1453+
1454+ let pubkeys = [ & pubkey1, & pubkey2] ;
1455+ let key_agg_cache = KeyAggCache :: new ( & secp, & pubkeys) ;
1456+
1457+ let msg_bytes: [ u8 ; 32 ] = * b"this_could_be_the_hash_of_a_msg!" ;
1458+ let msg = Message :: from_digest_slice ( & msg_bytes) . unwrap ( ) ;
1459+
1460+ let session_secrand1 = SessionSecretRand :: from_rng ( & mut rng) ;
1461+ let ( sec_nonce1, pub_nonce1) =
1462+ key_agg_cache. nonce_gen ( & secp, session_secrand1, pubkey1, msg, None ) ;
1463+
1464+ let session_secrand2 = SessionSecretRand :: from_rng ( & mut rng) ;
1465+ let ( sec_nonce2, pub_nonce2) =
1466+ key_agg_cache. nonce_gen ( & secp, session_secrand2, pubkey2, msg, None ) ;
1467+
1468+ let nonces = [ & pub_nonce1, & pub_nonce2] ;
1469+ let agg_nonce = AggregatedNonce :: new ( & secp, & nonces) ;
1470+ let session = Session :: new ( & secp, & key_agg_cache, agg_nonce, msg) ;
1471+
1472+ let keypair1 = Keypair :: from_secret_key ( & secp, & seckey1) ;
1473+ let partial_sign1 = session. partial_sign ( & secp, sec_nonce1, & keypair1, & key_agg_cache) ;
1474+
1475+ let keypair2 = Keypair :: from_secret_key ( & secp, & seckey2) ;
1476+ let partial_sign2 = session. partial_sign ( & secp, sec_nonce2, & keypair2, & key_agg_cache) ;
1477+
1478+ // Test signature verification
1479+ let aggregated_signature = session. partial_sig_agg ( & [ & partial_sign1, & partial_sign2] ) ;
1480+ let agg_pk = key_agg_cache. agg_pk ( ) ;
1481+ aggregated_signature. verify ( & secp, & agg_pk, & msg_bytes) . unwrap ( ) ;
1482+
1483+ // Test assume_valid
1484+ let schnorr_sig = aggregated_signature. assume_valid ( ) ;
1485+ secp. verify_schnorr ( & schnorr_sig, & msg_bytes, & agg_pk) . unwrap ( ) ;
1486+
1487+ // Test with wrong aggregate (repeated sigs)
1488+ let aggregated_signature = session. partial_sig_agg ( & [ & partial_sign1, & partial_sign1] ) ;
1489+ aggregated_signature. verify ( & secp, & agg_pk, & msg_bytes) . unwrap_err ( ) ;
1490+ let schnorr_sig = aggregated_signature. assume_valid ( ) ;
1491+ secp. verify_schnorr ( & schnorr_sig, & msg_bytes, & agg_pk) . unwrap_err ( ) ;
1492+
1493+ // Test with swapped sigs -- this will work. Unlike keys, sigs are not ordered.
1494+ let aggregated_signature = session. partial_sig_agg ( & [ & partial_sign2, & partial_sign1] ) ;
1495+ aggregated_signature. verify ( & secp, & agg_pk, & msg_bytes) . unwrap ( ) ;
1496+ let schnorr_sig = aggregated_signature. assume_valid ( ) ;
1497+ secp. verify_schnorr ( & schnorr_sig, & msg_bytes, & agg_pk) . unwrap ( ) ;
1498+ }
1499+
1500+ #[ test]
1501+ #[ cfg( feature = "std" ) ]
1502+ #[ cfg( feature = "rand" ) ]
1503+ #[ should_panic( expected = "Cannot aggregate an empty slice of partial signatures" ) ]
1504+ fn partial_sig_agg_empty_panic ( ) {
1505+ let secp = Secp256k1 :: new ( ) ;
1506+ let mut rng = rand:: rng ( ) ;
1507+
1508+ let ( _seckey1, pubkey1) = secp. generate_keypair ( & mut rng) ;
1509+ let seckey2 = SecretKey :: new ( & mut rng) ;
1510+ let pubkey2 = PublicKey :: from_secret_key ( & secp, & seckey2) ;
1511+
1512+ let pubkeys = [ pubkey1, pubkey2] ;
1513+ let mut pubkeys_ref: Vec < & PublicKey > = pubkeys. iter ( ) . collect ( ) ;
1514+ let pubkeys_ref = pubkeys_ref. as_mut_slice ( ) ;
1515+
1516+ let key_agg_cache = KeyAggCache :: new ( & secp, pubkeys_ref) ;
1517+ let msg_bytes: [ u8 ; 32 ] = * b"this_could_be_the_hash_of_a_msg!" ;
1518+ let msg = Message :: from_digest_slice ( & msg_bytes) . unwrap ( ) ;
1519+
1520+ let session_secrand1 = SessionSecretRand :: from_rng ( & mut rng) ;
1521+ let ( _, pub_nonce1) = key_agg_cache. nonce_gen ( & secp, session_secrand1, pubkey1, msg, None ) ;
1522+ let session_secrand2 = SessionSecretRand :: from_rng ( & mut rng) ;
1523+ let ( _, pub_nonce2) = key_agg_cache. nonce_gen ( & secp, session_secrand2, pubkey2, msg, None ) ;
1524+
1525+ let nonces = [ pub_nonce1, pub_nonce2] ;
1526+ let nonces_ref: Vec < & PublicNonce > = nonces. iter ( ) . collect ( ) ;
1527+ let agg_nonce = AggregatedNonce :: new ( & secp, & nonces_ref) ;
1528+ let session = Session :: new ( & secp, & key_agg_cache, agg_nonce, msg) ;
1529+
1530+ let _agg_sig = session. partial_sig_agg ( & [ ] ) ;
1531+ }
1532+ }
0 commit comments