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