Using javac to generate header

This commit is contained in:
Salomon BRYS
2020-07-01 13:53:26 +02:00
parent 720637ec24
commit 6e4763e55b
24 changed files with 358 additions and 385 deletions

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="fr.acinq.secp256k1">
</manifest>

View File

@@ -1,14 +0,0 @@
cmake_minimum_required(VERSION 3.10.0)
add_library( secp256k1-jni SHARED
${CMAKE_CURRENT_LIST_DIR}/../../../native/jni/src/org_bitcoin_NativeSecp256k1.c
${CMAKE_CURRENT_LIST_DIR}/../../../native/jni/src/org_bitcoin_Secp256k1Context.c
)
target_include_directories( secp256k1-jni
PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../../../native/secp256k1
)
target_link_libraries( secp256k1-jni
${CMAKE_CURRENT_LIST_DIR}/../../../native/build/android/${ANDROID_ABI}/libsecp256k1.a
)

View File

@@ -1,16 +0,0 @@
package fr.acinq.secp256k1.jni
import fr.acinq.secp256k1.Secp256k1
import org.bitcoin.NativeSecp256k1
public actual object NativeSecp256k1Loader {
@JvmStatic
@Synchronized
@Throws(Exception::class)
actual fun load(): Secp256k1 {
System.loadLibrary("secp256k1-jni")
return NativeSecp256k1
}
}

View File

@@ -1,10 +0,0 @@
package fr.acinq.secp256k1.jni
import fr.acinq.secp256k1.Secp256k1
public expect object NativeSecp256k1Loader {
public fun load(): Secp256k1
}

View File

