Full tests on native

This commit is contained in:
kngako 2024-08-21 17:28:07 +02:00
parent c39590a859
commit 5117507f25
4 changed files with 151 additions and 65 deletions

View File

@ -329,12 +329,12 @@ public interface Secp256k1 {
public const val FROST_PARTIAL_SIGNATURE_SIZE: Int = 36 public const val FROST_PARTIAL_SIGNATURE_SIZE: Int = 36
public const val FROST_SHARE_SIZE: Int = 32 public const val FROST_SHARE_SIZE: Int = 36
public const val FROST_TWEAK_CACHE_SIZE: Int = 102 public const val FROST_TWEAK_CACHE_SIZE: Int = 101
public const val FROST_SESSION_SIZE: Int = 134 public const val FROST_SESSION_SIZE: Int = 133
public const val FROST_SECNONCE_SIZE: Int = 69 public const val FROST_SECNONCE_SIZE: Int = 68
public const val FROST_PUBNONCE_SIZE: Int = 133 public const val FROST_PUBNONCE_SIZE: Int = 132
public const val FROST_SERIALIZED_PARTIAL_SIGNATURE_SIZE: Int = 33 public const val FROST_SERIALIZED_PARTIAL_SIGNATURE_SIZE: Int = 32
public const val FROST_SERIALIZED_SHARE_SIZE: Int = 32 public const val FROST_SERIALIZED_SHARE_SIZE: Int = 32
public const val FROST_SERIALIZED_PUBNONCE_SIZE: Int = 66 public const val FROST_SERIALIZED_PUBNONCE_SIZE: Int = 66
// @formatter:on // @formatter:on

View File

@ -522,7 +522,7 @@ public object Secp256k1Native : Secp256k1 {
} }
private fun MemScope.serializeFrostShare(nFrostShare: secp256k1_frost_share): ByteArray { private fun MemScope.serializeFrostShare(nFrostShare: secp256k1_frost_share): ByteArray {
val natOutput = allocArray<UByteVar>(Secp256k1.FROST_SHARE_SIZE) val natOutput = allocArray<UByteVar>(Secp256k1.FROST_SERIALIZED_SHARE_SIZE)
secp256k1_frost_share_serialize(ctx, natOutput, nFrostShare.ptr).requireSuccess("secp256k1_frost_share_serialize() failed") secp256k1_frost_share_serialize(ctx, natOutput, nFrostShare.ptr).requireSuccess("secp256k1_frost_share_serialize() failed")
return natOutput.readBytes(Secp256k1.FROST_SERIALIZED_SHARE_SIZE) return natOutput.readBytes(Secp256k1.FROST_SERIALIZED_SHARE_SIZE)
} }
@ -589,10 +589,10 @@ public object Secp256k1Native : Secp256k1 {
vssCommitment: Array<ByteArray> vssCommitment: Array<ByteArray>
): Int { ): Int {
require(threshold > 1) { "threshold should be greater then 1" } require(threshold > 1) { "threshold should be greater then 1" }
require(id33.size == 33) { "id size should be 33" } require(id33.size == 33) { "id size (${id33.size}) should be 33" }
require(share.size == Secp256k1.FROST_SHARE_SIZE) { "all shares should be of size 32" } require(share.size == Secp256k1.FROST_SERIALIZED_SHARE_SIZE) { "share size (${share.size}) should be of size ${Secp256k1.FROST_SERIALIZED_SHARE_SIZE}" }
require(vssCommitment.size == threshold) { "all vss commitment array size (${vssCommitment.size}) should be the same as the threshold size ($threshold)" } require(vssCommitment.size == threshold) { "vss commitment array size (${vssCommitment.size}) should be the same as the threshold size ($threshold)" }
vssCommitment.forEach { publicKey -> vssCommitment.forEach { publicKey ->
require(publicKey.size == 33 || publicKey.size == 65) { "vss commitment data size should be 33 or 65" } require(publicKey.size == 33 || publicKey.size == 65) { "vss commitment data size should be 33 or 65" }
} }
@ -656,7 +656,7 @@ public object Secp256k1Native : Secp256k1 {
} }
override fun frostPublicKeyTweak(xOnlyPublicKey: ByteArray): ByteArray { override fun frostPublicKeyTweak(xOnlyPublicKey: ByteArray): ByteArray {
require(xOnlyPublicKey.size == Secp256k1.X_ONLY_PUBKEY_SIZE) require(xOnlyPublicKey.size == Secp256k1.SERIALIZED_X_ONLY_PUBKEY_SIZE) { "pubkey size (${xOnlyPublicKey.size}) should be ${Secp256k1.SERIALIZED_X_ONLY_PUBKEY_SIZE}" }
memScoped { memScoped {
val nTweakCache = alloc<secp256k1_frost_tweak_cache>() val nTweakCache = alloc<secp256k1_frost_tweak_cache>()
@ -738,18 +738,18 @@ public object Secp256k1Native : Secp256k1 {
publicKey: ByteArray?, publicKey: ByteArray?,
extraInput32: ByteArray? extraInput32: ByteArray?
): Pair<ByteArray, ByteArray> { ): Pair<ByteArray, ByteArray> {
require(sessionId32.size == 32) require(sessionId32.size == 32) { "session id (${sessionId32.size}) size should be 32" }
share?.let { share?.let {
require(share.size == Secp256k1.FROST_SHARE_SIZE) require(share.size == Secp256k1.FROST_SERIALIZED_SHARE_SIZE) { "share size (${share.size}) should be ${Secp256k1.FROST_SERIALIZED_SHARE_SIZE}" }
} }
msg32?.let { msg32?.let {
require(msg32.size == 33) require(msg32.size == 32) { "msg32 (${sessionId32.size}) size should be 32" }
} }
publicKey?.let { publicKey?.let {
require(publicKey.size == 33 || publicKey.size == 65) require(publicKey.size == 32) { "public key (${publicKey.size}) should be 32" }
} }
extraInput32?.let { extraInput32?.let {
require(it.size == 33) require(it.size == 32) { "extraInput32 (${extraInput32.size}) size should be 32" }
} }
memScoped { memScoped {
@ -796,18 +796,18 @@ public object Secp256k1Native : Secp256k1 {
adaptor: ByteArray? adaptor: ByteArray?
): ByteArray { ): ByteArray {
publicNonces.forEach { publicNonce -> publicNonces.forEach { publicNonce ->
require(publicNonce.size == Secp256k1.FROST_PUBNONCE_SIZE) require(publicNonce.size == Secp256k1.FROST_SERIALIZED_PUBNONCE_SIZE) { "pubnonce size (${publicNonce.size}) size should be ${Secp256k1.FROST_SERIALIZED_PUBNONCE_SIZE}" }
} }
require(msg32.size == 32) require(msg32.size == 32) { "msg32 (${msg32.size}) size should be 32" }
require(publicKey.size == 33 || publicKey.size == 65) require(publicKey.size == Secp256k1.SERIALIZED_X_ONLY_PUBKEY_SIZE) { "publicKey size (${publicKey.size}) size should be ${Secp256k1.SERIALIZED_X_ONLY_PUBKEY_SIZE}" }
ids33.forEach { ids33.forEach {
require(it.size == 33) require(it.size == 33) { "id33 (${it.size}) size should be 33" }
} }
tweakCache?.let { tweakCache?.let {
require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) { "tweak cache size (${tweakCache.size}) size should be ${Secp256k1.FROST_TWEAK_CACHE_SIZE}" }
} }
adaptor?.let { adaptor?.let {
require(it.size == 33 || it.size == 65) require(it.size == 33 || it.size == 65) { "adaptor public key size (${it.size}) should be 33 or 65" }
} }
memScoped { memScoped {
@ -861,11 +861,11 @@ public object Secp256k1Native : Secp256k1 {
session: ByteArray, session: ByteArray,
tweakCache: ByteArray? tweakCache: ByteArray?
): ByteArray { ): ByteArray {
require(secnonce.size == Secp256k1.FROST_SECNONCE_SIZE) require(secnonce.size == Secp256k1.FROST_SECNONCE_SIZE) { "secnonce size (${secnonce.size}) should be of size ${Secp256k1.FROST_SECNONCE_SIZE}" }
require(share.size == Secp256k1.FROST_SHARE_SIZE) require(share.size == Secp256k1.FROST_SERIALIZED_SHARE_SIZE) { "share size (${share.size}) should be of size ${Secp256k1.FROST_SERIALIZED_SHARE_SIZE}" }
require(session.size == Secp256k1.FROST_SESSION_SIZE) require(session.size == Secp256k1.FROST_SESSION_SIZE) { "session size (${share.size}) should be of size ${Secp256k1.FROST_SESSION_SIZE}" }
tweakCache?.let { tweakCache?.let {
require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) { "tweak cache size (${tweakCache.size}) size should be ${Secp256k1.FROST_TWEAK_CACHE_SIZE}" }
} }
@ -907,12 +907,12 @@ public object Secp256k1Native : Secp256k1 {
session: ByteArray, session: ByteArray,
tweakCache: ByteArray? tweakCache: ByteArray?
): Int { ): Int {
require(partialSig.size == 32) require(partialSig.size == 32) { "partialSig (${partialSig.size}) size should be 32" }
require(publicNonce.size == Secp256k1.MUSIG2_PUBLIC_NONCE_SIZE) require(publicNonce.size == Secp256k1.FROST_SERIALIZED_PUBNONCE_SIZE) { "public nonce (${publicNonce.size}) size should be ${Secp256k1.FROST_SERIALIZED_PUBNONCE_SIZE}" }
require(publicShare.size == 33 || publicShare.size == 65) require(publicShare.size == 33 || publicShare.size == 65) { "public share size (${partialSig.size}) should be 33 or 65" }
require(session.size == Secp256k1.FROST_SESSION_SIZE) require(session.size == Secp256k1.FROST_SESSION_SIZE) { "session size (${session.size}) size should be ${Secp256k1.FROST_SESSION_SIZE}" }
tweakCache?.let { tweakCache?.let {
require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) { "tweak cache size (${tweakCache.size}) size should be ${Secp256k1.FROST_TWEAK_CACHE_SIZE}" }
} }

View File

@ -21,8 +21,6 @@ class FrostTest: BaseTest() {
val threshold = validTestCases.jsonObject["threshold"]!!.jsonPrimitive.int val threshold = validTestCases.jsonObject["threshold"]!!.jsonPrimitive.int
val ids33 = keyIndices.map { pubkeys[it] }.toTypedArray() val ids33 = keyIndices.map { pubkeys[it] }.toTypedArray()
println("Testing $keyIndices")
val result = Secp256k1.frostSharesGen( val result = Secp256k1.frostSharesGen(
seed32, seed32,
threshold, threshold,
@ -38,24 +36,18 @@ class FrostTest: BaseTest() {
result.first.forEachIndexed { index, share -> result.first.forEachIndexed { index, share ->
println( assertEquals(
Hex.encode(share) expected = Hex.encode(expectedShare[index]),
actual = Hex.encode(share),
"Unexpected $index:share for $keyIndices test case"
) )
// assertEquals(
// expected = Hex.encode(expectedShare[index]),
// actual = Hex.encode(share),
// "Unexpected $index:share for $keyIndices test case"
// )
} }
result.second.forEachIndexed { index, vssCommitment -> result.second.forEachIndexed { index, vssCommitment ->
println( assertEquals(
Hex.encode(vssCommitment) expected = Hex.encode(expectedVSSCommitment[index]),
actual = Hex.encode(vssCommitment),
"Unexpected $index:vss_commitment for the $keyIndices test case"
) )
// assertEquals(
// expected = Hex.encode(expectedVSSCommitment[index]),
// actual = Hex.encode(vssCommitment),
// "Unexpected $index:vss_commitment for the $keyIndices test case"
// )
} }
assertEquals( assertEquals(
expected = Hex.encode(expectedPoK64), expected = Hex.encode(expectedPoK64),
@ -458,28 +450,115 @@ class FrostTest: BaseTest() {
null null
) )
// assertEquals( assertEquals(
// expected = signer.jsonObject["session"]!!.jsonPrimitive.content, expected = signer.jsonObject["session"]!!.jsonPrimitive.content,
// actual = Hex.encode(session), actual = Hex.encode(session),
// message = "Invalid $signerIndex:session" message = "Invalid $signerIndex:session"
// ) )
} }
} }
@Test @Test
fun `frost partial sign`() { fun `frost partial sign`() {
val tests = readData("frost/frost_nonce_vectors.json")
val tweakCache = Hex.decode(
tests.jsonObject["tweak_cache"]!!.jsonPrimitive.content
)
tests.jsonObject["signers"]!!.jsonArray.forEachIndexed { signerIndex, signer ->
val secNonce = Hex.decode(
signer.jsonObject["secnonce"]!!.jsonPrimitive.content
)
val aggregateShare = Hex.decode(
signer.jsonObject["aggregate_share"]!!.jsonPrimitive.content
)
val session = Hex.decode(
signer.jsonObject["session"]!!.jsonPrimitive.content
)
val partialSignature = Secp256k1.frostPartialSign(
secNonce,
aggregateShare,
session,
tweakCache
)
assertEquals(
expected = signer.jsonObject["partial_signature"]!!.jsonPrimitive.content,
actual = Hex.encode(partialSignature),
message = "Invalid $signerIndex:partial signature"
)
}
} }
@Test @Test
fun `frost partial signature verify`() { fun `frost partial signature verify`() {
val tests = readData("frost/frost_nonce_vectors.json")
val tweakCache = Hex.decode(
tests.jsonObject["tweak_cache"]!!.jsonPrimitive.content
)
tests.jsonObject["signers"]!!.jsonArray.forEach { signer ->
val partialSignature = Hex.decode(
signer.jsonObject["partial_signature"]!!.jsonPrimitive.content
)
val pubNonce = Hex.decode(
signer.jsonObject["pubnonce"]!!.jsonPrimitive.content
)
val publicShare = Hex.decode(
signer.jsonObject["public_share"]!!.jsonPrimitive.content
)
val session = Hex.decode(
signer.jsonObject["session"]!!.jsonPrimitive.content
)
assertEquals(
expected = 1,
actual = Secp256k1.frostPartialSignatureVerify(
partialSignature,
pubNonce,
publicShare,
session,
tweakCache
),
message = "Failed to verify partial signature"
)
}
} }
@Test @Test
fun `frost partial signature aggregation`() { fun `frost partial signature aggregation`() {
val tests = readData("frost/frost_nonce_vectors.json")
val partialSignatures = tests.jsonObject["signers"]!!.jsonArray.map {
Hex.decode(it.jsonObject["partial_signature"]!!.jsonPrimitive.content)
}
tests.jsonObject["signers"]!!.jsonArray.forEach { signer ->
val session = Hex.decode(
signer.jsonObject["session"]!!.jsonPrimitive.content
)
val aggregatedSignature = Secp256k1.frostPartialSignatureAggregate(
session,
partialSignatures.toTypedArray(),
)
assertEquals(
expected = tests.jsonObject["aggregate_signature"]!!.jsonPrimitive.content,
actual = Hex.encode(aggregatedSignature),
message = "Invalid aggregate partial signature"
)
}
} }
} }

View File

@ -6,41 +6,48 @@
"03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659", "03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659",
"04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9" "04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9"
], ],
"threshold": 3,
"aggregate_public_key": "bd5561ef6dbff52d3f73b8cb0c065328988b71d3386d23890744a0dd6ad27c15", "aggregate_public_key": "bd5561ef6dbff52d3f73b8cb0c065328988b71d3386d23890744a0dd6ad27c15",
"aggregate_signature": "1c34b007ec896279304e7fbd80730991bd547b50b212fcdd983340c5392bfa6ede56bbf6dd50926cae1723119225572ac555dce37f9b0033a255ef233b5ac539",
"session_id": "7FB9E0E687ADA1EEBF7ECFE2F21E73EBDB51A7D450948DFE8D76D7F2D1007671", "session_id": "7FB9E0E687ADA1EEBF7ECFE2F21E73EBDB51A7D450948DFE8D76D7F2D1007671",
"tweak_cache": "40252e41157cd26adda0440789236d38d3718b982853060ccbb8733f2df5bf6def6155bdeefcc6b83fe690d621b793b08f5b1562a7bef628c4db33f2d0b3f3bf2f541aaa000000000000000000000000000000000000000000000000000000000000000000", "tweak_cache": "40252e41157cd26adda0440789236d38d3718b982853060ccbb8733f2df5bf6def6155bdeefcc6b83fe690d621b793b08f5b1562a7bef628c4db33f2d0b3f3bf2f541aaa000000000000000000000000000000000000000000000000000000000000000000",
"signers": [ "signers": [
{ {
"session": "5c11a803006f7c9545e2bb3482d468ca0eb3e13070730f9cb3d42402cfa29bb54876d208af362b2645f6cbd0b4b7de7d6e98b48c7dda48bc74d93fdca4b40077f278f868c2a92d82c8961b2f3663c44ea5928338e3cdf1e468a6a84bdd5a9c96158e0176dd0000000000000000000000000000000000000000000000000000000000000000", "partial_signature": "12a1bb40ef57c0be9c00641ad59c406a2b8b2624227c48f43291516fc906d935",
"secnonce": "847d4625fe87e00f9562351a9b7de8fc2420caba09535db177fc4fbac5b69b84c8700ae143946a0fffff4083d6377ee19a6448a55241160fbc7c793aace02f289a2fec8f03", "session": "5c11a803011c34b007ec896279304e7fbd80730991bd547b50b212fcdd983340c5392bfa6ee8d4b3288f9364e296c1516a09aa3e34605421a6536e2eaf2a341343b9a76443b59b5c7df0aebbb9fab718c312d862c85d4b25aeb20de84d3ef1a1aad667c3360000000000000000000000000000000000000000000000000000000000000000",
"secnonce": "847d4625fe87e00f9562351a9b7de8fc2420caba09535db177fc4fbac5b69b84c8700ae143946a0fffff4083d6377ee19a6448a55241160fbc7c793aace02f289a2fec8f",
"pubnonce": "03203a0450540686854df68f6c1d15661772e4d05c4442ee1e437d86842779ef2202d03839fd99faf7a11ccc319a9adc965c5e094ca3728455059a4911ae96192fae", "pubnonce": "03203a0450540686854df68f6c1d15661772e4d05c4442ee1e437d86842779ef2202d03839fd99faf7a11ccc319a9adc965c5e094ca3728455059a4911ae96192fae",
"aggregate_share": "1cfa28492e84e945343f1167401cdce061202a59e47e050c0c2f7f0c56e8e148", "aggregate_share": "1cfa28492e84e945343f1167401cdce061202a59e47e050c0c2f7f0c56e8e148",
"public_share": "0493effba7e50d3885bb0c4665149abd4fd13622047412f1da4c0e3754ecb1a9183aaadfdf0f2f82e24641e6ed7a0f7ee22a4a8a47c6d2df66daad37a4880fffe2" "public_share": "0493effba7e50d3885bb0c4665149abd4fd13622047412f1da4c0e3754ecb1a9183aaadfdf0f2f82e24641e6ed7a0f7ee22a4a8a47c6d2df66daad37a4880fffe2"
}, },
{ {
"session": "5c11a803001476eca00d1754deddff97f25479a0d9dbddaf6b1895d0b181d3fa0ebefd012c1192ed7ff2480492cbc95bea67211ec7148560882817b0fd655963dc65ae53dd69f0286afb3238617e485141eba41585ab5b92f708905f09cdfed710b070a70c0000000000000000000000000000000000000000000000000000000000000000", "partial_signature": "d504eaf51c4985f1f1c6d1fcaef0b4d934752e1e4bfd76cd86c6baed0d915e21",
"secnonce": "847d4625e6af707cb69026251afdfc2570a3fbdbbc7e72530354f0777fe2192c6aa8b23969172508dff48f7a21827935cce2ed019c570bb5552f9a3269a8ec34cfd23e2c03", "session": "5c11a803011c34b007ec896279304e7fbd80730991bd547b50b212fcdd983340c5392bfa6ee8d4b3288f9364e296c1516a09aa3e34605421a6536e2eaf2a341343b9a7644376dba5ba367ff93f06b8230cbbab6b608a175463168ea0a9ee175b7909f438b80000000000000000000000000000000000000000000000000000000000000000",
"secnonce": "847d4625e6af707cb69026251afdfc2570a3fbdbbc7e72530354f0777fe2192c6aa8b23969172508dff48f7a21827935cce2ed019c570bb5552f9a3269a8ec34cfd23e2c",
"pubnonce": "035c8f36d2cf868b9ccab3221b3f5eca64d60469a50245d6edc3b4f4bfb4358892023e832dcc0b5b55562ef6f1536679a2e996827747d3b824ca335daf00d51ab788", "pubnonce": "035c8f36d2cf868b9ccab3221b3f5eca64d60469a50245d6edc3b4f4bfb4358892023e832dcc0b5b55562ef6f1536679a2e996827747d3b824ca335daf00d51ab788",
"aggregate_share": "dd82fcc1806f1a968228c794a7001c18d209871fb3441bae80fd8229f6a9b0dd", "aggregate_share": "dd82fcc1806f1a968228c794a7001c18d209871fb3441bae80fd8229f6a9b0dd",
"public_share": "048482e27b533879d4f3d68bdb2038bf9480d4ce4cc614d7133238e55179c65a175c684afb7f983e60139542b80f0f12815f3194082f07c93e1f87f3cd1b1c0d8b" "public_share": "048482e27b533879d4f3d68bdb2038bf9480d4ce4cc614d7133238e55179c65a175c684afb7f983e60139542b80f0f12815f3194082f07c93e1f87f3cd1b1c0d8b"
}, },
{ {
"session": "5c11a803001476eca00d1754deddff97f25479a0d9dbddaf6b1895d0b181d3fa0ebefd012c1192ed7ff2480492cbc95bea67211ec7148560882817b0fd655963dc65ae53dd4e14c7a8b2b8aef94b7a5938d1ad2906e707302cca6bc3be90dba25565803ea40000000000000000000000000000000000000000000000000000000000000000", "partial_signature": "0e82e07de474c83387118c9b353b7ebbeeabd0279645d6ae499546df3b301d59",
"secnonce": "847d4625bd32503f81d016175829db4df8475660c77e28cf6dc7bc8b2f6e3fe6f67282b1cf81dcf2dabd867053461cf602f3e3345f42119066f4c493b85a0744ae7beb0802", "session": "5c11a803011c34b007ec896279304e7fbd80730991bd547b50b212fcdd983340c5392bfa6ee8d4b3288f9364e296c1516a09aa3e34605421a6536e2eaf2a341343b9a764436bc4ab3b7a585b2a759366523cb83fb2ff8b166e2503abd0f24ec58868bde3440000000000000000000000000000000000000000000000000000000000000000",
"secnonce": "847d4625bd32503f81d016175829db4df8475660c77e28cf6dc7bc8b2f6e3fe6f67282b1cf81dcf2dabd867053461cf602f3e3345f42119066f4c493b85a0744ae7beb08",
"pubnonce": "028b80bb46028338d41101deacd7910e09ba148f75d2c01e9f8f767fa9cdcbbc7e02b0cec1ba331750a22bf3bb8d1b724bd2874f7f0c19c70227f64c463c8c6bcab2", "pubnonce": "028b80bb46028338d41101deacd7910e09ba148f75d2c01e9f8f767fa9cdcbbc7e02b0cec1ba331750a22bf3bb8d1b724bd2874f7f0c19c70227f64c463c8c6bcab2",
"aggregate_share": "5fe629d5f34fdb3ea2f6e545fc3d2cf1f5ce23a504b144e6ebe928793cc85cb4", "aggregate_share": "5fe629d5f34fdb3ea2f6e545fc3d2cf1f5ce23a504b144e6ebe928793cc85cb4",
"public_share": "04d71784b58d8958141f8f405d56026f214a736e73f9c1f70776fc2e49f4e90fc0a9396bcc7471a83caf4076a18cb6ab4264aa37174ca19e142259aa5f6bb7fea3" "public_share": "04d71784b58d8958141f8f405d56026f214a736e73f9c1f70776fc2e49f4e90fc0a9396bcc7471a83caf4076a18cb6ab4264aa37174ca19e142259aa5f6bb7fea3"
}, },
{ {
"session": "5c11a803001476eca00d1754deddff97f25479a0d9dbddaf6b1895d0b181d3fa0ebefd012c1192ed7ff2480492cbc95bea67211ec7148560882817b0fd655963dc65ae53ddb68d444ba93f7adad7758d1efaa6895dce34947f18789783b43fcff9ca50c28d0000000000000000000000000000000000000000000000000000000000000000", "partial_signature": "c7158af40413f8174d38a36ae83737f633f183c45e83ec9caa88afe9e0ed9a4a",
"secnonce": "847d4625f2128d893c4b8b62818bbc972d158b0aa96b08dcacba149dd7517b7fc7ddb89b70234941338c242dbca6e27ebf337ae458381ef83bea4ba2baab8df3d7f6b77303", "session": "5c11a803011c34b007ec896279304e7fbd80730991bd547b50b212fcdd983340c5392bfa6ee8d4b3288f9364e296c1516a09aa3e34605421a6536e2eaf2a341343b9a7644347dededd1bcf6c4294a994e867475e5c52ef861b240fe8ff717fe73f6bf0426b0000000000000000000000000000000000000000000000000000000000000000",
"secnonce": "847d4625f2128d893c4b8b62818bbc972d158b0aa96b08dcacba149dd7517b7fc7ddb89b70234941338c242dbca6e27ebf337ae458381ef83bea4ba2baab8df3d7f6b773",
"pubnonce": "030b4d942e88b7674819f3020c290db1162beda60bae05964bb344378166ec61a20221e3e76bfa50c22b98832d451d51e3b7cdef420a2b06e9a29373449aa77aa46c", "pubnonce": "030b4d942e88b7674819f3020c290db1162beda60bae05964bb344378166ec61a20221e3e76bfa50c22b98832d451d51e3b7cdef420a2b06e9a29373449aa77aa46c",
"aggregate_share": "71181e5b46742333f12672d85d0e1472770a082f0a62d3d204c9e191fb45ef91", "aggregate_share": "71181e5b46742333f12672d85d0e1472770a082f0a62d3d204c9e191fb45ef91",
"public_share": "04ec0fb2b4c1ac2d9b761f32cb2972e6d6fb74ed4195d872aeaaf4306bb64eb465580d03102849363ec49c3d1eecdd239337d0a66cdfc4d74c29c824c0f941832a" "public_share": "04ec0fb2b4c1ac2d9b761f32cb2972e6d6fb74ed4195d872aeaaf4306bb64eb465580d03102849363ec49c3d1eecdd239337d0a66cdfc4d74c29c824c0f941832a"
}, },
{ {
"session": "5c11a803001476eca00d1754deddff97f25479a0d9dbddaf6b1895d0b181d3fa0ebefd012c1192ed7ff2480492cbc95bea67211ec7148560882817b0fd655963dc65ae53ddb5fe593c0f5ae3e7da52ff37cbe1e150a3ff4dca3e57a781979b2a79ba7056660000000000000000000000000000000000000000000000000000000000000000", "partial_signature": "2117aa4ee9268b714c05bcf3f025ab33fd67119bcba01d62b4b24a8a18db1781",
"secnonce": "847d4625ee1f0f41a485d2399b024b05d9a9b7cbb846cf107dcbfa125a136448cbd20441a5bbea0b8908781249bbd7a5f6c429e1678338d8a2f5a9095a85fd541cb4988403", "session": "5c11a803011c34b007ec896279304e7fbd80730991bd547b50b212fcdd983340c5392bfa6ee8d4b3288f9364e296c1516a09aa3e34605421a6536e2eaf2a341343b9a76443dad0efbc20454b2dc409cb6c7cfec24e3d45d3d417de97e47df531e11ef188450000000000000000000000000000000000000000000000000000000000000000",
"secnonce": "847d4625ee1f0f41a485d2399b024b05d9a9b7cbb846cf107dcbfa125a136448cbd20441a5bbea0b8908781249bbd7a5f6c429e1678338d8a2f5a9095a85fd541cb49884",
"pubnonce": "034a67a3dbe320486110fac55f4e7ef4f5c5216766b8e4d635c6f1119a5c5e75a3026ada48e6491d2c9890f65fd3f9d675f644df9224b5beb5fc41b2934bc28d9bcc", "pubnonce": "034a67a3dbe320486110fac55f4e7ef4f5c5216766b8e4d635c6f1119a5c5e75a3026ada48e6491d2c9890f65fd3f9d675f644df9224b5beb5fc41b2934bc28d9bcc",
"aggregate_share": "15bc5e3eeb4ec318a718b3015b78e8496cc5ede81c05727936ade625532dce55", "aggregate_share": "15bc5e3eeb4ec318a718b3015b78e8496cc5ede81c05727936ade625532dce55",
"public_share": "04b3ad3909e919f1a27faff7a3aec8f04a9ca54a065d9774ae37c3b9903ad4a19b71f11e148b549ef168465d065279f773175b254f64573e7ce30f4aba0954be19" "public_share": "04b3ad3909e919f1a27faff7a3aec8f04a9ca54a065d9774ae37c3b9903ad4a19b71f11e148b549ef168465d065279f773175b254f64573e7ce30f4aba0954be19"