@@ -5,6 +5,14 @@ import kotlin.test.*
5
5
6
6
class Secp256k1Test {
7
7
8
+ val random = Random .Default
9
+
10
+ fun randomBytes (length : Int ): ByteArray {
11
+ val buffer = ByteArray (length)
12
+ random.nextBytes(buffer)
13
+ return buffer
14
+ }
15
+
8
16
@Test
9
17
fun verifyValidPrivateKey () {
10
18
val priv = Hex .decode(" 67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530" .lowercase())
@@ -454,40 +462,55 @@ class Secp256k1Test {
454
462
455
463
@Test
456
464
fun testMusig2SigningSession () {
457
- val privkeys = listOf (
458
- " 0101010101010101010101010101010101010101010101010101010101010101" ,
459
- " 0202020202020202020202020202020202020202020202020202020202020202" ,
460
- ).map { Hex .decode(it) }.toTypedArray()
465
+ val privkeys = listOf (randomBytes(32 ), randomBytes(32 ))
466
+ val sessionId = randomBytes(32 )
467
+ val msg32 = randomBytes(32 )
461
468
val pubkeys = privkeys.map { Secp256k1 .pubkeyCreate(it) }
462
-
463
- val sessionId = Hex .decode(" 0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F" )
464
469
val nonces = pubkeys.map { Secp256k1 .musigNonceGen(sessionId, null , it, null , null , null ) }
470
+ val testData = run {
471
+ val builder = StringBuilder ()
472
+ builder.append(" private keys\n " )
473
+ privkeys.forEach { builder.append(Hex .encode(it)).append(" \n " ) }
474
+ builder.append(" sessionId ${Hex .encode(sessionId)} \n " )
475
+ builder.append(" msg32 ${Hex .encode(msg32)} \n " )
476
+ builder.append(" nonces\n " )
477
+ nonces.forEach { builder.append(Hex .encode(it)).append(" \n " ) }
478
+ builder.toString()
479
+ }
465
480
val secnonces = nonces.map { it.copyOfRange(0 , 132 ) }
466
481
val pubnonces = nonces.map { it.copyOfRange(132 , 132 + 66 ) }
467
482
val aggnonce = Secp256k1 .musigNonceAgg(pubnonces.toTypedArray())
468
483
469
484
val keyaggCaches = (0 until 2 ).map { ByteArray (Secp256k1 .MUSIG2_PUBLIC_KEYAGG_CACHE_SIZE ) }
470
485
val aggpubkey = Secp256k1 .musigPubkeyAgg(pubkeys.toTypedArray(), keyaggCaches[0 ])
471
- assertContentEquals(aggpubkey, Secp256k1 .musigPubkeyAgg(pubkeys.toTypedArray(), keyaggCaches[1 ]))
472
- assertContentEquals(keyaggCaches[0 ], keyaggCaches[1 ])
486
+ assertContentEquals(aggpubkey, Secp256k1 .musigPubkeyAgg(pubkeys.toTypedArray(), keyaggCaches[1 ]), testData )
487
+ assertContentEquals(keyaggCaches[0 ], keyaggCaches[1 ], testData )
473
488
474
- val msg32 = Hex .decode(" 0303030303030303030303030303030303030303030303030303030303030303" )
475
489
val sessions = (0 until 2 ).map { Secp256k1 .musigNonceProcess(aggnonce, msg32, keyaggCaches[it]) }
476
490
val psigs = (0 until 2 ).map {
477
491
val psig = Secp256k1 .musigPartialSign(secnonces[it], privkeys[it], keyaggCaches[it], sessions[it])
478
- assertEquals(1 , Secp256k1 .musigPartialSigVerify(psig, pubnonces[it], pubkeys[it], keyaggCaches[it], sessions[it]))
479
- assertEquals(0 , Secp256k1 .musigPartialSigVerify(Random .nextBytes(32 ), pubnonces[it], pubkeys[it], keyaggCaches[it], sessions[it]))
492
+ assertEquals(1 , Secp256k1 .musigPartialSigVerify(psig, pubnonces[it], pubkeys[it], keyaggCaches[it], sessions[it]), testData )
493
+ assertEquals(0 , Secp256k1 .musigPartialSigVerify(Random .nextBytes(32 ), pubnonces[it], pubkeys[it], keyaggCaches[it], sessions[it]), testData )
480
494
psig
481
495
}
482
496
497
+ // signing fails if the secret nonce does not match the private key's public key
498
+ assertFails(testData) {
499
+ Secp256k1 .musigPartialSign(secnonces[1 ], privkeys[0 ], keyaggCaches[0 ], sessions[0 ])
500
+ }
501
+
502
+ assertFails(testData) {
503
+ Secp256k1 .musigPartialSign(secnonces[0 ], privkeys[1 ], keyaggCaches[1 ], sessions[1 ])
504
+ }
505
+
483
506
val sig = Secp256k1 .musigPartialSigAgg(sessions[0 ], psigs.toTypedArray())
484
- assertContentEquals(sig, Secp256k1 .musigPartialSigAgg(sessions[1 ], psigs.toTypedArray()))
485
- assertTrue(Secp256k1 .verifySchnorr(sig, msg32, aggpubkey))
507
+ assertContentEquals(sig, Secp256k1 .musigPartialSigAgg(sessions[1 ], psigs.toTypedArray()), testData )
508
+ assertTrue(Secp256k1 .verifySchnorr(sig, msg32, aggpubkey), testData )
486
509
487
510
val invalidSig1 = Secp256k1 .musigPartialSigAgg(sessions[0 ], arrayOf(psigs[0 ], psigs[0 ]))
488
- assertFalse(Secp256k1 .verifySchnorr(invalidSig1, msg32, aggpubkey))
511
+ assertFalse(Secp256k1 .verifySchnorr(invalidSig1, msg32, aggpubkey), testData )
489
512
val invalidSig2 = Secp256k1 .musigPartialSigAgg(sessions[0 ], arrayOf(Random .nextBytes(32 ), Random .nextBytes(32 )))
490
- assertFalse(Secp256k1 .verifySchnorr(invalidSig2, msg32, aggpubkey))
513
+ assertFalse(Secp256k1 .verifySchnorr(invalidSig2, msg32, aggpubkey), testData )
491
514
}
492
515
493
516
@Test
@@ -523,15 +546,14 @@ class Secp256k1Test {
523
546
}
524
547
525
548
@Test
526
- fun fuzzEcdsaSignVerify () {
527
- val random = Random .Default
528
-
529
- fun randomBytes (length : Int ): ByteArray {
530
- val buffer = ByteArray (length)
531
- random.nextBytes(buffer)
532
- return buffer
549
+ fun fuzzMusig2SigningSession () {
550
+ repeat(1000 ) {
551
+ testMusig2SigningSession()
533
552
}
553
+ }
534
554
555
+ @Test
556
+ fun fuzzEcdsaSignVerify () {
535
557
repeat(200 ) {
536
558
val priv = randomBytes(32 )
537
559
assertTrue(Secp256k1 .secKeyVerify(priv))
0 commit comments