2020-07-02 17:52:21 +02:00
# include <string.h>
# include <stdlib.h>
2023-09-18 14:05:36 +02:00
# ifdef WIN32
# define SECP256K1_STATIC // needed on windows when linking to a static version of secp256k1
# endif
2020-07-02 17:52:21 +02:00
# include "include/secp256k1.h"
# include "include/secp256k1_ecdh.h"
# include "include/secp256k1_recovery.h"
2021-11-23 17:38:46 +01:00
# include "include/secp256k1_schnorrsig.h"
2024-02-14 13:28:22 +01:00
# include "include/secp256k1_musig.h"
2024-08-04 23:53:28 +02:00
# include "include/secp256k1_frost.h"
2020-07-02 17:52:21 +02:00
# include "fr_acinq_secp256k1_Secp256k1CFunctions.h"
# define SIG_FORMAT_UNKNOWN 0
# define SIG_FORMAT_COMPACT 1
# define SIG_FORMAT_DER 2
2024-02-14 13:28:22 +01:00
void JNI_ThrowByName ( JNIEnv * penv , const char * name , const char * msg )
{
jclass cls = ( * penv ) - > FindClass ( penv , name ) ;
if ( cls ! = NULL )
{
( * penv ) - > ThrowNew ( penv , cls , msg ) ;
( * penv ) - > DeleteLocalRef ( penv , cls ) ;
}
2020-07-02 17:52:21 +02:00
}
2024-02-14 13:28:22 +01:00
# define CHECKRESULT(errorcheck, message) \
{ \
if ( errorcheck ) \
{ \
JNI_ThrowByName ( penv , " fr/acinq/secp256k1/Secp256k1Exception " , message ) ; \
return 0 ; \
} \
}
# define CHECKRESULT1(errorcheck, message, dosomething) \
{ \
if ( errorcheck ) \
{ \
dosomething ; \
JNI_ThrowByName ( penv , " fr/acinq/secp256k1/Secp256k1Exception " , message ) ; \
return 0 ; \
} \
}
2020-07-02 17:52:21 +02:00
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_context_create
* Signature : ( I ) J
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jlong JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1context_1create ( JNIEnv * penv , jclass clazz , jint flags )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
return ( jlong ) secp256k1_context_create ( flags ) ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_context_destroy
* Signature : ( J ) V
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT void JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1context_1destroy ( JNIEnv * penv , jclass clazz , jlong ctx )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
if ( ctx ! = 0 )
{
secp256k1_context_destroy ( ( secp256k1_context * ) ctx ) ;
}
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_ec_seckey_verify
* Signature : ( J [ B ) I
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1seckey_1verify ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jseckey )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * seckey ;
int result = 0 ;
if ( jctx = = 0 )
return 0 ;
if ( jseckey = = NULL )
return 0 ;
if ( ( * penv ) - > GetArrayLength ( penv , jseckey ) ! = 32 )
return 0 ;
seckey = ( * penv ) - > GetByteArrayElements ( penv , jseckey , 0 ) ;
result = secp256k1_ec_seckey_verify ( ctx , ( unsigned char * ) seckey ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jseckey , seckey , 0 ) ;
return result ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ec_pubkey_parse
* Signature : ( J [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1parse ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jpubkey )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * pubkeyBytes ;
secp256k1_pubkey pubkey ;
size_t size ;
int result = 0 ;
if ( jctx = = 0 )
return 0 ;
if ( jpubkey = = NULL )
return 0 ;
size = ( * penv ) - > GetArrayLength ( penv , jpubkey ) ;
CHECKRESULT ( ( size ! = 33 ) & & ( size ! = 65 ) , " invalid public key size " ) ;
pubkeyBytes = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & pubkey , ( unsigned char * ) pubkeyBytes , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pubkeyBytes , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_parse failed " ) ;
size = 65 ;
jpubkey = ( * penv ) - > NewByteArray ( penv , 65 ) ;
pubkeyBytes = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_serialize ( ctx , ( unsigned char * ) pubkeyBytes , & size , & pubkey , SECP256K1_EC_UNCOMPRESSED ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pubkeyBytes , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_serialize failed " ) ;
return jpubkey ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ec_pubkey_create
* Signature : ( J [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1create ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jseckey )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * seckey , * pubkey ;
secp256k1_pubkey pub ;
int result = 0 ;
size_t len ;
jbyteArray jpubkey = 0 ;
if ( jseckey = = NULL )
return NULL ;
if ( jctx = = 0 )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jseckey ) ! = 32 , " secret key must be 32 bytes " ) ;
seckey = ( * penv ) - > GetByteArrayElements ( penv , jseckey , 0 ) ;
result = secp256k1_ec_pubkey_create ( ctx , & pub , ( unsigned char * ) seckey ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jseckey , seckey , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_create failed " ) ;
jpubkey = ( * penv ) - > NewByteArray ( penv , 65 ) ;
pubkey = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
len = 65 ;
result = secp256k1_ec_pubkey_serialize ( ctx , ( unsigned char * ) pubkey , & len , & pub , SECP256K1_EC_UNCOMPRESSED ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pubkey , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_serialize failed " ) ;
return jpubkey ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ecdsa_sign
* Signature : ( J [ B [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdsa_1sign ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jmsg , jbyteArray jseckey )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * seckey , * msg , * sig ;
secp256k1_ecdsa_signature signature ;
int result = 0 ;
jbyteArray jsig ;
if ( jctx = = 0 )
return NULL ;
if ( jmsg = = NULL )
return NULL ;
if ( jseckey = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jseckey ) ! = 32 , " secret key must be 32 bytes " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jmsg ) ! = 32 , " message key must be 32 bytes " ) ;
seckey = ( * penv ) - > GetByteArrayElements ( penv , jseckey , 0 ) ;
msg = ( * penv ) - > GetByteArrayElements ( penv , jmsg , 0 ) ;
result = secp256k1_ecdsa_sign ( ctx , & signature , ( unsigned char * ) msg , ( unsigned char * ) seckey , NULL , NULL ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jseckey , seckey , 0 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jmsg , msg , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_sign failed " ) ;
jsig = ( * penv ) - > NewByteArray ( penv , 64 ) ;
sig = ( * penv ) - > GetByteArrayElements ( penv , jsig , 0 ) ;
result = secp256k1_ecdsa_signature_serialize_compact ( ctx , ( unsigned char * ) sig , & signature ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsig , sig , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_serialize_compact failed " ) ;
return jsig ;
2020-07-02 17:52:21 +02:00
}
int GetSignatureFormat ( size_t size )
{
2024-02-14 13:28:22 +01:00
if ( size = = 64 )
return SIG_FORMAT_COMPACT ;
if ( size < 64 )
return SIG_FORMAT_UNKNOWN ;
return SIG_FORMAT_DER ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ecdsa_verify
* Signature : ( J [ B [ B [ B ) I
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdsa_1verify ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jsig , jbyteArray jmsg , jbyteArray jpubkey )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * pub , * msg , * sig ;
secp256k1_ecdsa_signature signature ;
secp256k1_pubkey pubkey ;
size_t sigSize , pubSize ;
int result = 0 ;
if ( jctx = = 0 )
return 0 ;
if ( jsig = = NULL )
return 0 ;
if ( jmsg = = NULL )
return 0 ;
if ( jpubkey = = NULL )
return 0 ;
sigSize = ( * penv ) - > GetArrayLength ( penv , jsig ) ;
int sigFormat = GetSignatureFormat ( sigSize ) ;
CHECKRESULT ( sigFormat = = SIG_FORMAT_UNKNOWN , " invalid signature size " ) ;
pubSize = ( * penv ) - > GetArrayLength ( penv , jpubkey ) ;
CHECKRESULT ( ( pubSize ! = 33 ) & & ( pubSize ! = 65 ) , " invalid public key size " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jmsg ) ! = 32 , " message must be 32 bytes " ) ;
sig = ( * penv ) - > GetByteArrayElements ( penv , jsig , 0 ) ;
switch ( sigFormat )
{
case SIG_FORMAT_COMPACT :
result = secp256k1_ecdsa_signature_parse_compact ( ctx , & signature , ( unsigned char * ) sig ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsig , sig , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_parse_compact failed " ) ;
break ;
case SIG_FORMAT_DER :
result = secp256k1_ecdsa_signature_parse_der ( ctx , & signature , ( unsigned char * ) sig , sigSize ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsig , sig , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_parse_der failed " ) ;
break ;
}
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & pubkey , ( unsigned char * ) pub , pubSize ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_parse failed " ) ;
msg = ( * penv ) - > GetByteArrayElements ( penv , jmsg , 0 ) ;
result = secp256k1_ecdsa_verify ( ctx , & signature , ( unsigned char * ) msg , & pubkey ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jmsg , msg , 0 ) ;
return result ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ecdsa_signature_normalize
* Signature : ( J [ B [ B ) I
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdsa_1signature_1normalize ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jsigin , jbyteArray jsigout )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * sig ;
secp256k1_ecdsa_signature signature_in , signature_out ;
size_t size ;
int result = 0 ;
int return_value = 0 ;
int sigFormat = SIG_FORMAT_UNKNOWN ;
if ( jctx = = 0 )
return 0 ;
if ( jsigin = = NULL )
return 0 ;
if ( jsigout = = NULL )
return 0 ;
size = ( * penv ) - > GetArrayLength ( penv , jsigin ) ;
sigFormat = GetSignatureFormat ( size ) ;
CHECKRESULT ( sigFormat = = SIG_FORMAT_UNKNOWN , " invalid signature size " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jsigout ) ! = 64 , " output signature length must be 64 bytes " ) ;
sig = ( * penv ) - > GetByteArrayElements ( penv , jsigin , 0 ) ;
switch ( sigFormat )
{
case SIG_FORMAT_COMPACT :
result = secp256k1_ecdsa_signature_parse_compact ( ctx , & signature_in , ( unsigned char * ) sig ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsigin , sig , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_parse_compact failed " ) ;
break ;
case SIG_FORMAT_DER :
result = secp256k1_ecdsa_signature_parse_der ( ctx , & signature_in , ( unsigned char * ) sig , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsigin , sig , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_parse_der failed " ) ;
break ;
}
return_value = secp256k1_ecdsa_signature_normalize ( ctx , & signature_out , & signature_in ) ;
sig = ( * penv ) - > GetByteArrayElements ( penv , jsigout , 0 ) ;
result = secp256k1_ecdsa_signature_serialize_compact ( ctx , ( unsigned char * ) sig , & signature_out ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsigout , sig , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_serialize_compact failed " ) ;
return return_value ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ec_privkey_negate
* Signature : ( J [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1privkey_1negate ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jseckey )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * seckey ;
int result = 0 ;
if ( jctx = = 0 )
return 0 ;
if ( jseckey = = NULL )
return 0 ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jseckey ) ! = 32 , " secret key must be 32 bytes " ) ;
seckey = ( * penv ) - > GetByteArrayElements ( penv , jseckey , 0 ) ;
result = secp256k1_ec_seckey_negate ( ctx , ( unsigned char * ) seckey ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jseckey , seckey , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_seckey_negate failed " ) ;
return jseckey ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ec_pubkey_negate
* Signature : ( J [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1negate ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jpubkey )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * pub ;
secp256k1_pubkey pubkey ;
size_t size ;
int result = 0 ;
if ( jctx = = 0 )
return 0 ;
if ( jpubkey = = NULL )
return 0 ;
size = ( * penv ) - > GetArrayLength ( penv , jpubkey ) ;
CHECKRESULT ( ( size ! = 33 ) & & ( size ! = 65 ) , " invalid public key size " ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & pubkey , ( unsigned char * ) pub , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_parse failed " ) ;
result = secp256k1_ec_pubkey_negate ( ctx , & pubkey ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_negate failed " ) ;
size = 65 ;
jpubkey = ( * penv ) - > NewByteArray ( penv , 65 ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_serialize ( ctx , ( unsigned char * ) pub , & size , & pubkey , SECP256K1_EC_UNCOMPRESSED ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_serialize failed " ) ;
return jpubkey ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ec_privkey_tweak_add
* Signature : ( J [ B [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1privkey_1tweak_1add ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jseckey , jbyteArray jtweak )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * seckey , * tweak ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jseckey = = NULL )
return NULL ;
if ( jtweak = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jseckey ) ! = 32 , " secret key must be 32 bytes " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jtweak ) ! = 32 , " tweak must be 32 bytes " ) ;
seckey = ( * penv ) - > GetByteArrayElements ( penv , jseckey , 0 ) ;
tweak = ( * penv ) - > GetByteArrayElements ( penv , jtweak , 0 ) ;
result = secp256k1_ec_seckey_tweak_add ( ctx , ( unsigned char * ) seckey , ( unsigned char * ) tweak ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jseckey , seckey , 0 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jtweak , tweak , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_seckey_tweak_add failed " ) ;
return jseckey ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ec_pubkey_tweak_add
* Signature : ( J [ B [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1tweak_1add ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jpubkey , jbyteArray jtweak )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * pub , * tweak ;
secp256k1_pubkey pubkey ;
size_t size ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jpubkey = = NULL )
return NULL ;
if ( jtweak = = NULL )
return NULL ;
size = ( * penv ) - > GetArrayLength ( penv , jpubkey ) ;
CHECKRESULT ( ( size ! = 33 ) & & ( size ! = 65 ) , " invalid public key size " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jtweak ) ! = 32 , " tweak must be 32 bytes " ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & pubkey , ( unsigned char * ) pub , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_parse failed " ) ;
tweak = ( * penv ) - > GetByteArrayElements ( penv , jtweak , 0 ) ;
result = secp256k1_ec_pubkey_tweak_add ( ctx , & pubkey , ( unsigned char * ) tweak ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jtweak , tweak , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_tweak_add failed " ) ;
size = 65 ;
jpubkey = ( * penv ) - > NewByteArray ( penv , 65 ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_serialize ( ctx , ( unsigned char * ) pub , & size , & pubkey , SECP256K1_EC_UNCOMPRESSED ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_serialize failed " ) ;
return jpubkey ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ec_privkey_tweak_mul
* Signature : ( J [ B [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1privkey_1tweak_1mul ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jseckey , jbyteArray jtweak )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * seckey , * tweak ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jseckey = = NULL )
return NULL ;
if ( jtweak = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jseckey ) ! = 32 , " secret key must be 32 bytes " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jtweak ) ! = 32 , " tweak must be 32 bytes " ) ;
seckey = ( * penv ) - > GetByteArrayElements ( penv , jseckey , 0 ) ;
tweak = ( * penv ) - > GetByteArrayElements ( penv , jtweak , 0 ) ;
result = secp256k1_ec_seckey_tweak_mul ( ctx , ( unsigned char * ) seckey , ( unsigned char * ) tweak ) ;
CHECKRESULT ( ! result , " secp256k1_ec_seckey_tweak_mul failed " ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jseckey , seckey , 0 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jtweak , tweak , 0 ) ;
return jseckey ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ec_pubkey_tweak_mul
* Signature : ( J [ B [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1tweak_1mul ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jpubkey , jbyteArray jtweak )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * pub , * tweak ;
secp256k1_pubkey pubkey ;
size_t size ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jpubkey = = NULL )
return NULL ;
if ( jtweak = = NULL )
return NULL ;
size = ( * penv ) - > GetArrayLength ( penv , jpubkey ) ;
CHECKRESULT ( ( size ! = 33 ) & & ( size ! = 65 ) , " invalid public key size " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jtweak ) ! = 32 , " tweak must be 32 bytes " ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & pubkey , ( unsigned char * ) pub , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_parse failed " ) ;
tweak = ( * penv ) - > GetByteArrayElements ( penv , jtweak , 0 ) ;
result = secp256k1_ec_pubkey_tweak_mul ( ctx , & pubkey , ( unsigned char * ) tweak ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jtweak , tweak , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_tweak_mul failed " ) ;
size = 65 ;
jpubkey = ( * penv ) - > NewByteArray ( penv , 65 ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_serialize ( ctx , ( unsigned char * ) pub , & size , & pubkey , SECP256K1_EC_UNCOMPRESSED ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_serialize failed " ) ;
return jpubkey ;
2020-07-02 17:52:21 +02:00
}
void free_pubkeys ( secp256k1_pubkey * * pubkeys , size_t count )
{
2024-02-14 13:28:22 +01:00
size_t i ;
for ( i = 0 ; i < count ; i + + )
{
if ( pubkeys [ i ] ! = NULL )
free ( pubkeys [ i ] ) ;
}
free ( pubkeys ) ;
2020-07-02 17:52:21 +02:00
}
2024-08-19 21:40:56 +02:00
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 ) ;
}
2020-07-02 17:52:21 +02:00
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ec_pubkey_combine
* Signature : ( J [ [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1combine ( JNIEnv * penv , jclass clazz , jlong jctx , jobjectArray jpubkeys )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * pub ;
secp256k1_pubkey * * pubkeys ;
secp256k1_pubkey combined ;
jbyteArray jpubkey ;
size_t size , count ;
size_t i ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jpubkeys = = NULL )
return NULL ;
2020-07-02 17:52:21 +02:00
count = ( * penv ) - > GetArrayLength ( penv , jpubkeys ) ;
2023-12-13 13:42:14 +01:00
CHECKRESULT ( count < 1 , " pubkey array cannot be empty " )
2024-02-14 13:28:22 +01:00
pubkeys = calloc ( count , sizeof ( secp256k1_pubkey * ) ) ;
for ( i = 0 ; i < count ; i + + )
{
pubkeys [ i ] = calloc ( 1 , sizeof ( secp256k1_pubkey ) ) ;
jpubkey = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jpubkeys , i ) ;
size = ( * penv ) - > GetArrayLength ( penv , jpubkey ) ;
CHECKRESULT1 ( ( size ! = 33 ) & & ( size ! = 65 ) , " invalid public key size " , free_pubkeys ( pubkeys , count ) ) ;
2020-07-02 17:52:21 +02:00
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
2024-02-14 13:28:22 +01:00
result = secp256k1_ec_pubkey_parse ( ctx , pubkeys [ i ] , ( unsigned char * ) pub , size ) ;
2020-07-02 17:52:21 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
2024-02-14 13:28:22 +01:00
CHECKRESULT1 ( ! result , " secp256k1_ec_pubkey_parse failed " , free_pubkeys ( pubkeys , count ) ) ;
}
result = secp256k1_ec_pubkey_combine ( ctx , & combined , ( const secp256k1_pubkey * const * ) pubkeys , count ) ;
free_pubkeys ( pubkeys , count ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_combine failed " ) ;
size = 65 ;
jpubkey = ( * penv ) - > NewByteArray ( penv , 65 ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_serialize ( ctx , ( unsigned char * ) pub , & size , & combined , SECP256K1_EC_UNCOMPRESSED ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_serialize failed " ) ;
return jpubkey ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ecdh
* Signature : ( J [ B [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdh ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jseckey , jbyteArray jpubkey )
2020-07-02 17:52:21 +02:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * seckeyBytes , * pubkeyBytes , * output ;
secp256k1_pubkey pubkey ;
jbyteArray joutput ;
size_t size ;
int result ;
if ( jctx = = 0 )
return NULL ;
if ( jseckey = = NULL )
return NULL ;
if ( jpubkey = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jseckey ) ! = 32 , " invalid private key size " ) ;
size = ( * penv ) - > GetArrayLength ( penv , jpubkey ) ;
CHECKRESULT ( ( size ! = 33 ) & & ( size ! = 65 ) , " invalid public key size " ) ;
pubkeyBytes = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & pubkey , ( unsigned char * ) pubkeyBytes , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pubkeyBytes , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_parse failed " ) ;
seckeyBytes = ( * penv ) - > GetByteArrayElements ( penv , jseckey , 0 ) ;
joutput = ( * penv ) - > NewByteArray ( penv , 32 ) ;
output = ( * penv ) - > GetByteArrayElements ( penv , joutput , 0 ) ;
result = secp256k1_ecdh ( ctx , ( unsigned char * ) output , & pubkey , ( unsigned char * ) seckeyBytes , NULL , NULL ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , joutput , output , 0 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jseckey , seckeyBytes , 0 ) ;
return joutput ;
2020-07-02 17:52:21 +02:00
}
/*
* Class : fr_acinq_bitcoin_Secp256k1Bindings
* Method : secp256k1_ecdsa_recover
* Signature : ( J [ B [ BI ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdsa_1recover ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jsig , jbyteArray jmsg , jint recid )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * sig , * msg , * pub ;
jbyteArray jpubkey ;
secp256k1_pubkey pubkey ;
secp256k1_ecdsa_recoverable_signature signature ;
secp256k1_ecdsa_signature dummy ;
unsigned char dummyBytes [ 64 ] ;
size_t sigSize , size ;
int result ;
if ( jctx = = 0 )
return NULL ;
if ( jsig = = NULL )
return NULL ;
if ( jmsg = = NULL )
return NULL ;
CHECKRESULT ( recid < 0 | | recid > 3 , " invalid recovery id " ) ;
sigSize = ( * penv ) - > GetArrayLength ( penv , jsig ) ;
int sigFormat = GetSignatureFormat ( sigSize ) ;
CHECKRESULT ( sigFormat = = SIG_FORMAT_UNKNOWN , " invalid signature size " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jmsg ) ! = 32 , " message must be 32 bytes " ) ;
sig = ( * penv ) - > GetByteArrayElements ( penv , jsig , 0 ) ;
switch ( sigFormat )
{
case SIG_FORMAT_COMPACT :
result = secp256k1_ecdsa_recoverable_signature_parse_compact ( ctx , & signature , ( unsigned char * ) sig , recid ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsig , sig , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_recoverable_signature_parse_compact failed " ) ;
break ;
case SIG_FORMAT_DER :
result = secp256k1_ecdsa_signature_parse_der ( ctx , & dummy , ( unsigned char * ) sig , sigSize ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsig , sig , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_parse_der failed " ) ;
result = secp256k1_ecdsa_signature_serialize_compact ( ctx , dummyBytes , & dummy ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_serialize_compact failed " ) ;
result = secp256k1_ecdsa_recoverable_signature_parse_compact ( ctx , & signature , dummyBytes , recid ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_recoverable_signature_parse_compact failed " ) ;
break ;
}
msg = ( * penv ) - > GetByteArrayElements ( penv , jmsg , 0 ) ;
result = secp256k1_ecdsa_recover ( ctx , & pubkey , & signature , ( unsigned char * ) msg ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jmsg , msg , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_recover failed " ) ;
size = 65 ;
jpubkey = ( * penv ) - > NewByteArray ( penv , 65 ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_serialize ( ctx , ( unsigned char * ) pub , & size , & pubkey , SECP256K1_EC_UNCOMPRESSED ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_serialize failed " ) ;
return jpubkey ;
2020-07-02 17:52:21 +02:00
}
2020-07-02 21:39:33 +02:00
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_compact_to_der
* Signature : ( J [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1compact_1to_1der ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jsig )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * sig ;
secp256k1_ecdsa_signature signature ;
unsigned char der [ 73 ] ;
size_t size ;
int result = 0 ;
if ( jctx = = 0 )
return 0 ;
if ( jsig = = NULL )
return 0 ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jsig ) ! = 64 , " invalid signature size " ) ;
size = ( * penv ) - > GetArrayLength ( penv , jsig ) ;
sig = ( * penv ) - > GetByteArrayElements ( penv , jsig , 0 ) ;
result = secp256k1_ecdsa_signature_parse_compact ( ctx , & signature , ( unsigned char * ) sig ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsig , sig , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_parse_compact failed " ) ;
size = 73 ;
result = secp256k1_ecdsa_signature_serialize_der ( ctx , der , & size , & signature ) ;
CHECKRESULT ( ! result , " secp256k1_ecdsa_signature_serialize_der failed " ) ;
jsig = ( * penv ) - > NewByteArray ( penv , size ) ;
sig = ( * penv ) - > GetByteArrayElements ( penv , jsig , 0 ) ;
memcpy ( sig , der , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsig , sig , 0 ) ;
return jsig ;
2020-07-02 21:39:33 +02:00
}
2021-11-23 17:38:46 +01:00
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_schnorrsig_sign
* Signature : ( J [ B [ B [ B ) [ B
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1schnorrsig_1sign ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jmsg , jbyteArray jseckey , jbyteArray jauxrand32 )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * seckey , * msg , * sig , * auxrand32 = NULL ;
secp256k1_keypair keypair ;
unsigned char signature [ 64 ] ;
int result = 0 ;
jbyteArray jsig ;
if ( jctx = = 0 )
return NULL ;
if ( jmsg = = NULL )
return NULL ;
if ( jseckey = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jseckey ) ! = 32 , " secret key must be 32 bytes " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jmsg ) ! = 32 , " message must be 32 bytes " ) ;
if ( jauxrand32 ! = 0 )
{
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jauxrand32 ) ! = 32 , " auxiliary random data must be 32 bytes " ) ;
}
seckey = ( * penv ) - > GetByteArrayElements ( penv , jseckey , 0 ) ;
result = secp256k1_keypair_create ( ctx , & keypair , seckey ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jseckey , seckey , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_keypair_create failed " ) ;
msg = ( * penv ) - > GetByteArrayElements ( penv , jmsg , 0 ) ;
if ( jauxrand32 ! = 0 )
{
auxrand32 = ( * penv ) - > GetByteArrayElements ( penv , jauxrand32 , 0 ) ;
}
result = secp256k1_schnorrsig_sign32 ( ctx , signature , ( unsigned char * ) msg , & keypair , auxrand32 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jmsg , msg , 0 ) ;
if ( auxrand32 ! = 0 )
{
( * penv ) - > ReleaseByteArrayElements ( penv , jauxrand32 , auxrand32 , 0 ) ;
}
CHECKRESULT ( ! result , " secp256k1_schnorrsig_sign failed " ) ;
jsig = ( * penv ) - > NewByteArray ( penv , 64 ) ;
sig = ( * penv ) - > GetByteArrayElements ( penv , jsig , 0 ) ;
memcpy ( sig , signature , 64 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsig , sig , 0 ) ;
return jsig ;
2021-11-23 17:38:46 +01:00
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_schnorrsig_verify
* Signature : ( J [ B [ B [ B ) I
*/
2024-02-14 13:28:22 +01:00
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1schnorrsig_1verify ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jsig , jbyteArray jmsg , jbyteArray jpubkey )
2021-11-23 17:38:46 +01:00
{
2024-02-14 13:28:22 +01:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * pub , * msg , * sig ;
secp256k1_xonly_pubkey pubkey ;
int result = 0 ;
if ( jctx = = 0 )
return 0 ;
if ( jsig = = NULL )
return 0 ;
if ( jmsg = = NULL )
return 0 ;
if ( jpubkey = = NULL )
return 0 ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jsig ) ! = 64 , " signature must be 64 bytes " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jpubkey ) ! = 32 , " public key must be 32 bytes " ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jmsg ) ! = 32 , " message must be 32 bytes " ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_xonly_pubkey_parse ( ctx , & pubkey , ( unsigned char * ) pub ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
2024-08-19 21:40:56 +02:00
CHECKRESULT ( ! result , " secp256k1_xonly_pubkey_parse failed " ) ;
2024-02-14 13:28:22 +01:00
sig = ( * penv ) - > GetByteArrayElements ( penv , jsig , 0 ) ;
msg = ( * penv ) - > GetByteArrayElements ( penv , jmsg , 0 ) ;
result = secp256k1_schnorrsig_verify ( ctx , ( unsigned char * ) sig , ( unsigned char * ) msg , 32 , & pubkey ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jsig , sig , 0 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jmsg , msg , 0 ) ;
return result ;
}
2021-11-23 17:38:46 +01:00
2024-02-14 13:28:22 +01:00
static void copy_bytes_from_java ( JNIEnv * penv , jbyteArray source , size_t size , unsigned char * dest )
{
jbyte * ptr = NULL ;
if ( source = = NULL )
return ; // nothing to do
ptr = ( * penv ) - > GetByteArrayElements ( penv , source , 0 ) ;
memcpy ( dest , ptr , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , source , ptr , 0 ) ;
}
2021-11-23 17:38:46 +01:00
2024-02-14 13:28:22 +01:00
static void copy_bytes_to_java ( JNIEnv * penv , jbyteArray dest , size_t size , unsigned char * source )
{
jbyte * ptr = ( * penv ) - > GetByteArrayElements ( penv , dest , 0 ) ;
memcpy ( ptr , source , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , dest , ptr , 0 ) ;
}
2021-11-23 17:38:46 +01:00
2024-02-14 13:28:22 +01:00
// session_id32: ByteArray, seckey: ByteArray?, pubkey: ByteArray, msg32: ByteArray?, keyagg_cache: ByteArray?, extra_input32: ByteArray?
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_musig_nonce_gen
* Signature : ( J [ B [ B [ B [ B [ B [ B ) [ B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1nonce_1gen ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jsession_id32 , jbyteArray jseckey , jbyteArray jpubkey , jbyteArray jmsg32 , jbyteArray jkeyaggcache , jbyteArray jextra_input32 )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
int result = 0 ;
size_t size ;
secp256k1_musig_pubnonce pubnonce ;
secp256k1_musig_secnonce secnonce ;
unsigned char session_id32 [ 32 ] ;
jbyte * pubkey_ptr ;
secp256k1_pubkey pubkey ;
unsigned char seckey [ 32 ] ;
unsigned char msg32 [ 32 ] ;
secp256k1_musig_keyagg_cache keyaggcache ;
unsigned char extra_input32 [ 32 ] ;
jbyteArray jnonce ;
jbyte * nonce_ptr = NULL ;
unsigned char nonce [ fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SECRET_NONCE_SIZE + fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE ] ;
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 ( jseckey ! = NULL )
{
size = ( * penv ) - > GetArrayLength ( penv , jseckey ) ;
CHECKRESULT ( size ! = 32 , " invalid private key size " ) ;
copy_bytes_from_java ( penv , jseckey , size , seckey ) ;
}
if ( jpubkey = = NULL )
return 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 ( jmsg32 ! = NULL )
{
size = ( * penv ) - > GetArrayLength ( penv , jmsg32 ) ;
CHECKRESULT ( size ! = 32 , " invalid message size " ) ;
copy_bytes_from_java ( penv , jmsg32 , size , msg32 ) ;
}
if ( jkeyaggcache ! = NULL )
{
size = ( * penv ) - > GetArrayLength ( penv , jkeyaggcache ) ;
CHECKRESULT ( size ! = sizeof ( secp256k1_musig_keyagg_cache ) , " invalid keyagg cache size " ) ;
copy_bytes_from_java ( penv , jkeyaggcache , size , keyaggcache . data ) ;
}
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_musig_nonce_gen ( ctx , & secnonce , & pubnonce , session_id32 ,
jseckey = = NULL ? NULL : seckey , & pubkey ,
jmsg32 = = NULL ? NULL : msg32 , jkeyaggcache = = NULL ? NULL : & keyaggcache , jextra_input32 = = NULL ? NULL : extra_input32 ) ;
CHECKRESULT ( ! result , " secp256k1_musig_nonce_gen failed " ) ;
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 ;
}
void free_nonces ( secp256k1_musig_pubnonce * * nonces , size_t count )
{
size_t i ;
for ( i = 0 ; i < count ; i + + )
{
if ( nonces [ i ] ! = NULL )
free ( nonces [ i ] ) ;
}
free ( nonces ) ;
}
2024-08-19 21:40:56 +02:00
void free_frost_nonces ( secp256k1_frost_pubnonce * * nonces , size_t count )
2024-08-12 02:55:41 +02:00
{
size_t i ;
for ( i = 0 ; i < count ; i + + )
{
if ( nonces [ i ] ! = NULL )
free ( nonces [ i ] ) ;
}
free ( nonces ) ;
}
2024-02-14 13:28:22 +01:00
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_musig_nonce_agg
* Signature : ( J [ [ B ) [ B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1nonce_1agg ( JNIEnv * penv , jclass clazz , jlong jctx , jobjectArray jnonces )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * in66 ;
secp256k1_musig_pubnonce * * pubnonces ;
secp256k1_musig_aggnonce combined ;
jbyteArray jnonce ;
size_t size , count ;
size_t i ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jnonces = = NULL )
return NULL ;
count = ( * penv ) - > GetArrayLength ( penv , jnonces ) ;
CHECKRESULT ( count < = 0 , " public nonces count cannot be 0 " ) ;
pubnonces = calloc ( count , sizeof ( secp256k1_musig_pubnonce * ) ) ;
for ( i = 0 ; i < count ; i + + )
{
pubnonces [ i ] = calloc ( 1 , sizeof ( secp256k1_musig_pubnonce ) ) ;
jnonce = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jnonces , 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 ) ;
result = secp256k1_musig_pubnonce_parse ( ctx , pubnonces [ i ] , ( unsigned char * ) in66 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jnonce , in66 , 0 ) ;
CHECKRESULT1 ( ! result , " secp256k1_musig_pubnonce_parse failed " , free_nonces ( pubnonces , count ) ) ;
}
result = secp256k1_musig_nonce_agg ( ctx , & combined , ( const secp256k1_musig_pubnonce * const * ) pubnonces , count ) ;
free_nonces ( pubnonces , count ) ;
CHECKRESULT ( ! result , " secp256k1_musig_nonce_agg failed " ) ;
jnonce = ( * penv ) - > NewByteArray ( penv , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE ) ;
in66 = ( * penv ) - > GetByteArrayElements ( penv , jnonce , 0 ) ;
result = secp256k1_musig_aggnonce_serialize ( ctx , ( unsigned char * ) in66 , & combined ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jnonce , in66 , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_musig_aggnonce_serialize failed " ) ;
return jnonce ;
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_musig_pubkey_agg
* Signature : ( J [ [ B [ B ) [ B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1pubkey_1agg ( JNIEnv * penv , jclass clazz , jlong jctx , jobjectArray jpubkeys , jbyteArray jkeyaggcache )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * pub ;
secp256k1_pubkey * * pubkeys ;
secp256k1_xonly_pubkey combined ;
secp256k1_musig_keyagg_cache keyaggcache ;
jbyteArray jpubkey ;
size_t size , count ;
size_t i ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jpubkeys = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jpubkeys ) < = 0 , " pubkeys count cannot be 0 " ) ;
if ( jkeyaggcache ! = NULL )
{
size = ( * penv ) - > GetArrayLength ( penv , jkeyaggcache ) ;
CHECKRESULT ( size ! = sizeof ( secp256k1_musig_keyagg_cache ) , " invalid keyagg cache size " ) ;
copy_bytes_from_java ( penv , jkeyaggcache , size , keyaggcache . data ) ;
}
count = ( * penv ) - > GetArrayLength ( penv , jpubkeys ) ;
pubkeys = calloc ( count , sizeof ( secp256k1_pubkey * ) ) ;
for ( i = 0 ; i < count ; i + + )
{
pubkeys [ i ] = calloc ( 1 , sizeof ( secp256k1_pubkey ) ) ;
jpubkey = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jpubkeys , i ) ;
size = ( * penv ) - > GetArrayLength ( penv , jpubkey ) ;
CHECKRESULT1 ( ( size ! = 33 ) & & ( size ! = 65 ) , " invalid public key size " , free_pubkeys ( pubkeys , count ) ) ;
2021-11-23 17:38:46 +01:00
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
2024-02-14 13:28:22 +01:00
result = secp256k1_ec_pubkey_parse ( ctx , pubkeys [ i ] , ( unsigned char * ) pub , size ) ;
2021-11-23 17:38:46 +01:00
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
2024-02-14 13:28:22 +01:00
CHECKRESULT1 ( ! result , " secp256k1_ec_pubkey_parse failed " , free_pubkeys ( pubkeys , count ) ) ;
}
2024-08-01 02:45:16 +02:00
result = secp256k1_musig_pubkey_agg ( ctx , NULL , & combined , jkeyaggcache = = NULL ? NULL : & keyaggcache , ( const secp256k1_pubkey * const * ) pubkeys , count ) ;
2024-02-14 13:28:22 +01:00
free_pubkeys ( pubkeys , count ) ;
CHECKRESULT ( ! result , " secp256k1_musig_pubkey_agg failed " ) ;
jpubkey = ( * penv ) - > NewByteArray ( penv , 32 ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_xonly_pubkey_serialize ( ctx , ( unsigned char * ) pub , & combined ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_xonly_pubkey_serialize failed " ) ;
if ( jkeyaggcache ! = NULL )
{
pub = ( * penv ) - > GetByteArrayElements ( penv , jkeyaggcache , 0 ) ;
memcpy ( pub , keyaggcache . data , sizeof ( secp256k1_musig_keyagg_cache ) ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jkeyaggcache , pub , 0 ) ;
}
return jpubkey ;
}
2021-11-23 17:38:46 +01:00
2024-02-14 13:28:22 +01:00
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_musig_pubkey_ec_tweak_add
* Signature : ( J [ B [ B [ B ) [ B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1pubkey_1ec_1tweak_1add ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jkeyaggcache , jbyteArray jtweak32 )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * tweak32 , * pub ;
secp256k1_pubkey pubkey ;
secp256k1_musig_keyagg_cache keyaggcache ;
jbyteArray jpubkey ;
size_t size ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jkeyaggcache = = NULL )
return NULL ;
size = ( * penv ) - > GetArrayLength ( penv , jkeyaggcache ) ;
CHECKRESULT ( size ! = sizeof ( secp256k1_musig_keyagg_cache ) , " invalid keyagg cache size " ) ;
copy_bytes_from_java ( penv , jkeyaggcache , size , keyaggcache . data ) ;
if ( jtweak32 = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jtweak32 ) ! = 32 , " tweak must be 32 bytes " ) ;
tweak32 = ( * penv ) - > GetByteArrayElements ( penv , jtweak32 , 0 ) ;
result = secp256k1_musig_pubkey_ec_tweak_add ( ctx , & pubkey , & keyaggcache , tweak32 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jtweak32 , tweak32 , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_musig_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 , jkeyaggcache , 0 ) ;
memcpy ( pub , keyaggcache . data , sizeof ( secp256k1_musig_keyagg_cache ) ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jkeyaggcache , pub , 0 ) ;
return jpubkey ;
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_musig_pubkey_xonly_tweak_add
* Signature : ( J [ B [ B ) [ B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1pubkey_1xonly_1tweak_1add ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jkeyaggcache , jbyteArray jtweak32 )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * tweak32 , * pub ;
secp256k1_pubkey pubkey ;
secp256k1_musig_keyagg_cache keyaggcache ;
jbyteArray jpubkey ;
size_t size ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jkeyaggcache = = NULL )
return NULL ;
size = ( * penv ) - > GetArrayLength ( penv , jkeyaggcache ) ;
CHECKRESULT ( size ! = sizeof ( secp256k1_musig_keyagg_cache ) , " invalid keyagg cache size " ) ;
copy_bytes_from_java ( penv , jkeyaggcache , size , keyaggcache . data ) ;
if ( jtweak32 = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jtweak32 ) ! = 32 , " tweak must be 32 bytes " ) ;
tweak32 = ( * penv ) - > GetByteArrayElements ( penv , jtweak32 , 0 ) ;
result = secp256k1_musig_pubkey_xonly_tweak_add ( ctx , & pubkey , & keyaggcache , tweak32 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jtweak32 , tweak32 , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_musig_pubkey_xonly_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 , jkeyaggcache , 0 ) ;
memcpy ( pub , keyaggcache . data , sizeof ( secp256k1_musig_keyagg_cache ) ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jkeyaggcache , pub , 0 ) ;
return jpubkey ;
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_musig_nonce_process
* Signature : ( J [ B [ B [ B [ B ) [ B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1nonce_1process ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jaggnonce , jbyteArray jmsg32 , jbyteArray jkeyaggcache )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
secp256k1_musig_keyagg_cache keyaggcache ;
secp256k1_musig_aggnonce aggnonce ;
secp256k1_musig_session session ;
unsigned char msg32 [ 32 ] ;
jbyteArray jsession ;
jbyte * ptr ;
size_t size ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jaggnonce = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jaggnonce ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE , " invalid nonce size " ) ;
if ( jmsg32 = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jmsg32 ) ! = 32 , " invalid message size " ) ;
if ( jkeyaggcache = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jkeyaggcache ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_KEYAGG_CACHE_SIZE , " invalid keyagg cache size " ) ;
ptr = ( * penv ) - > GetByteArrayElements ( penv , jaggnonce , 0 ) ;
result = secp256k1_musig_aggnonce_parse ( ctx , & aggnonce , ptr ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jaggnonce , ptr , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_musig_aggnonce_parse failed " ) ;
copy_bytes_from_java ( penv , jmsg32 , 32 , msg32 ) ;
copy_bytes_from_java ( penv , jkeyaggcache , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_KEYAGG_CACHE_SIZE , keyaggcache . data ) ;
2024-08-01 02:45:16 +02:00
result = secp256k1_musig_nonce_process ( ctx , & session , & aggnonce , msg32 , & keyaggcache , NULL ) ;
2024-02-14 13:28:22 +01:00
CHECKRESULT ( ! result , " secp256k1_musig_nonce_process failed " ) ;
jsession = ( * penv ) - > NewByteArray ( penv , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SESSION_SIZE ) ;
copy_bytes_to_java ( penv , jsession , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SESSION_SIZE , session . data ) ;
return jsession ;
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_musig_partial_sign
* Signature : ( J [ B [ B [ B [ B [ B ) [ B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1partial_1sign ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jsecnonce , jbyteArray jprivkey , jbyteArray jkeyaggcache , jbyteArray jsession )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
secp256k1_musig_partial_sig psig ;
secp256k1_musig_secnonce secnonce ;
unsigned char seckey [ 32 ] ;
secp256k1_keypair keypair ;
secp256k1_musig_keyagg_cache keyaggcache ;
secp256k1_musig_session session ;
jbyteArray jpsig ;
jbyte * ptr ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jsecnonce = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jsecnonce ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SECRET_NONCE_SIZE , " invalid secret nonce size " ) ;
if ( jprivkey = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jprivkey ) ! = 32 , " invalid private key size " ) ;
if ( jkeyaggcache = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jkeyaggcache ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_KEYAGG_CACHE_SIZE , " invalid cache size " ) ;
if ( jsession = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jsession ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SESSION_SIZE , " invalid session size " ) ;
copy_bytes_from_java ( penv , jsecnonce , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SECRET_NONCE_SIZE , secnonce . data ) ;
copy_bytes_from_java ( penv , jprivkey , 32 , seckey ) ;
result = secp256k1_keypair_create ( ctx , & keypair , seckey ) ;
CHECKRESULT ( ! result , " secp256k1_keypair_create failed " ) ;
copy_bytes_from_java ( penv , jkeyaggcache , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_KEYAGG_CACHE_SIZE , keyaggcache . data ) ;
copy_bytes_from_java ( penv , jsession , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SESSION_SIZE , session . data ) ;
result = secp256k1_musig_partial_sign ( ctx , & psig , & secnonce , & keypair , & keyaggcache , & session ) ;
CHECKRESULT ( ! result , " secp256k1_musig_partial_sign failed " ) ;
result = secp256k1_musig_partial_sig_serialize ( ctx , seckey , & psig ) ;
CHECKRESULT ( ! result , " secp256k1_musig_partial_sig_serialize failed " ) ;
jpsig = ( * penv ) - > NewByteArray ( penv , 32 ) ;
copy_bytes_to_java ( penv , jpsig , 32 , seckey ) ;
return jpsig ;
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_musig_partial_sig_verify
* Signature : ( J [ B [ B [ B [ B [ B ) I
*/
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1partial_1sig_1verify ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jpsig , jbyteArray jpubnonce , jbyteArray jpubkey , jbyteArray jkeyaggcache , jbyteArray jsession )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
secp256k1_musig_partial_sig psig ;
secp256k1_musig_pubnonce pubnonce ;
secp256k1_pubkey pubkey ;
secp256k1_musig_keyagg_cache keyaggcache ;
secp256k1_musig_session session ;
jbyte * ptr ;
int result = 0 ;
if ( jctx = = 0 )
return 0 ;
if ( jpsig = = NULL )
return 0 ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jpsig ) ! = 32 , " invalid partial signature size " ) ;
if ( jpubnonce = = NULL )
return 0 ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jpubnonce ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE , " invalid public nonce size " ) ;
if ( jpubkey = = NULL )
return 0 ;
CHECKRESULT ( ( ( * penv ) - > GetArrayLength ( penv , jpubkey ) ! = 33 ) & & ( ( * penv ) - > GetArrayLength ( penv , jpubkey ) ! = 65 ) , " invalid public key size " ) ;
if ( jkeyaggcache = = NULL )
return 0 ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jkeyaggcache ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_KEYAGG_CACHE_SIZE , " invalid cache size " ) ;
if ( jsession = = NULL )
return 0 ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jsession ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SESSION_SIZE , " invalid session size " ) ;
ptr = ( * penv ) - > GetByteArrayElements ( penv , jpsig , 0 ) ;
result = secp256k1_musig_partial_sig_parse ( ctx , & psig , ptr ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpsig , ptr , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_musig_partial_sig_parse failed " ) ;
ptr = ( * penv ) - > GetByteArrayElements ( penv , jpubnonce , 0 ) ;
result = secp256k1_musig_pubnonce_parse ( ctx , & pubnonce , ptr ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubnonce , ptr , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_musig_pubnonce_parse failed " ) ;
ptr = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & pubkey , ptr , ( * penv ) - > GetArrayLength ( penv , jpubkey ) ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , ptr , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_musig_pubkey_parse failed " ) ;
copy_bytes_from_java ( penv , jkeyaggcache , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_KEYAGG_CACHE_SIZE , keyaggcache . data ) ;
copy_bytes_from_java ( penv , jsession , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SESSION_SIZE , session . data ) ;
result = secp256k1_musig_partial_sig_verify ( ctx , & psig , & pubnonce , & pubkey , & keyaggcache , & session ) ;
return result ;
}
void free_partial_sigs ( secp256k1_musig_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_musig_partial_sig_agg
* Signature : ( J [ B [ [ B ) [ B
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1partial_1sig_1agg ( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jsession , jobjectArray jpsigs )
{
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
secp256k1_musig_session session ;
secp256k1_musig_partial_sig * * psigs ;
unsigned char sig64 [ 64 ] ;
secp256k1_musig_keyagg_cache keyaggcache ;
jbyteArray jpsig ;
jbyte * ptr ;
size_t size , count ;
size_t i ;
int result = 0 ;
if ( jctx = = 0 )
return NULL ;
if ( jsession = = NULL )
return NULL ;
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 ) ;
if ( jpsigs = = NULL )
return NULL ;
count = ( * penv ) - > GetArrayLength ( penv , jpsigs ) ;
CHECKRESULT ( count < = 0 , " partial sigs count cannot be 0 " ) ;
psigs = calloc ( count , sizeof ( secp256k1_musig_partial_sig * ) ) ;
for ( i = 0 ; i < count ; i + + )
{
psigs [ i ] = calloc ( 1 , sizeof ( secp256k1_musig_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_musig_partial_sig_parse ( ctx , psigs [ i ] , ( unsigned char * ) ptr ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpsig , ptr , 0 ) ;
CHECKRESULT1 ( ! result , " secp256k1_musig_partial_sig_parse failed " , free_partial_sigs ( psigs , count ) ) ;
}
result = secp256k1_musig_partial_sig_agg ( ctx , sig64 , & session , ( const secp256k1_musig_partial_sig * const * ) psigs , count ) ;
free_partial_sigs ( psigs , count ) ;
CHECKRESULT ( ! result , " secp256k1_musig_pubkey_agg failed " ) ;
jpsig = ( * penv ) - > NewByteArray ( penv , 64 ) ;
copy_bytes_to_java ( penv , jpsig , 64 , sig64 ) ;
return jpsig ;
2021-11-23 17:38:46 +01:00
}
2024-08-04 23:53:28 +02:00
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
2024-08-07 02:48:25 +02:00
* Method : secp256k1_frost_shares_gen
2024-08-19 22:14:27 +02:00
* Signature : ( J [ B [ BII [ [ B ) [ B
2024-08-04 23:53:28 +02:00
*/
2024-08-19 22:14:27 +02:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1shares_1gen
2024-08-14 09:14:34 +02:00
( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jpok64 , jbyteArray jseed32 , jint jthreshold , jint jn_participants , jobjectArray jids33 )
2024-08-04 23:53:28 +02:00
{
2024-08-07 02:48:25 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
2024-08-12 22:15:17 +02:00
2024-08-19 21:40:56 +02:00
secp256k1_frost_share shares [ jn_participants ] ;
secp256k1_pubkey vss_commitment [ jn_participants ] ;
2024-08-14 09:14:34 +02:00
jbyte * pok64 ;
2024-08-07 02:48:25 +02:00
2024-08-19 21:40:56 +02:00
size_t size , i ;
2024-08-11 03:43:30 +02:00
jbyte * pubkeyBytes ;
2024-08-07 02:48:25 +02:00
unsigned char seed32 [ 32 ] ;
2024-08-21 21:35:27 +02:00
unsigned char * ids33 [ jn_participants ] ;
2024-08-12 22:15:17 +02:00
if ( jctx = = 0 )
return NULL ;
2024-08-12 23:02:56 +02:00
if ( jseed32 = = NULL )
2024-08-12 22:15:17 +02:00
return NULL ;
2024-08-07 02:48:25 +02:00
2024-08-12 23:02:56 +02:00
if ( jids33 = = NULL )
2024-08-12 22:15:17 +02:00
return NULL ;
2024-08-20 01:05:29 +02:00
CHECKRESULT ( jthreshold < = 1 , " threshold can't be less then 1 " ) ;
2024-08-12 23:02:56 +02:00
CHECKRESULT ( jn_participants < = 0 , " n_participants can't be 0 " ) ;
CHECKRESULT ( jthreshold > jn_participants , " threshold can't be greater then n_participants " ) ;
2024-08-12 22:15:17 +02:00
size = ( * penv ) - > GetArrayLength ( penv , jseed32 ) ;
CHECKRESULT ( size ! = 32 , " invalid seed32 size " ) ;
copy_bytes_from_java ( penv , jseed32 , size , seed32 ) ;
size = ( * penv ) - > GetArrayLength ( penv , jids33 ) ;
2024-08-20 01:39:22 +02:00
CHECKRESULT ( size ! = jn_participants , " ids33 needs to be of size jn_participants " ) ;
2024-08-14 09:14:34 +02:00
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jpok64 ) ! = 64 , " pok64 length must be 64 bytes " ) ;
2024-08-21 21:35:27 +02:00
// for (i = 0; i < jn_participants; i++)
// {
// jbyteArray id33 = (jbyteArray)(*penv)->GetObjectArrayElement(penv, jids33, i);
// size = (*penv)->GetArrayLength(penv, id33);
// CHECKRESULT(size != 33, "invalid id33 size");
// ids33[i] = (*penv)->GetByteArrayElements(penv, id33, 0);
// (*penv)->ReleaseByteArrayElements(penv, id33, ids33[i], 0);
// }
2024-08-12 22:15:17 +02:00
for ( i = 0 ; i < jn_participants ; i + + )
2024-08-21 21:35:27 +02:00
{
jbyteArray jid33 = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jids33 , i ) ;
size = ( * penv ) - > GetArrayLength ( penv , jid33 ) ;
CHECKRESULT ( size ! = 33 , " invalid id33 size " ) ;
ids33 [ i ] = ( unsigned char * ) calloc ( 1 , size ) ;
copy_bytes_from_java ( penv , jid33 , size , ids33 [ i ] ) ;
}
2024-08-07 02:48:25 +02:00
2024-08-19 22:14:27 +02:00
int sharesLength = jn_participants * 32 ;
int vssCommitmentLength = jthreshold * 65 ;
jbyteArray jShareGenOutput ;
jbyte * share_gen_output_ptr = NULL ;
unsigned char shareGenOutput [ sharesLength + vssCommitmentLength ] ;
2024-08-07 02:48:25 +02:00
int result = 0 ;
2024-08-11 03:43:30 +02:00
2024-08-14 09:14:34 +02:00
pok64 = ( * penv ) - > GetByteArrayElements ( penv , jpok64 , 0 ) ;
2024-08-07 02:48:25 +02:00
result = secp256k1_frost_shares_gen (
ctx ,
shares ,
vss_commitment ,
2024-08-14 09:14:34 +02:00
( unsigned char * ) pok64 ,
2024-08-11 03:43:30 +02:00
seed32 ,
2024-08-07 02:48:25 +02:00
jthreshold ,
2024-08-11 03:43:30 +02:00
jn_participants ,
2024-08-19 21:40:56 +02:00
( const unsigned char * const * ) ids33
2024-08-07 02:48:25 +02:00
) ;
2024-08-14 09:14:34 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jpok64 , pok64 , 0 ) ;
2024-08-07 02:48:25 +02:00
CHECKRESULT ( ! result , " secp256k1_frost_shares_gen failed " ) ;
2024-08-18 01:27:04 +02:00
for ( i = 0 ; i < jn_participants ; i + + )
{
2024-08-19 22:14:27 +02:00
result = secp256k1_frost_share_serialize ( ctx , shareGenOutput + ( 32 * i ) , & shares [ i ] ) ;
2024-08-18 01:27:04 +02:00
CHECKRESULT ( ! result , " secp256k1_frost_share_serialize failed " ) ;
}
for ( i = 0 ; i < jn_participants ; i + + )
{
2024-08-19 22:14:27 +02:00
size = 65 ;
secp256k1_ec_pubkey_serialize ( ctx , shareGenOutput + sharesLength + ( 65 * i ) , & size , & vss_commitment [ i ] , SECP256K1_EC_UNCOMPRESSED ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_serialize failed " ) ;
2024-08-18 01:27:04 +02:00
}
2024-08-07 02:48:25 +02:00
2024-08-19 22:14:27 +02:00
jbyteArray jresult = ( * penv ) - > NewByteArray ( penv , sizeof ( shareGenOutput ) ) ;
share_gen_output_ptr = ( * penv ) - > GetByteArrayElements ( penv , jresult , 0 ) ;
memcpy ( share_gen_output_ptr , shareGenOutput , sizeof ( shareGenOutput ) ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jresult , share_gen_output_ptr , 0 ) ;
return jresult ;
2024-08-11 03:43:30 +02:00
}
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
*/
2024-08-13 01:41:45 +02:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1share_1agg
2024-08-11 03:43:30 +02:00
( JNIEnv * penv , jclass clazz , jlong jctx , jobjectArray jshares , jobjectArray jvss_commitments , jint jtotalShareCount , jint jthreshold , jbyteArray jid33 )
{
2024-08-12 22:15:17 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
2024-08-11 03:43:30 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_share aggregate_share ;
jbyteArray jaggregate_share ;
secp256k1_xonly_pubkey aggregate_public_key ;
jbyteArray jaggregate_public_key ;
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
secp256k1_frost_share * * shares ;
2024-08-12 22:15:17 +02:00
jbyteArray jshare ;
jbyte * in32 ;
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
secp256k1_pubkey * * vss_commitments ;
2024-08-20 00:09:56 +02:00
jbyteArray jvss_commitment , jvss_commitment_bytes ;
2024-08-12 22:15:17 +02:00
jbyte * pub ;
2024-08-11 03:43:30 +02:00
2024-08-12 22:15:17 +02:00
jbyte * id33 ;
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
size_t size , count , i ;
int result = 0 ;
2024-08-11 03:43:30 +02:00
2024-08-13 01:41:45 +02:00
jbyteArray jresult ;
jbyte * result_ptr = NULL ;
unsigned char result_array [ 32 + 32 ] ; // TODO: Put correct pubnonce
2024-08-12 22:15:17 +02:00
if ( jctx = = 0 )
return NULL ;
2024-08-11 03:43:30 +02:00
2024-08-12 23:02:56 +02:00
if ( jshares = = NULL )
return NULL ;
if ( jvss_commitments = = NULL )
return NULL ;
if ( jid33 = = NULL )
return NULL ;
2024-08-20 01:05:29 +02:00
CHECKRESULT ( jthreshold < = 1 , " threshold can't be less then 1 " ) ;
CHECKRESULT ( jtotalShareCount < = 1 , " totalShareCount can't be 0 " ) ;
2024-08-12 23:02:56 +02:00
CHECKRESULT ( jthreshold > jtotalShareCount , " threshold can't be greater then totalShareCount " ) ;
2024-08-19 21:40:56 +02:00
count = ( * penv ) - > GetArrayLength ( penv , jshares ) ;
2024-08-12 22:15:17 +02:00
CHECKRESULT ( count ! = jtotalShareCount , " jshares count should be total share count. " ) ;
shares = calloc ( count , sizeof ( secp256k1_frost_share * ) ) ;
2024-08-11 03:43:30 +02:00
2024-08-12 22:15:17 +02:00
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 ) ;
2024-08-20 00:09:56 +02:00
CHECKRESULT1 ( size ! = 32 , " invalid share size " , free_shares ( shares , count ) ) ;
2024-08-12 22:15:17 +02:00
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 ) ) ;
}
2024-08-11 03:43:30 +02:00
2024-08-12 22:15:17 +02:00
count = ( * penv ) - > GetArrayLength ( penv , jvss_commitments ) ;
vss_commitments = calloc ( count , sizeof ( secp256k1_pubkey * ) ) ;
2024-08-20 00:09:56 +02:00
for ( i = 0 ; i < count ; i + + ) {
2024-08-12 22:15:17 +02:00
jvss_commitment = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jvss_commitments , i ) ;
size = ( * penv ) - > GetArrayLength ( penv , jvss_commitment ) ;
2024-08-20 00:09:56 +02:00
CHECKRESULT1 ( size ! = jthreshold , " vss commitments should have the same size as threshold " , free_pubkeys ( vss_commitments , count ) ) ;
// TODO: Check table of contents
vss_commitments [ i ] = calloc ( jthreshold , sizeof ( secp256k1_pubkey ) ) ;
for ( int j = 0 ; j < jthreshold ; j + + )
{
jvss_commitment_bytes = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jvss_commitment , j ) ;
size = ( * penv ) - > GetArrayLength ( penv , jvss_commitment_bytes ) ;
CHECKRESULT1 ( size ! = 65 , " invalid vss commitment size " , free_pubkeys ( vss_commitments , count ) ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jvss_commitment_bytes , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & vss_commitments [ i ] [ j ] , ( unsigned char * ) pub , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jvss_commitment_bytes , pub , 0 ) ;
CHECKRESULT1 ( ! result , " secp256k1_ec_pubkey_parse failed " , free_pubkeys ( vss_commitments , count ) ) ;
}
2024-08-12 22:15:17 +02:00
}
2024-08-11 03:43:30 +02:00
2024-08-12 22:15:17 +02:00
id33 = ( * penv ) - > GetByteArrayElements ( penv , jid33 , 0 ) ;
2024-08-11 03:43:30 +02:00
2024-08-12 22:15:17 +02:00
result = secp256k1_frost_share_agg (
ctx ,
& aggregate_share ,
& aggregate_public_key ,
2024-08-19 21:40:56 +02:00
( const secp256k1_frost_share * const * ) shares ,
( const secp256k1_pubkey * const * ) vss_commitments ,
2024-08-12 22:15:17 +02:00
jtotalShareCount ,
jthreshold ,
( unsigned char * ) id33
) ;
2024-08-13 01:41:45 +02:00
result = secp256k1_frost_share_serialize ( ctx , result_array , & aggregate_share ) ;
2024-08-12 22:15:17 +02:00
CHECKRESULT ( ! result , " secp256k1_frost_share_serialize failed " ) ;
2024-08-11 03:43:30 +02:00
2024-08-13 01:41:45 +02:00
result = secp256k1_xonly_pubkey_serialize ( ctx , result_array + 32 , & aggregate_public_key ) ;
2024-08-12 22:15:17 +02:00
CHECKRESULT ( ! result , " secp256k1_xonly_pubkey_serialize failed " ) ;
2024-08-11 03:43:30 +02:00
2024-08-13 01:41:45 +02:00
jresult = ( * penv ) - > NewByteArray ( penv , sizeof ( result_array ) ) ;
result_ptr = ( * penv ) - > GetByteArrayElements ( penv , jresult , 0 ) ;
memcpy ( result_ptr , result_array , sizeof ( result_array ) ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jresult , result_ptr , 0 ) ;
return jresult ;
2024-08-11 03:43:30 +02:00
}
/*
* 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 ;
2024-08-19 21:40:56 +02:00
secp256k1_pubkey * vss_commitment ;
2024-08-20 01:05:29 +02:00
jbyteArray jvss_commitment_bytes ;
2024-08-19 21:40:56 +02:00
jbyteArray jpubkey ;
jbyte * pub ;
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
size_t size , count , i ;
2024-08-12 22:15:17 +02:00
if ( jctx = = 0 )
2024-08-19 21:40:56 +02:00
return 0 ;
2024-08-12 22:15:17 +02:00
2024-08-12 23:02:56 +02:00
if ( jid33 = = NULL )
2024-08-19 21:40:56 +02:00
return 0 ;
2024-08-12 23:02:56 +02:00
if ( jshare = = NULL )
2024-08-19 21:40:56 +02:00
return 0 ;
2024-08-12 23:02:56 +02:00
if ( jvss_commitment = = NULL )
2024-08-19 21:40:56 +02:00
return 0 ;
int result = 0 ;
2024-08-12 23:02:56 +02:00
2024-08-20 01:05:29 +02:00
CHECKRESULT ( jthreshold < = 1 , " threshold can't be less then 1 " ) ;
2024-08-12 23:02:56 +02:00
2024-08-19 21:40:56 +02:00
2024-08-11 03:43:30 +02:00
size = ( * penv ) - > GetArrayLength ( penv , jshare ) ;
2024-08-20 00:09:56 +02:00
CHECKRESULT ( size ! = 32 , " invalid share size " ) ;
2024-08-11 03:43:30 +02:00
in32 = ( * penv ) - > GetByteArrayElements ( penv , jshare , 0 ) ;
2024-08-14 09:14:34 +02:00
result = secp256k1_frost_share_parse ( ctx , & share , ( unsigned char * ) in32 ) ;
2024-08-11 03:43:30 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jshare , in32 , 0 ) ;
2024-08-19 22:14:27 +02:00
CHECKRESULT ( ! result , " secp256k1_frost_share_parse failed " ) ;
2024-08-11 03:43:30 +02:00
id33 = ( * penv ) - > GetByteArrayElements ( penv , jid33 , 0 ) ;
2024-08-19 21:40:56 +02:00
count = ( * penv ) - > GetArrayLength ( penv , jvss_commitment ) ;
2024-08-20 01:05:29 +02:00
CHECKRESULT ( count ! = jthreshold , " vss_commitment needs to be the same as the threshold " ) ;
vss_commitment = calloc ( jthreshold , sizeof ( secp256k1_pubkey ) ) ;
2024-08-19 21:40:56 +02:00
for ( i = 0 ; i < count ; i + + )
{
2024-08-20 01:05:29 +02:00
jvss_commitment_bytes = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jvss_commitment , i ) ;
size = ( * penv ) - > GetArrayLength ( penv , jvss_commitment_bytes ) ;
CHECKRESULT1 ( size ! = 65 , " invalid vss commitment size " , free ( vss_commitment ) ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jvss_commitment_bytes , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & vss_commitment [ i ] , ( unsigned char * ) pub , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jvss_commitment_bytes , pub , 0 ) ;
CHECKRESULT1 ( ! result , " secp256k1_ec_pubkey_parse failed " , free ( vss_commitment ) ) ;
2024-08-19 21:40:56 +02:00
}
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
result = secp256k1_frost_share_verify (
2024-08-11 03:43:30 +02:00
ctx ,
jthreshold ,
( unsigned char * ) id33 ,
2024-08-19 21:40:56 +02:00
& share ,
2024-08-20 01:05:29 +02:00
& vss_commitment
2024-08-11 03:43:30 +02:00
) ;
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 )
{
2024-08-12 22:15:17 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
secp256k1_pubkey pubshare ;
2024-08-19 21:40:56 +02:00
jbyte * id33 , * jpubkey ;
2024-08-12 22:15:17 +02:00
2024-08-19 21:40:56 +02:00
secp256k1_pubkey * * vss_commitments ;
2024-08-20 00:09:56 +02:00
jbyteArray jvss_commitment , jvss_commitment_bytes ;
jbyte * pub ;
2024-08-19 21:40:56 +02:00
jbyteArray jpubshare ;
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
size_t size , count , i ;
2024-08-11 03:43:30 +02:00
2024-08-12 22:15:17 +02:00
if ( jctx = = 0 )
return NULL ;
2024-08-11 03:43:30 +02:00
2024-08-12 23:02:56 +02:00
if ( jid33 = = NULL )
return NULL ;
if ( jvss_commitments = = NULL )
return NULL ;
2024-08-19 21:40:56 +02:00
int result = 0 ;
2024-08-20 01:05:29 +02:00
CHECKRESULT ( jthreshold < = 1 , " threshold can't be less then 1 " ) ;
CHECKRESULT ( jtotalSignersCount < = 1 , " totalSignersCount can't be less then 1 " ) ;
CHECKRESULT ( jthreshold > jtotalSignersCount , " threshold can't be greater then n_participants " ) ;
2024-08-12 23:02:56 +02:00
2024-08-12 22:15:17 +02:00
id33 = ( * penv ) - > GetByteArrayElements ( penv , jid33 , 0 ) ;
2024-08-11 03:43:30 +02:00
2024-08-12 22:15:17 +02:00
count = ( * penv ) - > GetArrayLength ( penv , jvss_commitments ) ;
vss_commitments = calloc ( count , sizeof ( secp256k1_pubkey * ) ) ;
2024-08-11 03:43:30 +02:00
2024-08-20 00:09:56 +02:00
for ( i = 0 ; i < count ; i + + ) {
2024-08-12 22:15:17 +02:00
jvss_commitment = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jvss_commitments , i ) ;
size = ( * penv ) - > GetArrayLength ( penv , jvss_commitment ) ;
2024-08-20 00:09:56 +02:00
CHECKRESULT1 ( size ! = jthreshold , " vss commitments should have the same size as threshold " , free_pubkeys ( vss_commitments , count ) ) ;
vss_commitments [ i ] = calloc ( jthreshold , sizeof ( secp256k1_pubkey ) ) ;
for ( int j = 0 ; j < jthreshold ; j + + )
{
jvss_commitment_bytes = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jvss_commitment , j ) ;
size = ( * penv ) - > GetArrayLength ( penv , jvss_commitment_bytes ) ;
CHECKRESULT1 ( size ! = 65 , " invalid vss commitment size " , free_pubkeys ( vss_commitments , count ) ) ;
pub = ( * penv ) - > GetByteArrayElements ( penv , jvss_commitment_bytes , 0 ) ;
result = secp256k1_ec_pubkey_parse ( ctx , & vss_commitments [ i ] [ j ] , ( unsigned char * ) pub , size ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jvss_commitment_bytes , pub , 0 ) ;
CHECKRESULT1 ( ! result , " secp256k1_ec_pubkey_parse failed " , free_pubkeys ( vss_commitments , count ) ) ;
}
2024-08-12 22:15:17 +02:00
}
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
result = secp256k1_frost_compute_pubshare (
2024-08-12 22:15:17 +02:00
ctx ,
& pubshare ,
jthreshold ,
2024-08-19 21:40:56 +02:00
( unsigned char * ) id33 ,
( const secp256k1_pubkey * const * ) vss_commitments ,
2024-08-12 22:15:17 +02:00
jtotalSignersCount
) ;
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
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 ) ;
2024-08-12 22:15:17 +02:00
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_serialize failed " ) ;
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
return jpubshare ;
2024-08-11 03:43:30 +02:00
}
/*
* 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 ;
2024-08-12 22:15:17 +02:00
size_t size , count ;
if ( jctx = = 0 )
return NULL ;
2024-08-12 23:02:56 +02:00
if ( jpublicKey = = NULL )
return NULL ;
2024-08-19 21:40:56 +02:00
int result = 0 ;
2024-08-21 18:35:41 +02:00
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jpublicKey ) ! = 32 , " public key must be 32 bytes " ) ;
2024-08-11 03:43:30 +02:00
pub = ( * penv ) - > GetByteArrayElements ( penv , jpublicKey , 0 ) ;
2024-08-12 22:15:17 +02:00
result = secp256k1_xonly_pubkey_parse ( ctx , & public_key , ( unsigned char * ) pub ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpublicKey , pub , 0 ) ;
2024-08-19 21:40:56 +02:00
CHECKRESULT ( ! result , " secp256k1_xonly_pubkey_parse failed " ) ;
2024-08-11 03:43:30 +02:00
2024-08-19 21:40:56 +02:00
result = secp256k1_frost_pubkey_tweak (
2024-08-12 22:15:17 +02:00
ctx ,
& tweak_cache ,
& public_key
2024-08-11 03:43:30 +02:00
) ;
2024-08-12 02:55:41 +02:00
CHECKRESULT ( ! result , " secp256k1_frost_pubkey_tweak failed " ) ;
2024-08-12 22:15:17 +02:00
size = sizeof ( secp256k1_frost_tweak_cache ) ;
2024-08-12 02:55:41 +02:00
jbyteArray jtweak_cache = ( * penv ) - > NewByteArray ( penv , size ) ;
copy_bytes_to_java ( penv , jtweak_cache , size , tweak_cache . data ) ;
2024-08-11 03:43:30 +02:00
2024-08-12 02:55:41 +02:00
return jtweak_cache ;
2024-08-11 03:43:30 +02:00
}
/*
* 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
2024-08-12 02:16:54 +02:00
( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jtweak_cache , jbyteArray jtweak32 )
2024-08-11 03:43:30 +02:00
{
2024-08-12 22:15:17 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * tweak32 , * pub ;
secp256k1_pubkey pubkey ;
jbyteArray jpubkey ;
secp256k1_frost_tweak_cache tweak_cache ;
size_t size , count ;
if ( jctx = = 0 )
return NULL ;
if ( jtweak_cache = = NULL )
return NULL ;
if ( jtweak32 = = NULL )
return NULL ;
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 ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jtweak32 ) ! = 32 , " tweak must be 32 bytes " ) ;
tweak32 = ( * penv ) - > GetByteArrayElements ( penv , jtweak32 , 0 ) ;
2024-08-19 21:40:56 +02:00
// TODO: Release Array Elements...
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
int result = secp256k1_frost_pubkey_ec_tweak_add (
ctx ,
2024-08-19 21:40:56 +02:00
& pubkey ,
2024-08-12 22:15:17 +02:00
& tweak_cache ,
2024-08-19 21:40:56 +02:00
( unsigned char * ) tweak32
2024-08-12 22:15:17 +02:00
) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jtweak32 , tweak32 , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_frost_pubkey_ec_tweak_add failed " ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
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 ;
2024-08-12 02:16:54 +02:00
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_frost_pubkey_xonly_tweak_add
* Signature : ( J [ B [ B ) [ [ B
*/
2024-08-13 01:41:45 +02:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1pubkey_1xonly_1tweak_1add
2024-08-12 02:16:54 +02:00
( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jtweak_cache , jbyteArray jtweak32 )
{
2024-08-12 22:15:17 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
jbyte * tweak32 , * pub ;
secp256k1_pubkey pubkey ;
jbyteArray jpubkey ;
secp256k1_frost_tweak_cache tweak_cache ;
size_t size , count ;
if ( jctx = = 0 )
return NULL ;
if ( jtweak_cache = = NULL )
return NULL ;
2024-08-12 23:02:56 +02:00
if ( jtweak32 = = NULL )
return NULL ;
2024-08-12 22:15:17 +02:00
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 ) ;
if ( jtweak32 = = NULL )
return NULL ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jtweak32 ) ! = 32 , " tweak must be 32 bytes " ) ;
tweak32 = ( * penv ) - > GetByteArrayElements ( penv , jtweak32 , 0 ) ;
2024-08-19 21:40:56 +02:00
// TODO: Release Array elements...
2024-08-12 02:16:54 +02:00
2024-08-13 01:41:45 +02:00
int result = secp256k1_frost_pubkey_xonly_tweak_add (
2024-08-12 22:15:17 +02:00
ctx ,
2024-08-13 01:41:45 +02:00
& pubkey ,
2024-08-12 22:15:17 +02:00
& tweak_cache ,
2024-08-19 21:40:56 +02:00
( unsigned char * ) tweak32
2024-08-12 22:15:17 +02:00
) ;
2024-08-13 01:41:45 +02:00
2024-08-12 22:15:17 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jtweak32 , tweak32 , 0 ) ;
2024-08-13 01:41:45 +02:00
CHECKRESULT ( ! result , " secp256k1_frost_pubkey_xonly_tweak_add failed " ) ;
jbyteArray jresult ;
jbyte * result_ptr = NULL ;
unsigned char result_array [ 32 + sizeof ( secp256k1_frost_tweak_cache ) ] ; // TODO: Put correct pubnonce
2024-08-12 22:15:17 +02:00
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 " ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
pub = ( * penv ) - > GetByteArrayElements ( penv , jtweak_cache , 0 ) ;
2024-08-13 01:41:45 +02:00
memcpy ( pub , tweak_cache . data , sizeof ( secp256k1_frost_tweak_cache ) ) ;
2024-08-12 22:15:17 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jtweak_cache , pub , 0 ) ;
return jpubkey ;
2024-08-12 02:16:54 +02:00
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_frost_nonce_gen
* Signature : ( J [ B [ B [ B [ B [ B ) [ [ B
*/
2024-08-13 01:41:45 +02:00
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1nonce_1gen
2024-08-12 02:16:54 +02:00
( JNIEnv * penv , jclass clazz , jlong jctx , jbyteArray jsession_id32 , jbyteArray jshare , jbyteArray jmsg32 , jbyteArray jpubkey , jbyteArray jextra_input32 )
{
2024-08-12 22:15:17 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
int result = 0 ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_secnonce secnonce ;
secp256k1_frost_pubnonce pubnonce ;
unsigned char session_id32 [ 32 ] ;
2024-08-12 02:16:54 +02:00
secp256k1_frost_share share ;
jbyte * in32 ;
2024-08-12 22:15:17 +02:00
jbyte * pubkey_ptr ;
2024-08-19 21:40:56 +02:00
secp256k1_xonly_pubkey pubkey ;
2024-08-12 22:15:17 +02:00
unsigned char msg32 [ 32 ] ;
unsigned char extra_input32 [ 32 ] ;
2024-08-12 02:16:54 +02:00
2024-08-13 01:41:45 +02:00
jbyteArray jnonce ;
jbyte * nonce_ptr = NULL ;
2024-08-20 22:29:29 +02:00
unsigned char nonce [ sizeof ( secp256k1_frost_secnonce ) + 66 ] ; // TODO: Put correct pubnonce
2024-08-13 01:41:45 +02:00
2024-08-12 22:15:17 +02:00
size_t size , count ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
if ( jctx = = 0 )
return NULL ;
2024-08-12 02:16:54 +02:00
2024-08-12 23:02:56 +02:00
if ( jsession_id32 = = NULL )
2024-08-12 22:15:17 +02:00
return NULL ;
2024-08-12 23:02:56 +02:00
2024-08-12 22:15:17 +02:00
size = ( * penv ) - > GetArrayLength ( penv , jsession_id32 ) ;
CHECKRESULT ( size ! = 32 , " invalid session_id size " ) ;
copy_bytes_from_java ( penv , jsession_id32 , size , session_id32 ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
if ( jshare ! = NULL ) {
size = ( * penv ) - > GetArrayLength ( penv , jshare ) ;
2024-08-19 21:40:56 +02:00
// TODO: CHECKRESULT1(size != fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE, "invalid public nonce size", free_frost_nonces(pubnonces, count));
2024-08-12 22:15:17 +02:00
in32 = ( * penv ) - > GetByteArrayElements ( penv , jshare , 0 ) ;
2024-08-14 09:14:34 +02:00
result = secp256k1_frost_share_parse ( ctx , & share , ( unsigned char * ) in32 ) ;
2024-08-12 22:15:17 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jshare , in32 , 0 ) ;
// TODO: CHECKRESULT1(!result, "secp256k1_frost_share_parse failed", free_shares(shares, count));
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
}
if ( jmsg32 ! = NULL )
{
size = ( * penv ) - > GetArrayLength ( penv , jmsg32 ) ;
CHECKRESULT ( size ! = 32 , " invalid message size " ) ;
copy_bytes_from_java ( penv , jmsg32 , size , msg32 ) ;
}
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
if ( jpubkey ! = NULL ) {
2024-08-21 18:35:41 +02:00
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jpubkey ) ! = 32 , " public key must be 32 bytes " ) ;
2024-08-12 22:15:17 +02:00
pubkey_ptr = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
2024-08-19 21:40:56 +02:00
result = secp256k1_xonly_pubkey_parse ( ctx , & pubkey , ( unsigned char * ) pubkey_ptr ) ;
2024-08-12 22:15:17 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pubkey_ptr , 0 ) ;
2024-08-19 21:40:56 +02:00
CHECKRESULT ( ! result , " secp256k1_xonly_pubkey_parse failed " ) ;
2024-08-12 22:15:17 +02:00
}
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
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 ,
2024-08-19 21:40:56 +02:00
jpubkey = = NULL ? NULL : & pubkey ,
2024-08-12 22:15:17 +02:00
jextra_input32 = = NULL ? NULL : extra_input32
) ;
CHECKRESULT ( ! result , " secp256k1_frost_nonce_gen failed " ) ;
2024-08-12 02:16:54 +02:00
2024-08-13 01:41:45 +02:00
memcpy ( nonce , secnonce . data , sizeof ( secp256k1_frost_secnonce ) ) ;
result = secp256k1_frost_pubnonce_serialize ( ctx , nonce + sizeof ( secp256k1_frost_secnonce ) , & pubnonce ) ;
CHECKRESULT ( ! result , " secp256k1_frost_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 ;
2024-08-12 02:16:54 +02:00
}
/*
* Class : fr_acinq_secp256k1_Secp256k1CFunctions
* Method : secp256k1_frost_nonce_process
2024-08-12 02:55:41 +02:00
* Signature : ( J [ [ BI [ B [ B [ B [ [ B [ B [ B ) [ B
2024-08-12 02:16:54 +02:00
*/
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1nonce_1process
2024-08-12 02:55:41 +02:00
( JNIEnv * penv , jclass clazz , jlong jctx , jobjectArray jpubnonces , jint n_pubnonces , jbyteArray jmsg32 , jbyteArray jpubkey , jbyteArray jmy_id33 , jobjectArray jids33 , jbyteArray jtweak_cache , jbyteArray jadaptor )
2024-08-12 02:16:54 +02:00
{
2024-08-12 22:15:17 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
secp256k1_frost_session session ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_pubnonce * * pubnonces ;
2024-08-21 21:35:27 +02:00
jbyte * in66 , * pub , * my_id33 ;
2024-08-19 21:40:56 +02:00
jbyteArray jpubnonce ;
2024-08-12 22:15:17 +02:00
unsigned char msg32 [ 32 ] ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_xonly_pubkey public_key ;
2024-08-12 02:55:41 +02:00
2024-08-21 21:35:27 +02:00
unsigned char * ids33 [ n_pubnonces ] ;
2024-08-12 02:55:41 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_tweak_cache tweak_cache ;
secp256k1_pubkey adaptor ;
2024-08-12 02:55:41 +02:00
2024-08-19 21:40:56 +02:00
size_t size , count , i ;
2024-08-12 02:55:41 +02:00
2024-08-12 22:15:17 +02:00
if ( jctx = = 0 )
return NULL ;
2024-08-12 02:55:41 +02:00
2024-08-12 23:02:56 +02:00
if ( jpubnonces = = NULL )
return NULL ;
if ( jmsg32 = = NULL )
return NULL ;
if ( jpubkey = = NULL )
return NULL ;
if ( jmy_id33 = = NULL )
return NULL ;
if ( jids33 = = NULL )
return NULL ;
2024-08-19 21:40:56 +02:00
int result = 0 ;
2024-08-12 23:02:56 +02:00
CHECKRESULT ( n_pubnonces < = 0 , " n_pubnonces can't be 0 " ) ;
2024-08-12 22:15:17 +02:00
count = ( * penv ) - > GetArrayLength ( penv , jpubnonces ) ;
CHECKRESULT ( count < = 0 , " public nonces count cannot be 0 " ) ;
2024-08-20 22:29:29 +02:00
CHECKRESULT ( n_pubnonces ! = count , " n_pubnonces doesn't match public nonces count " ) ;
2024-08-12 02:55:41 +02:00
2024-08-12 22:15:17 +02:00
pubnonces = calloc ( count , sizeof ( secp256k1_frost_pubnonce * ) ) ;
2024-08-12 02:55:41 +02:00
2024-08-12 22:15:17 +02:00
for ( i = 0 ; i < count ; i + + )
{
pubnonces [ i ] = calloc ( 1 , sizeof ( secp256k1_frost_pubnonce ) ) ;
2024-08-19 21:40:56 +02:00
jpubnonce = ( * penv ) - > GetObjectArrayElement ( penv , jpubnonces , i ) ;
size = ( * penv ) - > GetArrayLength ( penv , jpubnonce ) ;
2024-08-21 21:35:27 +02:00
CHECKRESULT1 ( size ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_FROST_PUBLIC_NONCE_SIZE , " invalid public nonce size " , free_frost_nonces ( pubnonces , count ) ) ;
2024-08-19 21:40:56 +02:00
in66 = ( * penv ) - > GetByteArrayElements ( penv , jpubnonce , 0 ) ;
2024-08-12 22:15:17 +02:00
result = secp256k1_frost_pubnonce_parse ( ctx , pubnonces [ i ] , ( unsigned char * ) in66 ) ;
2024-08-19 21:40:56 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jpubnonce , in66 , 0 ) ;
CHECKRESULT1 ( ! result , " secp256k1_frost_pubnonce_parse failed " , free_frost_nonces ( pubnonces , count ) ) ;
2024-08-12 22:15:17 +02:00
}
2024-08-12 02:55:41 +02:00
2024-08-12 23:02:56 +02:00
size = ( * penv ) - > GetArrayLength ( penv , jmsg32 ) ;
CHECKRESULT ( size ! = 32 , " invalid message size " ) ;
copy_bytes_from_java ( penv , jmsg32 , size , msg32 ) ;
2024-08-12 02:55:41 +02:00
2024-08-21 18:35:41 +02:00
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jpubkey ) ! = 32 , " public key must be 32 bytes " ) ;
2024-08-12 22:15:17 +02:00
pub = ( * penv ) - > GetByteArrayElements ( penv , jpubkey , 0 ) ;
result = secp256k1_xonly_pubkey_parse ( ctx , & public_key , ( unsigned char * ) pub ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpubkey , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_xonly_pubkey_parse failed " ) ;
2024-08-12 02:55:41 +02:00
2024-08-21 21:35:27 +02:00
my_id33 = ( * penv ) - > GetByteArrayElements ( penv , jmy_id33 , 0 ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jmy_id33 , my_id33 , 0 ) ;
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jids33 ) ! = n_pubnonces , " invalid ids33 array size " ) ;
2024-08-12 02:55:41 +02:00
2024-08-12 23:02:56 +02:00
for ( i = 0 ; i < n_pubnonces ; i + + )
2024-08-12 22:15:17 +02:00
{
2024-08-21 21:35:27 +02:00
jbyteArray jid33 = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jids33 , i ) ;
size = ( * penv ) - > GetArrayLength ( penv , jid33 ) ;
2024-08-20 22:29:29 +02:00
CHECKRESULT ( size ! = 33 , " invalid id33 size " ) ;
2024-08-12 02:55:41 +02:00
2024-08-21 21:35:27 +02:00
ids33 [ i ] = ( unsigned char * ) calloc ( 1 , size ) ;
copy_bytes_from_java ( penv , jid33 , size , ids33 [ i ] ) ;
}
2024-08-12 02:55:41 +02:00
2024-08-12 23:02:56 +02:00
if ( jtweak_cache ! = NULL )
{
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 ) ;
}
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
if ( jadaptor ! = NULL )
{
2024-08-19 21:40:56 +02:00
size = ( * penv ) - > GetArrayLength ( penv , jadaptor ) ;
CHECKRESULT ( ( size ! = 33 ) & & ( size ! = 65 ) , " invalid public key size " ) ;
2024-08-12 22:15:17 +02:00
pub = ( * penv ) - > GetByteArrayElements ( penv , jadaptor , 0 ) ;
2024-08-19 21:40:56 +02:00
result = secp256k1_ec_pubkey_parse ( ctx , & adaptor , ( unsigned char * ) pub , size ) ;
2024-08-12 22:15:17 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jadaptor , pub , 0 ) ;
CHECKRESULT ( ! result , " secp256k1_ec_pubkey_parse failed " ) ;
}
2024-08-12 23:02:56 +02:00
2024-08-19 21:40:56 +02:00
result = secp256k1_frost_nonce_process (
2024-08-12 22:15:17 +02:00
ctx ,
& session ,
( const secp256k1_frost_pubnonce * const * ) pubnonces ,
n_pubnonces ,
msg32 ,
& public_key ,
2024-08-21 21:35:27 +02:00
my_id33 ,
2024-08-19 21:40:56 +02:00
( const unsigned char * const * ) ids33 ,
2024-08-12 23:02:56 +02:00
jtweak_cache = = NULL ? NULL : & tweak_cache ,
jadaptor = = NULL ? NULL : & adaptor
2024-08-12 22:15:17 +02:00
) ;
CHECKRESULT ( ! result , " secp256k1_frost_nonce_process failed " ) ;
2024-08-12 02:55:41 +02:00
size = sizeof ( secp256k1_frost_session ) ;
jbyteArray jsession = ( * penv ) - > NewByteArray ( penv , size ) ;
copy_bytes_to_java ( penv , jsession , size , session . data ) ;
return jsession ;
2024-08-12 02:16:54 +02:00
}
/*
* 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 )
{
2024-08-12 22:15:17 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_partial_sig partial_sig ;
secp256k1_frost_secnonce secnonce ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_share agg_share ;
jbyte * in32 ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_session session ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_tweak_cache tweak_cache ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
jbyteArray jpsig ;
jbyte * ptr ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
size_t size , count ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
if ( jctx = = 0 )
return NULL ;
2024-08-12 02:16:54 +02:00
2024-08-12 23:02:56 +02:00
if ( jsecnonce = = NULL )
return NULL ;
if ( jagg_share = = NULL )
return NULL ;
if ( jsession = = NULL )
return NULL ;
2024-08-19 21:40:56 +02:00
int result = 0 ;
2024-08-21 18:35:41 +02:00
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jsecnonce ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_FROST_SECRET_NONCE_SIZE , " invalid secnonce size " ) ;
copy_bytes_from_java ( penv , jsecnonce , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_FROST_SECRET_NONCE_SIZE , secnonce . data ) ;
2024-08-12 02:16:54 +02:00
2024-08-21 18:35:41 +02:00
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jagg_share ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_FROST_AGGREGATE_SHARE_SIZE , " invalid agg_share size " ) ;
2024-08-12 23:02:56 +02:00
in32 = ( * penv ) - > GetByteArrayElements ( penv , jagg_share , 0 ) ;
2024-08-14 09:14:34 +02:00
result = secp256k1_frost_share_parse ( ctx , & agg_share , ( unsigned char * ) in32 ) ;
2024-08-12 23:02:56 +02:00
( * penv ) - > ReleaseByteArrayElements ( penv , jagg_share , in32 , 0 ) ;
2024-08-14 09:14:34 +02:00
CHECKRESULT ( ! result , " secp256k1_frost_share_parse failed " ) ;
2024-08-12 02:16:54 +02:00
2024-08-21 18:35:41 +02:00
CHECKRESULT ( ( * penv ) - > GetArrayLength ( penv , jsession ) ! = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_FROST_SESSION_SIZE , " invalid session size " ) ;
copy_bytes_from_java ( penv , jsession , fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_FROST_SESSION_SIZE , session . data ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 23:02:56 +02:00
if ( jtweak_cache ! = NULL )
{
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 ) ;
}
2024-08-12 22:15:17 +02:00
2024-08-19 21:40:56 +02:00
result = secp256k1_frost_partial_sign (
2024-08-12 22:15:17 +02:00
ctx ,
& partial_sig ,
& secnonce ,
& agg_share ,
& session ,
2024-08-12 23:02:56 +02:00
jtweak_cache = = NULL ? NULL : & tweak_cache
2024-08-12 22:15:17 +02:00
) ;
CHECKRESULT ( ! result , " secp256k1_frost_partial_sign failed " ) ;
2024-08-21 18:35:41 +02:00
unsigned char partial_sig_bytes [ 32 ] ;
result = secp256k1_frost_partial_sig_serialize ( ctx , partial_sig_bytes , & partial_sig ) ;
2024-08-12 22:15:17 +02:00
CHECKRESULT ( ! result , " secp256k1_frost_partial_sig_serialize failed " ) ;
2024-08-12 02:16:54 +02:00
2024-08-21 18:35:41 +02:00
jpsig = ( * penv ) - > NewByteArray ( penv , 32 ) ;
copy_bytes_to_java ( penv , jpsig , 32 , partial_sig_bytes ) ;
2024-08-12 22:15:17 +02:00
return jpsig ;
2024-08-12 02:16:54 +02:00
}
/*
* 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 )
{
2024-08-12 22:15:17 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_partial_sig partial_sig ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_pubnonce pubnonce ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_pubkey pubshare ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_session session ;
secp256k1_frost_tweak_cache tweak_cache ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
jbyte * ptr , * pubkeyBytes ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
size_t size , count ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
if ( jctx = = 0 )
2024-08-19 21:40:56 +02:00
return 0 ;
2024-08-12 02:16:54 +02:00
2024-08-12 23:02:56 +02:00
if ( jpartial_sig = = NULL )
2024-08-19 21:40:56 +02:00
return 0 ;
2024-08-12 23:02:56 +02:00
if ( jpubnonce = = NULL )
2024-08-19 21:40:56 +02:00
return 0 ;
2024-08-12 23:02:56 +02:00
if ( jpubshare = = NULL )
2024-08-19 21:40:56 +02:00
return 0 ;
2024-08-12 23:02:56 +02:00
if ( jsession = = NULL )
2024-08-19 21:40:56 +02:00
return 0 ;
int result = 0 ;
2024-08-12 23:02:56 +02:00
2024-08-12 22:15:17 +02:00
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 " ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
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 " ) ;
2024-08-12 02:16:54 +02:00
2024-08-19 21:40:56 +02:00
size = ( * penv ) - > GetArrayLength ( penv , jpubshare ) ;
CHECKRESULT ( ( size ! = 33 ) & & ( size ! = 65 ) , " invalid public share size " ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
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 " ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
size = ( * penv ) - > GetArrayLength ( penv , jsession ) ;
CHECKRESULT ( size ! = sizeof ( secp256k1_frost_session ) , " invalid session size " ) ;
copy_bytes_from_java ( penv , jsession , size , session . data ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 23:02:56 +02:00
if ( jtweak_cache ! = NULL )
{
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 ) ;
}
2024-08-12 22:15:17 +02:00
2024-08-19 21:40:56 +02:00
result = secp256k1_frost_partial_sig_verify (
2024-08-12 22:15:17 +02:00
ctx ,
& partial_sig ,
& pubnonce ,
& pubshare ,
& session ,
& tweak_cache
) ;
return result ;
2024-08-12 02:16:54 +02:00
}
2024-08-19 21:40:56 +02:00
void free_frost_partial_sigs ( secp256k1_frost_partial_sig * * psigs , size_t count )
2024-08-12 02:16:54 +02:00
{
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 )
{
2024-08-12 22:15:17 +02:00
secp256k1_context * ctx = ( secp256k1_context * ) jctx ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
unsigned char sig64 [ 64 ] ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
secp256k1_frost_session session ;
secp256k1_frost_partial_sig * * psigs ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
jbyteArray jpsig ;
jbyte * ptr ;
size_t size , count ;
size_t i ;
int result = 0 ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
if ( jctx = = 0 )
return NULL ;
2024-08-12 23:02:56 +02:00
2024-08-12 22:15:17 +02:00
if ( jsession = = NULL )
return NULL ;
2024-08-12 02:16:54 +02:00
2024-08-12 23:02:56 +02:00
if ( jpartial_sigs = = NULL )
return NULL ;
CHECKRESULT ( jn_sigs < = 0 , " n_sigs can't be 0 " ) ;
2024-08-12 22:15:17 +02:00
size = ( * penv ) - > GetArrayLength ( penv , jsession ) ;
CHECKRESULT ( size ! = sizeof ( secp256k1_frost_session ) , " invalid session size " ) ;
copy_bytes_from_java ( penv , jsession , size , session . data ) ;
2024-08-12 02:16:54 +02:00
2024-08-19 21:40:56 +02:00
count = ( * penv ) - > GetArrayLength ( penv , jpartial_sigs ) ;
2024-08-12 22:15:17 +02:00
CHECKRESULT ( count < = 0 , " partial sigs count cannot be 0 " ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
psigs = calloc ( count , sizeof ( secp256k1_frost_partial_sig * ) ) ;
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
for ( i = 0 ; i < count ; i + + )
{
psigs [ i ] = calloc ( 1 , sizeof ( secp256k1_frost_partial_sig ) ) ;
2024-08-19 21:40:56 +02:00
jpsig = ( jbyteArray ) ( * penv ) - > GetObjectArrayElement ( penv , jpartial_sigs , i ) ;
2024-08-12 22:15:17 +02:00
size = ( * penv ) - > GetArrayLength ( penv , jpsig ) ;
2024-08-19 21:40:56 +02:00
CHECKRESULT1 ( size ! = 32 , " invalid partial signature size " , free_frost_partial_sigs ( psigs , count ) ) ;
2024-08-12 22:15:17 +02:00
ptr = ( * penv ) - > GetByteArrayElements ( penv , jpsig , 0 ) ;
result = secp256k1_frost_partial_sig_parse ( ctx , psigs [ i ] , ( unsigned char * ) ptr ) ;
( * penv ) - > ReleaseByteArrayElements ( penv , jpsig , ptr , 0 ) ;
2024-08-19 21:40:56 +02:00
CHECKRESULT1 ( ! result , " secp256k1_frost_partial_sig_parse failed " , free_frost_partial_sigs ( psigs , count ) ) ;
2024-08-12 22:15:17 +02:00
}
2024-08-12 02:16:54 +02:00
2024-08-12 22:15:17 +02:00
result = secp256k1_frost_partial_sig_agg (
ctx ,
sig64 ,
& session ,
( const secp256k1_frost_partial_sig * const * ) psigs ,
jn_sigs
) ;
2024-08-19 21:40:56 +02:00
free_frost_partial_sigs ( psigs , count ) ;
2024-08-12 22:15:17 +02:00
CHECKRESULT ( ! result , " secp256k1_frost_partial_sig_agg failed " ) ;
2024-08-21 18:35:41 +02:00
jbyteArray jsig = ( * penv ) - > NewByteArray ( penv , 64 ) ;
copy_bytes_to_java ( penv , jsig , 64 , sig64 ) ;
return jsig ;
2024-08-04 23:53:28 +02:00
}