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

@@ -0,0 +1,48 @@
plugins {
id("com.android.library")
kotlin("android")
}
kotlin {
explicitApi()
}
dependencies {
api(project(":jni"))
implementation(kotlin("stdlib-jdk8"))
}
android {
defaultConfig {
compileSdkVersion(30)
minSdkVersion(21)
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {}
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
setPath("src/main/CMakeLists.txt")
}
}
ndkVersion = "21.3.6528147"
afterEvaluate {
tasks.withType<com.android.build.gradle.tasks.factory.AndroidUnitTest>().all {
enabled = false
}
}
}
afterEvaluate {
configure(listOf("Debug", "Release").map { tasks["externalNativeBuild$it"] }) {
dependsOn(":native:buildSecp256k1Android")
}
}

View File

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

View File

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

View File

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

View File

@@ -1,104 +1,27 @@
plugins {
kotlin("multiplatform") // version "1.4-M2-mt"
id("com.android.library")
`maven-publish`
kotlin("jvm")
}
val currentOs = org.gradle.internal.os.OperatingSystem.current()
kotlin {
explicitApi()
val commonMain by sourceSets.getting {
dependencies {
api(rootProject)
implementation(kotlin("stdlib-common"))
}
}
val commonTest by sourceSets.getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
jvm {
compilations.all {
kotlinOptions.jvmTarget = "1.8"
}
(tasks[compilations["main"].processResourcesTaskName] as ProcessResources).apply {
dependsOn("copyJni")
from(buildDir.resolve("jniResources"))
}
compilations["main"].dependencies {
implementation(kotlin("stdlib-jdk8"))
}
compilations["test"].dependencies {
implementation(kotlin("test-junit"))
}
}
android {
publishLibraryVariants("release", "debug")
compilations.all {
kotlinOptions.jvmTarget = "1.8"
}
sourceSets["androidMain"].dependencies {
implementation(kotlin("stdlib-jdk8"))
}
sourceSets["androidTest"].dependencies {
implementation(kotlin("test-junit"))
implementation("androidx.test.ext:junit:1.1.1")
implementation("androidx.test.espresso:espresso-core:3.2.0")
}
}
sourceSets.all {
languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn")
}
}
android {
defaultConfig {
compileSdkVersion(30)
minSdkVersion(21)
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {}
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
setPath("src/androidMain/CMakeLists.txt")
}
}
ndkVersion = "21.3.6528147"
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
afterEvaluate {
tasks.withType<com.android.build.gradle.tasks.factory.AndroidUnitTest>().all {
enabled = false
}
}
dependencies {
api(rootProject)
implementation(kotlin("stdlib-jdk8"))
}
val copyJni by tasks.creating(Sync::class) {
dependsOn(":native:buildSecp256k1Jvm")
from(rootDir.resolve("native/build/linux/libsecp256k1-jni.so")) { rename { "libsecp256k1-jni-linux-x86_64.so" } }
from(rootDir.resolve("native/build/darwin/libsecp256k1-jni.dylib")) { rename { "libsecp256k1-jni-darwin-x86_64.dylib" } }
from(rootDir.resolve("native/build/mingw/secp256k1-jni.dll")) { rename { "secp256k1-jni-mingw-x86_64.dll" } }
into(buildDir.resolve("jniResources/fr/acinq/secp256k1/jni/native"))
}
afterEvaluate {
configure(listOf("Debug", "Release").map { tasks["externalNativeBuild$it"] }) {
dependsOn(":native:buildSecp256k1Android")
val generateJniHeaders by tasks.creating(JavaCompile::class) {
group = "build"
classpath = sourceSets["main"].compileClasspath
destinationDir = file("${buildDir}/generated/jni")
source = sourceSets["main"].java
options.compilerArgs = listOf(
"-h", file("${buildDir}/generated/jni").absolutePath,
"-d", file("${buildDir}/generated/jni-tmp").absolutePath
)
// options.verbose = true
doLast {
delete(file("${buildDir}/generated/jni-tmp"))
}
}

25
jni/jvm/build.gradle.kts Normal file
View File

@@ -0,0 +1,25 @@
plugins {
kotlin("jvm")
}
kotlin {
explicitApi()
}
dependencies {
api(project(":jni"))
implementation(kotlin("stdlib-jdk8"))
}
val copyJni by tasks.creating(Sync::class) {
dependsOn(":native:buildSecp256k1Jvm")
from(rootDir.resolve("native/build/linux/libsecp256k1-jni.so")) { rename { "libsecp256k1-jni-linux-x86_64.so" } }
from(rootDir.resolve("native/build/darwin/libsecp256k1-jni.dylib")) { rename { "libsecp256k1-jni-darwin-x86_64.dylib" } }
from(rootDir.resolve("native/build/mingw/secp256k1-jni.dll")) { rename { "secp256k1-jni-mingw-x86_64.dll" } }
into(buildDir.resolve("jniResources/fr/acinq/secp256k1/jni/native"))
}
(tasks["processResources"] as ProcessResources).apply {
dependsOn("copyJni")
from(buildDir.resolve("jniResources"))
}

View File

@@ -14,7 +14,7 @@ import java.util.*
*
* @author leo
*/
public actual object NativeSecp256k1Loader {
public object NativeSecp256k1Loader {
private var extracted = false
/**
@@ -26,7 +26,7 @@ public actual object NativeSecp256k1Loader {
@JvmStatic
@Synchronized
@Throws(Exception::class)
public actual fun load(): Secp256k1 {
public fun load(): Secp256k1 {
// only cleanup before the first extract
if (!extracted) {
cleanup()

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,10 +0,0 @@
package fr.acinq.secp256k1.jni
import fr.acinq.secp256k1.Secp256k1
public expect object NativeSecp256k1Loader {
public fun load(): Secp256k1
}

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()
}
}