@@ -1,214 +0,0 @@
package fr.acinq.secp256k1.jni
import fr.acinq.secp256k1.Secp256k1
import org.bitcoin.NativeSecp256k1
import java.io.*
import java.util.*
/**
* Set the system properties, org.sqlite.lib.path, org.sqlite.lib.name,
* appropriately so that the SQLite JDBC driver can find *.dll, *.jnilib and
* *.so files, according to the current OS (win, linux, mac).
* The library files are automatically extracted from this project's package (JAR).
* usage: call [.initialize] before using SQLite JDBC driver.
*
* @author leo
*/
public actual object NativeSecp256k1Loader {
private var extracted = false
/**
* Loads secp256k1 native library.
*
* @return True if secp256k1 native library is successfully loaded; false otherwise.
* @throws Exception if loading fails
*/
@JvmStatic
@Synchronized
@Throws(Exception::class)
public actual fun load(): Secp256k1 {
// only cleanup before the first extract
if (!extracted) {
cleanup()
}
loadSecp256k1NativeLibrary()
return NativeSecp256k1
}
private val tempDir: File
get() = File(
System.getProperty(
"fr.acinq.secp256k1.tmpdir",
System.getProperty("java.io.tmpdir")
)
)
/**
* Deleted old native libraries e.g. on Windows the DLL file is not removed
* on VM-Exit (bug #80)
*/
@JvmStatic
public fun cleanup() {
val tempFolder = tempDir.absolutePath
val dir = File(tempFolder)
val nativeLibFiles = dir.listFiles(object : FilenameFilter {
private val searchPattern = "secp256k1-"
override fun accept(dir: File, name: String): Boolean {
return name.startsWith(searchPattern) && !name.endsWith(".lck")
}
})
if (nativeLibFiles != null) {
for (nativeLibFile in nativeLibFiles) {
val lckFile = File(nativeLibFile.absolutePath + ".lck")
if (!lckFile.exists()) {
try {
nativeLibFile.delete()
} catch (e: SecurityException) {
System.err.println("Failed to delete old native lib" + e.message)
}
}
}
}
}
@Throws(IOException::class)
private fun InputStream.contentsEquals(other: InputStream): Boolean {
val bufThis = this as? BufferedInputStream
?: BufferedInputStream(this)
val bufOther = other as? BufferedInputStream
?: BufferedInputStream(other)
var ch = bufThis.read()
while (ch != -1) {
val ch2 = bufOther.read()
if (ch != ch2) return false
ch = bufThis.read()
}
val ch2 = bufOther.read()
return ch2 == -1
}
/**
* Extracts and loads the specified library file to the target folder
*
* @param libDir Library path.
* @param libFileName Library name.
* @param targetDirectory Target folder.
* @return
*/
private fun extractAndLoadLibraryFile(libDir: String, libFileName: String, targetDirectory: String): Boolean {
val libPath = "$libDir/$libFileName"
// Include architecture name in temporary filename in order to avoid conflicts
// when multiple JVMs with different architectures running at the same time
val uuid = UUID.randomUUID().toString()
val extractedLibFileName = String.format("secp256k1-%s-%s", uuid, libFileName)
val extractedLckFileName = "$extractedLibFileName.lck"
val extractedLibFile = File(targetDirectory, extractedLibFileName)
val extractedLckFile = File(targetDirectory, extractedLckFileName)
return try {
// Extract a native library file into the target directory
val reader = NativeSecp256k1Loader::class.java.getResourceAsStream(libPath)
if (!extractedLckFile.exists()) {
FileOutputStream(extractedLckFile).close()
}
val writer = FileOutputStream(extractedLibFile)
try {
val buffer = ByteArray(8192)
var bytesRead = reader.read(buffer)
while (bytesRead != -1) {
writer.write(buffer, 0, bytesRead)
bytesRead = reader.read(buffer)
}
} finally {
// Delete the extracted lib file on JVM exit.
extractedLibFile.deleteOnExit()
extractedLckFile.deleteOnExit()
writer.close()
reader.close()
}
// Set executable (x) flag to enable Java to load the native library
extractedLibFile.setReadable(true)
extractedLibFile.setWritable(true, true)
extractedLibFile.setExecutable(true)
// Check whether the contents are properly copied from the resource folder
NativeSecp256k1Loader::class.java.getResourceAsStream(libPath).use { nativeIn ->
FileInputStream(extractedLibFile).use { extractedLibIn ->
if (!nativeIn.contentsEquals(extractedLibIn)) {
throw RuntimeException(
String.format(
"Failed to write a native library file at %s",
extractedLibFile
)
)
}
}
}
loadNativeLibrary(targetDirectory, extractedLibFileName)
} catch (e: IOException) {
System.err.println(e.message)
false
}
}
/**
* Loads native library using the given path and name of the library.
*
* @param path Path of the native library.
* @param name Name of the native library.
* @return True for successfully loading; false otherwise.
*/
private fun loadNativeLibrary(path: String, name: String): Boolean {
val libPath = File(path, name)
return if (libPath.exists()) {
try {
System.load(File(path, name).absolutePath)
true
} catch (e: UnsatisfiedLinkError) {
System.err.println("Failed to load native library:$name. osinfo: ${OSInfo.nativeSuffix}")
System.err.println(e)
false
}
} else {
false
}
}
/**
* Loads secp256k1 native library using given path and name of the library.
*
* @throws
*/
private fun loadSecp256k1NativeLibrary() {
if (extracted) {
return
}
// Try loading library from fr.acinq.secp256k1.lib.path library path */
val libraryPath = System.getProperty("fr.acinq.secp256k1.lib.path")
val libraryName = System.getProperty("fr.acinq.secp256k1.lib.name") ?: System.mapLibraryName("secp256k1-jni-${OSInfo.nativeSuffix}")
if (libraryPath != null) {
if (loadNativeLibrary(libraryPath, libraryName)) {
extracted = true
return
}
}
// Load the os-dependent library from the jar file
val packagePath = NativeSecp256k1Loader::class.java.getPackage().name.replace("\\.".toRegex(), "/")
val embeddedLibraryPath = "/$packagePath/native"
val hasNativeLib = NativeSecp256k1Loader::class.java.getResource("$embeddedLibraryPath/$libraryName") != null
if (!hasNativeLib) {
error("No native library found: at $embeddedLibraryPath/$libraryName")
}
// Try extracting the library from jar
if (extractAndLoadLibraryFile(embeddedLibraryPath, libraryName, tempDir.absolutePath)) {
extracted = true
return
}
extracted = false
return
}
}

