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