package fr.acinq.secp256k1 import kotlinx.serialization.json.* import kotlin.test.* class FrostTest: BaseTest() { // Frost Share Generation @Test fun `frost share generation`() { val tests = readData("frost/share_gen_vectors.json") val pubkeys = tests.jsonObject["pubkeys"]!!.jsonArray.map { Hex.decode(it.jsonPrimitive.content) } tests.jsonObject["valid_share_gen_test_cases"]!!.jsonArray.forEach { validTestCases -> val keyIndices = validTestCases.jsonObject["key_indices"]!!.jsonArray.map { it.jsonPrimitive.int } val seed32 = Hex.decode(validTestCases.jsonObject["seed"]!!.jsonPrimitive.content) val nParticipants = keyIndices.size val threshold = validTestCases.jsonObject["threshold"]!!.jsonPrimitive.int val ids33 = keyIndices.map { pubkeys[it] }.toTypedArray() val result = Secp256k1.frostSharesGen( seed32, threshold, nParticipants, ids33 ) val expected = validTestCases.jsonObject["expected"]!!; val expectedShare = expected.jsonObject["frost_share"]!!.jsonArray.map { Hex.decode(it.jsonPrimitive.content) } val expectedVSSCommitment = expected.jsonObject["vss_commitment"]!!.jsonArray.map { Hex.decode(it.jsonPrimitive.content) } val expectedPoK64 = Hex.decode(expected.jsonObject["pok64"]!!.jsonPrimitive.content) result.first.forEachIndexed { index, share -> assertEquals( expected = Hex.encode(expectedShare[index]), actual = Hex.encode(share), "Unexpected $index:share for $keyIndices test case" ) } result.second.forEachIndexed { index, vssCommitment -> assertEquals( expected = Hex.encode(expectedVSSCommitment[index]), actual = Hex.encode(vssCommitment), "Unexpected $index:vss_commitment for the $keyIndices test case" ) } assertEquals( expected = Hex.encode(expectedPoK64), actual = Hex.encode(result.third), message = "Unexpected pok64 for $keyIndices test case" ) } val signerShareGenTestCase = tests.jsonObject["valid_signers_share_gen_test_case"]!! val keyIndices = signerShareGenTestCase.jsonObject["key_indices"]!!.jsonArray.map { it.jsonPrimitive.int } val nParticipants = keyIndices.size val threshold = signerShareGenTestCase.jsonObject["threshold"]!!.jsonPrimitive.int val ids33 = keyIndices.map { pubkeys[it] }.toTypedArray() signerShareGenTestCase.jsonObject["signers"]!!.jsonArray.forEachIndexed { signerIndex, signer -> val seed32 = Hex.decode(signer.jsonObject["seed"]!!.jsonPrimitive.content) val result = Secp256k1.frostSharesGen( seed32, threshold, nParticipants, ids33 ) val expected = signer.jsonObject["expected"]!!; val expectedShare = expected.jsonObject["frost_share"]!!.jsonArray.map { Hex.decode(it.jsonPrimitive.content) } val expectedVSSCommitment = expected.jsonObject["vss_commitment"]!!.jsonArray.map { Hex.decode(it.jsonPrimitive.content) } val expectedPoK64 = Hex.decode(expected.jsonObject["pok64"]!!.jsonPrimitive.content) result.first.forEachIndexed { index, share -> assertEquals( expected = Hex.encode(expectedShare[index]), actual = Hex.encode(share), "Unexpected $signerIndex:signer $index:share for $keyIndices test case" ) } result.second.forEachIndexed { index, vssCommitment -> assertEquals( expected = Hex.encode(expectedVSSCommitment[index]), actual = Hex.encode(vssCommitment), "Unexpected $signerIndex:signer $index:vss_commitment for the $keyIndices test case" ) } assertEquals( expected = Hex.encode(expectedPoK64), actual = Hex.encode(result.third), message = "Unexpected $signerIndex:signer pok64 for $keyIndices test case" ) } } @Test fun `frost share aggregation`() { val shareGenTests = readData("frost/share_gen_vectors.json") val tests = readData("frost/share_agg_vectors.json") val publicKeys = shareGenTests.jsonObject["pubkeys"]!!.jsonArray.map { Hex.decode(it.jsonPrimitive.content) } val signerShareGenTestCase = shareGenTests.jsonObject["valid_signers_share_gen_test_case"]!!; val keyIndices = signerShareGenTestCase.jsonObject["key_indices"]!!.jsonArray.map { it.jsonPrimitive.int } val nParticipants = keyIndices.size val threshold = signerShareGenTestCase.jsonObject["threshold"]!!.jsonPrimitive.int val ids33 = keyIndices.map { publicKeys[it] }.toTypedArray() val vssCommitments = signerShareGenTestCase.jsonObject["signers"]!!.jsonArray.map { signer -> signer.jsonObject["expected"]!!.jsonObject["vss_commitment"]!!.jsonArray.map { Hex.decode(it.jsonPrimitive.content) }.toTypedArray() } signerShareGenTestCase.jsonObject["signers"]!!.jsonArray.forEachIndexed { index, _signer -> val assignedShares = signerShareGenTestCase.jsonObject["signers"]!!.jsonArray.map { Hex.decode( it.jsonObject["expected"]!!.jsonObject["frost_share"]!!.jsonArray[index].jsonPrimitive.content ) } println("Indexs: $index") // println(assignedShares.map { Hex.encode(it) }) // println(vssCommitments.map { vssCommitment -> // vssCommitment.map { Hex.encode(it) } // }) // println( // Hex.encode(ids33[index]) // ) val result = Secp256k1.frostShareAggregate( assignedShares.toTypedArray(), vssCommitments.toTypedArray(), nParticipants, threshold, ids33[index] ) val expected = tests.jsonObject["expected"]!!.jsonArray[index]; val expectedAggregateShare = expected.jsonObject["aggregate_share"]!!.jsonPrimitive.content val expectedPublicKey = expected.jsonObject["aggregate_public_key"]!!.jsonPrimitive.content assertEquals( expected = expectedAggregateShare, actual = Hex.encode(result.first), "Unexpected $index:aggregate_share" ) assertEquals( expected = expectedPublicKey, actual = Hex.encode(result.second), "Unexpected $index:aggregate_public_key" ) // assertEquals( // expected = 1, // actual = Secp256k1.frostShareVerify( // threshold, // ids33[index], // assignedShares[index], // vssCommitments[index] // ), // message = "Couldn't verify share from $index signer" // ) } } @Test fun `frost share verify`() { } @Test fun `frost compute pubshare`() { } // Frost Tweak @Test fun `frost pubkey tweak`() { } @Test fun `frost pubkey ec tweak add`() { } @Test fun `frost pubkey xonly tweak add`() { } // Frost Sign functionality @Test fun `frost nonce gen`() { } @Test fun `frost nonce process`() { } @Test fun `frost partial sign `() { } @Test fun `frost partial signature verify`() { } @Test fun `frost partial signature aggregation`() { } }