|
|
|
@ -14,28 +14,82 @@
|
|
|
|
|
#define SIG_FORMAT_COMPACT 1
|
|
|
|
|
#define SIG_FORMAT_DER 2
|
|
|
|
|
|
|
|
|
|
void JNI_ThrowByName(JNIEnv *penv, const char* name, const char* msg)
|
|
|
|
|
{
|
|
|
|
|
void JNI_ThrowByName(JNIEnv *penv, const char *name, const char *msg)
|
|
|
|
|
{
|
|
|
|
|
jclass cls = (*penv)->FindClass(penv, name);
|
|
|
|
|
if (cls != NULL) {
|
|
|
|
|
if (cls != NULL)
|
|
|
|
|
{
|
|
|
|
|
(*penv)->ThrowNew(penv, cls, msg);
|
|
|
|
|
(*penv)->DeleteLocalRef(penv, cls);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* secp256k1 uses callbacks for errors that are either hw pbs or bugs in the calling library, for example
|
|
|
|
|
* passing parameters with values that are explicitly defined as illegal in the API, and should never be called for normal operations
|
|
|
|
|
* But if they are, default behaviour is to print an error to stderr and abort which is not what we want especially in mobile apps
|
|
|
|
|
* => we set up string pointers in every method, and custom callback that will set them to the message passed in by sec256k1's callbacks, which
|
|
|
|
|
* we turn into specific Sec256k1 exceptions
|
|
|
|
|
*/
|
|
|
|
|
#define SETUP_ERROR_CALLBACKS \
|
|
|
|
|
char *error_callback_message = NULL; \
|
|
|
|
|
char *illegal_callback_message = NULL; \
|
|
|
|
|
secp256k1_context_set_error_callback(ctx, my_error_callback_fn, &error_callback_message); \
|
|
|
|
|
secp256k1_context_set_illegal_callback(ctx, my_illegal_callback_fn, &illegal_callback_message);
|
|
|
|
|
|
|
|
|
|
#define CHECKRESULT(errorcheck, message) \
|
|
|
|
|
{ \
|
|
|
|
|
if (error_callback_message) \
|
|
|
|
|
{ \
|
|
|
|
|
JNI_ThrowByName(penv, "fr/acinq/secp256k1/Secp256k1ErrorCallbackException", error_callback_message); \
|
|
|
|
|
return 0; \
|
|
|
|
|
} \
|
|
|
|
|
if (illegal_callback_message) \
|
|
|
|
|
{ \
|
|
|
|
|
JNI_ThrowByName(penv, "fr/acinq/secp256k1/Secp256k1IllegalCallbackException", illegal_callback_message); \
|
|
|
|
|
return 0; \
|
|
|
|
|
} \
|
|
|
|
|
if (errorcheck) \
|
|
|
|
|
{ \
|
|
|
|
|
JNI_ThrowByName(penv, "fr/acinq/secp256k1/Secp256k1Exception", message); \
|
|
|
|
|
return 0; \
|
|
|
|
|
} \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define CHECKRESULT(errorcheck, message) { \
|
|
|
|
|
if (errorcheck) { \
|
|
|
|
|
#define CHECKRESULT1(errorcheck, message, dosomething) \
|
|
|
|
|
{ \
|
|
|
|
|
if (error_callback_message) \
|
|
|
|
|
{ \
|
|
|
|
|
dosomething; \
|
|
|
|
|
JNI_ThrowByName(penv, "fr/acinq/secp256k1/Secp256k1ErrorCallbackException", error_callback_message); \
|
|
|
|
|
return 0; \
|
|
|
|
|
} \
|
|
|
|
|
if (illegal_callback_message) \
|
|
|
|
|
{ \
|
|
|
|
|
dosomething; \
|
|
|
|
|
JNI_ThrowByName(penv, "fr/acinq/secp256k1/Secp256k1IllegalCallbackException", illegal_callback_message); \
|
|
|
|
|
return 0; \
|
|
|
|
|
} \
|
|
|
|
|
if (errorcheck) \
|
|
|
|
|
{ \
|
|
|
|
|
JNI_ThrowByName(penv, "fr/acinq/secp256k1/Secp256k1Exception", message); \
|
|
|
|
|
return 0; \
|
|
|
|
|
} \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void my_illegal_callback_fn(const char *str, void *data)
|
|
|
|
|
{
|
|
|
|
|
if (data != NULL)
|
|
|
|
|
{
|
|
|
|
|
*(char **)data = str;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define CHECKRESULT1(errorcheck, message, dosomething) { \
|
|
|
|
|
if (errorcheck) { \
|
|
|
|
|
dosomething; \
|
|
|
|
|
JNI_ThrowByName(penv, "fr/acinq/secp256k1/Secp256k1Exception", message); \
|
|
|
|
|
return 0; \
|
|
|
|
|
} \
|
|
|
|
|
void my_error_callback_fn(const char *str, void *data)
|
|
|
|
|
{
|
|
|
|
|
if (data != NULL)
|
|
|
|
|
{
|
|
|
|
|
*(char **)data = str;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -43,10 +97,9 @@ void JNI_ThrowByName(JNIEnv *penv, const char* name, const char* msg)
|
|
|
|
|
* Method: secp256k1_context_create
|
|
|
|
|
* Signature: (I)J
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jlong JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1context_1create
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jint flags)
|
|
|
|
|
JNIEXPORT jlong JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1context_1create(JNIEnv *penv, jclass clazz, jint flags)
|
|
|
|
|
{
|
|
|
|
|
return (jlong) secp256k1_context_create(flags);
|
|
|
|
|
return (jlong)secp256k1_context_create(flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -54,11 +107,11 @@ JNIEXPORT jlong JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1c
|
|
|
|
|
* Method: secp256k1_context_destroy
|
|
|
|
|
* Signature: (J)V
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT void JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1context_1destroy
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong ctx)
|
|
|
|
|
JNIEXPORT void JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1context_1destroy(JNIEnv *penv, jclass clazz, jlong ctx)
|
|
|
|
|
{
|
|
|
|
|
if (ctx != 0) {
|
|
|
|
|
secp256k1_context_destroy((secp256k1_context*)ctx);
|
|
|
|
|
if (ctx != 0)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context_destroy((secp256k1_context *)ctx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -67,19 +120,23 @@ JNIEXPORT void JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1co
|
|
|
|
|
* Method: secp256k1_ec_seckey_verify
|
|
|
|
|
* Signature: (J[B)I
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1seckey_1verify
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey)
|
|
|
|
|
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1seckey_1verify(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jseckey == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if ((*penv)->GetArrayLength(penv, jseckey) != 32)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
seckey = (*penv)->GetByteArrayElements(penv, jseckey, 0);
|
|
|
|
|
result = secp256k1_ec_seckey_verify(ctx, (unsigned char*)seckey);
|
|
|
|
|
result = secp256k1_ec_seckey_verify(ctx, (unsigned char *)seckey);
|
|
|
|
|
(*penv)->ReleaseByteArrayElements(penv, jseckey, seckey, 0);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -89,30 +146,33 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec
|
|
|
|
|
* Method: secp256k1_ec_pubkey_parse
|
|
|
|
|
* Signature: (J[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1parse
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpubkey)
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1parse(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpubkey)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jpubkey == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
@ -123,28 +183,31 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_ec_pubkey_create
|
|
|
|
|
* Signature: (J[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1create
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey)
|
|
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
if (jseckey == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
@ -155,32 +218,36 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_ecdsa_sign
|
|
|
|
|
* Signature: (J[B[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdsa_1sign
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jmsg, jbyteArray jseckey)
|
|
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jmsg == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jseckey == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
@ -188,8 +255,10 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
|
|
|
|
|
int GetSignatureFormat(size_t size)
|
|
|
|
|
{
|
|
|
|
|
if (size == 64) return SIG_FORMAT_COMPACT;
|
|
|
|
|
if (size < 64) return SIG_FORMAT_UNKNOWN;
|
|
|
|
|
if (size == 64)
|
|
|
|
|
return SIG_FORMAT_COMPACT;
|
|
|
|
|
if (size < 64)
|
|
|
|
|
return SIG_FORMAT_UNKNOWN;
|
|
|
|
|
return SIG_FORMAT_DER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -198,20 +267,25 @@ int GetSignatureFormat(size_t size)
|
|
|
|
|
* Method: secp256k1_ecdsa_verify
|
|
|
|
|
* Signature: (J[B[B[B)I
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdsa_1verify
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jsig, jbyteArray jmsg, jbyteArray jpubkey)
|
|
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jsig == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jmsg == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jpubkey == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
sigSize = (*penv)->GetArrayLength(penv, jsig);
|
|
|
|
|
int sigFormat = GetSignatureFormat(sigSize);
|
|
|
|
@ -223,26 +297,27 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec
|
|
|
|
|
CHECKRESULT((*penv)->GetArrayLength(penv, jmsg) != 32, "message must be 32 bytes");
|
|
|
|
|
|
|
|
|
|
sig = (*penv)->GetByteArrayElements(penv, jsig, 0);
|
|
|
|
|
switch(sigFormat) {
|
|
|
|
|
switch (sigFormat)
|
|
|
|
|
{
|
|
|
|
|
case SIG_FORMAT_COMPACT:
|
|
|
|
|
result = secp256k1_ecdsa_signature_parse_compact(ctx, &signature, (unsigned char*)sig);
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
result = secp256k1_ecdsa_verify(ctx, &signature, (unsigned char *)msg, &pubkey);
|
|
|
|
|
(*penv)->ReleaseByteArrayElements(penv, jmsg, msg, 0);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -252,10 +327,9 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec
|
|
|
|
|
* Method: secp256k1_ecdsa_signature_normalize
|
|
|
|
|
* Signature: (J[B[B)I
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdsa_1signature_1normalize
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jsigin, jbyteArray jsigout)
|
|
|
|
|
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;
|
|
|
|
|
secp256k1_context *ctx = (secp256k1_context *)jctx;
|
|
|
|
|
jbyte *sig;
|
|
|
|
|
secp256k1_ecdsa_signature signature_in, signature_out;
|
|
|
|
|
size_t size;
|
|
|
|
@ -263,9 +337,14 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec
|
|
|
|
|
int return_value = 0;
|
|
|
|
|
int sigFormat = SIG_FORMAT_UNKNOWN;
|
|
|
|
|
|
|
|
|
|
if (jctx == 0) return 0;
|
|
|
|
|
if (jsigin == NULL) return 0;
|
|
|
|
|
if (jsigout == NULL) return 0;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jsigin == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jsigout == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
size = (*penv)->GetArrayLength(penv, jsigin);
|
|
|
|
|
sigFormat = GetSignatureFormat(size);
|
|
|
|
@ -273,21 +352,22 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec
|
|
|
|
|
CHECKRESULT((*penv)->GetArrayLength(penv, jsigout) != 64, "output signature length must be 64 bytes");
|
|
|
|
|
|
|
|
|
|
sig = (*penv)->GetByteArrayElements(penv, jsigin, 0);
|
|
|
|
|
switch(sigFormat) {
|
|
|
|
|
switch (sigFormat)
|
|
|
|
|
{
|
|
|
|
|
case SIG_FORMAT_COMPACT:
|
|
|
|
|
result = secp256k1_ecdsa_signature_parse_compact(ctx, &signature_in, (unsigned char*)sig);
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
|
@ -299,18 +379,22 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec
|
|
|
|
|
* Method: secp256k1_ec_privkey_negate
|
|
|
|
|
* Signature: (J[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1privkey_1negate
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey)
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1privkey_1negate(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
secp256k1_context *ctx = (secp256k1_context *)jctx;
|
|
|
|
|
jbyte *seckey;
|
|
|
|
|
int result = 0;
|
|
|
|
|
|
|
|
|
|
if (jctx == 0) return 0;
|
|
|
|
|
if (jseckey == NULL) return 0;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jseckey == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
result = secp256k1_ec_seckey_negate(ctx, (unsigned char *)seckey);
|
|
|
|
|
(*penv)->ReleaseByteArrayElements(penv, jseckey, seckey, 0);
|
|
|
|
|
CHECKRESULT(!result, "secp256k1_ec_seckey_negate failed");
|
|
|
|
|
return jseckey;
|
|
|
|
@ -321,22 +405,25 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_ec_pubkey_negate
|
|
|
|
|
* Signature: (J[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1negate
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpubkey)
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1negate(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpubkey)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jpubkey == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
result = secp256k1_ec_pubkey_parse(ctx, &pubkey, (unsigned char *)pub, size);
|
|
|
|
|
(*penv)->ReleaseByteArrayElements(penv, jpubkey, pub, 0);
|
|
|
|
|
CHECKRESULT(!result, "secp256k1_ec_pubkey_parse failed");
|
|
|
|
|
|
|
|
|
@ -346,7 +433,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
@ -357,22 +444,26 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_ec_privkey_tweak_add
|
|
|
|
|
* Signature: (J[B[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1privkey_1tweak_1add
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey, jbyteArray jtweak)
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1privkey_1tweak_1add(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey, jbyteArray jtweak)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jseckey == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jtweak == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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");
|
|
|
|
@ -384,37 +475,41 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_ec_pubkey_tweak_add
|
|
|
|
|
* Signature: (J[B[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1tweak_1add
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpubkey, jbyteArray jtweak)
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1tweak_1add(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpubkey, jbyteArray jtweak)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jpubkey == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jtweak == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
@ -425,22 +520,26 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_ec_privkey_tweak_mul
|
|
|
|
|
* Signature: (J[B[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1privkey_1tweak_1mul
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey, jbyteArray jtweak)
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1privkey_1tweak_1mul(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey, jbyteArray jtweak)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jseckey == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jtweak == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
@ -452,36 +551,40 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_ec_pubkey_tweak_mul
|
|
|
|
|
* Signature: (J[B[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1tweak_1mul
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpubkey, jbyteArray jtweak)
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1tweak_1mul(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jpubkey, jbyteArray jtweak)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jpubkey == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jtweak == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
@ -490,8 +593,10 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
void free_pubkeys(secp256k1_pubkey **pubkeys, size_t count)
|
|
|
|
|
{
|
|
|
|
|
size_t i;
|
|
|
|
|
for(i = 0; i < count; i++) {
|
|
|
|
|
if (pubkeys[i] != NULL) free(pubkeys[i]);
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (pubkeys[i] != NULL)
|
|
|
|
|
free(pubkeys[i]);
|
|
|
|
|
}
|
|
|
|
|
free(pubkeys);
|
|
|
|
|
}
|
|
|
|
@ -501,10 +606,9 @@ void free_pubkeys(secp256k1_pubkey **pubkeys, size_t count)
|
|
|
|
|
* Method: secp256k1_ec_pubkey_combine
|
|
|
|
|
* Signature: (J[[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1combine
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jobjectArray jpubkeys)
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1combine(JNIEnv *penv, jclass clazz, jlong jctx, jobjectArray jpubkeys)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
secp256k1_context *ctx = (secp256k1_context *)jctx;
|
|
|
|
|
jbyte *pub;
|
|
|
|
|
secp256k1_pubkey **pubkeys;
|
|
|
|
|
secp256k1_pubkey combined;
|
|
|
|
@ -513,30 +617,35 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
size_t i;
|
|
|
|
|
int result = 0;
|
|
|
|
|
|
|
|
|
|
if (jctx == 0) return NULL;
|
|
|
|
|
if (jpubkeys == NULL) return NULL;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jpubkeys == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
count = (*penv)->GetArrayLength(penv, jpubkeys);
|
|
|
|
|
pubkeys = calloc(count, sizeof(secp256k1_pubkey*));
|
|
|
|
|
pubkeys = calloc(count, sizeof(secp256k1_pubkey *));
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < count; i++) {
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
pubkeys[i] = calloc(1, sizeof(secp256k1_pubkey));
|
|
|
|
|
jpubkey = (jbyteArray) (*penv)->GetObjectArrayElement(penv, jpubkeys, i);
|
|
|
|
|
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));
|
|
|
|
|
pub = (*penv)->GetByteArrayElements(penv, jpubkey, 0);
|
|
|
|
|
result = secp256k1_ec_pubkey_parse(ctx, pubkeys[i], (unsigned char*)pub, size);
|
|
|
|
|
result = secp256k1_ec_pubkey_parse(ctx, pubkeys[i], (unsigned char *)pub, size);
|
|
|
|
|
(*penv)->ReleaseByteArrayElements(penv, jpubkey, pub, 0);
|
|
|
|
|
CHECKRESULT1(!result, "secp256k1_ec_pubkey_parse failed", free_pubkeys(pubkeys, count));
|
|
|
|
|
}
|
|
|
|
|
result = secp256k1_ec_pubkey_combine(ctx, &combined, (const secp256k1_pubkey * const *)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);
|
|
|
|
|
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;
|
|
|
|
@ -547,33 +656,37 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_ecdh
|
|
|
|
|
* Signature: (J[B[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdh
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey, jbyteArray jpubkey)
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdh(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jseckey, jbyteArray jpubkey)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
jbyte* seckeyBytes, *pubkeyBytes, *output;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jseckey == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jpubkey == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
@ -584,11 +697,10 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_ecdsa_recover
|
|
|
|
|
* Signature: (J[B[BI)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1ecdsa_1recover
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jsig, jbyteArray jmsg, jint recid)
|
|
|
|
|
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;
|
|
|
|
|
secp256k1_context *ctx = (secp256k1_context *)jctx;
|
|
|
|
|
jbyte *sig, *msg, *pub;
|
|
|
|
|
jbyteArray jpubkey;
|
|
|
|
|
secp256k1_pubkey pubkey;
|
|
|
|
|
secp256k1_ecdsa_recoverable_signature signature;
|
|
|
|
@ -597,23 +709,32 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
size_t sigSize, size;
|
|
|
|
|
int result;
|
|
|
|
|
|
|
|
|
|
if (jctx == 0) return NULL;
|
|
|
|
|
if (jsig == NULL) return NULL;
|
|
|
|
|
if (jmsg == NULL) return NULL;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jsig == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jmsg == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
// we do not check that recid is valid, which should trigger our illegal callback handler to throw a Secp256k1IllegalCallbackException
|
|
|
|
|
// CHECKRESULT(recid < 0 || recid > 3, "recid must be 0, 1, 2 or 3")
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
switch (sigFormat)
|
|
|
|
|
{
|
|
|
|
|
case SIG_FORMAT_COMPACT:
|
|
|
|
|
result = secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &signature, (unsigned char*)sig, recid);
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
@ -623,14 +744,14 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
msg = (*penv)->GetByteArrayElements(penv, jmsg, 0);
|
|
|
|
|
result = secp256k1_ecdsa_recover(ctx, &pubkey, &signature, (unsigned char*)msg);
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
@ -641,23 +762,27 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_compact_to_der
|
|
|
|
|
* Signature: (J[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1compact_1to_1der
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jsig)
|
|
|
|
|
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;
|
|
|
|
|
secp256k1_context *ctx = (secp256k1_context *)jctx;
|
|
|
|
|
jbyte *sig;
|
|
|
|
|
secp256k1_ecdsa_signature signature;;
|
|
|
|
|
secp256k1_ecdsa_signature signature;
|
|
|
|
|
unsigned char der[73];
|
|
|
|
|
size_t size;
|
|
|
|
|
int result = 0;
|
|
|
|
|
|
|
|
|
|
if (jctx == 0) return 0;
|
|
|
|
|
if (jsig == NULL) return 0;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jsig == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
|
@ -676,23 +801,28 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_schnorrsig_sign
|
|
|
|
|
* Signature: (J[B[B[B)[B
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1schnorrsig_1sign
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jmsg, jbyteArray jseckey, jbyteArray jauxrand32)
|
|
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jmsg == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (jseckey == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
if (jauxrand32 != 0)
|
|
|
|
|
{
|
|
|
|
|
CHECKRESULT((*penv)->GetArrayLength(penv, jauxrand32) != 32, "auxiliary random data must be 32 bytes");
|
|
|
|
|
}
|
|
|
|
|
seckey = (*penv)->GetByteArrayElements(penv, jseckey, 0);
|
|
|
|
@ -701,13 +831,15 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
CHECKRESULT(!result, "secp256k1_keypair_create failed");
|
|
|
|
|
|
|
|
|
|
msg = (*penv)->GetByteArrayElements(penv, jmsg, 0);
|
|
|
|
|
if (jauxrand32 != 0) {
|
|
|
|
|
if (jauxrand32 != 0)
|
|
|
|
|
{
|
|
|
|
|
auxrand32 = (*penv)->GetByteArrayElements(penv, jauxrand32, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = secp256k1_schnorrsig_sign32(ctx, signature, (unsigned char*)msg, &keypair, auxrand32);
|
|
|
|
|
result = secp256k1_schnorrsig_sign32(ctx, signature, (unsigned char *)msg, &keypair, auxrand32);
|
|
|
|
|
(*penv)->ReleaseByteArrayElements(penv, jmsg, msg, 0);
|
|
|
|
|
if (auxrand32 != 0) {
|
|
|
|
|
if (auxrand32 != 0)
|
|
|
|
|
{
|
|
|
|
|
(*penv)->ReleaseByteArrayElements(penv, jauxrand32, auxrand32, 0);
|
|
|
|
|
}
|
|
|
|
|
CHECKRESULT(!result, "secp256k1_schnorrsig_sign failed");
|
|
|
|
@ -724,31 +856,36 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
|
|
|
|
* Method: secp256k1_schnorrsig_verify
|
|
|
|
|
* Signature: (J[B[B[B)I
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1schnorrsig_1verify
|
|
|
|
|
(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jsig, jbyteArray jmsg, jbyteArray jpubkey)
|
|
|
|
|
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1schnorrsig_1verify(JNIEnv *penv, jclass clazz, jlong jctx, jbyteArray jsig, jbyteArray jmsg, jbyteArray jpubkey)
|
|
|
|
|
{
|
|
|
|
|
secp256k1_context* ctx = (secp256k1_context *)jctx;
|
|
|
|
|
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;
|
|
|
|
|
if (jctx == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jsig == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jmsg == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if (jpubkey == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
SETUP_ERROR_CALLBACKS
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
result = secp256k1_xonly_pubkey_parse(ctx, &pubkey, (unsigned char *)pub);
|
|
|
|
|
(*penv)->ReleaseByteArrayElements(penv, jpubkey, pub, 0);
|
|
|
|
|
CHECKRESULT(!result, "secp256k1_ec_pubkey_parse failed");
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
|