View File

@@ -1,214 +0,0 @@
package fr.acinq.secp256k1.jni
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.util.*
/**
* Provides OS name and architecture name.
*
* @author leo
*/
@Suppress("DuplicatedCode")
internal object OSInfo {
private val archMapping = HashMap<String, String>()
private const val X86 = "x86"
private const val X86_64 = "x86_64"
private const val IA64_32 = "ia64_32"
private const val IA64 = "ia64"
private const val PPC = "ppc"
private const val PPC64 = "ppc64"
@JvmStatic val nativeSuffix: String get() = "$os-$arch"
@JvmStatic val os: String get() = translateOSName(System.getProperty("os.name"))
@JvmStatic val hardwareName: String get() =
try {
val p = Runtime.getRuntime().exec("uname -m")
p.waitFor()
val input = p.inputStream
input.use {
val b = ByteArrayOutputStream()
val buf = ByteArray(32)
var readLen = it.read(buf, 0, buf.size)
while (readLen >= 0) {
b.write(buf, 0, readLen)
readLen = it.read(buf, 0, buf.size)
}
b.toString()
}
} catch (e: Throwable) {
System.err.println("Error while running uname -m: " + e.message)
"unknown"
}
@JvmStatic
private fun resolveArmArchType(): String {
if (System.getProperty("os.name").contains("Linux")) {
val armType = hardwareName
// armType (uname -m) can be armv5t, armv5te, armv5tej, armv5tejl, armv6, armv7, armv7l, aarch64, i686// ignored: fall back to "arm" arch (soft-float ABI)
// ignored: fall back to "arm" arch (soft-float ABI)
// determine if first JVM found uses ARM hard-float ABI
when {
armType.startsWith("armv6") -> {
// Raspberry PI
return "armv6"
}
armType.startsWith("armv7") -> {
// Generic
return "armv7"
}
armType.startsWith("armv5") -> {
// Use armv5, soft-float ABI
return "arm"
}
armType == "aarch64" -> {
// Use arm64
return "arm64"
}
// Java 1.8 introduces a system property to determine armel or armhf
// http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8005545
// For java7, we stil need to if run some shell commands to determine ABI of JVM
else -> {
val abi = System.getProperty("sun.arch.abi")
if (abi != null && abi.startsWith("gnueabihf")) {
return "armv7"
}
// For java7, we stil need to if run some shell commands to determine ABI of JVM
val javaHome = System.getProperty("java.home")
try {
// determine if first JVM found uses ARM hard-float ABI
var exitCode = Runtime.getRuntime().exec("which readelf").waitFor()
if (exitCode == 0) {
val cmdarray = arrayOf(
"/bin/sh", "-c", "find '" + javaHome +
"' -name 'libjvm.so' | head -1 | xargs readelf -A | " +
"grep 'Tag_ABI_VFP_args: VFP registers'"
)
exitCode = Runtime.getRuntime().exec(cmdarray).waitFor()
if (exitCode == 0) {
return "armv7"
}
} else {
System.err.println(
"WARNING! readelf not found. Cannot check if running on an armhf system, " +
"armel architecture will be presumed."
)
}
} catch (e: IOException) {
// ignored: fall back to "arm" arch (soft-float ABI)
} catch (e: InterruptedException) {
// ignored: fall back to "arm" arch (soft-float ABI)
}
}
}
// Java 1.8 introduces a system property to determine armel or armhf
// http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8005545
val abi = System.getProperty("sun.arch.abi")
if (abi != null && abi.startsWith("gnueabihf")) {
return "armv7"
}
// For java7, we stil need to if run some shell commands to determine ABI of JVM
val javaHome = System.getProperty("java.home")
try {
// determine if first JVM found uses ARM hard-float ABI
var exitCode = Runtime.getRuntime().exec("which readelf").waitFor()
if (exitCode == 0) {
val cmdarray = arrayOf(
"/bin/sh", "-c", "find '" + javaHome +
"' -name 'libjvm.so' | head -1 | xargs readelf -A | " +
"grep 'Tag_ABI_VFP_args: VFP registers'"
)
exitCode = Runtime.getRuntime().exec(cmdarray).waitFor()
if (exitCode == 0) {
return "armv7"
}
} else {
System.err.println(
"WARNING! readelf not found. Cannot check if running on an armhf system, " +
"armel architecture will be presumed."
)
}
} catch (e: IOException) {
// ignored: fall back to "arm" arch (soft-float ABI)
} catch (e: InterruptedException) {
// ignored: fall back to "arm" arch (soft-float ABI)
}
}
// Use armv5, soft-float ABI
return "arm"
}
// For Android
@JvmStatic
val arch: String?
get() {
val systemOsArch = System.getProperty("os.arch")
val osArch =
if (systemOsArch.startsWith("arm")) {
resolveArmArchType()
} else {
val lc = systemOsArch.toLowerCase(Locale.US)
if (archMapping.containsKey(lc)) return archMapping[lc]
systemOsArch
}
return translateArchNameToFolderName(osArch)
}
@JvmStatic
fun translateOSName(osName: String): String =
when {
osName.contains("Windows") -> "mingw"
osName.contains("Mac") || osName.contains("Darwin") -> "darwin"
osName.contains("Linux") -> "linux"
osName.contains("AIX") -> "aix"
else -> osName.replace("\\W".toRegex(), "")
}
@JvmStatic
fun translateArchNameToFolderName(archName: String): String = archName.replace("\\W".toRegex(), "")
init {
// x86 mappings
archMapping[X86] = X86
archMapping["i386"] = X86
archMapping["i486"] = X86
archMapping["i586"] = X86
archMapping["i686"] = X86
archMapping["pentium"] = X86
// x86_64 mappings
archMapping[X86_64] = X86_64
archMapping["amd64"] = X86_64
archMapping["em64t"] = X86_64
archMapping["universal"] = X86_64 // Needed for openjdk7 in Mac
// Itenium 64-bit mappings
archMapping[IA64] = IA64
archMapping["ia64w"] = IA64
// Itenium 32-bit mappings, usually an HP-UX construct
archMapping[IA64_32] = IA64_32
archMapping["ia64n"] = IA64_32
// PowerPC mappings
archMapping[PPC] = PPC
archMapping["power"] = PPC
archMapping["powerpc"] = PPC
archMapping["power_pc"] = PPC
archMapping["power_rs"] = PPC
// TODO: PowerPC 64bit mappings
archMapping[PPC64] = PPC64
archMapping["power64"] = PPC64
archMapping["powerpc64"] = PPC64
archMapping["power_pc64"] = PPC64
archMapping["power_rs64"] = PPC64
}
}

