JNI implementations

This commit is contained in:
kngako 2024-08-11 03:43:30 +02:00
parent 5c4186770f
commit b439181376

View File

@ -1343,18 +1343,40 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
* Method: secp256k1_frost_shares_gen
* Signature: (J[B[BII[[B)[[[B
*/
JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1shares_1gen(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseed32, jint jthreshold, jint n_participants, jobjectArray jids33)
JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1shares_1gen(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseed32, jint jthreshold, jint jn_participants, jobjectArray jids33)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
// This is what gets returned
secp256k1_frost_share shares[n_participants];
secp256k1_pubkey vss_commitment[n_participants];
secp256k1_frost_share shares[jn_participants];
secp256k1_pubkey vss_commitment[jthreshold];
unsigned char pok64[64];
// This is what gets passed
unsigned char seed32[32];
size_t size;
const unsigned char *ids[n_participants];
// This is what gets passed
jbyte *pubkeyBytes;
unsigned char seed32[32];
if (jseed32 != NULL)
{
size = (*penv)->GetArrayLength(penv, jseed32);
CHECKRESULT(size != 32, "invalid seed32 size");
copy_bytes_from_java(penv, jseed32, size, seed32);
}
const jbyte *ids33[jn_participants];
// Copy over data from jids33
if (jids33 != NULL)
{
size = (*penv)->GetArrayLength(penv, jids33);
CHECKRESULT(size != jn_participants, "invalid ids33 size");
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);
}
}
int result = 0;
@ -1362,25 +1384,271 @@ JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp2
ctx,
shares,
vss_commitment,
jpok64,
jseed32,
pok64,
seed32,
jthreshold,
n_participants,
jids33
jn_participants,
ids33
);
(*penv)->ReleaseByteArrayElements(penv, jseed32, seed32, 0);
CHECKRESULT(!result, "secp256k1_frost_shares_gen failed");
jobjectArray output = (*penv)->NewObjectArray(penv, 3, jbyteArray, NULL);
jbyte* jpok64;
jnonce = (*penv)->NewByteArray(penv, sizeof(shares));
nonce_ptr = (*penv)->GetByteArrayElements(penv, jnonce, 0);
memcpy(nonce_ptr, nonce, sizeof(nonce));
(*penv)->ReleaseByteArrayElements(penv, jnonce, nonce_ptr, 0);
jobjectArray output = (*penv)->NewObjectArray(penv, 3, jobjectArray, NULL);
output[0];
output[1];
output[2];
output[0] = (*penv)->NewObjectArray(penv, jn_participants, jbyteArray, NULL);
output[1] = (*penv)->NewObjectArray(penv, jthreshold, jbyteArray, NULL);
output[2] = (*penv)->NewObjectArray(penv, 1, jbyteArray, NULL);
// TODO: Copy over the required data...
return output;
}
void free_shares(secp256k1_frost_share **shares, size_t count)
{
size_t i;
for (i = 0; i < count; i++)
{
if (shares[i] != NULL)
free(shares[i]);
}
free(shares);
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_share_agg
* Signature: (J[[B[[[BII[B)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1share_1agg
(JNIEnv *penv, jclass clazz, jlong jctx, jobjectArray jshares, jobjectArray jvss_commitments, jint jtotalShareCount, jint jthreshold, jbyteArray jid33)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
secp256k1_frost_share aggregate_share;
jbyteArray jaggregate_share;
secp256k1_xonly_pubkey aggregate_public_key;
jbyteArray jaggregate_public_key;
const secp256k1_frost_share **shares;
jbyteArray jshare;
jbyte *in32;
secp256k1_xonly_pubkey **vss_commitments;
jbyteArray jvss_commitment;
jbyte *pub;
jbyte *id33;
size_t size, count;
count = (*penv)->GetArrayLength(penv, jnonces);
CHECKRESULT(count != jtotalShareCount, "jshares count should be total share count.");
shares = calloc(count, sizeof(secp256k1_frost_share*));
for (i = 0; i < count; i++)
{
shares[i] = calloc(1, sizeof(secp256k1_frost_share));
jshare = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jshares, i);
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, shares[i], (unsigned char *)in32);
(*penv)->ReleaseByteArrayElements(penv, jshare, in32, 0);
CHECKRESULT1(!result, "secp256k1_frost_share_parse failed", free_shares(shares, count));
}
count = (*penv)->GetArrayLength(penv, jvss_commitments);
vss_commitments = calloc(count, sizeof(secp256k1_pubkey *));
for (i = 0; i < count; i++)
{
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));
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);
CHECKRESULT1(!result, "secp256k1_ec_pubkey_parse failed", free_pubkeys(vss_commitments, count));
}
id33 = (*penv)->GetByteArrayElements(penv, jid33, 0);
int result = 0;
result = secp256k1_frost_share_agg(
ctx,
&aggregate_share,
&aggregate_public_key,
shares,
vss_commitments,
jtotalShareCount,
jthreshold,
(unsigned char *)id33
);
jobjectArray output = (*penv)->NewObjectArray(penv, 2, jbyteArray, NULL);
jaggregate_share = (*penv)->NewByteArray(penv, 64);
copy_bytes_to_java(penv, jaggregate_share, 64, aggregate_share);
output[0] = (*penv)->NewByteArray(penv, 32);
pub = (*penv)->GetByteArrayElements(penv, output[0], 0);
result = secp256k1_frost_share_serialize(ctx, (unsigned char *)pub, &aggregate_share);
(*penv)->ReleaseByteArrayElements(penv, output[0], pub, 0);
CHECKRESULT(!result, "secp256k1_frost_share_serialize failed");
output[1] = (*penv)->NewByteArray(penv, 32);
pub = (*penv)->GetByteArrayElements(penv, output[1], 0);
result = secp256k1_xonly_pubkey_serialize(ctx, (unsigned char *)pub, &aggregate_public_key);
(*penv)->ReleaseByteArrayElements(penv, output[1], pub, 0);
CHECKRESULT(!result, "secp256k1_xonly_pubkey_serialize failed");
return output;
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_share_verify
* Signature: (JI[B[B[[B)I
*/
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1share_1verify
(JNIEnv *penv, jclass clazz, jlong jctx, jint jthreshold, jbyteArray jid33, jbyteArray jshare, jobjectArray jvss_commitment)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
secp256k1_frost_share share;
jbyte *in32;
jbyte *id33;
secp256k1_xonly_pubkey *vss_commitment;
jbyte *jpub;
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));
id33 = (*penv)->GetByteArrayElements(penv, jid33, 0);
vss_commitment = calloc(1, sizeof(secp256k1_pubkey));
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));
int result = secp256k1_frost_share_verify(
ctx,
jthreshold,
(unsigned char *)id33,
share,
vss_commitment
);
return result;
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_compute_pubshare
* Signature: (JI[B[[[BI)[B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1compute_1pubshare
(JNIEnv *penv, jclass clazz, jlong jctx, jint jthreshold, jbyteArray jid33, jobjectArray jvss_commitments, jint jtotalSignersCount)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
secp256k1_pubkey pubshare;
jbyte *id33;
secp256k1_xonly_pubkey **vss_commitments;
jbyteArray jvss_commitment;
jbyte *jpubkey;
id33 = (*penv)->GetByteArrayElements(penv, jid33, 0);
count = (*penv)->GetArrayLength(penv, jvss_commitments);
vss_commitments = calloc(count, sizeof(secp256k1_pubkey *));
for (i = 0; i < count; i++)
{
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));
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);
CHECKRESULT1(!result, "secp256k1_ec_pubkey_parse failed", free_pubkeys(vss_commitments, count));
}
int result = secp256k1_frost_compute_pubshare(
ctx,
&pubshare,
jthreshold,
(unsigned char *)id33
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);
CHECKRESULT(!result, "secp256k1_ec_pubkey_serialize failed");
return jpubkey;
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_pubkey_tweak
* Signature: (J[B)[B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1pubkey_1tweak
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpublicKey)
{
secp256k1_context *ctx = (secp256k1_context *)jctx;
secp256k1_frost_tweak_cache tweak_cache;
secp256k1_xonly_pubkey public_key;
jbyte *pub;
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");
int result = secp256k1_frost_pubkey_tweak(
ctx,
&tweak_cache,
&public_key
);
// TODO: Return jbyte of the tweak_cache
}
/*
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
* Method: secp256k1_frost_pubkey_ec_tweak_add
* 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)
{
// TODO: Implement secp256k1_frost_pubkey_ec_tweak_add
}