JNI built in JNI

This commit is contained in:
Salomon BRYS
2020-07-01 18:26:24 +02:00
parent 6e4763e55b
commit 3b3d67a4fe
15 changed files with 95 additions and 40 deletions

View File

@@ -41,5 +41,5 @@ make
cd ..
mkdir -p build/android/$ARCH
cp -v secp256k1/.libs/libsecp256k1.a build/android/$ARCH
mkdir -p build/android-$ARCH
cp -v secp256k1/.libs/libsecp256k1.a build/android-$ARCH

View File

@@ -4,29 +4,23 @@ val currentOs = org.gradle.internal.os.OperatingSystem.current()
val buildSecp256k1 by tasks.creating { group = "build" }
val generateJniHeaders by tasks.creating(Sync::class) {
group = "build"
dependsOn(":jni:generateJniHeaders")
from(rootDir.resolve("jni/build/generated/jni"))
into(projectDir.resolve("jni/headers/java"))
}
sealed class Cross {
abstract fun cmd(target: String, nativeDir: File): List<String>
abstract fun cmd(target: String, project: Project): List<String>
class DockCross(val cross: String) : Cross() {
override fun cmd(target: String, nativeDir: File): List<String> = listOf("./dockcross-$cross", "bash", "-c", "CROSS=1 TARGET=$target ./build.sh")
override fun cmd(target: String, project: Project): List<String> = listOf("${project.rootDir}/cross-scripts/dockcross-$cross", "bash", "-c", "CROSS=1 TARGET=$target ./build.sh")
}
class MultiArch(val crossTriple: String) : Cross() {
override fun cmd(target: String, nativeDir: File): List<String> {
override fun cmd(target: String, project: Project): List<String> {
val uid = Runtime.getRuntime().exec("id -u").inputStream.use { it.reader().readText() }.trim().toInt()
return listOf(
"docker", "run", "--rm", "-v", "${nativeDir.absolutePath}:/workdir",
"docker", "run", "--rm", "-v", "${project.projectDir.absolutePath}:/workdir",
"-e", "CROSS_TRIPLE=$crossTriple", "-e", "TARGET=$target", "-e", "TO_UID=$uid", "-e", "CROSS=1",
"multiarch/crossbuild", "./build.sh"
)
}
}
}
val buildSecp256k1Jvm by tasks.creating {
group = "build"
buildSecp256k1.dependsOn(this)
@@ -40,7 +34,7 @@ fun creatingBuildSecp256k1(target: String, cross: Cross?) = tasks.creating(Exec:
workingDir = projectDir
environment("TARGET", target)
commandLine((cross?.cmd(target, workingDir) ?: emptyList()) + "./build.sh")
commandLine((cross?.cmd(target, project) ?: emptyList()) + "./build.sh")
}
val buildSecp256k1Darwin by creatingBuildSecp256k1("darwin", if (currentOs.isMacOsX) null else Cross.MultiArch("x86_64-apple-darwin"))
val buildSecp256k1Linux by creatingBuildSecp256k1("linux", if (currentOs.isLinux) null else Cross.DockCross("linux-x64"))

View File

@@ -7,6 +7,8 @@ if [ "$(id -u)" == "0" ]; then
[[ -z "$TO_UID" ]] && echo "Please set the TO_UID variable" && exit 1
fi
cd "$(dirname "$0")"
cd secp256k1
if [ "$TARGET" == "mingw" ]; then
@@ -32,26 +34,4 @@ cp -v secp256k1/.libs/libsecp256k1.a build/$TARGET/
[[ ! -z "$TO_UID" ]] && chown -R $TO_UID:$TO_UID build
CC=gcc
JNI_HEADERS=$TARGET
if [ "$TARGET" == "linux" ]; then
OUTFILE=libsecp256k1-jni.so
ADD_LIB=-lgmp
elif [ "$TARGET" == "darwin" ]; then
OUTFILE=libsecp256k1-jni.dylib
if [ -z "$CROSS_TRIPLE" ]; then
ADD_LIB=-lgmp
fi
elif [ "$TARGET" == "mingw" ]; then
OUTFILE=secp256k1-jni.dll
CC=/usr/src/mxe/usr/bin/x86_64-w64-mingw32.static-gcc
JNI_HEADERS=linux
CC_OPTS="-fpic"
fi
$CC -shared $CC_OPTS -o build/$TARGET/$OUTFILE jni/src/org_bitcoin_Secp256k1CFunctions.c -Ijni/headers/ -Ijni/headers/java -Ijni/headers/$JNI_HEADERS/ -Isecp256k1/ -lsecp256k1 -Lbuild/$TARGET/ $ADD_LIB
[[ ! -z "$TO_UID" ]] && chown -R $TO_UID:$TO_UID build
echo "Build done for $TARGET"

View File

@@ -1,256 +0,0 @@
#!/usr/bin/env bash
DEFAULT_DOCKCROSS_IMAGE=dockcross/linux-x64:latest
#------------------------------------------------------------------------------
# Helpers
#
err() {
echo -e >&2 ERROR: $@\\n
}
die() {
err $@
exit 1
}
has() {
# eg. has command update
local kind=$1
local name=$2
type -t $kind:$name | grep -q function
}
#------------------------------------------------------------------------------
# Command handlers
#
command:update-image() {
docker pull $FINAL_IMAGE
}
help:update-image() {
echo Pull the latest $FINAL_IMAGE .
}
command:update-script() {
if cmp -s <( docker run --rm $FINAL_IMAGE ) $0; then
echo $0 is up to date
else
echo -n Updating $0 '... '
docker run --rm $FINAL_IMAGE > $0 && echo ok
fi
}
help:update-image() {
echo Update $0 from $FINAL_IMAGE .
}
command:update() {
command:update-image
command:update-script
}
help:update() {
echo Pull the latest $FINAL_IMAGE, and then update $0 from that.
}
command:help() {
if [[ $# != 0 ]]; then
if ! has command $1; then
err \"$1\" is not an dockcross command
command:help
elif ! has help $1; then
err No help found for \"$1\"
else
help:$1
fi
else
cat >&2 <<ENDHELP
Usage: dockcross [options] [--] command [args]
By default, run the given *command* in an dockcross Docker container.
The *options* can be one of:
--args|-a Extra args to the *docker run* command
--image|-i Docker cross-compiler image to use
--config|-c Bash script to source before running this script
Additionally, there are special update commands:
update-image
update-script
update
For update command help use: $0 help <command>
ENDHELP
exit 1
fi
}
#------------------------------------------------------------------------------
# Option processing
#
special_update_command=''
while [[ $# != 0 ]]; do
case $1 in
--)
shift
break
;;
--args|-a)
ARG_ARGS="$2"
shift 2
;;
--config|-c)
ARG_CONFIG="$2"
shift 2
;;
--image|-i)
ARG_IMAGE="$2"
shift 2
;;
update|update-image|update-script)
special_update_command=$1
break
;;
-*)
err Unknown option \"$1\"
command:help
exit
;;
*)
break
;;
esac
done
# The precedence for options is:
# 1. command-line arguments
# 2. environment variables
# 3. defaults
# Source the config file if it exists
DEFAULT_DOCKCROSS_CONFIG=~/.dockcross
FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}}
[[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG"
# Set the docker image
FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}}
# Handle special update command
if [ "$special_update_command" != "" ]; then
case $special_update_command in
update)
command:update
exit $?
;;
update-image)
command:update-image
exit $?
;;
update-script)
command:update-script
exit $?
;;
esac
fi
# Set the docker run extra args (if any)
FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}}
# Bash on Ubuntu on Windows
UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "")
# MSYS, Git Bash, etc.
MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "")
if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" ]; then
USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )")
fi
# Change the PWD when working in Docker on Windows
if [ -n "$UBUNTU_ON_WINDOWS" ]; then
WSL_ROOT="/mnt/"
CFG_FILE=/etc/wsl.conf
if [ -f "$CFG_FILE" ]; then
CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g')
eval "$CFG_CONTENT"
if [ -n "$root" ]; then
WSL_ROOT=$root
fi
fi
HOST_PWD=`pwd -P`
HOST_PWD=${HOST_PWD/$WSL_ROOT//}
elif [ -n "$MSYS" ]; then
HOST_PWD=$PWD
HOST_PWD=${HOST_PWD/\//}
HOST_PWD=${HOST_PWD/\//:\/}
else
HOST_PWD=$PWD
[ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD)
fi
# Mount Additional Volumes
if [ -z "$SSH_DIR" ]; then
SSH_DIR="$HOME/.ssh"
fi
HOST_VOLUMES=
if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then
HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh"
fi
#------------------------------------------------------------------------------
# Now, finally, run the command in a container
#
TTY_ARGS=
tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti
CONTAINER_NAME=dockcross_$RANDOM
docker run $TTY_ARGS --name $CONTAINER_NAME \
-v "$HOST_PWD":/work \
$HOST_VOLUMES \
"${USER_IDS[@]}" \
$FINAL_ARGS \
$FINAL_IMAGE "$@"
run_exit_code=$?
# Attempt to delete container
rm_output=$(docker rm -f $CONTAINER_NAME 2>&1)
rm_exit_code=$?
if [[ $rm_exit_code != 0 ]]; then
if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then
: # Ignore error because of https://circleci.com/docs/docker-btrfs-error/
else
echo "$rm_output"
exit $rm_exit_code
fi
fi
exit $run_exit_code
################################################################################
#
# This image is not intended to be run manually.
#
# To create a dockcross helper script for the
# dockcross/linux-x64:latest image, run:
#
# docker run --rm dockcross/linux-x64:latest > dockcross-linux-x64-latest
# chmod +x dockcross-linux-x64-latest
#
# You may then wish to move the dockcross script to your PATH.
#
################################################################################

View File

@@ -1,200 +0,0 @@
#!/bin/bash
DEFAULT_DOCKCROSS_IMAGE=dockcross/windows-x64
#------------------------------------------------------------------------------
# Helpers
#
err() {
echo -e >&2 ERROR: $@\\n
}
die() {
err $@
exit 1
}
has() {
# eg. has command update
local kind=$1
local name=$2
type -t $kind:$name | grep -q function
}
#------------------------------------------------------------------------------
# Command handlers
#
command:update-image() {
docker pull $FINAL_IMAGE
}
help:update-image() {
echo Pull the latest $FINAL_IMAGE .
}
command:update-script() {
if cmp -s <( docker run $FINAL_IMAGE ) $0; then
echo $0 is up to date
else
echo -n Updating $0 '... '
docker run $FINAL_IMAGE > $0 && echo ok
fi
}
help:update-image() {
echo Update $0 from $FINAL_IMAGE .
}
command:update() {
command:update-image
command:update-script
}
help:update() {
echo Pull the latest $FINAL_IMAGE, and then update $0 from that.
}
command:help() {
if [[ $# != 0 ]]; then
if ! has command $1; then
err \"$1\" is not an dockcross command
command:help
elif ! has help $1; then
err No help found for \"$1\"
else
help:$1
fi
else
cat >&2 <<ENDHELP
Usage: dockcross [options] [--] command [args]
By default, run the given *command* in an dockcross Docker container.
The *options* can be one of:
--args|-a Extra args to the *docker run* command
--image|-i Docker cross-compiler image to use
--config|-c Bash script to source before running this script
Additionally, there are special update commands:
update-image
update-script
update
For update command help use: $0 help <command>
ENDHELP
exit 1
fi
}
#------------------------------------------------------------------------------
# Option processing
#
special_update_command=''
while [[ $# != 0 ]]; do
case $1 in
--)
break
;;
--args|-a)
ARG_ARGS="$2"
shift 2
;;
--config|-c)
ARG_CONFIG="$2"
shift 2
;;
--image|-i)
ARG_IMAGE="$2"
shift 2
;;
update|update-image|update-script)
special_update_command=$1
break
;;
-*)
err Unknown option \"$1\"
command:help
exit
;;
*)
break
;;
esac
done
# The precedence for options is:
# 1. command-line arguments
# 2. environment variables
# 3. defaults
# Source the config file if it exists
DEFAULT_DOCKCROSS_CONFIG=~/.dockcross
FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}}
[[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG"
# Set the docker image
FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}}
# Handle special update command
if [ "$special_update_command" != "" ]; then
case $special_update_command in
update)
command:update
exit $?
;;
update-image)
command:update-image
exit $?
;;
update-script)
command:update-script
exit $?
;;
esac
fi
# Set the docker run extra args (if any)
FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}}
# If we are not running via boot2docker
if [ -z $DOCKER_HOST ]; then
USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )")
fi
#------------------------------------------------------------------------------
# Now, finally, run the command in a container
#
docker run --rm \
-v $PWD:/work \
"${USER_IDS[@]}" \
$FINAL_ARGS \
$FINAL_IMAGE "$@"
################################################################################
#
# This image is not intended to be run manually.
#
# To create a dockcross helper script for the
# dockcross/linux-armv7 image, run:
#
# docker run --rm dockcross/linux-armv7 > dockcross-linux-armv7
# chmod +x dockcross-linux-armv7
#
# You may then wish to move the dockcross script to your PATH.
#
################################################################################

