Android implementation
This commit is contained in:
3
src/androidMain/AndroidManifest.xml
Normal file
3
src/androidMain/AndroidManifest.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="fr.acinq.secp256k1">
|
||||
</manifest>
|
||||
14
src/androidMain/CMakeLists.txt
Normal file
14
src/androidMain/CMakeLists.txt
Normal 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_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
|
||||
)
|
||||
15
src/androidMain/kotlin/fr/acinq/secp256k1/Secp256k1Loader.kt
Normal file
15
src/androidMain/kotlin/fr/acinq/secp256k1/Secp256k1Loader.kt
Normal file
@@ -0,0 +1,15 @@
|
||||
package fr.acinq.secp256k1
|
||||
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
|
||||
internal actual object Secp256k1Loader {
|
||||
|
||||
@JvmStatic
|
||||
@Synchronized
|
||||
@Throws(Exception::class)
|
||||
actual fun initialize() {
|
||||
System.loadLibrary("secp256k1-jni")
|
||||
}
|
||||
|
||||
}
|
||||
4
src/androidTest/java/fr/acinq/secp256k1/Placeholder.kt
Normal file
4
src/androidTest/java/fr/acinq/secp256k1/Placeholder.kt
Normal file
@@ -0,0 +1,4 @@
|
||||
package fr.acinq.secp256k1
|
||||
|
||||
|
||||
class Placeholder {}
|
||||
@@ -17,7 +17,10 @@
|
||||
package fr.acinq.secp256k1
|
||||
|
||||
import org.bitcoin.NativeSecp256k1
|
||||
import java.math.BigInteger
|
||||
|
||||
internal expect object Secp256k1Loader {
|
||||
fun initialize()
|
||||
}
|
||||
|
||||
public actual object Secp256k1 {
|
||||
|
||||
@@ -78,7 +78,12 @@ public object NativeSecp256k1 {
|
||||
val byteBuff = pack(data, signature, pub)
|
||||
r.lock()
|
||||
return try {
|
||||
secp256k1_ecdsa_verify(byteBuff, Secp256k1Context.getContext(), signature.size, pub.size) == 1
|
||||
secp256k1_ecdsa_verify(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext(),
|
||||
signature.size,
|
||||
pub.size
|
||||
) == 1
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -100,14 +105,21 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_ecdsa_sign(byteBuff, Secp256k1Context.getContext())
|
||||
secp256k1_ecdsa_sign(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext()
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
val sigArr = retByteArray[0]
|
||||
val sigLen = BigInteger(byteArrayOf(retByteArray[1][0])).toInt()
|
||||
val retVal = BigInteger(byteArrayOf(retByteArray[1][1])).toInt()
|
||||
NativeSecp256k1Util.assertEquals(sigArr.size, sigLen, "Got bad signature length.")
|
||||
NativeSecp256k1Util.assertEquals(
|
||||
sigArr.size,
|
||||
sigLen,
|
||||
"Got bad signature length."
|
||||
)
|
||||
return if (retVal == 0) ByteArray(0) else sigArr
|
||||
}
|
||||
|
||||
@@ -130,14 +142,21 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_ecdsa_sign_compact(byteBuff, Secp256k1Context.getContext())
|
||||
secp256k1_ecdsa_sign_compact(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext()
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
val sigArr = retByteArray[0]
|
||||
val sigLen = BigInteger(byteArrayOf(retByteArray[1][0])).toInt()
|
||||
val retVal = BigInteger(byteArrayOf(retByteArray[1][1])).toInt()
|
||||
NativeSecp256k1Util.assertEquals(sigArr.size, sigLen, "Got bad signature length.")
|
||||
NativeSecp256k1Util.assertEquals(
|
||||
sigArr.size,
|
||||
sigLen,
|
||||
"Got bad signature length."
|
||||
)
|
||||
return if (retVal == 0) ByteArray(0) else sigArr
|
||||
}
|
||||
|
||||
@@ -153,7 +172,10 @@ public object NativeSecp256k1 {
|
||||
val byteBuff = pack(seckey)
|
||||
r.lock()
|
||||
return try {
|
||||
secp256k1_ec_seckey_verify(byteBuff, Secp256k1Context.getContext()) == 1
|
||||
secp256k1_ec_seckey_verify(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext()
|
||||
) == 1
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -175,7 +197,10 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_ec_pubkey_create(byteBuff, Secp256k1Context.getContext())
|
||||
secp256k1_ec_pubkey_create(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext()
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -199,12 +224,16 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_ec_pubkey_parse(byteBuff, Secp256k1Context.getContext(), pubkey.size)
|
||||
secp256k1_ec_pubkey_parse(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext(),
|
||||
pubkey.size
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
val pubArr = retByteArray[0]
|
||||
val pubLen = BigInteger(byteArrayOf(retByteArray[1][0])).toInt()
|
||||
BigInteger(byteArrayOf(retByteArray[1][0])).toInt()
|
||||
val retVal = BigInteger(byteArrayOf(retByteArray[1][1])).toInt()
|
||||
NativeSecp256k1Util.assertEquals(pubArr.size, 65, "Got bad pubkey length.")
|
||||
return if (retVal == 0) ByteArray(0) else pubArr
|
||||
@@ -233,14 +262,21 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_privkey_negate(byteBuff, Secp256k1Context.getContext())
|
||||
secp256k1_privkey_negate(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext()
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
val privArr = retByteArray[0]
|
||||
val privLen: Int = BigInteger(byteArrayOf(retByteArray[1][0])).toInt() and 0xFF
|
||||
val retVal = BigInteger(byteArrayOf(retByteArray[1][1])).toInt()
|
||||
NativeSecp256k1Util.assertEquals(privArr.size, privLen, "Got bad privkey length.")
|
||||
NativeSecp256k1Util.assertEquals(
|
||||
privArr.size,
|
||||
privLen,
|
||||
"Got bad privkey length."
|
||||
)
|
||||
NativeSecp256k1Util.assertEquals(retVal, 1, "Failed return value check.")
|
||||
return privArr
|
||||
}
|
||||
@@ -257,18 +293,25 @@ public object NativeSecp256k1 {
|
||||
@Throws(AssertFailException::class)
|
||||
public fun privKeyTweakMul(privkey: ByteArray, tweak: ByteArray): ByteArray {
|
||||
require(privkey.size == 32)
|
||||
val byteBuff = pack(privkey, tweak!!)
|
||||
val byteBuff = pack(privkey, tweak)
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_privkey_tweak_mul(byteBuff, Secp256k1Context.getContext())
|
||||
secp256k1_privkey_tweak_mul(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext()
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
val privArr = retByteArray[0]
|
||||
val privLen: Int = BigInteger(byteArrayOf(retByteArray[1][0])).toInt() and 0xFF
|
||||
val retVal = BigInteger(byteArrayOf(retByteArray[1][1])).toInt()
|
||||
NativeSecp256k1Util.assertEquals(privArr.size, privLen, "Got bad privkey length.")
|
||||
NativeSecp256k1Util.assertEquals(
|
||||
privArr.size,
|
||||
privLen,
|
||||
"Got bad privkey length."
|
||||
)
|
||||
NativeSecp256k1Util.assertEquals(retVal, 1, "Failed return value check.")
|
||||
return privArr
|
||||
}
|
||||
@@ -285,11 +328,14 @@ public object NativeSecp256k1 {
|
||||
@Throws(AssertFailException::class)
|
||||
public fun privKeyTweakAdd(privkey: ByteArray, tweak: ByteArray): ByteArray {
|
||||
require(privkey.size == 32)
|
||||
val byteBuff = pack(privkey, tweak!!)
|
||||
val byteBuff = pack(privkey, tweak)
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_privkey_tweak_add(byteBuff, Secp256k1Context.getContext())
|
||||
secp256k1_privkey_tweak_add(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext()
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -309,7 +355,11 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_pubkey_negate(byteBuff, Secp256k1Context.getContext(), pubkey.size)
|
||||
secp256k1_pubkey_negate(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext(),
|
||||
pubkey.size
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -337,7 +387,11 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_pubkey_tweak_add(byteBuff, Secp256k1Context.getContext(), pubkey.size)
|
||||
secp256k1_pubkey_tweak_add(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext(),
|
||||
pubkey.size
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -361,11 +415,15 @@ public object NativeSecp256k1 {
|
||||
@Throws(AssertFailException::class)
|
||||
public fun pubKeyTweakMul(pubkey: ByteArray, tweak: ByteArray): ByteArray {
|
||||
require(pubkey.size == 33 || pubkey.size == 65)
|
||||
val byteBuff = pack(pubkey, tweak!!)
|
||||
val byteBuff = pack(pubkey, tweak)
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_pubkey_tweak_mul(byteBuff, Secp256k1Context.getContext(), pubkey.size)
|
||||
secp256k1_pubkey_tweak_mul(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext(),
|
||||
pubkey.size
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -386,7 +444,12 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_ec_pubkey_add(byteBuff, Secp256k1Context.getContext(), pubkey1.size, pubkey2.size)
|
||||
secp256k1_ec_pubkey_add(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext(),
|
||||
pubkey1.size,
|
||||
pubkey2.size
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -414,7 +477,11 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_ecdh(byteBuff, Secp256k1Context.getContext(), pubkey.size)
|
||||
secp256k1_ecdh(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext(),
|
||||
pubkey.size
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -434,7 +501,11 @@ public object NativeSecp256k1 {
|
||||
val retByteArray: Array<ByteArray>
|
||||
r.lock()
|
||||
retByteArray = try {
|
||||
secp256k1_ecdsa_recover(byteBuff, Secp256k1Context.getContext(), recid)
|
||||
secp256k1_ecdsa_recover(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext(),
|
||||
recid
|
||||
)
|
||||
} finally {
|
||||
r.unlock()
|
||||
}
|
||||
@@ -460,7 +531,10 @@ public object NativeSecp256k1 {
|
||||
val byteBuff = pack(seed)
|
||||
w.lock()
|
||||
return try {
|
||||
secp256k1_context_randomize(byteBuff, Secp256k1Context.getContext()) == 1
|
||||
secp256k1_context_randomize(
|
||||
byteBuff,
|
||||
Secp256k1Context.getContext()
|
||||
) == 1
|
||||
} finally {
|
||||
w.unlock()
|
||||
}
|
||||
@@ -34,23 +34,7 @@ public object Secp256k1Context {
|
||||
@JvmStatic private external fun secp256k1_init_context(): Long
|
||||
|
||||
init { //static initializer
|
||||
var isEnabled = true
|
||||
var contextRef: Long = -1
|
||||
try {
|
||||
if ("The Android Project" == System.getProperty("java.vm.vendor")) {
|
||||
System.loadLibrary("secp256k1")
|
||||
} else {
|
||||
initialize()
|
||||
}
|
||||
contextRef = secp256k1_init_context()
|
||||
} catch (e: UnsatisfiedLinkError) {
|
||||
println("Cannot load secp256k1 native library: $e")
|
||||
isEnabled = false
|
||||
} catch (e: Exception) {
|
||||
println("Cannot load secp256k1 native library: $e")
|
||||
isEnabled = false
|
||||
}
|
||||
this.isEnabled = isEnabled
|
||||
this.context = contextRef
|
||||
isEnabled = true
|
||||
context = secp256k1_init_context()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import java.util.*
|
||||
*
|
||||
* @author leo
|
||||
*/
|
||||
public object Secp256k1Loader {
|
||||
internal actual object Secp256k1Loader {
|
||||
private var extracted = false
|
||||
|
||||
/**
|
||||
@@ -38,13 +38,12 @@ public object Secp256k1Loader {
|
||||
@JvmStatic
|
||||
@Synchronized
|
||||
@Throws(Exception::class)
|
||||
public fun initialize(): Boolean {
|
||||
actual fun initialize() {
|
||||
// only cleanup before the first extract
|
||||
if (!extracted) {
|
||||
cleanup()
|
||||
}
|
||||
loadSecp256k1NativeLibrary()
|
||||
return extracted
|
||||
}
|
||||
|
||||
private val tempDir: File
|
||||
@@ -55,7 +54,7 @@ public object Secp256k1Loader {
|
||||
* on VM-Exit (bug #80)
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun cleanup() {
|
||||
fun cleanup() {
|
||||
val tempFolder = tempDir.absolutePath
|
||||
val dir = File(tempFolder)
|
||||
val nativeLibFiles = dir.listFiles(object : FilenameFilter {
|
||||
|
||||
Reference in New Issue
Block a user