JNI implementations continued

This commit is contained in:
kngako 2024-08-12 02:16:54 +02:00
parent b439181376
commit 1b29cfa2d7

View File

@ -1648,7 +1648,412 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
* Signature: (J[B[B)[B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1pubkey_1ec_1tweak_1add
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray, jbyteArray)
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jtweak_cache, jbyteArray jtweak32)
{
// TODO: Implement secp256k1_frost_pubkey_ec_tweak_add
secp256k1_context *ctx = (secp256k1_context *)jctx;
jbyte *tweak32, *pub;
secp256k1_pubkey pubkey;
jbyteArray jpubkey;
secp256k1_frost_tweak_cache tweak_cache;
jbyte *tweak32 = (*penv)->GetByteArrayElements(penv, jtweak32, 0);;
if (jctx == 0)
return NULL;
if (jtweak_cache == NULL)
return NULL;
size = (*penv)->GetArrayLength(penv, jtweak_cache);
CHECKRESULT(size != sizeof(secp256k1_frost_tweak_cache), "invalid keyagg cache size");
copy_bytes_from_java(penv, jtweak_cache, size, tweak_cache.data);
if (jtweak32 == NULL)
return NULL;
CHECKRESULT((*penv)->GetArrayLength(penv, jtweak32) != 32, "tweak must be 32 bytes");
tweak32 = (*penv)->GetByteArrayElements(penv, jtweak32, 0);
int result = secp256k1_frost_pubkey_ec_tweak_add(
ctx,
pubkey,
&tweak_cache,
&public_key
);
(*penv)->ReleaseByteArrayElements(penv, jtweak32, tweak32, 0);
CHECKRESULT(!result, "secp256k1_frost_pubkey_ec_tweak_add failed");
jpubkey = (*penv)->NewByteArray(penv, 65);
pub = (*penv)->GetByteArrayElements(penv, jpubkey, 0);
size = 65;
result = secp256k1_ec_pubkey_serialize(ctx, pub, &size, &pubkey, SECP256K1_EC_UNCOMPRESSED);
(*penv)->ReleaseByteArrayElements(penv, jpubkey, pub, 0);
CHECKRESULT(!result, "secp256k1_ec_pubkey_serialize failed");
pub = (*penv)->GetByteArrayElements(penv, jtweak_cache, 0);
memcpy(pub, tweak_cache.data, sizeof(secp256k1_frost_tweak_cache));
(*penv)->ReleaseByteArrayElements(penv, jtweak_cache, pub, 0);
return jpubkey;
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_pubkey_xonly_tweak_add
* Signature: (J[B[B)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1pubkey_1xonly_1tweak_1add
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jtweak_cache, jbyteArray jtweak32)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
jbyte *tweak32, *pub;
secp256k1_pubkey pubkey;
jbyteArray jpubkey;
secp256k1_frost_tweak_cache tweak_cache;
jbyte *tweak32 = (*penv)->GetByteArrayElements(penv, jtweak32, 0);;
if (jctx == 0)
return NULL;
if (jtweak_cache == NULL)
return NULL;
size = (*penv)->GetArrayLength(penv, jtweak_cache);
CHECKRESULT(size != sizeof(secp256k1_frost_tweak_cache), "invalid keyagg cache size");
copy_bytes_from_java(penv, jtweak_cache, size, tweak_cache.data);
if (jtweak32 == NULL)
return NULL;
CHECKRESULT((*penv)->GetArrayLength(penv, jtweak32) != 32, "tweak must be 32 bytes");
tweak32 = (*penv)->GetByteArrayElements(penv, jtweak32, 0);
int result = secp256k1_frost_pubkey_ec_tweak_add(
ctx,
pubkey,
&tweak_cache,
&public_key
);
(*penv)->ReleaseByteArrayElements(penv, jtweak32, tweak32, 0);
CHECKRESULT(!result, "secp256k1_frost_pubkey_ec_tweak_add failed");
jpubkey = (*penv)->NewByteArray(penv, 65);
pub = (*penv)->GetByteArrayElements(penv, jpubkey, 0);
size = 65;
result = secp256k1_ec_pubkey_serialize(ctx, pub, &size, &pubkey, SECP256K1_EC_UNCOMPRESSED);
(*penv)->ReleaseByteArrayElements(penv, jpubkey, pub, 0);
CHECKRESULT(!result, "secp256k1_ec_pubkey_serialize failed");
pub = (*penv)->GetByteArrayElements(penv, jtweak_cache, 0);
memcpy(pub, tweak_cache.data, sizeof(secp256k1_musig_keyagg_cache));
(*penv)->ReleaseByteArrayElements(penv, jtweak_cache, pub, 0);
return jpubkey;
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_nonce_gen
* Signature: (J[B[B[B[B[B)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1nonce_1gen
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jsession_id32, jbyteArray jshare, jbyteArray jmsg32, jbyteArray jpubkey, jbyteArray jextra_input32)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
int result = 0;
size_t size;
secp256k1_frost_secnonce secnonce;
secp256k1_frost_pubnonce pubnonce;
unsigned char session_id32[32];
secp256k1_frost_share share;
jbyte *in32;
jbyte *pubkey_ptr;
secp256k1_pubkey pubkey;
unsigned char msg32[32];
secp256k1_musig_keyagg_cache keyaggcache;
unsigned char extra_input32[32];
if (jctx == 0)
return NULL;
if (jsession_id32 == 0)
return NULL;
size = (*penv)->GetArrayLength(penv, jsession_id32);
CHECKRESULT(size != 32, "invalid session_id size");
copy_bytes_from_java(penv, jsession_id32, size, session_id32);
if (jshare != NULL) {
share = calloc(1, sizeof(secp256k1_frost_share));
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));
in32 = (*penv)->GetByteArrayElements(penv, jshare, 0);
result = secp256k1_frost_share_parse(ctx, share, (unsigned char *)in32);
(*penv)->ReleaseByteArrayElements(penv, jshare, in32, 0);
// TODO: CHECKRESULT1(!result, "secp256k1_frost_share_parse failed", free_shares(shares, count));
}
if (jmsg32 != NULL)
{
size = (*penv)->GetArrayLength(penv, jmsg32);
CHECKRESULT(size != 32, "invalid message size");
copy_bytes_from_java(penv, jmsg32, size, msg32);
}
if (jpubkey != NULL) {
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);
(*penv)->ReleaseByteArrayElements(penv, jpubkey, pubkey_ptr, 0);
CHECKRESULT(!result, "secp256k1_ec_pubkey_parse failed");
}
if (jextra_input32 != NULL)
{
size = (*penv)->GetArrayLength(penv, jextra_input32);
CHECKRESULT(size != 32, "invalid extra input size");
copy_bytes_from_java(penv, jextra_input32, size, extra_input32);
}
result = secp256k1_frost_nonce_gen(
ctx,
&secnonce,
&pubnonce,
session_id32,
jshare == NULL ? NULL : &share,
jmsg32 == NULL ? NULL : msg32,
jpubkey == NULL ? NULL :pubkey_ptr,
jextra_input32 == NULL ? NULL : extra_input32
);
CHECKRESULT(!result, "secp256k1_frost_nonce_gen failed");
// TODO: copy nonce result...
// memcpy(nonce, secnonce.data, fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SECRET_NONCE_SIZE);
// result = secp256k1_musig_pubnonce_serialize(ctx, nonce + fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SECRET_NONCE_SIZE, &pubnonce);
// CHECKRESULT(!result, "secp256k1_musig_pubnonce_serialize failed");
//
// jnonce = (*penv)->NewByteArray(penv, sizeof(nonce));
// nonce_ptr = (*penv)->GetByteArrayElements(penv, jnonce, 0);
// memcpy(nonce_ptr, nonce, sizeof(nonce));
// (*penv)->ReleaseByteArrayElements(penv, jnonce, nonce_ptr, 0);
//
// return jnonce;
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_nonce_process
* Signature: (J[[B[B[B[B[[B[B[B)[B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1nonce_1process
(JNIEnv *penv, jclass clazz, jlong jctx, jobjectArray jpubnonces, jbyteArray jmsg32, jbyteArray jpubkey, jbyteArray jmy_id33, jobjectArray jids33, jbyteArray jtweak_cache, jbyteArray jadaptor)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
secp256k1_frost_session session;
// TODO: Implement logic for the secp256k1_frost_nonce_process
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_partial_sign
* Signature: (J[B[B[B[B)[B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1partial_1sign
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jsecnonce, jbyteArray jagg_share, jbyteArray jsession, jbyteArray jtweak_cache)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
secp256k1_frost_partial_sig partial_sig;
secp256k1_frost_secnonce secnonce;
secp256k1_frost_share agg_share;
jbyte *in32;
secp256k1_frost_session session;
secp256k1_frost_tweak_cache tweak_cache;
jbyteArray jpsig;
jbyte *ptr;
copy_bytes_from_java(penv, jsecnonce, fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SECRET_NONCE_SIZE, secnonce.data);
if (jagg_share != NULL) {
agg_share = calloc(1, sizeof(secp256k1_frost_share));
size = (*penv)->GetArrayLength(penv, jagg_share);
// TODO: CHECKRESULT1(size != fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE, "invalid public nonce size", free_nonces(pubnonces, count));
in32 = (*penv)->GetByteArrayElements(penv, jagg_share, 0);
result = secp256k1_frost_share_parse(ctx, agg_share, (unsigned char *)in32);
(*penv)->ReleaseByteArrayElements(penv, jagg_share, in32, 0);
// TODO: CHECKRESULT1(!result, "secp256k1_frost_share_parse failed", free_shares(shares, count));
}
CHECKRESULT((*penv)->GetArrayLength(penv, jsession) != fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SESSION_SIZE, "invalid session size");
copy_bytes_from_java(penv, jsession, fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SESSION_SIZE, session.data);
size = (*penv)->GetArrayLength(penv, jtweak_cache);
CHECKRESULT(size != sizeof(secp256k1_frost_tweak_cache), "invalid keyagg cache size");
copy_bytes_from_java(penv, jtweak_cache, size, tweak_cache.data);
int result = secp256k1_frost_partial_sign(
ctx,
&partial_sig,
&secnonce,
&agg_share,
&session,
&tweak_cache
);
CHECKRESULT(!result, "secp256k1_frost_partial_sign failed");
jpsig = (*penv)->NewByteArray(penv, 32);
ptr = (*penv)->GetByteArrayElements(penv, jpsig, 0);
result = secp256k1_frost_partial_sig_serialize(ctx, (unsigned char *)ptr, &partial_sig);
CHECKRESULT(!result, "secp256k1_frost_partial_sig_serialize failed");
return jpsig;
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_partial_sig_verify
* Signature: (J[B[B[B[B[B)I
*/
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1partial_1sig_1verify
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpartial_sig, jbyteArray jpubnonce, jbyteArray jpubshare, jbyteArray jsession, jbyteArray jtweak_cache)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
secp256k1_frost_partial_sig partial_sig;
secp256k1_frost_pubnonce pubnonce;
secp256k1_pubkey pubshare;
secp256k1_frost_session session;
secp256k1_frost_tweak_cache tweak_cache;
jbyte *ptr, *pubkeyBytes;
ptr = (*penv)->GetByteArrayElements(penv, jpartial_sig, 0);
result = secp256k1_frost_partial_sig_parse(ctx, &partial_sig, ptr);
(*penv)->ReleaseByteArrayElements(penv, jpartial_sig, ptr, 0);
CHECKRESULT(!result, "secp256k1_frost_partial_sig_parse failed");
ptr = (*penv)->GetByteArrayElements(penv, jpubnonce, 0);
result = secp256k1_frost_pubnonce_parse(ctx, &pubnonce, ptr);
(*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");
pubkeyBytes = (*penv)->GetByteArrayElements(penv, jpubshare, 0);
result = secp256k1_ec_pubkey_parse(ctx, &pubshare, (unsigned char *)pubkeyBytes, size);
(*penv)->ReleaseByteArrayElements(penv, jpubshare, pubkeyBytes, 0);
CHECKRESULT(!result, "secp256k1_ec_pubkey_parse failed");
size = (*penv)->GetArrayLength(penv, jsession);
CHECKRESULT(size != sizeof(secp256k1_frost_session), "invalid session size");
copy_bytes_from_java(penv, jsession, size, session.data);
size = (*penv)->GetArrayLength(penv, jtweak_cache);
CHECKRESULT(size != sizeof(secp256k1_frost_tweak_cache), "invalid tweak_cache size");
copy_bytes_from_java(penv, jtweak_cache, size, tweak_cache.data);
int result = secp256k1_frost_partial_sig_verify(
ctx,
&partial_sig,
&pubnonce,
&pubshare,
&session,
&tweak_cache
);
return result;
}
void free_partial_sigs(secp256k1_frost_partial_sig **psigs, size_t count)
{
size_t i;
for (i = 0; i < count; i++)
{
if (psigs[i] != NULL)
free(psigs[i]);
}
free(psigs);
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_partial_sig_agg
* Signature: (J[B[[BI)[B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1partial_1sig_1agg
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jsession, jobjectArray jpartial_sigs, jint jn_sigs)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
unsigned char sig64[64];
secp256k1_frost_session session;
secp256k1_frost_partial_sig **psigs;
jbyteArray jpsig;
jbyte *ptr;
size_t size, count;
size_t i;
int result = 0;
if (jctx == 0)
return NULL;
if (jsession == NULL)
return NULL;
size = (*penv)->GetArrayLength(penv, jsession);
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);
CHECKRESULT(count <= 0, "partial sigs count cannot be 0");
psigs = calloc(count, sizeof(secp256k1_frost_partial_sig *));
for (i = 0; i < count; i++)
{
psigs[i] = calloc(1, sizeof(secp256k1_frost_partial_sig));
jpsig = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jpsigs, i);
size = (*penv)->GetArrayLength(penv, jpsig);
CHECKRESULT1(size != 32, "invalid partial signature size", free_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));
}
result = secp256k1_frost_partial_sig_agg(
ctx,
sig64,
&session,
(const secp256k1_frost_partial_sig *const *)psigs,
jn_sigs
);
free_partial_sigs(psigs, count);
CHECKRESULT(!result, "secp256k1_frost_partial_sig_agg failed");
jpsig = (*penv)->NewByteArray(penv, 64);
copy_bytes_to_java(penv, jpsig, 64, sig64);
return jpsig;
}