diff --git a/jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c b/jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c index 2e323a0..da3147b 100644 --- a/jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c +++ b/jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c @@ -529,6 +529,17 @@ void free_pubkeys(secp256k1_pubkey **pubkeys, size_t count) free(pubkeys); } +void free_xonly_pubkeys(secp256k1_xonly_pubkey **pubkeys, size_t count) +{ + size_t i; + for (i = 0; i < count; i++) + { + if (pubkeys[i] != NULL) + free(pubkeys[i]); + } + free(pubkeys); +} + /* * Class: fr_acinq_bitcoin_Secp256k1Bindings * Method: secp256k1_ec_pubkey_combine @@ -795,7 +806,7 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1sc pub = (*penv)->GetByteArrayElements(penv, jpubkey, 0); result = secp256k1_xonly_pubkey_parse(ctx, &pubkey, (unsigned char *)pub); (*penv)->ReleaseByteArrayElements(penv, jpubkey, pub, 0); - CHECKRESULT(!result, "secp256k1_ec_pubkey_parse failed"); + CHECKRESULT(!result, "secp256k1_xonly_pubkey_parse failed"); sig = (*penv)->GetByteArrayElements(penv, jsig, 0); msg = (*penv)->GetByteArrayElements(penv, jmsg, 0); @@ -919,7 +930,7 @@ void free_nonces(secp256k1_musig_pubnonce **nonces, size_t count) free(nonces); } -void free_nonces(secp256k1_frost_pubnonce **nonces, size_t count) +void free_frost_nonces(secp256k1_frost_pubnonce **nonces, size_t count) { size_t i; for (i = 0; i < count; i++) @@ -1359,16 +1370,16 @@ 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[jn_participants]; + secp256k1_pubkey vss_commitment[jn_participants]; jbyte* pok64; - size_t size; + size_t size, i; jbyte *pubkeyBytes; unsigned char seed32[32]; - const jbyte *ids33[jn_participants]; + unsigned char *ids33[jn_participants]; if (jctx == 0) return NULL; @@ -1392,14 +1403,15 @@ JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp2 CHECKRESULT((*penv)->GetArrayLength(penv, jpok64) != 64, "pok64 length must be 64 bytes"); - shares = calloc(jn_participants, sizeof(secp256k1_frost_share*)); - vss_commitment = calloc(jthreshold, sizeof(secp256k1_pubkey*)); +// shares = calloc(jn_participants, sizeof(secp256k1_frost_share*)); +// vss_commitment = calloc(jthreshold, sizeof(secp256k1_pubkey*)); for (i = 0; i < jn_participants; i++) { - jbyteArray id33 = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jids33, i); - // TODO: Check id33 size is 33... - ids33[i] = (*penv)->GetByteArrayElements(penv, id33, 0); // TODO: use setElement + jbyteArray jid33 = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jids33, i); + size = (*penv)->GetArrayLength(penv, jid33); + CHECKRESULT(size != 33, "invalid id33 size"); + copy_bytes_from_java(penv, jid33, 33, ids33[i]); } int result = 0; @@ -1413,7 +1425,7 @@ JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp2 seed32, jthreshold, jn_participants, - ids33 + (const unsigned char * const*) ids33 ); (*penv)->ReleaseByteArrayElements(penv, jpok64, pok64, 0); CHECKRESULT(!result, "secp256k1_frost_shares_gen failed"); @@ -1425,7 +1437,7 @@ JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp2 unsigned char out32[32]; for (i = 0; i < jn_participants; i++) { - result = secp256k1_frost_share_serialize(ctx, out32, shares[i]); + result = secp256k1_frost_share_serialize(ctx, out32, &shares[i]); CHECKRESULT(!result, "secp256k1_frost_share_serialize failed"); jbyteArray jshare = (*penv)->NewByteArray(penv, 32); @@ -1481,17 +1493,18 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 secp256k1_xonly_pubkey aggregate_public_key; jbyteArray jaggregate_public_key; - const secp256k1_frost_share **shares; + secp256k1_frost_share **shares; jbyteArray jshare; jbyte *in32; - secp256k1_xonly_pubkey **vss_commitments; + secp256k1_pubkey **vss_commitments; jbyteArray jvss_commitment; jbyte *pub; jbyte *id33; - size_t size, count; + size_t size, count, i; + int result = 0; jbyteArray jresult; jbyte *result_ptr = NULL; @@ -1513,7 +1526,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 CHECKRESULT(jtotalShareCount <= 0, "totalShareCount can't be 0"); CHECKRESULT(jthreshold > jtotalShareCount, "threshold can't be greater then totalShareCount"); - count = (*penv)->GetArrayLength(penv, jnonces); + count = (*penv)->GetArrayLength(penv, jshares); CHECKRESULT(count != jtotalShareCount, "jshares count should be total share count."); shares = calloc(count, sizeof(secp256k1_frost_share*)); @@ -1537,7 +1550,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 vss_commitments[i] = calloc(1, sizeof(secp256k1_pubkey)); jvss_commitment = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jvss_commitments, i); size = (*penv)->GetArrayLength(penv, jvss_commitment); - CHECKRESULT1((size != 33) && (size != 65), "invalid public key size", free_pubkeys(pubkeys, count)); + CHECKRESULT1((size != 33) && (size != 65), "invalid public key size", free_pubkeys(vss_commitments, count)); pub = (*penv)->GetByteArrayElements(penv, jvss_commitment, 0); result = secp256k1_ec_pubkey_parse(ctx, vss_commitments[i], (unsigned char *)pub, size); (*penv)->ReleaseByteArrayElements(penv, jvss_commitment, pub, 0); @@ -1546,19 +1559,16 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 id33 = (*penv)->GetByteArrayElements(penv, jid33, 0); - int result = 0; - result = secp256k1_frost_share_agg( ctx, &aggregate_share, &aggregate_public_key, - shares, - vss_commitments, + (const secp256k1_frost_share *const *)shares, + (const secp256k1_pubkey *const *)vss_commitments, jtotalShareCount, jthreshold, (unsigned char *)id33 ); - result = secp256k1_frost_share_serialize(ctx, result_array, &aggregate_share); CHECKRESULT(!result, "secp256k1_frost_share_serialize failed"); @@ -1588,25 +1598,29 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1fr jbyte *id33; - secp256k1_xonly_pubkey *vss_commitment; - jbyte *jpub; + secp256k1_pubkey *vss_commitment; + jbyteArray jpubkey; + jbyte *pub; - size_t size, count; + size_t size, count, i; if (jctx == 0) - return NULL; + return 0; if (jid33 == NULL) - return NULL; + return 0; if (jshare == NULL) - return NULL; + return 0; if (jvss_commitment == NULL) - return NULL; + return 0; + + int result = 0; CHECKRESULT(jthreshold <= 0, "threshold can't be 0"); + size = (*penv)->GetArrayLength(penv, jshare); CHECKRESULT1(size != sizeof(secp256k1_frost_share), "invalid share size", free(&share)); in32 = (*penv)->GetByteArrayElements(penv, jshare, 0); @@ -1616,20 +1630,27 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1fr id33 = (*penv)->GetByteArrayElements(penv, jid33, 0); - jpub = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jvss_commitment, i); - size = (*penv)->GetArrayLength(penv, jpub); - CHECKRESULT1((size != 33) && (size != 65), "invalid public key size", free_pubkeys(pubkeys, count)); - jpub = (*penv)->GetByteArrayElements(penv, jpub, 0); - result = secp256k1_ec_pubkey_parse(ctx, &vss_commitment, (unsigned char *)jpub, size); - (*penv)->ReleaseByteArrayElements(penv, jpub, jpub, 0); - CHECKRESULT1(!result, "secp256k1_ec_pubkey_parse failed", free(vss_commitment)); + count = (*penv)->GetArrayLength(penv, jvss_commitment); + vss_commitment = calloc(count, sizeof(secp256k1_pubkey *)); - int result = secp256k1_frost_share_verify( + for (i = 0; i < count; i++) + { +// vss_commitment[i] = calloc(1, sizeof(secp256k1_pubkey)); + jpubkey = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jvss_commitment, i); + size = (*penv)->GetArrayLength(penv, jpubkey); + CHECKRESULT1((size != 33) && (size != 65), "invalid public key size", free(vss_commitment)); + pub = (*penv)->GetByteArrayElements(penv, jpubkey, 0); + result = secp256k1_ec_pubkey_parse(ctx, &vss_commitment[i], (unsigned char *)pub, size); + (*penv)->ReleaseByteArrayElements(penv, jpubkey, pub, 0); + CHECKRESULT1(!result, "secp256k1_ec_pubkey_parse failed", free(vss_commitment)); + } + + result = secp256k1_frost_share_verify( ctx, jthreshold, (unsigned char *)id33, - share, - vss_commitment + &share, + (const secp256k1_pubkey *const *)vss_commitment ); return result; @@ -1647,13 +1668,13 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 secp256k1_pubkey pubshare; - jbyte *id33; + jbyte *id33, *jpubkey; - secp256k1_xonly_pubkey **vss_commitments; + secp256k1_pubkey **vss_commitments; jbyteArray jvss_commitment; - jbyte *jpubkey; + jbyteArray jpubshare; - size_t size, count; + size_t size, count, i; if (jctx == 0) return NULL; @@ -1664,6 +1685,8 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 if (jvss_commitments == NULL) return NULL; + int result = 0; + CHECKRESULT(jthreshold <= 0, "threshold can't be 0"); CHECKRESULT(jtotalSignersCount <= 0, "totalSignersCount can't be 0"); CHECKRESULT(jthreshold > jtotalSignersCount, "totalSignersCount can't be greater then n_participants"); @@ -1678,29 +1701,29 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 vss_commitments[i] = calloc(1, sizeof(secp256k1_pubkey)); jvss_commitment = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jvss_commitments, i); size = (*penv)->GetArrayLength(penv, jvss_commitment); - CHECKRESULT1((size != 33) && (size != 65), "invalid public key size", free_pubkeys(pubkeys, count)); + CHECKRESULT1((size != 33) && (size != 65), "invalid public key size", free_pubkeys(vss_commitments, count)); jpubkey = (*penv)->GetByteArrayElements(penv, jvss_commitment, 0); - result = secp256k1_ec_pubkey_parse(ctx, vss_commitments[i], (unsigned char *)jpub, size); - (*penv)->ReleaseByteArrayElements(penv, jvss_commitment, jpub, 0); + result = secp256k1_ec_pubkey_parse(ctx, vss_commitments[i], (unsigned char *)jpubkey, size); + (*penv)->ReleaseByteArrayElements(penv, jvss_commitment, jpubkey, 0); CHECKRESULT1(!result, "secp256k1_ec_pubkey_parse failed", free_pubkeys(vss_commitments, count)); } - int result = secp256k1_frost_compute_pubshare( + result = secp256k1_frost_compute_pubshare( ctx, &pubshare, jthreshold, - (unsigned char *)id33 - vss_commitments, + (unsigned char *)id33, + (const secp256k1_pubkey * const*)vss_commitments, jtotalSignersCount ); - jpubkey = (*penv)->NewByteArray(penv, 65); - jbyte *jpubkeyBytes = (*penv)->GetByteArrayElements(penv, jpubkey, 0); - result = secp256k1_ec_pubkey_serialize(ctx, (unsigned char *)jpubkeyBytes, &size, &pubkey, SECP256K1_EC_UNCOMPRESSED); - (*penv)->ReleaseByteArrayElements(penv, jpubkey, jpubkeyBytes, 0); + jpubshare = (*penv)->NewByteArray(penv, 65); + jbyte *jpubshareBytes = (*penv)->GetByteArrayElements(penv, jpubshare, 0); + result = secp256k1_ec_pubkey_serialize(ctx, (unsigned char *)jpubshareBytes, &size, &pubshare, SECP256K1_EC_UNCOMPRESSED); + (*penv)->ReleaseByteArrayElements(penv, jpubshare, jpubshareBytes, 0); CHECKRESULT(!result, "secp256k1_ec_pubkey_serialize failed"); - return jpubkey; + return jpubshare; } /* @@ -1725,12 +1748,14 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 if (jpublicKey == NULL) return NULL; + int result = 0; + pub = (*penv)->GetByteArrayElements(penv, jpublicKey, 0); result = secp256k1_xonly_pubkey_parse(ctx, &public_key, (unsigned char *)pub); (*penv)->ReleaseByteArrayElements(penv, jpublicKey, pub, 0); - CHECKRESULT(!result, "secp256k1_ec_pubkey_parse failed"); + CHECKRESULT(!result, "secp256k1_xonly_pubkey_parse failed"); - int result = secp256k1_frost_pubkey_tweak( + result = secp256k1_frost_pubkey_tweak( ctx, &tweak_cache, &public_key @@ -1759,7 +1784,6 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 jbyteArray jpubkey; secp256k1_frost_tweak_cache tweak_cache; - jbyte *tweak32 = (*penv)->GetByteArrayElements(penv, jtweak32, 0);; size_t size, count; @@ -1776,12 +1800,13 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 CHECKRESULT((*penv)->GetArrayLength(penv, jtweak32) != 32, "tweak must be 32 bytes"); tweak32 = (*penv)->GetByteArrayElements(penv, jtweak32, 0); + // TODO: Release Array Elements... int result = secp256k1_frost_pubkey_ec_tweak_add( ctx, - pubkey, + &pubkey, &tweak_cache, - &public_key + (unsigned char *) tweak32 ); (*penv)->ReleaseByteArrayElements(penv, jtweak32, tweak32, 0); CHECKRESULT(!result, "secp256k1_frost_pubkey_ec_tweak_add failed"); @@ -1815,7 +1840,6 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 jbyteArray jpubkey; secp256k1_frost_tweak_cache tweak_cache; - jbyte *tweak32 = (*penv)->GetByteArrayElements(penv, jtweak32, 0);; size_t size, count; @@ -1833,12 +1857,13 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 return NULL; CHECKRESULT((*penv)->GetArrayLength(penv, jtweak32) != 32, "tweak must be 32 bytes"); tweak32 = (*penv)->GetByteArrayElements(penv, jtweak32, 0); + // TODO: Release Array elements... int result = secp256k1_frost_pubkey_xonly_tweak_add( ctx, &pubkey, &tweak_cache, - &public_key + (unsigned char *) tweak32 ); (*penv)->ReleaseByteArrayElements(penv, jtweak32, tweak32, 0); @@ -1883,7 +1908,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 jbyte *in32; jbyte *pubkey_ptr; - secp256k1_pubkey pubkey; + secp256k1_xonly_pubkey pubkey; unsigned char msg32[32]; secp256k1_musig_keyagg_cache keyaggcache; unsigned char extra_input32[32]; @@ -1906,7 +1931,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 if (jshare != NULL) { size = (*penv)->GetArrayLength(penv, jshare); - // TODO: CHECKRESULT1(size != fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE, "invalid public nonce size", free_nonces(pubnonces, count)); + // TODO: CHECKRESULT1(size != fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE, "invalid public nonce size", free_frost_nonces(pubnonces, count)); in32 = (*penv)->GetByteArrayElements(penv, jshare, 0); result = secp256k1_frost_share_parse(ctx, &share, (unsigned char *)in32); (*penv)->ReleaseByteArrayElements(penv, jshare, in32, 0); @@ -1925,9 +1950,9 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 size = (*penv)->GetArrayLength(penv, jpubkey); CHECKRESULT((size != 33) && (size != 65), "invalid public key size"); pubkey_ptr = (*penv)->GetByteArrayElements(penv, jpubkey, 0); - result = secp256k1_ec_pubkey_parse(ctx, &pubkey, (unsigned char *)pubkey_ptr, size); + result = secp256k1_xonly_pubkey_parse(ctx, &pubkey, (unsigned char *)pubkey_ptr); (*penv)->ReleaseByteArrayElements(penv, jpubkey, pubkey_ptr, 0); - CHECKRESULT(!result, "secp256k1_ec_pubkey_parse failed"); + CHECKRESULT(!result, "secp256k1_xonly_pubkey_parse failed"); } @@ -1945,7 +1970,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 session_id32, jshare == NULL ? NULL : &share, jmsg32 == NULL ? NULL : msg32, - jpubkey == NULL ? NULL :pubkey_ptr, + jpubkey == NULL ? NULL : &pubkey, jextra_input32 == NULL ? NULL : extra_input32 ); @@ -1976,18 +2001,20 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 secp256k1_frost_session session; secp256k1_frost_pubnonce **pubnonces; - jbyte *in66, *pub, *id33;; + jbyte *in66, *pub, *id33; + + jbyteArray jpubnonce; unsigned char msg32[32]; secp256k1_xonly_pubkey public_key; - const jbyte *ids33[jn_participants]; + const jbyte *ids33[n_pubnonces]; secp256k1_frost_tweak_cache tweak_cache; secp256k1_pubkey adaptor; - size_t size, count; + size_t size, count, i; if (jctx == 0) return NULL; @@ -2007,6 +2034,8 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 if (jids33 == NULL) return NULL; + int result = 0; + CHECKRESULT(n_pubnonces <= 0, "n_pubnonces can't be 0"); count = (*penv)->GetArrayLength(penv, jpubnonces); @@ -2018,13 +2047,13 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 for (i = 0; i < count; i++) { pubnonces[i] = calloc(1, sizeof(secp256k1_frost_pubnonce)); - jnonce = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jpubnonces, i); - size = (*penv)->GetArrayLength(penv, jnonce); - CHECKRESULT1(size != fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE, "invalid public nonce size", free_nonces(pubnonces, count)); - in66 = (*penv)->GetByteArrayElements(penv, jnonce, 0); + jpubnonce = (*penv)->GetObjectArrayElement(penv, jpubnonces, i); + size = (*penv)->GetArrayLength(penv, jpubnonce); + CHECKRESULT1(size != sizeof(secp256k1_frost_pubnonce), "invalid public nonce size", free_frost_nonces(pubnonces, count)); + in66 = (*penv)->GetByteArrayElements(penv, jpubnonce, 0); result = secp256k1_frost_pubnonce_parse(ctx, pubnonces[i], (unsigned char *)in66); - (*penv)->ReleaseByteArrayElements(penv, jnonce, in66, 0); - CHECKRESULT1(!result, "secp256k1_frost_pubnonce_parse failed", free_nonces(pubnonces, count)); + (*penv)->ReleaseByteArrayElements(penv, jpubnonce, in66, 0); + CHECKRESULT1(!result, "secp256k1_frost_pubnonce_parse failed", free_frost_nonces(pubnonces, count)); } size = (*penv)->GetArrayLength(penv, jmsg32); @@ -2058,13 +2087,16 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 if (jadaptor != NULL) { + size = (*penv)->GetArrayLength(penv, jadaptor); + CHECKRESULT((size != 33) && (size != 65), "invalid public key size"); + pub = (*penv)->GetByteArrayElements(penv, jadaptor, 0); - result = secp256k1_ec_pubkey_parse(ctx, &adaptor, (unsigned char *)pub, pubSize); + result = secp256k1_ec_pubkey_parse(ctx, &adaptor, (unsigned char *)pub, size); (*penv)->ReleaseByteArrayElements(penv, jadaptor, pub, 0); CHECKRESULT(!result, "secp256k1_ec_pubkey_parse failed"); } - int result = secp256k1_frost_nonce_process( + result = secp256k1_frost_nonce_process( ctx, &session, (const secp256k1_frost_pubnonce *const *)pubnonces, @@ -2072,7 +2104,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 msg32, &public_key, id33, - ids33, + (const unsigned char * const*) ids33, jtweak_cache == NULL ? NULL : &tweak_cache, jadaptor == NULL ? NULL : &adaptor ); @@ -2122,6 +2154,8 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 if (jsession == NULL) return NULL; + int result = 0; + copy_bytes_from_java(penv, jsecnonce, fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SECRET_NONCE_SIZE, secnonce.data); size = (*penv)->GetArrayLength(penv, jagg_share); @@ -2142,7 +2176,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 } - int result = secp256k1_frost_partial_sign( + result = secp256k1_frost_partial_sign( ctx, &partial_sig, &secnonce, @@ -2184,19 +2218,21 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1fr size_t size, count; if (jctx == 0) - return NULL; + return 0; if (jpartial_sig == NULL) - return NULL; + return 0; if (jpubnonce == NULL) - return NULL; + return 0; if (jpubshare == NULL) - return NULL; + return 0; if (jsession == NULL) - return NULL; + return 0; + + int result = 0; ptr = (*penv)->GetByteArrayElements(penv, jpartial_sig, 0); result = secp256k1_frost_partial_sig_parse(ctx, &partial_sig, ptr); @@ -2208,8 +2244,8 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1fr (*penv)->ReleaseByteArrayElements(penv, jpubnonce, ptr, 0); CHECKRESULT(!result, "secp256k1_frost_pubnonce_parse failed"); - size = (*penv)->GetArrayLength(penv, jpubkey); - CHECKRESULT((size != 33) && (size != 65), "invalid public key size"); + size = (*penv)->GetArrayLength(penv, jpubshare); + CHECKRESULT((size != 33) && (size != 65), "invalid public share size"); pubkeyBytes = (*penv)->GetByteArrayElements(penv, jpubshare, 0); result = secp256k1_ec_pubkey_parse(ctx, &pubshare, (unsigned char *)pubkeyBytes, size); @@ -2229,7 +2265,7 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1fr } - int result = secp256k1_frost_partial_sig_verify( + result = secp256k1_frost_partial_sig_verify( ctx, &partial_sig, &pubnonce, @@ -2241,7 +2277,7 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1fr return result; } -void free_partial_sigs(secp256k1_frost_partial_sig **psigs, size_t count) +void free_frost_partial_sigs(secp256k1_frost_partial_sig **psigs, size_t count) { size_t i; for (i = 0; i < count; i++) @@ -2288,10 +2324,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 CHECKRESULT(size != sizeof(secp256k1_frost_session), "invalid session size"); copy_bytes_from_java(penv, jsession, size, session.data); - if (jpsigs == NULL) - return NULL; - - count = (*penv)->GetArrayLength(penv, jpsigs); + count = (*penv)->GetArrayLength(penv, jpartial_sigs); CHECKRESULT(count <= 0, "partial sigs count cannot be 0"); psigs = calloc(count, sizeof(secp256k1_frost_partial_sig *)); @@ -2299,13 +2332,13 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 for (i = 0; i < count; i++) { psigs[i] = calloc(1, sizeof(secp256k1_frost_partial_sig)); - jpsig = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jpsigs, i); + jpsig = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jpartial_sigs, i); size = (*penv)->GetArrayLength(penv, jpsig); - CHECKRESULT1(size != 32, "invalid partial signature size", free_partial_sigs(psigs, count)); + CHECKRESULT1(size != 32, "invalid partial signature size", free_frost_partial_sigs(psigs, count)); ptr = (*penv)->GetByteArrayElements(penv, jpsig, 0); result = secp256k1_frost_partial_sig_parse(ctx, psigs[i], (unsigned char *)ptr); (*penv)->ReleaseByteArrayElements(penv, jpsig, ptr, 0); - CHECKRESULT1(!result, "secp256k1_frost_partial_sig_parse failed", free_partial_sigs(psigs, count)); + CHECKRESULT1(!result, "secp256k1_frost_partial_sig_parse failed", free_frost_partial_sigs(psigs, count)); } result = secp256k1_frost_partial_sig_agg( @@ -2315,7 +2348,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 (const secp256k1_frost_partial_sig *const *)psigs, jn_sigs ); - free_partial_sigs(psigs, count); + free_frost_partial_sigs(psigs, count); CHECKRESULT(!result, "secp256k1_frost_partial_sig_agg failed"); jpsig = (*penv)->NewByteArray(penv, 64); diff --git a/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt b/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt index 298d318..b0d3a95 100644 --- a/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt +++ b/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt @@ -147,8 +147,8 @@ public object NativeSecp256k1 : Secp256k1 { ) return Triple( - result[0], - result[1], + emptyArray(), + emptyArray(), pok64 ) } diff --git a/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt b/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt index 898dbce..5f590b9 100644 --- a/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt +++ b/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt @@ -329,7 +329,7 @@ public interface Secp256k1 { public const val FROST_PARTIAL_SIGNATURE_SIZE: Int = 36 - public const val FROST_SHARE_SIZE: Int = 37 + public const val FROST_SHARE_SIZE: Int = 32 public const val FROST_TWEAK_CACHE_SIZE: Int = 102 public const val FROST_SESSION_SIZE: Int = 134 public const val FROST_SECNONCE_SIZE: Int = 69 diff --git a/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt b/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt index a054b11..b8c6cb8 100644 --- a/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt +++ b/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt @@ -489,11 +489,11 @@ public object Secp256k1Native : Secp256k1 { totalSigners: Int, ids33: Array ): Triple, Array, ByteArray> { - 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" }) } + 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(ids33.size) @@ -534,18 +534,18 @@ public object Secp256k1Native : Secp256k1 { threshold: Int, id33: ByteArray ): Pair { - require(totalShares.size == totalShareCount) - totalShares.forEach { require(it.size == 33) } - require(vssCommitments.size == totalShareCount) + require(totalShares.size == totalShareCount) { "totalShare array size (${totalShares.size}) should be the same as total share count ($totalShareCount)" } + totalShares.forEach { require(it.size == 32) { "all shares should be of size 32" } } + require(vssCommitments.size == totalShareCount) { "vssCommitments array size ${vssCommitments.size} should be the same as total share count ($totalShareCount)" } vssCommitments.forEach { vssCommitment -> - require(vssCommitment.size == threshold) + require(vssCommitment.size == threshold) { "all vss commitment array size (${vssCommitment.size}) should be the same as the threshold size ($threshold)" } vssCommitment.forEach { publicKey -> - require(publicKey.size == 33 || publicKey.size == 65) + require(publicKey.size == 33 || publicKey.size == 65) { "vss commitment data size should be 33 or 65" } } } - require(threshold > 1) - require(threshold <= totalShareCount) - require(id33.size == 33) + require(threshold > 1) { "threshold should be greater then 1" } + require(threshold <= totalShareCount) { "Threshold can not be greater then the total share count" } + require(id33.size == 33) { "id size should be 33" } memScoped { val nAggregateShare = alloc() @@ -562,7 +562,7 @@ public object Secp256k1Native : Secp256k1 { ).reinterpret() } - secp256k1_frost_share_agg( + val result = secp256k1_frost_share_agg( ctx = ctx, agg_share = nAggregateShare.ptr, agg_pk = nAggregatePublicKey.ptr, @@ -572,6 +572,7 @@ public object Secp256k1Native : Secp256k1 { threshold = threshold.convert(), id33 = toNat(id33) ) + println("Aggregate Result: $result") return Pair( serializeFrostShare(nAggregateShare), @@ -587,13 +588,13 @@ public object Secp256k1Native : Secp256k1 { share: ByteArray, vssCommitment: Array ): Int { - require(threshold > 1) - require(id33.size == 33) - require(share.size == Secp256k1.FROST_SHARE_SIZE) + require(threshold > 1) { "threshold should be greater then 1" } + require(id33.size == 33) { "id size should be 33" } + require(share.size == Secp256k1.FROST_SHARE_SIZE) { "all shares should be of size 32" } - require(vssCommitment.size == threshold) + require(vssCommitment.size == threshold) { "all vss commitment array size (${vssCommitment.size}) should be the same as the threshold size ($threshold)" } vssCommitment.forEach { publicKey -> - require(publicKey.size == 33 || publicKey.size == 65) + require(publicKey.size == 33 || publicKey.size == 65) { "vss commitment data size should be 33 or 65" } } memScoped { diff --git a/tests/src/commonTest/kotlin/fr/acinq/secp256k1/FrostTest.kt b/tests/src/commonTest/kotlin/fr/acinq/secp256k1/FrostTest.kt index fb75a7c..9a46bcb 100644 --- a/tests/src/commonTest/kotlin/fr/acinq/secp256k1/FrostTest.kt +++ b/tests/src/commonTest/kotlin/fr/acinq/secp256k1/FrostTest.kt @@ -12,10 +12,11 @@ class FrostTest: BaseTest() { 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 -> + tests.jsonObject["valid_share_gen_test_cases"]!!.jsonArray.forEach { validTestCases -> + val keyIndices = validTestCases.jsonObject["key_indices"]!!.jsonArray.map { it.jsonPrimitive.int } - val seed32 = ByteArray(32) + 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() @@ -53,10 +54,131 @@ class FrostTest: BaseTest() { 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 + + println( + Hex.encode(result.first) + ) + + println( + Hex.encode(result.second) + ) +// 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" + ) + } + + } diff --git a/tests/src/commonTest/resources/frost/share_agg_vectors.json b/tests/src/commonTest/resources/frost/share_agg_vectors.json new file mode 100644 index 0000000..a12c806 --- /dev/null +++ b/tests/src/commonTest/resources/frost/share_agg_vectors.json @@ -0,0 +1,24 @@ +{ + "expected": [ + { + "aggregate_share": "4f633c97b4c59fda057bd680bac8b8f810716e0873159a1086b9fa200b9e8475", + "aggregate_public_key": "1da141d0fb5768f04f9581051a76fb37e3b547be4de363dc3c659dbc12f69d7e" + }, + { + "aggregate_share": "09915c6249fd9008cf7b8f75e267ab37fe81cc879a66751f1b5681a342683838", + "aggregate_public_key": "4cad15e1dc3783d079ec11d9335e895d1a2c94667ae46c75a7ba99926002c228" + }, + { + "aggregate_share": "dcfa471d9b8b5b7e2664e2bc00a2a1dc9631dd41d6f56739f2bd4551e0e88996", + "aggregate_public_key": "ab1a31f7986183a3ce4e8b7f5ea45a1f244e9cea4ef7ac88f8a284ef70d3e3e0" + }, + { + "aggregate_share": "6cfd8a1443dd80d2ed570444ee82edab999eff3e4cef08b41df628a8e1424c18", + "aggregate_public_key": "33dfe581f7adeb652354c15eff7cb921233da979fc0718d59b3d2697b5f1f4f3" + }, + { + "aggregate_share": "48b11a68e9c4ada9e4056db15ab3308e621c1b15d6dc683b90d20dc85ffbc3a9", + "aggregate_public_key": "7ba53e9a397ceb5d6ae1e6fe550e98bb1db531a53b7a7ad0baee7058b35dbb3b" + } + ] +} \ No newline at end of file diff --git a/tests/src/commonTest/resources/frost/share_gen_vectors.json b/tests/src/commonTest/resources/frost/share_gen_vectors.json index 942d7fc..86b8b26 100644 --- a/tests/src/commonTest/resources/frost/share_gen_vectors.json +++ b/tests/src/commonTest/resources/frost/share_gen_vectors.json @@ -1,84 +1,182 @@ { "pubkeys": [ - "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", - "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", - "023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66", - "04F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", - "03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9", - "020000000000000000000000000000000000000000000000000000000000000005", - "02FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30" + "023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66", + "02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9", + "03935f972da013f80ae011890fa89b67a27b7be6ccb24d3274d18b2d4067f261a9", + "03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659", + "04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9" ], - "valid_test_cases": [ + "valid_share_gen_test_cases": [ { + "seed": "0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F", "key_indices": [0, 1, 2, 3, 4], "threshold": 3, "expected": { "frost_share": [ - "0d9c85106ab6168b13e3b569695fb57bf91cbbe1e589a205b48bb7e15ff6908b", - "807eb5b22ef56d6ae3601f2774a1985485386f6317e6bc075b2134818fd44c5b", - "5e67fe075e91549bf28558a0d55e4b954bf5f9f229ddc0d6e9ab76a139367bbf", - "d248680a6aa524a75c9f59c2732e77ac2d334b98ac2b09defc9030da218d17ca", - "7bdf748e9fd56cd87e0430847e3212d0814528aeb83e1d83aeda279cbc20b481" + "9a04e37bc40df0e1c3e05b82e7a7af6b7cdaadf337ec3eaa2b50bb9ffdb2da99", + "8d7b24fa2421a9157ce01b7a900fe4b06dbb922def5d0f8a6b6f420e94310d27", + "8cda987d0a9817ecb544f1ffcd7912006c6406bb95c9a9a45b70d641f6a0300c", + "bf0eaac669eac6ac43d094bb2e07e4fa7fd4b1d317188c690aad7ea211b49bdb", + "00c266074c34720f6d9a8511e4ec82bed44e104f93f20d9bbfbff8e2edf44400" ], "vss_commitment": [ - "044c865c8c3f29a10a55bee4deca73b135d768eb7727a7ccc0fd47db82d7c9f4763d0ebe8feabf6b2119098f1f1f52ba165ae373d75a73c053f4bff6bd2ddb361f", - "045500faa3f2c4279bb95e66bd4c0011da084806e260395c0ff02ae25bd80102f45a7b7fe4d90cc76e9b26a1f9a9febcd0c767aeee63ab463fcfe559ac3b3ad653", - "0499c4d8f4ed163d07a112a74c0b03e1f6851b86b499b916d66824cec9694e5bd866e108b3f82413bdf96c6abde9995a165684432467b82be13dd73e67e4cf29f9" + "04bc2f60d5a7494d506e6517c49db2104b05e087536ccb1cb2730282f469782bb93e2c0029d733beeea75120e831ed71255adde4ddbd0be049419572502d7b73b9", + "04ced2029d64827253175b5382cb327123fd2cdcdb5b2092e66020e9b6ece639f675029e36604347735eef9bf64137474b14d92d2996e67f5721705ee574c916a1", + "044f34156e0a6d49c96298a845fd07a122490dee82b80f090b3214162ed2b030c88a2cec6cac580d63d770f1d2933f21e58ec8d4b94ca1939e590add1616f6ea38" ], - "pok64": "e79e0d894639155ffebbe03e97030758e6060929a468010ce70627b1ce92b553597f1709f2d82a2ad884f868123344ec871eec4cbf1fa12c5794df6fe5d06e27" + "pok64": "8f63ac15582fd77b4c50eef4ca7f5810e9d31ff86a5e7c0c14483edc076290bcfdb481e5c41b24419c65ac7525560a8d3bbbcc303c8c232d63650252e7aff576" } }, { + "seed": "0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F", "key_indices": [4, 3, 2, 1, 0], "threshold": 3, "expected": { "frost_share": [ - "bdf8c4896736812a5548610bd39b66dc91b266e1bc68db4e760bcee797a695e3", - "5afe66c979b666141b8bf46747293797e74580341527f5f6aa01277a468fd9f2", - "9efe2e26dcf8e6f4224fea1fec9a9167ec29cb3b727f841ef76e23d592d2512f", - "dd4fd050344dc625737d018c69298ed312bd7043d3343583625703ed45726ac6", - "eb486a1c2e3ff755473fc41b01138b6a0d3f99f3b99b420e57271689d40eb7e4" + "7f3d4b3c13fe574ce2b24412aff67f19cc3d198b40e6bb57865df4f519ef65fa", + "9a46587ac615fc8afd0bc3a234075fb190f20a951df57ce21c7c7f6331117ab3", + "9188f7516271f4e4d9c71837db17f3a4e9ee1f979ca0245405ed13f88d8d54f2", + "afea9adf149439f663bb787190f7503984e632823607433e7c0d86884ba3ac58", + "11492bef4d7f35e038a1270a3a1a0a55c8e72a313d6086fec4bbdbe0522b9575" ], "vss_commitment": [ - "0496291d2a1ec0f0e38d622db473004c18bd6713be47642cfdd7ad9c458a12506da5eb9d0b0a99aab0c97f5ac6d94f2becd8075eef8675d06e4b6cf9e58ed4c30b", - "0473b3681ac295de098568695b02820d57cab4c09f953518bfe1d133b54d794564da8a4c508942789b32fd483719bd847ab0a6f87e0ef7bb7d40376e1c109c0bda", - "044cd2e10e73b39450f2ce02609985ea1f2d84891a0485fbf42ddf9164c0dd5222306a396efb13eff789837b894ca6bf3681d1f937b94e209a8e8333e1e5a7d6c1" + "04ba2dd42da281b300358ed004da8755cc5b93c2ea56c8b79d63492501f2a8e69e4beb0f7a7adb01f2edec1ec84e338db286319f5be9faa82c2ac9ccd976e459eb", + "04d0be30dbc1da6ed9c84e33bf976671b7fadd38ee2243ec1c86780456092b4b5504416548cfae342746b8cde08a3aa3323c338a125031fbb31693e4fa94d4c3d9", + "04146aa11a44a2d2e1c53eb91f274c2145ff9d69d7af27ec85d34fb0df318bc4c9ab75f2d473b03fb133b0d8c1166dd6116c934fa7ff1498df2e6a51650a32940a" ], - "pok64": "5f4e653cd392b04042629b78bc5982c552a4027816321355e519912e1e46514b6425bd31ae684a1ce1941a98cfb0d2b9ad108a39e230b4303e0e0237d7136998" + "pok64": "c5fc820d0d64d447eec6c5f5eade3c08f2a0dac2fa244be7558247989c71a14dd51bfe784983a84fefc76fd4d049434d88df02b5474c14304150b9dce304e842" } }, { + "seed": "0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F", "key_indices": [0, 0, 0], "threshold": 2, "expected": { "frost_share": [ - "2bc9a1e8064cc39759023561f07507ad72db7e7fa20b7a01ec467d40bed167ff", - "2bc9a1e8064cc39759023561f07507ad72db7e7fa20b7a01ec467d40bed167ff", - "2bc9a1e8064cc39759023561f07507ad72db7e7fa20b7a01ec467d40bed167ff" + "6a2ca571b1b83fbe65bb589949538f2d4c6cada3aa914232b96160584642262b", + "6a2ca571b1b83fbe65bb589949538f2d4c6cada3aa914232b96160584642262b", + "6a2ca571b1b83fbe65bb589949538f2d4c6cada3aa914232b96160584642262b" ], "vss_commitment": [ - "041857d4fce91165cba35a6a074ce182883c92eaf0e8c97d985bb73db2befcee02dbcd9ba5bb8e01878d9900738833bc5111c20996b9f5f14da50011a0a4e0767f", - "04702b5ed0a3f937ca894a976f7927f537e37e19eafcf7ed970087b860bfa80f7c64a060e1835fdfe8780abf7d0dbb11b4334471aa133f1fa159c0151faf16edee" + "04a17464b9a1c4e7fb1f22221ba552640d891fdaca04b6a4c9570be4bfb8fdc0c0ca13853d1ea1eccf8e8f81d79d1500dac44a53282f58d17468e358ff78bc7e14", + "04af3c0779299cd72cf5f5dbe919068f4d9d3b525a48665363fa8b1ca26d6908cf477c156e3603f6cfe3d6f394d2a9e9f55e86d7b90a2ad2f0ea62f6ac4bd1f4b2" ], - "pok64": "2081623ec3b670010d6a8ce55073cf0ef9906798b18db58b1385211d6a7b206e2408e5fc9c399fd1a448686cd29aa71e6053229bf42c5710a5f10af0af1140b0" + "pok64": "a006b9b996888d552ce756bf7f217228e487fe510473c08b025ff145ccae6c015265e4f3ca39d488068f385afe0766b636fcbd3a5ac4cdd96f90e704dcce58d7" } }, { + "seed": "0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F", "key_indices": [0, 0, 1, 1], "threshold": 2, "expected": { "frost_share": [ - "70656f19f741cb3e1a46d033321c1627e4464f08316f0d2faad738903b2b2df9", - "70656f19f741cb3e1a46d033321c1627e4464f08316f0d2faad738903b2b2df9", - "624956ad9497abe08d08e4e367519b0c263d79d14754c4a6fb7b2b67796c3636", - "624956ad9497abe08d08e4e367519b0c263d79d14754c4a6fb7b2b67796c3636" + "9b84df35de7d30724c5ef2593c40e349e086e43bcbc4534034e0312510e55e6d", + "9b84df35de7d30724c5ef2593c40e349e086e43bcbc4534034e0312510e55e6d", + "ade61b5f4aec435ac0c4ff7ef61280a9f00150f88068cd391be3ea2f50128199", + "ade61b5f4aec435ac0c4ff7ef61280a9f00150f88068cd391be3ea2f50128199" ], "vss_commitment": [ - "04267d0994c34e87b281506e325a64b83935acb172e5d51a451b5e5f21f51490489dd865654935008aa6afb48955259ace1f8a7eeeafb95c2b0d78dec8e5f25361", - "04c616024ec0c9317bd7574b4fb55a9202d2e6d53465bfb37d1f9edcffc775df537c7c521eac64316f1339943c219df37fa597a49d6be6a2487d776b8305c3880c" + "04840febfcb959d1425df55ae74b78dbd1f9641438fbc6d5e5fc8a315dfdca30106b8846c149a27b2896a312e598cd4b447b375a46b5787f01ecd0a8b642bf5017", + "04935008aeb03eef3dfee5b9c42d1575dd53c8ab8078cabf38d8bd1768e1ee1f92ffe6bb6997b085104a048cac6ba7d7fa6a57c41c639ebfde516ce6d9292dc84b" ], - "pok64": "ea25763debd2b96d9e24a3cf3d87f792bce88a27787c0b84bc0b2fc5a1fec841afc6606bc970e477694b1f3c6ad25370c06a7b9705d52c3acfec13b036a94df8" + "pok64": "9d3c1f08ff8215d65e25ea8678ac923d089f10d7be7a77d2fa2f802174094d62d0f713dd874570ad4bdcbfc17cf02464523387893d85c134f201fee7cdbe3b14" } } - ] + ], + "valid_signers_share_gen_test_case": { + "key_indices": [0, 1, 2, 3, 4], + "threshold": 3, + "signers": [ + { + "seed": "0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F", + "expected": { + "frost_share": [ + "9a04e37bc40df0e1c3e05b82e7a7af6b7cdaadf337ec3eaa2b50bb9ffdb2da99", + "8d7b24fa2421a9157ce01b7a900fe4b06dbb922def5d0f8a6b6f420e94310d27", + "8cda987d0a9817ecb544f1ffcd7912006c6406bb95c9a9a45b70d641f6a0300c", + "bf0eaac669eac6ac43d094bb2e07e4fa7fd4b1d317188c690aad7ea211b49bdb", + "00c266074c34720f6d9a8511e4ec82bed44e104f93f20d9bbfbff8e2edf44400" + ], + "vss_commitment": [ + "04bc2f60d5a7494d506e6517c49db2104b05e087536ccb1cb2730282f469782bb93e2c0029d733beeea75120e831ed71255adde4ddbd0be049419572502d7b73b9", + "04ced2029d64827253175b5382cb327123fd2cdcdb5b2092e66020e9b6ece639f675029e36604347735eef9bf64137474b14d92d2996e67f5721705ee574c916a1", + "044f34156e0a6d49c96298a845fd07a122490dee82b80f090b3214162ed2b030c88a2cec6cac580d63d770f1d2933f21e58ec8d4b94ca1939e590add1616f6ea38" + ], + "pok64": "8f63ac15582fd77b4c50eef4ca7f5810e9d31ff86a5e7c0c14483edc076290bcfdb481e5c41b24419c65ac7525560a8d3bbbcc303c8c232d63650252e7aff576" + } + }, + { + "seed": "F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0", + "expected": { + "frost_share": [ + "7adaa6dbd9df3f0944a516d13b6d7a826a956d05412a9f656b26b36e6507ff0c", + "69cedd07db8a28a4cfd70fcd672b573b842675a9a0222239173c2dcc2f300dd1", + "ca1df886e57b1ede4501a09b2c8e433f4503bdf9627784369650fd76a7ada20c", + "f53e5fb436fae00581f5077cb4736af110d5fe1ceb9c4047852adfea6fa2e8b0", + "8addd4121d313a0458b3649466f27dafadc5cb6dba441f7e1e5c4f2fb62139c0" + ], + "vss_commitment": [ + "0498fce8a40dd9fc23fd87cc4fecd572bd87a6d961576ba7eef3e140f61655c9ee276942ef761cf0cd2845d1c6f149c73e411c2869ac8e4faeedcc6235d0954460", + "04581308e2c7b7367f5f711a95c6f72a99b53f138cf8eafd6c0119ea038e18b51ec8e1bab854e22c42f56e0ddf6922bcac4064254700194a5a9abcdb619e96e701", + "04ebb8b0c4fcecb70d91b9e65ea897ed8930f6d7b41cdcd150718ebbcef40b50f7fb9817fd425b598e09f3133a9100d513e9ba97bcb26b8ef371ada9669a6ed11f" + ], + "pok64": "b2d68140014812cfa83116100deba8a6152a20a243ea73e3e4edf7f25031805f25f3dd78e6d921de1bcebc0d9a57069af905d3f1d613896f6ef69820c601e651" + } + }, + { + "seed": "7FB9E0E687ADA1EEBF7ECFE2F21E73EBDB51A7D450948DFE8D76D7F2D1007671", + "expected": { + "frost_share": [ + "7bde839ba686bdadce0dd854f1f71455c2dd9257b2bfd1995a92e7601dc8ebb8", + "15b62e7af6dfbc1035197fa1439b0b93639798e52a52efb964ff8eb118f0218e", + "6a4179474660abdda21b9cb0c7f27f487b18dd96b7a78f24b2b3b2e7d53504f6", + "97c53a07bd8b7a27a1ba83e3be7b913d55d3112a9ece472c0e3ab2f3e18e34df", + "f5bb1c36ec28f1a2845dcfb10af91772609f401d5ab4357a2a23e4c4d4e1be0d" + ], + "vss_commitment": [ + "046b17a9bca13b4cec2ae589973ab0471915fd77c93374d7d5dfcfacac9da7132bf2d07f55f98caf84927c97fe2946174d73609afe7d9aba0364b0abe2d174d544", + "04abaab1242f669205aa0eb26a876a89cbe80c6c7364b1fba0d095d8181767b96d3d44e5014c2d5a82cc9cf7b9e5ae269e5bc22ffe0212ef1a0b7a2379778be500", + "0415d97c46268a919acbfadcdc0a23fb463d94473787365a6bdd8f5bce95d6d83156448f2582bddcbdbb9bfc58cde1db47e5fb6350530bfb1102b7d0d44a70b5c0" + ], + "pok64": "5cca5711ca05df39c82fe518e4afcd2871654bbfe6fed31b97101bfc27e1d0083d1cbc2cb3d3fa7a972bd84c7c025f71042a3a0aec27311732ae8b679bdebda3" + } + }, + { + "seed": "F95466D086770E689964664219266FE5ED215C92AE20BAB5C9D79ADDDDF3C0CF", + "expected": { + "frost_share": [ + "28b9d1730cd16190c0e9903144bc93f1ea5febf0046a290e00887540c7f726cf", + "d423aafb512cb983b00bdca3e8b398d2f197db8339889b4d0934852f3a0be1cb", + "3d71eab243f39cb2a83ccf78cb611f24544d01dc53a14616cfcf7044f4cfd8c3", + "78b75d47b540a9f29937e7a9187abc31286e7fcafb112c25829ddec7ae73f2d8", + "0a917790664eb85b54b2527449fe445c93a9c384b31ccc8b9ade6638ff55dd96" + ], + "vss_commitment": [ + "04919b0ecff3c10aebec20d55f6eff6736df2cb9b0e549d633ea1711eea4def643c00c89025bd567b79e7fd808c821bca9e6516542ebd689a06f97f52bb8937b7c", + "041583c3a25ebab0fbddbc9c9c491f889ff1df5991b0963c3c6363c6040eb505f2a9e279987f70d30415ddae2bcace1ccf2f96f1d220016c526a363aebed6c02a8", + "04e53ec77bf28672cb36a527fd5ac2ec90b88ab99dfd54c734b4837ea84759332ff7259e9044af6a9847c9432f023a5c7039f95313d564572a326b0e34b3e2299d" + ], + "pok64": "ff6bf4b90faf7a66dc54bfa2cd047be44e1c42622410d6e3a23697d30212d3bde11fc7fb4e61b2bc1e4310ad86089721ba912191d7ca561b9c5dcbcb604116fc" + } + }, + { + "seed": "012ABBCB52B3016AC03AD82395A1A415C48B93DEF78718E62A7A90052FE224FB", + "expected": { + "frost_share": [ + "638248e2dd3f9a1b9cc2368ce6540aa841d04ae712ce6ccc9a417076aeda779e", + "fc5f214938b6d348504c400783763bc40055c4ad1e7a9f5c0fc2bb8880b9150e", + "613a34d878e85be35e57e6816ee23942ea5e394a5fb88247f748eead74e22f65", + "ac4e7c9132c25867f06e6b13a39c7714982a5dfd7ba8748323900cf05a8f0712", + "89cf905e2f716d0707baa735baa28c096bc6c8561e8f83d11334102e7b4d3774" + ], + "vss_commitment": [ + "04f63b636f91fda4fa756c64cd34c186e4595a5b4a6ed6351ba0e99961f2a189001f6f708312ed0ac8c1e291d6064e236e265f2b1b561925a29a39c2d3ad9f866b", + "040269fedd5bdb0d7bed5dd50f9fec28415d51694441dc6c5b0b3e2fd577429c40832c6263e9d218f6ae8cc6a87f72d69d3dc0096a8779d7530fec4983ed6c95b1", + "04fa8cf2f9a25d2d5b52872dd27afd89dfff5bad33f3335726fc56b49989f64c041e765acd4719bad295620393b00ec3f1b5420f02bad4794998d5f26c435deee5" + ], + "pok64": "6888a2ffd199e69806e2c067befc41bd58de0605407542163031e8d75dd1cf80b7fae9e12c8e618081cf79a84d2a3a293dd260234383e5ab587f4459c5963d15" + } + } + ] + } } \ No newline at end of file