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_context *ctx = (secp256k1_context *)jctx;
|
||||||
|
|
||||||
secp256k1_frost_share *shares;
|
secp256k1_frost_share **shares;
|
||||||
secp256k1_pubkey* vss_commitment;
|
secp256k1_pubkey **vss_commitment;
|
||||||
jbyte* pok64;
|
jbyte* pok64;
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
@ -1420,11 +1420,37 @@ JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp2
|
|||||||
|
|
||||||
jobjectArray output = (*penv)->NewObjectArray(penv, 2, jobjectArray, NULL);
|
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;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,11 +489,11 @@ public object Secp256k1Native : Secp256k1 {
|
|||||||
totalSigners: Int,
|
totalSigners: Int,
|
||||||
ids33: Array<ByteArray>
|
ids33: Array<ByteArray>
|
||||||
): Triple<Array<ByteArray>, Array<ByteArray>, ByteArray> {
|
): Triple<Array<ByteArray>, Array<ByteArray>, ByteArray> {
|
||||||
require(seed32.size == 32)
|
require(seed32.size == 32, { "seed size should be 32" })
|
||||||
require(threshold > 0)
|
require(threshold > 1, { "threshold cannot be less then 1" })
|
||||||
require(threshold <= totalSigners)
|
require(threshold <= totalSigners, { "threshold($threshold) cannot be greater then totalSigners ($totalSigners)" })
|
||||||
require(ids33.size == totalSigners)
|
require(ids33.size == totalSigners, { "ids33 size need to be the same as totalSigners size" })
|
||||||
ids33.forEach { require(it.size == 33) }
|
ids33.forEach { require(it.size == 33, { "id33 size must be 33" }) }
|
||||||
|
|
||||||
memScoped {
|
memScoped {
|
||||||
val nShares = allocArray<secp256k1_frost_share>(ids33.size)
|
val nShares = allocArray<secp256k1_frost_share>(ids33.size)
|
||||||
@ -543,7 +543,7 @@ public object Secp256k1Native : Secp256k1 {
|
|||||||
require(publicKey.size == 33 || publicKey.size == 65)
|
require(publicKey.size == 33 || publicKey.size == 65)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require(threshold > 0)
|
require(threshold > 1)
|
||||||
require(threshold <= totalShareCount)
|
require(threshold <= totalShareCount)
|
||||||
require(id33.size == 33)
|
require(id33.size == 33)
|
||||||
|
|
||||||
@ -587,7 +587,7 @@ public object Secp256k1Native : Secp256k1 {
|
|||||||
share: ByteArray,
|
share: ByteArray,
|
||||||
vssCommitment: Array<ByteArray>
|
vssCommitment: Array<ByteArray>
|
||||||
): Int {
|
): Int {
|
||||||
require(threshold > 0)
|
require(threshold > 1)
|
||||||
require(id33.size == 33)
|
require(id33.size == 33)
|
||||||
require(share.size == Secp256k1.FROST_SHARE_SIZE)
|
require(share.size == Secp256k1.FROST_SHARE_SIZE)
|
||||||
|
|
||||||
@ -617,7 +617,7 @@ public object Secp256k1Native : Secp256k1 {
|
|||||||
vssCommitments: Array<Array<ByteArray>>,
|
vssCommitments: Array<Array<ByteArray>>,
|
||||||
totalSignersCount: Int
|
totalSignersCount: Int
|
||||||
): ByteArray {
|
): ByteArray {
|
||||||
require(threshold > 0)
|
require(threshold > 1)
|
||||||
require(threshold <= totalSignersCount)
|
require(threshold <= totalSignersCount)
|
||||||
require(id33.size == 33)
|
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 org.kodein.memory.use
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
class Musig2Test {
|
class Musig2Test: 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `aggregate public keys`() {
|
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