View File

@@ -1,23 +0,0 @@
/*
* @(#)jni_md.h 1.19 05/11/17
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT __attribute__((visibility("default")))
#define JNIIMPORT
#define JNICALL
#if defined(__LP64__) && __LP64__ /* for -Wundef */
typedef int jint;
#else
typedef long jint;
#endif
typedef long long jlong;
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */

View File

@@ -1,157 +0,0 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_bitcoin_Secp256k1CFunctions */
#ifndef _Included_org_bitcoin_Secp256k1CFunctions
#define _Included_org_bitcoin_Secp256k1CFunctions
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_init_context
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1init_1context
(JNIEnv *, jclass);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_context_randomize
* Signature: (Ljava/nio/ByteBuffer;J)I
*/
JNIEXPORT jint JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1context_1randomize
(JNIEnv *, jclass, jobject, jlong);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_privkey_negate
* Signature: (Ljava/nio/ByteBuffer;J)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1privkey_1negate
(JNIEnv *, jclass, jobject, jlong);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_privkey_tweak_add
* Signature: (Ljava/nio/ByteBuffer;J)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1privkey_1tweak_1add
(JNIEnv *, jclass, jobject, jlong);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_privkey_tweak_mul
* Signature: (Ljava/nio/ByteBuffer;J)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1privkey_1tweak_1mul
(JNIEnv *, jclass, jobject, jlong);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_pubkey_negate
* Signature: (Ljava/nio/ByteBuffer;JI)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1pubkey_1negate
(JNIEnv *, jclass, jobject, jlong, jint);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_pubkey_tweak_add
* Signature: (Ljava/nio/ByteBuffer;JI)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1pubkey_1tweak_1add
(JNIEnv *, jclass, jobject, jlong, jint);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_pubkey_tweak_mul
* Signature: (Ljava/nio/ByteBuffer;JI)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1pubkey_1tweak_1mul
(JNIEnv *, jclass, jobject, jlong, jint);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_destroy_context
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1destroy_1context
(JNIEnv *, jclass, jlong);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_ecdsa_verify
* Signature: (Ljava/nio/ByteBuffer;JII)I
*/
JNIEXPORT jint JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdsa_1verify
(JNIEnv *, jclass, jobject, jlong, jint, jint);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_ecdsa_sign
* Signature: (Ljava/nio/ByteBuffer;ZJ)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdsa_1sign
(JNIEnv *, jclass, jobject, jboolean, jlong);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_ecdsa_normalize
* Signature: (Ljava/nio/ByteBuffer;IZJ)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdsa_1normalize
(JNIEnv *, jclass, jobject, jint, jboolean, jlong);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_ec_seckey_verify
* Signature: (Ljava/nio/ByteBuffer;J)I
*/
JNIEXPORT jint JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ec_1seckey_1verify
(JNIEnv *, jclass, jobject, jlong);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_ec_pubkey_create
* Signature: (Ljava/nio/ByteBuffer;ZJ)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1create
(JNIEnv *, jclass, jobject, jboolean, jlong);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_ec_pubkey_parse
* Signature: (Ljava/nio/ByteBuffer;JIZ)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1parse
(JNIEnv *, jclass, jobject, jlong, jint, jboolean);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_ec_pubkey_add
* Signature: (Ljava/nio/ByteBuffer;JII)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1add
(JNIEnv *, jclass, jobject, jlong, jint, jint);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_ecdh
* Signature: (Ljava/nio/ByteBuffer;JI)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdh
(JNIEnv *, jclass, jobject, jlong, jint);
/*
* Class: org_bitcoin_Secp256k1CFunctions
* Method: secp256k1_ecdsa_recover
* Signature: (Ljava/nio/ByteBuffer;JIZ)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdsa_1recover
(JNIEnv *, jclass, jobject, jlong, jint, jboolean);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +0,0 @@
/*
* %W% %E%
*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT __attribute__((__visibility__("default")))
#define JNIIMPORT
#define JNICALL
typedef int jint;
#ifdef _LP64 /* 64-bit Solaris */
typedef long jlong;
#else
typedef long long jlong;
#endif
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */

