Getting started with unit tests
This commit is contained in:
parent
32ee077995
commit
e7f074d36e
@ -1359,8 +1359,8 @@ JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp2
|
||||
{
|
||||
secp256k1_context *ctx = (secp256k1_context *)jctx;
|
||||
|
||||
secp256k1_frost_share *shares;
|
||||
secp256k1_pubkey* vss_commitment;
|
||||
secp256k1_frost_share **shares;
|
||||
secp256k1_pubkey **vss_commitment;
|
||||
jbyte* pok64;
|
||||
|
||||
size_t size;
|
||||
@ -1420,11 +1420,37 @@ JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp2
|
||||
|
||||
jobjectArray output = (*penv)->NewObjectArray(penv, 2, jobjectArray, NULL);
|
||||
|
||||
output[0] = (*penv)->NewObjectArray(penv, jn_participants, jbyteArray, NULL);
|
||||
jobjectArray jshares = (*penv)->NewObjectArray(penv, jn_participants, jbyteArray, NULL);
|
||||
// Copy shares into jshares
|
||||
unsigned char out32[32];
|
||||
for (i = 0; i < jn_participants; i++)
|
||||
{
|
||||
result = secp256k1_frost_share_serialize(ctx, out32, shares[i]);
|
||||
CHECKRESULT(!result, "secp256k1_frost_share_serialize failed");
|
||||
|
||||
output[1] = (*penv)->NewObjectArray(penv, jthreshold, jbyteArray, NULL);
|
||||
jbyteArray jshare = (*penv)->NewByteArray(penv, 32);
|
||||
copy_bytes_to_java(penv, jshare, 32, out32);
|
||||
|
||||
jshares[i] = jshare;
|
||||
}
|
||||
output[0] = jshares;
|
||||
|
||||
jobjectArray jvss_commitment = (*penv)->NewObjectArray(penv, jthreshold, jbyteArray, NULL);
|
||||
|
||||
// Copy vss_commitment into jvss_commitment
|
||||
for (i = 0; i < jn_participants; i++)
|
||||
{
|
||||
// need share object...
|
||||
result = secp256k1_xonly_pubkey_serialize(ctx, out32, vss_commitment[i]);
|
||||
CHECKRESULT(!result, "secp256k1_xonly_pubkey_serialize failed");
|
||||
|
||||
jbyteArray jpubkey = (*penv)->NewByteArray(penv, 32);
|
||||
copy_bytes_to_java(penv, jpubkey, 32, out32);
|
||||
|
||||
jvss_commitment[i] = jpubkey;
|
||||
}
|
||||
output[1] = jvss_commitment;
|
||||
|
||||
// TODO: Copy over the required data...
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@ -489,11 +489,11 @@ public object Secp256k1Native : Secp256k1 {
|
||||
totalSigners: Int,
|
||||
ids33: Array<ByteArray>
|
||||
): Triple<Array<ByteArray>, Array<ByteArray>, ByteArray> {
|
||||
require(seed32.size == 32)
|
||||
require(threshold > 0)
|
||||
require(threshold <= totalSigners)
|
||||
require(ids33.size == totalSigners)
|
||||
ids33.forEach { require(it.size == 33) }
|
||||
require(seed32.size == 32, { "seed size should be 32" })
|
||||
require(threshold > 1, { "threshold cannot be less then 1" })
|
||||
require(threshold <= totalSigners, { "threshold($threshold) cannot be greater then totalSigners ($totalSigners)" })
|
||||
require(ids33.size == totalSigners, { "ids33 size need to be the same as totalSigners size" })
|
||||
ids33.forEach { require(it.size == 33, { "id33 size must be 33" }) }
|
||||
|
||||
memScoped {
|
||||
val nShares = allocArray<secp256k1_frost_share>(ids33.size)
|
||||
@ -543,7 +543,7 @@ public object Secp256k1Native : Secp256k1 {
|
||||
require(publicKey.size == 33 || publicKey.size == 65)
|
||||
}
|
||||
}
|
||||
require(threshold > 0)
|
||||
require(threshold > 1)
|
||||
require(threshold <= totalShareCount)
|
||||
require(id33.size == 33)
|
||||
|
||||
@ -587,7 +587,7 @@ public object Secp256k1Native : Secp256k1 {
|
||||
share: ByteArray,
|
||||
vssCommitment: Array<ByteArray>
|
||||
): Int {
|
||||
require(threshold > 0)
|
||||
require(threshold > 1)
|
||||
require(id33.size == 33)
|
||||
require(share.size == Secp256k1.FROST_SHARE_SIZE)
|
||||
|
||||
@ -617,7 +617,7 @@ public object Secp256k1Native : Secp256k1 {
|
||||
vssCommitments: Array<Array<ByteArray>>,
|
||||
totalSignersCount: Int
|
||||
): ByteArray {
|
||||
require(threshold > 0)
|
||||
require(threshold > 1)
|
||||
require(threshold <= totalSignersCount)
|
||||
require(id33.size == 33)
|
||||
|
||||
|
24
tests/src/commonTest/kotlin/fr/acinq/secp256k1/BaseTest.kt
Normal file
24
tests/src/commonTest/kotlin/fr/acinq/secp256k1/BaseTest.kt
Normal file
@ -0,0 +1,24 @@
|
||||
package fr.acinq.secp256k1
|
||||
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import org.kodein.memory.file.FileSystem
|
||||
import org.kodein.memory.file.Path
|
||||
import org.kodein.memory.file.openReadableFile
|
||||
import org.kodein.memory.file.resolve
|
||||
import org.kodein.memory.system.Environment
|
||||
import org.kodein.memory.text.readString
|
||||
import org.kodein.memory.use
|
||||
|
||||
abstract class BaseTest {
|
||||
fun resourcesDir() =
|
||||
Environment.findVariable("TEST_RESOURCES_PATH")?.let { Path(it) }
|
||||
?: FileSystem.workingDir().resolve("src/commonTest/resources")
|
||||
|
||||
fun readData(filename: String): JsonElement {
|
||||
val file = resourcesDir().resolve(filename)
|
||||
val raw = file.openReadableFile().use { it.readString() }
|
||||
val format = Json { ignoreUnknownKeys = true }
|
||||
return format.parseToJsonElement(raw)
|
||||
}
|
||||
}
|
115
tests/src/commonTest/kotlin/fr/acinq/secp256k1/FrostTest.kt
Normal file
115
tests/src/commonTest/kotlin/fr/acinq/secp256k1/FrostTest.kt
Normal file
@ -0,0 +1,115 @@
|
||||
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_test_cases"]!!.jsonArray.forEach { validTestCases ->
|
||||
val keyIndices = validTestCases.jsonObject["key_indices"]!!.jsonArray.map { it.jsonPrimitive.int }
|
||||
|
||||
val seed32 = ByteArray(32)
|
||||
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"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `frost share aggregation`() {
|
||||
|
||||
}
|
||||
|
||||
@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`() {
|
||||
|
||||
}
|
||||
}
|
@ -10,17 +10,7 @@ import org.kodein.memory.text.readString
|
||||
import org.kodein.memory.use
|
||||
import kotlin.test.*
|
||||
|
||||
class Musig2Test {
|
||||
fun resourcesDir() =
|
||||
Environment.findVariable("TEST_RESOURCES_PATH")?.let { Path(it) }
|
||||
?: FileSystem.workingDir().resolve("src/commonTest/resources")
|
||||
|
||||
fun readData(filename: String): JsonElement {
|
||||
val file = resourcesDir().resolve(filename)
|
||||
val raw = file.openReadableFile().use { it.readString() }
|
||||
val format = Json { ignoreUnknownKeys = true }
|
||||
return format.parseToJsonElement(raw)
|
||||
}
|
||||
class Musig2Test: BaseTest() {
|
||||
|
||||
@Test
|
||||
fun `aggregate public keys`() {
|
||||
|
84
tests/src/commonTest/resources/frost/share_gen_vectors.json
Normal file
84
tests/src/commonTest/resources/frost/share_gen_vectors.json
Normal file
@ -0,0 +1,84 @@
|
||||
{
|
||||
"pubkeys": [
|
||||
"02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9",
|
||||
"03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659",
|
||||
"023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66",
|
||||
"04F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9",
|
||||
"03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9",
|
||||
"020000000000000000000000000000000000000000000000000000000000000005",
|
||||
"02FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30"
|
||||
],
|
||||
"valid_test_cases": [
|
||||
{
|
||||
"key_indices": [0, 1, 2, 3, 4],
|
||||
"threshold": 3,
|
||||
"expected": {
|
||||
"frost_share": [
|
||||
"0d9c85106ab6168b13e3b569695fb57bf91cbbe1e589a205b48bb7e15ff6908b",
|
||||
"807eb5b22ef56d6ae3601f2774a1985485386f6317e6bc075b2134818fd44c5b",
|
||||
"5e67fe075e91549bf28558a0d55e4b954bf5f9f229ddc0d6e9ab76a139367bbf",
|
||||
"d248680a6aa524a75c9f59c2732e77ac2d334b98ac2b09defc9030da218d17ca",
|
||||
"7bdf748e9fd56cd87e0430847e3212d0814528aeb83e1d83aeda279cbc20b481"
|
||||
],
|
||||
"vss_commitment": [
|
||||
"044c865c8c3f29a10a55bee4deca73b135d768eb7727a7ccc0fd47db82d7c9f4763d0ebe8feabf6b2119098f1f1f52ba165ae373d75a73c053f4bff6bd2ddb361f",
|
||||
"045500faa3f2c4279bb95e66bd4c0011da084806e260395c0ff02ae25bd80102f45a7b7fe4d90cc76e9b26a1f9a9febcd0c767aeee63ab463fcfe559ac3b3ad653",
|
||||
"0499c4d8f4ed163d07a112a74c0b03e1f6851b86b499b916d66824cec9694e5bd866e108b3f82413bdf96c6abde9995a165684432467b82be13dd73e67e4cf29f9"
|
||||
],
|
||||
"pok64": "e79e0d894639155ffebbe03e97030758e6060929a468010ce70627b1ce92b553597f1709f2d82a2ad884f868123344ec871eec4cbf1fa12c5794df6fe5d06e27"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key_indices": [4, 3, 2, 1, 0],
|
||||
"threshold": 3,
|
||||
"expected": {
|
||||
"frost_share": [
|
||||
"bdf8c4896736812a5548610bd39b66dc91b266e1bc68db4e760bcee797a695e3",
|
||||
"5afe66c979b666141b8bf46747293797e74580341527f5f6aa01277a468fd9f2",
|
||||
"9efe2e26dcf8e6f4224fea1fec9a9167ec29cb3b727f841ef76e23d592d2512f",
|
||||
"dd4fd050344dc625737d018c69298ed312bd7043d3343583625703ed45726ac6",
|
||||
"eb486a1c2e3ff755473fc41b01138b6a0d3f99f3b99b420e57271689d40eb7e4"
|
||||
],
|
||||
"vss_commitment": [
|
||||
"0496291d2a1ec0f0e38d622db473004c18bd6713be47642cfdd7ad9c458a12506da5eb9d0b0a99aab0c97f5ac6d94f2becd8075eef8675d06e4b6cf9e58ed4c30b",
|
||||
"0473b3681ac295de098568695b02820d57cab4c09f953518bfe1d133b54d794564da8a4c508942789b32fd483719bd847ab0a6f87e0ef7bb7d40376e1c109c0bda",
|
||||
"044cd2e10e73b39450f2ce02609985ea1f2d84891a0485fbf42ddf9164c0dd5222306a396efb13eff789837b894ca6bf3681d1f937b94e209a8e8333e1e5a7d6c1"
|
||||
],
|
||||
"pok64": "5f4e653cd392b04042629b78bc5982c552a4027816321355e519912e1e46514b6425bd31ae684a1ce1941a98cfb0d2b9ad108a39e230b4303e0e0237d7136998"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key_indices": [0, 0, 0],
|
||||
"threshold": 2,
|
||||
"expected": {
|
||||
"frost_share": [
|
||||
"2bc9a1e8064cc39759023561f07507ad72db7e7fa20b7a01ec467d40bed167ff",
|
||||
"2bc9a1e8064cc39759023561f07507ad72db7e7fa20b7a01ec467d40bed167ff",
|
||||
"2bc9a1e8064cc39759023561f07507ad72db7e7fa20b7a01ec467d40bed167ff"
|
||||
],
|
||||
"vss_commitment": [
|
||||
"041857d4fce91165cba35a6a074ce182883c92eaf0e8c97d985bb73db2befcee02dbcd9ba5bb8e01878d9900738833bc5111c20996b9f5f14da50011a0a4e0767f",
|
||||
"04702b5ed0a3f937ca894a976f7927f537e37e19eafcf7ed970087b860bfa80f7c64a060e1835fdfe8780abf7d0dbb11b4334471aa133f1fa159c0151faf16edee"
|
||||
],
|
||||
"pok64": "2081623ec3b670010d6a8ce55073cf0ef9906798b18db58b1385211d6a7b206e2408e5fc9c399fd1a448686cd29aa71e6053229bf42c5710a5f10af0af1140b0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key_indices": [0, 0, 1, 1],
|
||||
"threshold": 2,
|
||||
"expected": {
|
||||
"frost_share": [
|
||||
"70656f19f741cb3e1a46d033321c1627e4464f08316f0d2faad738903b2b2df9",
|
||||
"70656f19f741cb3e1a46d033321c1627e4464f08316f0d2faad738903b2b2df9",
|
||||
"624956ad9497abe08d08e4e367519b0c263d79d14754c4a6fb7b2b67796c3636",
|
||||
"624956ad9497abe08d08e4e367519b0c263d79d14754c4a6fb7b2b67796c3636"
|
||||
],
|
||||
"vss_commitment": [
|
||||
"04267d0994c34e87b281506e325a64b83935acb172e5d51a451b5e5f21f51490489dd865654935008aa6afb48955259ace1f8a7eeeafb95c2b0d78dec8e5f25361",
|
||||
"04c616024ec0c9317bd7574b4fb55a9202d2e6d53465bfb37d1f9edcffc775df537c7c521eac64316f1339943c219df37fa597a49d6be6a2487d776b8305c3880c"
|
||||
],
|
||||
"pok64": "ea25763debd2b96d9e24a3cf3d87f792bce88a27787c0b84bc0b2fc5a1fec841afc6606bc970e477694b1f3c6ad25370c06a7b9705d52c3acfec13b036a94df8"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user