View File

@@ -0,0 +1,24 @@
package org.bitcoin;
import java.nio.ByteBuffer;
public class Secp256k1CFunctions {
static native long secp256k1_init_context();
static native int secp256k1_context_randomize(ByteBuffer byteBuff, long context);
static native byte[][] secp256k1_privkey_negate(ByteBuffer byteBuff, long context);
static native byte[][] secp256k1_privkey_tweak_add(ByteBuffer byteBuff, long context);
static native byte[][] secp256k1_privkey_tweak_mul(ByteBuffer byteBuff, long context);
static native byte[][] secp256k1_pubkey_negate(ByteBuffer byteBuff, long context, int pubLen);
static native byte[][] secp256k1_pubkey_tweak_add(ByteBuffer byteBuff, long context, int pubLen);
static native byte[][] secp256k1_pubkey_tweak_mul(ByteBuffer byteBuff, long context, int pubLen);
static native void secp256k1_destroy_context(long context);
static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff, long context, int sigLen, int pubLen);
static native byte[][] secp256k1_ecdsa_sign(ByteBuffer byteBuff, boolean compact, long context);
static native byte[][] secp256k1_ecdsa_normalize(ByteBuffer byteBuff, int sigLen, boolean compact, long context);
static native int secp256k1_ec_seckey_verify(ByteBuffer byteBuff, long context);
static native byte[][] secp256k1_ec_pubkey_create(ByteBuffer byteBuff, boolean compressed, long context);
static native byte[][] secp256k1_ec_pubkey_parse(ByteBuffer byteBuff, long context, int inputLen, boolean compressed);
static native byte[][] secp256k1_ec_pubkey_add(ByteBuffer byteBuff, long context, int lent1, int len2);
static native byte[][] secp256k1_ecdh(ByteBuffer byteBuff, long context, int inputLen);
static native byte[][] secp256k1_ecdsa_recover(ByteBuffer byteBuff, long context, int recid, boolean compressed);
}

