1515#define SIG_FORMAT_COMPACT 1
1616#define SIG_FORMAT_DER 2
1717
18+ #define MAX_PUBKEY_COUNT 200
19+ #define MAX_NONCE_COUNT 200
20+ #define MAX_PSIGS_COUNT 200
21+
22+ #define STR_HELPER (x ) #x
23+ #define STR (x ) STR_HELPER(x)
24+
25+
1826static void JNI_ThrowByName (JNIEnv * penv , const char * name , const char * msg )
1927{
2028 jclass cls = (* penv )-> FindClass (penv , name );
@@ -475,18 +483,6 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
475483 return jpubkey ;
476484}
477485
478- static void free_pubkeys (secp256k1_pubkey * * pubkeys , size_t count )
479- {
480- size_t i ;
481- if (pubkeys == NULL ) return ;
482- for (i = 0 ; i < count ; i ++ )
483- {
484- if (pubkeys [i ] != NULL )
485- free (pubkeys [i ]);
486- }
487- free (pubkeys );
488- }
489-
490486/*
491487 * Class: fr_acinq_bitcoin_Secp256k1Bindings
492488 * Method: secp256k1_ec_pubkey_combine
@@ -496,7 +492,8 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
496492{
497493 const secp256k1_context * ctx = (const secp256k1_context * )jctx ;
498494 jbyte pub [65 ];
499- secp256k1_pubkey * * pubkeys ;
495+ static secp256k1_pubkey pubkeys [MAX_PUBKEY_COUNT ];
496+ const secp256k1_pubkey * pubkeys_ptr [MAX_PUBKEY_COUNT ];
500497 secp256k1_pubkey combined ;
501498 jbyteArray jpubkey ;
502499 size_t size , count ;
@@ -508,24 +505,21 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
508505 if (jpubkeys == NULL )
509506 return NULL ;
510507
508+ for (i = 0 ; i < MAX_PUBKEY_COUNT ; i ++ ) pubkeys_ptr [i ] = & pubkeys [i ];
511509 count = (* penv )-> GetArrayLength (penv , jpubkeys );
512510 CHECKRESULT (count < 1 , "pubkey array cannot be empty" )
513- pubkeys = calloc (count , sizeof (secp256k1_pubkey * ));
514- CHECKRESULT (pubkeys == NULL , "memory allocation failed" );
511+ CHECKRESULT (count > MAX_PUBKEY_COUNT , "pubkey array cannot be greater than " STR (MAX_PUBKEY_COUNT ))
515512
516513 for (i = 0 ; i < count ; i ++ )
517514 {
518- pubkeys [i ] = calloc (1 , sizeof (secp256k1_pubkey ));
519- CHECKRESULT1 (pubkeys [i ] == NULL , "memory allocation failed" , free_pubkeys (pubkeys , i ));
520515 jpubkey = (jbyteArray )(* penv )-> GetObjectArrayElement (penv , jpubkeys , i );
521516 size = (* penv )-> GetArrayLength (penv , jpubkey );
522- CHECKRESULT1 ((size != 33 ) && (size != 65 ), "invalid public key size" , free_pubkeys ( pubkeys , i ) );
517+ CHECKRESULT ((size != 33 ) && (size != 65 ), "invalid public key size" );
523518 (* penv )-> GetByteArrayRegion (penv , jpubkey , 0 , size , pub );
524- result = secp256k1_ec_pubkey_parse (ctx , pubkeys [i ], (unsigned char * )pub , size );
525- CHECKRESULT1 (!result , "secp256k1_ec_pubkey_parse failed" , free_pubkeys ( pubkeys , i ) );
519+ result = secp256k1_ec_pubkey_parse (ctx , & pubkeys [i ], (unsigned char * )pub , size );
520+ CHECKRESULT (!result , "secp256k1_ec_pubkey_parse failed" );
526521 }
527- result = secp256k1_ec_pubkey_combine (ctx , & combined , (const secp256k1_pubkey * const * )pubkeys , count );
528- free_pubkeys (pubkeys , count );
522+ result = secp256k1_ec_pubkey_combine (ctx , & combined , pubkeys_ptr , count );
529523 CHECKRESULT (!result , "secp256k1_ec_pubkey_combine failed" );
530524
531525 size = 65 ;
@@ -869,18 +863,6 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
869863 return jnonce ;
870864}
871865
872- static void free_nonces (secp256k1_musig_pubnonce * * nonces , size_t count )
873- {
874- size_t i ;
875- if (nonces == NULL ) return ;
876- for (i = 0 ; i < count ; i ++ )
877- {
878- if (nonces [i ] != NULL )
879- free (nonces [i ]);
880- }
881- free (nonces );
882- }
883-
884866/*
885867 * Class: fr_acinq_secp256k1_Secp256k1CFunctions
886868 * Method: secp256k1_musig_nonce_agg
@@ -890,7 +872,8 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
890872{
891873 const secp256k1_context * ctx = (const secp256k1_context * )jctx ;
892874 jbyte in66 [fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE ];
893- secp256k1_musig_pubnonce * * pubnonces ;
875+ static secp256k1_musig_pubnonce pubnonces [MAX_NONCE_COUNT ];
876+ const secp256k1_musig_pubnonce * pubnonces_ptr [MAX_NONCE_COUNT ];
894877 secp256k1_musig_aggnonce combined ;
895878 jbyteArray jnonce ;
896879 size_t size , count ;
@@ -899,31 +882,22 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
899882
900883 if (jctx == 0 ) return NULL ;
901884 if (jnonces == NULL ) return NULL ;
885+ for (i = 0 ; i < MAX_NONCE_COUNT ; i ++ ) pubnonces_ptr [i ] = & pubnonces [i ];
902886
903887 count = (* penv )-> GetArrayLength (penv , jnonces );
904888 CHECKRESULT (count == 0 , "public nonces count cannot be 0" );
905- for (i = 0 ; i < count ; i ++ )
906- {
907- jnonce = (jbyteArray )(* penv )-> GetObjectArrayElement (penv , jnonces , i );
908- size = (* penv )-> GetArrayLength (penv , jnonce );
909- CHECKRESULT (size != fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE , "invalid public nonce size" );
910- }
911-
912- pubnonces = calloc (count , sizeof (secp256k1_musig_pubnonce * ));
913- CHECKRESULT (pubnonces == NULL , "memory allocation error" );
889+ CHECKRESULT (count > MAX_NONCE_COUNT , "public nonces count cannot be greater than " STR (MAX_NONCE_COUNT ));
914890
915891 for (i = 0 ; i < count ; i ++ )
916892 {
917- pubnonces [i ] = calloc (1 , sizeof (secp256k1_musig_pubnonce ));
918- CHECKRESULT1 (pubnonces [i ] == NULL , "memory allocation error" , free_nonces (pubnonces , i ));
919893 jnonce = (jbyteArray )(* penv )-> GetObjectArrayElement (penv , jnonces , i );
920894 size = fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE ;
895+ CHECKRESULT (size != fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_PUBLIC_NONCE_SIZE , "invalid public nonce size" );
921896 (* penv )-> GetByteArrayRegion (penv , jnonce , 0 , size , in66 );
922- result = secp256k1_musig_pubnonce_parse (ctx , pubnonces [i ], (unsigned char * )in66 );
923- CHECKRESULT1 (!result , "secp256k1_musig_pubnonce_parse failed" , free_nonces ( pubnonces , i ) );
897+ result = secp256k1_musig_pubnonce_parse (ctx , & pubnonces [i ], (unsigned char * )in66 );
898+ CHECKRESULT (!result , "secp256k1_musig_pubnonce_parse failed" );
924899 }
925- result = secp256k1_musig_nonce_agg (ctx , & combined , (const secp256k1_musig_pubnonce * const * )pubnonces , count );
926- free_nonces (pubnonces , count );
900+ result = secp256k1_musig_nonce_agg (ctx , & combined , pubnonces_ptr , count );
927901 CHECKRESULT (!result , "secp256k1_musig_nonce_agg failed" );
928902
929903 result = secp256k1_musig_aggnonce_serialize (ctx , (unsigned char * )in66 , & combined );
@@ -942,24 +916,21 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
942916{
943917 const secp256k1_context * ctx = (const secp256k1_context * )jctx ;
944918 jbyte pub [65 ];
945- secp256k1_pubkey * * pubkeys ;
919+ static secp256k1_pubkey pubkeys [MAX_PUBKEY_COUNT ];
920+ const secp256k1_pubkey * pubkeys_ptr [MAX_PUBKEY_COUNT ];
946921 secp256k1_xonly_pubkey combined ;
947922 secp256k1_musig_keyagg_cache keyaggcache ;
948923 jbyteArray jpubkey ;
949924 size_t size , count ;
950925 size_t i ;
951926 int result = 0 ;
952927
928+ for (i = 0 ; i < MAX_PUBKEY_COUNT ; i ++ ) pubkeys_ptr [i ] = & (pubkeys [i ]);
953929 if (jctx == 0 ) return NULL ;
954930 if (jpubkeys == NULL ) return NULL ;
955931 count = (* penv )-> GetArrayLength (penv , jpubkeys );
956932 CHECKRESULT (count == 0 , "pubkeys count cannot be 0" );
957- for (i = 0 ; i < count ; i ++ )
958- {
959- jpubkey = (jbyteArray )(* penv )-> GetObjectArrayElement (penv , jpubkeys , i );
960- size = (* penv )-> GetArrayLength (penv , jpubkey );
961- CHECKRESULT ((size != 33 ) && (size != 65 ), "invalid public key size" );
962- }
933+ CHECKRESULT (count > MAX_PUBKEY_COUNT , "pubkeys count cannot be greater than " STR (MAX_PUBKEY_COUNT ));
963934
964935 if (jkeyaggcache != NULL )
965936 {
@@ -968,21 +939,16 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
968939 (* penv )-> GetByteArrayRegion (penv , jkeyaggcache , 0 , size , keyaggcache .data );
969940 }
970941
971- pubkeys = calloc (count , sizeof (secp256k1_pubkey * ));
972- CHECKRESULT (pubkeys == NULL , "memory allocation error" );
973-
974942 for (i = 0 ; i < count ; i ++ )
975943 {
976- pubkeys [i ] = calloc (1 , sizeof (secp256k1_pubkey ));
977- CHECKRESULT1 (pubkeys [i ] == NULL , "memory allocation error" , free_pubkeys (pubkeys , i ));
978944 jpubkey = (jbyteArray )(* penv )-> GetObjectArrayElement (penv , jpubkeys , i );
979945 size = (* penv )-> GetArrayLength (penv , jpubkey );
946+ CHECKRESULT ((size != 33 ) && (size != 65 ), "invalid public key size" );
980947 (* penv )-> GetByteArrayRegion (penv , jpubkey , 0 , size , pub );
981- result = secp256k1_ec_pubkey_parse (ctx , pubkeys [i ], (unsigned char * )pub , size );
982- CHECKRESULT1 (!result , "secp256k1_ec_pubkey_parse failed" , free_pubkeys ( pubkeys , i ) );
948+ result = secp256k1_ec_pubkey_parse (ctx , & pubkeys [i ], (unsigned char * )pub , size );
949+ CHECKRESULT (!result , "secp256k1_ec_pubkey_parse failed" );
983950 }
984- result = secp256k1_musig_pubkey_agg (ctx , & combined , jkeyaggcache == NULL ? NULL : & keyaggcache , (const secp256k1_pubkey * const * )pubkeys , count );
985- free_pubkeys (pubkeys , count );
951+ result = secp256k1_musig_pubkey_agg (ctx , & combined , jkeyaggcache == NULL ? NULL : & keyaggcache , pubkeys_ptr , count );
986952 CHECKRESULT (!result , "secp256k1_musig_pubkey_agg failed" );
987953 result = secp256k1_xonly_pubkey_serialize (ctx , (unsigned char * )pub , & combined );
988954 CHECKRESULT (!result , "secp256k1_xonly_pubkey_serialize failed" );
@@ -1222,18 +1188,6 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1mu
12221188 return result ;
12231189}
12241190
1225- static void free_partial_sigs (secp256k1_musig_partial_sig * * psigs , size_t count )
1226- {
1227- size_t i ;
1228- if (psigs == NULL ) return ;
1229- for (i = 0 ; i < count ; i ++ )
1230- {
1231- if (psigs [i ] != NULL )
1232- free (psigs [i ]);
1233- }
1234- free (psigs );
1235- }
1236-
12371191/*
12381192 * Class: fr_acinq_secp256k1_Secp256k1CFunctions
12391193 * Method: secp256k1_musig_partial_sig_agg
@@ -1243,13 +1197,16 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
12431197{
12441198 const secp256k1_context * ctx = (const secp256k1_context * )jctx ;
12451199 secp256k1_musig_session session ;
1246- secp256k1_musig_partial_sig * * psigs ;
1200+ static secp256k1_musig_partial_sig psigs [MAX_PSIGS_COUNT ];
1201+ const secp256k1_musig_partial_sig * psigs_ptr [MAX_PSIGS_COUNT ];
1202+
12471203 unsigned char sig64 [64 ];
12481204 jbyteArray jpsig ;
12491205 size_t size , count ;
12501206 size_t i ;
12511207 int result = 0 ;
12521208
1209+ for (i = 0 ; i < MAX_PSIGS_COUNT ; i ++ ) psigs_ptr [i ] = & (psigs [i ]);
12531210 if (jctx == 0 ) return NULL ;
12541211 if (jsession == NULL ) return NULL ;
12551212 CHECKRESULT ((* penv )-> GetArrayLength (penv , jsession ) != fr_acinq_secp256k1_Secp256k1CFunctions_SECP256K1_MUSIG_SESSION_SIZE , "invalid session size" );
@@ -1258,23 +1215,18 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
12581215 if (jpsigs == NULL ) return NULL ;
12591216 count = (* penv )-> GetArrayLength (penv , jpsigs );
12601217 CHECKRESULT (count == 0 , "partial sigs count cannot be 0" );
1261-
1262- psigs = calloc (count , sizeof (secp256k1_musig_partial_sig * ));
1263- CHECKRESULT (psigs == NULL , "memory allocation error" );
1218+ CHECKRESULT (count > MAX_PSIGS_COUNT , "partial sigs count cannot greater than " STR (MAX_PSIGS_COUNT ));
12641219
12651220 for (i = 0 ; i < count ; i ++ )
12661221 {
1267- psigs [i ] = calloc (1 , sizeof (secp256k1_musig_partial_sig ));
1268- CHECKRESULT1 (psigs [i ] == NULL , "memory allocation error" , free_partial_sigs (psigs , i ));
12691222 jpsig = (jbyteArray )(* penv )-> GetObjectArrayElement (penv , jpsigs , i );
12701223 size = (* penv )-> GetArrayLength (penv , jpsig );
1271- CHECKRESULT1 (size != 32 , "invalid partial signature size" , free_partial_sigs ( psigs , i ) );
1224+ CHECKRESULT (size != 32 , "invalid partial signature size" );
12721225 (* penv )-> GetByteArrayRegion (penv , jpsig , 0 , 32 , (jbyte * )sig64 );
1273- result = secp256k1_musig_partial_sig_parse (ctx , psigs [i ], sig64 );
1274- CHECKRESULT1 (!result , "secp256k1_musig_partial_sig_parse failed" , free_partial_sigs ( psigs , i ) );
1226+ result = secp256k1_musig_partial_sig_parse (ctx , & ( psigs [i ]) , sig64 );
1227+ CHECKRESULT (!result , "secp256k1_musig_partial_sig_parse failed" );
12751228 }
1276- result = secp256k1_musig_partial_sig_agg (ctx , sig64 , & session , (const secp256k1_musig_partial_sig * const * )psigs , count );
1277- free_partial_sigs (psigs , count );
1229+ result = secp256k1_musig_partial_sig_agg (ctx , sig64 , & session , psigs_ptr , count );
12781230 CHECKRESULT (!result , "secp256k1_musig_pubkey_agg failed" );
12791231
12801232 jpsig = (* penv )-> NewByteArray (penv , 64 );
0 commit comments