View File

@@ -1,19 +0,0 @@
/*
* @(#)jni_md.h 1.14 03/12/19
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall
typedef long jint;
typedef int64_t jlong;
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */

View File

@@ -1,658 +0,0 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "org_bitcoin_Secp256k1CFunctions.h"
#include "include/secp256k1.h"
#include "include/secp256k1_ecdh.h"
#include "include/secp256k1_recovery.h"
SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1init_1context
(JNIEnv* env, jclass classObject)
{
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
(void)classObject;(void)env;
return (uintptr_t)ctx;
}
SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ctx_1clone
(JNIEnv* env, jclass classObject, jlong ctx_l)
{
const secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
jlong ctx_clone_l = (uintptr_t) secp256k1_context_clone(ctx);
(void)classObject;(void)env;
return ctx_clone_l;
}
SECP256K1_API jint JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1context_1randomize
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
const unsigned char* seed = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
(void)classObject;
return secp256k1_context_randomize(ctx, seed);
}
SECP256K1_API void JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1destroy_1context
(JNIEnv* env, jclass classObject, jlong ctx_l)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
secp256k1_context_destroy(ctx);
(void)classObject;(void)env;
}
SECP256K1_API jint JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdsa_1verify
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint siglen, jint publen)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
const unsigned char* sigdata = { (unsigned char*) (data + 32) };
const unsigned char* pubdata = { (unsigned char*) (data + siglen + 32) };
secp256k1_ecdsa_signature sig;
secp256k1_pubkey pubkey;
int ret = 0;
if (siglen == 64) {
ret = secp256k1_ecdsa_signature_parse_compact(ctx, &sig, sigdata);
} else {
ret = secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigdata, siglen);
}
if( ret ) {
ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen);
if( ret ) {
ret = secp256k1_ecdsa_verify(ctx, &sig, data, &pubkey);
}
}
(void)classObject;
return ret;
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdsa_1sign
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jboolean compact, jlong ctx_l)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
unsigned char* secKey = (unsigned char*) (data + 32);
jobjectArray retArray;
jbyteArray sigArray, intsByteArray;
unsigned char intsarray[2];
secp256k1_ecdsa_signature sig;
int ret = secp256k1_ecdsa_sign(ctx, &sig, data, secKey, NULL, NULL);
unsigned char outputSer[72];
size_t outputLen = compact ? 64 : 72;
if( ret ) {
if (compact) {
int ret2 = secp256k1_ecdsa_signature_serialize_compact(ctx, outputSer, &sig ); (void)ret2;
} else {
int ret2 = secp256k1_ecdsa_signature_serialize_der(ctx, outputSer, &outputLen, &sig ); (void)ret2;
}
}
intsarray[0] = outputLen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
sigArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, sigArray, 0, outputLen, (jbyte*)outputSer);
(*env)->SetObjectArrayElement(env, retArray, 0, sigArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdsa_1normalize
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jint siglen, jboolean compact, jlong ctx_l)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
unsigned char* sigdata = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
jobjectArray retArray;
jbyteArray sigArray, intsByteArray;
unsigned char intsarray[3];
secp256k1_ecdsa_signature sig;
int ret = 0;
if (siglen == 64) {
ret = secp256k1_ecdsa_signature_parse_compact(ctx, &sig, sigdata);
} else {
ret = secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigdata, siglen);
}
int ret2 = 0;
if (ret) {
ret2 = secp256k1_ecdsa_signature_normalize(ctx, &sig, &sig);
}
unsigned char outputSer[72];
size_t outputLen = compact ? 64 : 72;
if( ret ) {
if (compact) {
int ret3 = secp256k1_ecdsa_signature_serialize_compact(ctx, outputSer, &sig ); (void)ret3;
} else {
int ret3 = secp256k1_ecdsa_signature_serialize_der(ctx, outputSer, &outputLen, &sig ); (void)ret3;
}
}
intsarray[0] = outputLen;
intsarray[1] = ret;
intsarray[2] = ret2;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
sigArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, sigArray, 0, outputLen, (jbyte*)outputSer);
(*env)->SetObjectArrayElement(env, retArray, 0, sigArray);
intsByteArray = (*env)->NewByteArray(env, 3);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 3, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
SECP256K1_API jint JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ec_1seckey_1verify
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
(void)classObject;
return secp256k1_ec_seckey_verify(ctx, secKey);
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1create
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jboolean compressed, jlong ctx_l)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
const unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
secp256k1_pubkey pubkey;
jobjectArray retArray;
jbyteArray pubkeyArray, intsByteArray;
unsigned char intsarray[2];
int ret = secp256k1_ec_pubkey_create(ctx, &pubkey, secKey);
unsigned char outputSer[65];
size_t outputLen = compressed ? 33 : 65;
if( ret ) {
int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey, compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED );(void)ret2;
}
intsarray[0] = outputLen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
pubkeyArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, pubkeyArray, 0, outputLen, (jbyte*)outputSer);
(*env)->SetObjectArrayElement(env, retArray, 0, pubkeyArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1parse
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint inputlen, jboolean compressed)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
const unsigned char* pubkeydata = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
secp256k1_pubkey pubkey;
jobjectArray retArray;
jbyteArray pubkeyArray, intsByteArray;
unsigned char intsarray[2];
int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeydata, inputlen);
unsigned char outputSer[65];
size_t outputLen = compressed ? 33 : 65;
if( ret ) {
int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey, compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED );(void)ret2;
}
intsarray[0] = outputLen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
pubkeyArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, pubkeyArray, 0, outputLen, (jbyte*)outputSer);
(*env)->SetObjectArrayElement(env, retArray, 0, pubkeyArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1privkey_1negate
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
jobjectArray retArray;
jbyteArray privArray, intsByteArray;
unsigned char intsarray[2];
int privkeylen = 32;
int ret = secp256k1_ec_privkey_negate(ctx, privkey);
intsarray[0] = privkeylen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
privArray = (*env)->NewByteArray(env, privkeylen);
(*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey);
(*env)->SetObjectArrayElement(env, retArray, 0, privArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1privkey_1tweak_1add
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
const unsigned char* tweak = (unsigned char*) (privkey + 32);
jobjectArray retArray;
jbyteArray privArray, intsByteArray;
unsigned char intsarray[2];
int privkeylen = 32;
int ret = secp256k1_ec_privkey_tweak_add(ctx, privkey, tweak);
intsarray[0] = privkeylen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
privArray = (*env)->NewByteArray(env, privkeylen);
(*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey);
(*env)->SetObjectArrayElement(env, retArray, 0, privArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1privkey_1tweak_1mul
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
const unsigned char* tweak = (unsigned char*) (privkey + 32);
jobjectArray retArray;
jbyteArray privArray, intsByteArray;
unsigned char intsarray[2];
int privkeylen = 32;
int ret = secp256k1_ec_privkey_tweak_mul(ctx, privkey, tweak);
intsarray[0] = privkeylen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
privArray = (*env)->NewByteArray(env, privkeylen);
(*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey);
(*env)->SetObjectArrayElement(env, retArray, 0, privArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1pubkey_1negate
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject);
jobjectArray retArray;
jbyteArray pubArray, intsByteArray;
unsigned char intsarray[2];
unsigned char outputSer[65];
size_t outputLen = publen;
secp256k1_pubkey pubkey;
int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen);
if( ret ) {
ret = secp256k1_ec_pubkey_negate(ctx, &pubkey);
}
if( ret ) {
int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey, publen == 33 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED );(void)ret2;
}
intsarray[0] = outputLen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
pubArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer);
(*env)->SetObjectArrayElement(env, retArray, 0, pubArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1pubkey_1tweak_1add
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
/* secp256k1_pubkey* pubkey = (secp256k1_pubkey*) (*env)->GetDirectBufferAddress(env, byteBufferObject);*/
unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject);
const unsigned char* tweak = (unsigned char*) (pkey + publen);
jobjectArray retArray;
jbyteArray pubArray, intsByteArray;
unsigned char intsarray[2];
unsigned char outputSer[65];
size_t outputLen = publen;
secp256k1_pubkey pubkey;
int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen);
if( ret ) {
ret = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, tweak);
}
if( ret ) {
int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey, publen == 33 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);(void)ret2;
}
intsarray[0] = outputLen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
pubArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer);
(*env)->SetObjectArrayElement(env, retArray, 0, pubArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1pubkey_1tweak_1mul
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject);
const unsigned char* tweak = (unsigned char*) (pkey + publen);
jobjectArray retArray;
jbyteArray pubArray, intsByteArray;
unsigned char intsarray[2];
unsigned char outputSer[65];
size_t outputLen = publen;
secp256k1_pubkey pubkey;
int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen);
if ( ret ) {
ret = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, tweak);
}
if( ret ) {
int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey, publen == 33 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);(void)ret2;
}
intsarray[0] = outputLen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
pubArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer);
(*env)->SetObjectArrayElement(env, retArray, 0, pubArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ec_1pubkey_1add
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen1, jint publen2)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
const unsigned char* pubdata1 = (*env)->GetDirectBufferAddress(env, byteBufferObject);
const unsigned char* pubdata2 = (const unsigned char*) (pubdata1 + publen1);
jobjectArray retArray;
jbyteArray pubArray, intsByteArray;
unsigned char intsarray[2];
secp256k1_pubkey pubkey1, pubkey2;
const secp256k1_pubkey *pubkeys[2];
unsigned char outputSer[65];
size_t outputLen = publen1;
int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey1, pubdata1, publen1);
if (ret) {
ret = secp256k1_ec_pubkey_parse(ctx, &pubkey2, pubdata2, publen2);
}
secp256k1_pubkey result;
if (ret) {
pubkeys[0] = &pubkey1;
pubkeys[1] = &pubkey2;
ret = secp256k1_ec_pubkey_combine(ctx, &result, pubkeys, 2);
}
if (ret) {
ret = secp256k1_ec_pubkey_serialize(ctx, outputSer, &outputLen, &result, publen1 == 33 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED );
}
intsarray[0] = outputLen;
intsarray[1] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
pubArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer);
(*env)->SetObjectArrayElement(env, retArray, 0, pubArray);
intsByteArray = (*env)->NewByteArray(env, 2);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdh
(JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
const unsigned char* secdata = (*env)->GetDirectBufferAddress(env, byteBufferObject);
const unsigned char* pubdata = (const unsigned char*) (secdata + 32);
jobjectArray retArray;
jbyteArray outArray, intsByteArray;
unsigned char intsarray[1];
secp256k1_pubkey pubkey;
unsigned char nonce_res[32];
size_t outputLen = 32;
int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen);
if (ret) {
ret = secp256k1_ecdh(
ctx,
nonce_res,
&pubkey,
secdata,
NULL,
NULL
);
}
intsarray[0] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
outArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, outArray, 0, 32, (jbyte*)nonce_res);
(*env)->SetObjectArrayElement(env, retArray, 0, outArray);
intsByteArray = (*env)->NewByteArray(env, 1);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 1, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}
/*
* Class: org_bitcoin_NativeSecp256k1
* Method: secp256k1_ecdsa_recover
* Signature: (Ljava/nio/ByteBuffer;JI)[[B
*/
JNIEXPORT jobjectArray JNICALL Java_org_bitcoin_Secp256k1CFunctions_secp256k1_1ecdsa_1recover
(JNIEnv *env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint recid, jboolean compressed)
{
secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
const unsigned char* sigdata = (*env)->GetDirectBufferAddress(env, byteBufferObject);
const unsigned char* msgdata = (const unsigned char*)(sigdata + 64);
secp256k1_ecdsa_recoverable_signature sig;
secp256k1_pubkey pub;
unsigned char outputSer[65];
size_t outputLen = compressed ? 33 : 65;
jobjectArray retArray;
jbyteArray pubArray, intsByteArray;
unsigned char intsarray[1];
int ret = secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &sig, sigdata, recid);
if (ret) {
ret = secp256k1_ecdsa_recover(ctx, &pub, &sig, msgdata);
if (ret) {
ret = secp256k1_ec_pubkey_serialize(ctx, outputSer, &outputLen, &pub, compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED );
}
}
intsarray[0] = ret;
retArray = (*env)->NewObjectArray(env, 2,
(*env)->FindClass(env, "[B"),
(*env)->NewByteArray(env, 1));
pubArray = (*env)->NewByteArray(env, outputLen);
(*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer);
(*env)->SetObjectArrayElement(env, retArray, 0, pubArray);
intsByteArray = (*env)->NewByteArray(env, 1);
(*env)->SetByteArrayRegion(env, intsByteArray, 0, 1, (jbyte*)intsarray);
(*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);
(void)classObject;
return retArray;
}