View File

@@ -40,7 +40,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock
* or point the JVM to the folder containing it with -Djava.library.path
*
*/
internal object NativeSecp256k1 : Secp256k1 {
public object NativeSecp256k1 : Secp256k1 {
private val rwl = ReentrantReadWriteLock()
private val r: Lock = rwl.readLock()
private val w: Lock = rwl.writeLock()
@@ -80,7 +80,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val byteBuff = pack(data, signature, pub)
r.lock()
return try {
secp256k1_ecdsa_verify(
Secp256k1CFunctions.secp256k1_ecdsa_verify(
byteBuff,
Secp256k1Context.getContext(),
signature.size,
@@ -107,7 +107,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_ecdsa_sign(
Secp256k1CFunctions.secp256k1_ecdsa_sign(
byteBuff,
format == SigFormat.COMPACT,
Secp256k1Context.getContext()
@@ -133,7 +133,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_ecdsa_normalize(
Secp256k1CFunctions.secp256k1_ecdsa_normalize(
byteBuff,
sig.size,
format == SigFormat.COMPACT,
@@ -165,7 +165,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val byteBuff = pack(seckey)
r.lock()
return try {
secp256k1_ec_seckey_verify(
Secp256k1CFunctions.secp256k1_ec_seckey_verify(
byteBuff,
Secp256k1Context.getContext()
) == 1
@@ -189,7 +189,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_ec_pubkey_create(
Secp256k1CFunctions.secp256k1_ec_pubkey_create(
byteBuff,
format == PubKeyFormat.COMPRESSED,
Secp256k1Context.getContext()
@@ -216,7 +216,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_ec_pubkey_parse(
Secp256k1CFunctions.secp256k1_ec_pubkey_parse(
byteBuff,
Secp256k1Context.getContext(),
pubkey.size,
@@ -244,7 +244,7 @@ internal object NativeSecp256k1 : Secp256k1 {
override fun cleanup() {
w.lock()
try {
secp256k1_destroy_context(Secp256k1Context.getContext())
Secp256k1CFunctions.secp256k1_destroy_context(Secp256k1Context.getContext())
} finally {
w.unlock()
}
@@ -257,7 +257,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_privkey_negate(
Secp256k1CFunctions.secp256k1_privkey_negate(
byteBuff,
Secp256k1Context.getContext()
)
@@ -291,7 +291,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_privkey_tweak_mul(
Secp256k1CFunctions.secp256k1_privkey_tweak_mul(
byteBuff,
Secp256k1Context.getContext()
)
@@ -325,7 +325,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_privkey_tweak_add(
Secp256k1CFunctions.secp256k1_privkey_tweak_add(
byteBuff,
Secp256k1Context.getContext()
)
@@ -347,7 +347,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_pubkey_negate(
Secp256k1CFunctions.secp256k1_pubkey_negate(
byteBuff,
Secp256k1Context.getContext(),
pubkey.size
@@ -378,7 +378,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_pubkey_tweak_add(
Secp256k1CFunctions.secp256k1_pubkey_tweak_add(
byteBuff,
Secp256k1Context.getContext(),
pubkey.size
@@ -409,7 +409,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_pubkey_tweak_mul(
Secp256k1CFunctions.secp256k1_pubkey_tweak_mul(
byteBuff,
Secp256k1Context.getContext(),
pubkey.size
@@ -433,7 +433,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_ec_pubkey_add(
Secp256k1CFunctions.secp256k1_ec_pubkey_add(
byteBuff,
Secp256k1Context.getContext(),
pubkey1.size,
@@ -465,7 +465,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_ecdh(
Secp256k1CFunctions.secp256k1_ecdh(
byteBuff,
Secp256k1Context.getContext(),
pubkey.size
@@ -488,7 +488,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val retByteArray: Array<ByteArray>
r.lock()
retByteArray = try {
secp256k1_ecdsa_recover(
Secp256k1CFunctions.secp256k1_ecdsa_recover(
byteBuff,
Secp256k1Context.getContext(),
recid,
@@ -522,7 +522,7 @@ internal object NativeSecp256k1 : Secp256k1 {
val byteBuff = pack(seed)
w.lock()
return try {
secp256k1_context_randomize(
Secp256k1CFunctions.secp256k1_context_randomize(
byteBuff,
Secp256k1Context.getContext()
) == 1
@@ -530,22 +530,4 @@ internal object NativeSecp256k1 : Secp256k1 {
w.unlock()
}
}
@JvmStatic private external fun secp256k1_context_randomize(byteBuff: ByteBuffer, context: Long): Int
@JvmStatic private external fun secp256k1_privkey_negate(byteBuff: ByteBuffer, context: Long): Array<ByteArray>
@JvmStatic private external fun secp256k1_privkey_tweak_add(byteBuff: ByteBuffer, context: Long): Array<ByteArray>
@JvmStatic private external fun secp256k1_privkey_tweak_mul(byteBuff: ByteBuffer, context: Long): Array<ByteArray>
@JvmStatic private external fun secp256k1_pubkey_negate(byteBuff: ByteBuffer, context: Long, pubLen: Int): Array<ByteArray>
@JvmStatic private external fun secp256k1_pubkey_tweak_add(byteBuff: ByteBuffer, context: Long, pubLen: Int): Array<ByteArray>
@JvmStatic private external fun secp256k1_pubkey_tweak_mul(byteBuff: ByteBuffer, context: Long, pubLen: Int): Array<ByteArray>
@JvmStatic private external fun secp256k1_destroy_context(context: Long)
@JvmStatic private external fun secp256k1_ecdsa_verify(byteBuff: ByteBuffer, context: Long, sigLen: Int, pubLen: Int): Int
@JvmStatic private external fun secp256k1_ecdsa_sign(byteBuff: ByteBuffer, compact: Boolean, context: Long): Array<ByteArray>
@JvmStatic private external fun secp256k1_ecdsa_normalize(byteBuff: ByteBuffer, sigLen: Int, compact: Boolean, context: Long): Array<ByteArray>
@JvmStatic private external fun secp256k1_ec_seckey_verify(byteBuff: ByteBuffer, context: Long): Int
@JvmStatic private external fun secp256k1_ec_pubkey_create(byteBuff: ByteBuffer, compressed: Boolean, context: Long): Array<ByteArray>
@JvmStatic private external fun secp256k1_ec_pubkey_parse(byteBuff: ByteBuffer, context: Long, inputLen: Int, compressed: Boolean): Array<ByteArray>
@JvmStatic private external fun secp256k1_ec_pubkey_add(byteBuff: ByteBuffer, context: Long, lent1: Int, len2: Int): Array<ByteArray>
@JvmStatic private external fun secp256k1_ecdh(byteBuff: ByteBuffer, context: Long, inputLen: Int): Array<ByteArray>
@JvmStatic private external fun secp256k1_ecdsa_recover(byteBuff: ByteBuffer, context: Long, recid: Int, compressed: Boolean): Array<ByteArray>
}
}

View File

@@ -29,11 +29,8 @@ public object Secp256k1Context {
return if (!isEnabled) -1 else context //sanity check
}
@JvmStatic private external fun secp256k1_init_context(): Long
init { //static initializer
isEnabled = true
context =
secp256k1_init_context()
context = Secp256k1CFunctions.secp256k1_init_context()
}
}