16 Commits

Author SHA1 Message Date
Fabrice Drouin
cec3fb385f Set version to 0.7.1 (#70) 2023-01-04 15:33:55 +01:00
Fabrice Drouin
d59def1c79 Use secp256k1 0.2.0 (#67) 2022-12-13 19:33:28 +01:00
Fabrice Drouin
52d73951e6 Set version to 0.7.1-SNAPSHOT (#68) 2022-12-13 19:33:06 +01:00
Fabrice Drouin
08669500b6 Update README.md
Upgrade to a kotlin 1.6.21 badge
2022-09-22 10:29:21 +02:00
thunderbiscuit
68e77c70be Fix artifact names in README (#65) 2022-09-21 17:17:16 +02:00
Fabrice Drouin
5e59132e2a Set version to 0.7.0 (#64) 2022-09-21 16:25:50 +02:00
Fabrice Drouin
d4eba9fb96 Update to kotlin 1.6 (#63)
Use kotlin 1.6 (and gradle 7.5.1)
2022-09-21 16:00:19 +02:00
Fabrice Drouin
d01a067159 Update secp256k1 sources (#60)
* Set version to 0.6.5-SNAPSHOT

* Update secp256k1 sources

We use 44c2452fd387f7ca604ab42d73746e7d3a44d8a2, same as bitcoin core at c41bfd1070176efcaae7fa33313cb4c3e88b44b0
2022-08-03 10:01:40 +02:00
Fabrice Drouin
75f45e9191 Set version to 0.6.4 (#53) 2022-04-11 15:17:42 +02:00
Fabrice Drouin
118c72064c Update secp256k1 sources (#52)
We're now at 8746600eec5e7fcd35dabd480839a3a4bdfee87b, same as bitcoin core at 747cdf1d652d8587e9f2e3d4436c3ecdbf56d0a5
2022-04-11 13:34:59 +02:00
Fabrice Drouin
7af7b7760e Document how to add custom JNI bindings (#50)
This is how we add Linux Arm64 JNI bindings.
2022-04-04 11:26:18 +02:00
Fabrice Drouin
4df49dd8f6 Document publishing process (#46)
Document publishing process
2022-03-29 18:42:01 +02:00
Fabrice Drouin
48c3e4723b Set version to 0.6.4-SNAPSHOT (#49) 2022-03-24 16:26:17 +01:00
Fabrice Drouin
df183e88b2 Set version to 0.6.3 (#45) 2022-03-23 19:15:00 +01:00
Fabrice Drouin
de3fc7fe11 CI: fix windows tests (#48)
Github Actions modified their windows runners which broke our build. As recommended, we now uses `msys2` on windows and install the packages that we need.
2022-03-23 15:45:45 +01:00
sstone
d074a03f2d Set version to 0.6.3-SNAPSHOT 2022-01-04 13:52:26 +01:00
23 changed files with 349 additions and 198 deletions

View File

@@ -29,11 +29,13 @@ jobs:
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }} key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: ${{ runner.os }}-gradle- restore-keys: ${{ runner.os }}-gradle-
- name: Android environment - name: Android environment
if: matrix.os != 'windows-latest'
shell: bash shell: bash
run: | run: |
echo "ANDROID_HOME=$ANDROID_HOME" >> $GITHUB_ENV echo "ANDROID_HOME=$ANDROID_HOME" >> $GITHUB_ENV
echo "ANDROID_NDK_VERSION=21.4.7075529" >> $GITHUB_ENV echo "ANDROID_NDK_VERSION=21.4.7075529" >> $GITHUB_ENV
- name: Cached Android NDK - name: Cached Android NDK
if: matrix.os != 'windows-latest'
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
path: ${{ format('{0}/ndk/{1}', env.ANDROID_HOME, env.ANDROID_NDK_VERSION) }} path: ${{ format('{0}/ndk/{1}', env.ANDROID_HOME, env.ANDROID_NDK_VERSION) }}
@@ -43,6 +45,19 @@ jobs:
run: | run: |
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
rm.exe "C:/WINDOWS/system32/bash.EXE" rm.exe "C:/WINDOWS/system32/bash.EXE"
- name: Install Automake
if: matrix.os == 'macOS-latest'
run: brew install automake
- name: Install Automake (windows)
if: matrix.os == 'windows-latest'
uses: msys2/setup-msys2@v2
with:
path-type: minimal
update: true
install: >-
base-devel
autotools
mingw-w64-x86_64-gcc
- name: Set up JDK 8 - name: Set up JDK 8
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
@@ -54,18 +69,19 @@ jobs:
$ANDROID_HOME/tools/bin/sdkmanager "ndk;$ANDROID_NDK_VERSION" $ANDROID_HOME/tools/bin/sdkmanager "ndk;$ANDROID_NDK_VERSION"
- name: Setup Android - name: Setup Android
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
shell: bash shell: msys2 {0}
run: | run: |
$ANDROID_HOME\\tools\\bin\\sdkmanager.bat "ndk;$ANDROID_NDK_VERSION" echo "skip.android=true" > local.properties
- name: Set up JDK 11 - name: Set up JDK 11
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: 11 java-version: 11
- name: Install Automake
if: matrix.os == 'macOS-latest'
run: brew install automake
- name: Check JVM - name: Check JVM
shell: bash if: matrix.os != 'windows-latest'
run: ./gradlew jvmTest
- name: Check JVM (Windows)
if: matrix.os == 'windows-latest'
shell: msys2 {0}
run: ./gradlew jvmTest run: ./gradlew jvmTest
- name: Check Linux - name: Check Linux
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
@@ -87,27 +103,15 @@ jobs:
script: ./gradlew connectedCheck script: ./gradlew connectedCheck
- name: Publish Linux - name: Publish Linux
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
env:
BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
shell: bash shell: bash
# ./gradlew publishLinuxPublicationToBintrayRepository :jni:jvm:linux:publishJvmPublicationToBintrayRepository
run: ./gradlew publishLinuxPublicationToMavenLocal :jni:jvm:linux:publishJvmPublicationToMavenLocal run: ./gradlew publishLinuxPublicationToMavenLocal :jni:jvm:linux:publishJvmPublicationToMavenLocal
- name: Publish Windows - name: Publish Windows
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
env: shell: msys2 {0}
BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
shell: bash
# ./gradlew :jni:jvm:mingw:publishJvmPublicationToBintrayRepository
run: ./gradlew :jni:jvm:mingw:publishToMavenLocal run: ./gradlew :jni:jvm:mingw:publishToMavenLocal
- name: Publish MacOS - name: Publish MacOS
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
env:
BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
shell: bash shell: bash
# ./gradlew publish
run: ./gradlew publishToMavenLocal run: ./gradlew publishToMavenLocal
- name: Copy artifact files - name: Copy artifact files
run: | run: |
@@ -120,9 +124,3 @@ jobs:
path: | path: |
maven-local maven-local
!maven-local/**/maven-metadata-local.xml !maven-local/**/maven-metadata-local.xml
# - name: Discard
# if: ${{ failure() || cancelled() }}
# env:
# BINTRAY_USER: ${{ secrets.bintray_user }}
# BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
# run: ./gradlew postBintrayDiscard

View File

@@ -54,6 +54,19 @@ jobs:
run: | run: |
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
rm.exe "C:/WINDOWS/system32/bash.EXE" rm.exe "C:/WINDOWS/system32/bash.EXE"
- name: Install Automake
if: matrix.os == 'macOS-latest'
run: brew install automake
- name: Install Automake (windows)
if: matrix.os == 'windows-latest'
uses: msys2/setup-msys2@v2
with:
path-type: minimal
update: true
install: >-
base-devel
autotools
mingw-w64-x86_64-gcc
- name: Set up JDK 8 - name: Set up JDK 8
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
@@ -63,15 +76,21 @@ jobs:
shell: bash shell: bash
run: | run: |
$ANDROID_HOME/tools/bin/sdkmanager "ndk;$ANDROID_NDK_VERSION" $ANDROID_HOME/tools/bin/sdkmanager "ndk;$ANDROID_NDK_VERSION"
- name: Setup Android
if: matrix.os == 'windows-latest'
shell: msys2 {0}
run: |
echo "skip.android=true" > local.properties
- name: Set up JDK 11 - name: Set up JDK 11
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: 11 java-version: 11
- name: Install Automake
if: matrix.os == 'macOS-latest'
run: brew install automake
- name: Check JVM - name: Check JVM
shell: bash if: matrix.os != 'windows-latest'
run: ./gradlew jvmTest
- name: Check JVM (Windows)
if: matrix.os == 'windows-latest'
shell: msys2 {0}
run: ./gradlew jvmTest run: ./gradlew jvmTest
- name: Check Linux - name: Check Linux
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
@@ -97,7 +116,7 @@ jobs:
run: ./gradlew publishLinuxPublicationToMavenLocal :jni:jvm:linux:publishJvmPublicationToMavenLocal -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }} run: ./gradlew publishLinuxPublicationToMavenLocal :jni:jvm:linux:publishJvmPublicationToMavenLocal -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }}
- name: Publish Windows - name: Publish Windows
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
shell: bash shell: msys2 {0}
run: ./gradlew :jni:jvm:mingw:publishToMavenLocal -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }} run: ./gradlew :jni:jvm:mingw:publishToMavenLocal -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }}
- name: Publish MacOS - name: Publish MacOS
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'

View File

@@ -44,11 +44,13 @@ jobs:
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }} key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: ${{ runner.os }}-gradle- restore-keys: ${{ runner.os }}-gradle-
- name: Android environment - name: Android environment
if: matrix.os != 'windows-latest'
shell: bash shell: bash
run: | run: |
echo "ANDROID_HOME=$ANDROID_HOME" >> $GITHUB_ENV echo "ANDROID_HOME=$ANDROID_HOME" >> $GITHUB_ENV
echo "ANDROID_NDK_VERSION=21.4.7075529" >> $GITHUB_ENV echo "ANDROID_NDK_VERSION=21.4.7075529" >> $GITHUB_ENV
- name: Cached Android NDK - name: Cached Android NDK
if: matrix.os != 'windows-latest'
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
path: ${{ format('{0}/ndk/{1}', env.ANDROID_HOME, env.ANDROID_NDK_VERSION) }} path: ${{ format('{0}/ndk/{1}', env.ANDROID_HOME, env.ANDROID_NDK_VERSION) }}
@@ -58,6 +60,19 @@ jobs:
run: | run: |
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
rm.exe "C:/WINDOWS/system32/bash.EXE" rm.exe "C:/WINDOWS/system32/bash.EXE"
- name: Install Automake
if: matrix.os == 'macOS-latest'
run: brew install automake
- name: Install Automake (windows)
if: matrix.os == 'windows-latest'
uses: msys2/setup-msys2@v2
with:
path-type: minimal
update: true
install: >-
base-devel
autotools
mingw-w64-x86_64-gcc
- name: Set up JDK 8 - name: Set up JDK 8
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
@@ -69,18 +84,19 @@ jobs:
$ANDROID_HOME/tools/bin/sdkmanager "ndk;$ANDROID_NDK_VERSION" $ANDROID_HOME/tools/bin/sdkmanager "ndk;$ANDROID_NDK_VERSION"
- name: Setup Android - name: Setup Android
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
shell: bash shell: msys2 {0}
run: | run: |
$ANDROID_HOME\\tools\\bin\\sdkmanager.bat "ndk;$ANDROID_NDK_VERSION" echo "skip.android=true" > local.properties
- name: Set up JDK 11 - name: Set up JDK 11
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: 11 java-version: 11
- name: Install Automake
if: matrix.os == 'macOS-latest'
run: brew install automake
- name: Check JVM - name: Check JVM
shell: bash if: matrix.os != 'windows-latest'
run: ./gradlew jvmTest
- name: Check JVM (Windows)
if: matrix.os == 'windows-latest'
shell: msys2 {0}
run: ./gradlew jvmTest run: ./gradlew jvmTest
- name: Check Linux - name: Check Linux
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'

View File

@@ -1,4 +1,4 @@
[![Kotlin](https://img.shields.io/badge/Kotlin-1.5.31-blue.svg?style=flat&logo=kotlin)](http://kotlinlang.org) [![Kotlin](https://img.shields.io/badge/Kotlin-1.6.21-blue.svg?style=flat&logo=kotlin)](http://kotlinlang.org)
[![Maven Central](https://img.shields.io/maven-central/v/fr.acinq.secp256k1/secp256k1-kmp)](https://search.maven.org/search?q=g:fr.acinq.secp256k1%20a:secp256k1-kmp*) [![Maven Central](https://img.shields.io/maven-central/v/fr.acinq.secp256k1/secp256k1-kmp)](https://search.maven.org/search?q=g:fr.acinq.secp256k1%20a:secp256k1-kmp*)
![Github Actions](https://github.com/ACINQ/secp256k1-kmp/actions/workflows/test.yml/badge.svg) ![Github Actions](https://github.com/ACINQ/secp256k1-kmp/actions/workflows/test.yml/badge.svg)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/ACINQ/secp256k1-kmp/blob/master/LICENSE) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/ACINQ/secp256k1-kmp/blob/master/LICENSE)
@@ -30,19 +30,19 @@ kotlin {
val commonMain by getting { val commonMain by getting {
dependencies { dependencies {
implementation(kotlin("stdlib-common")) implementation(kotlin("stdlib-common"))
implementation(kotlin("fr.acinq.secp256k1:secp256k1:$secp256k1_version")) implementation(kotlin("fr.acinq.secp256k1:secp256k1-kmp:$secp256k1_version"))
} }
} }
val jvmMain by getting { val jvmMain by getting {
dependencies { dependencies {
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))
implementation(kotlin("fr.acinq.secp256k1:secp256k1-jni-jvm:$secp256k1_version")) implementation(kotlin("fr.acinq.secp256k1:secp256k1-kmp-jni-jvm:$secp256k1_version"))
} }
} }
val androidMain by getting { val androidMain by getting {
dependencies { dependencies {
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))
implementation(kotlin("fr.acinq.secp256k1:secp256k1-jni-android:$secp256k1_version")) implementation(kotlin("fr.acinq.secp256k1:secp256k1-kmp-jni-android:$secp256k1_version"))
} }
} }
} }
@@ -65,15 +65,15 @@ JNI libraries are included for:
Along this library, you **must** specify which JNI native library to use in your dependency manager: Along this library, you **must** specify which JNI native library to use in your dependency manager:
* **For desktop or server JVMs**, you must add the dependency: * **For desktop or server JVMs**, you must add the dependency:
* Either the `fr.acinq.secp256k1:secp256k1-jni-jvm` dependency which imports all supported platforms. * Either the `fr.acinq.secp256k1:secp256k1-kmp-jni-jvm` dependency which imports all supported platforms.
* Or the platform specific dependencies (note that you can add multiple as they do not conflict): * Or the platform specific dependencies (note that you can add multiple as they do not conflict):
* `fr.acinq.secp256k1:secp256k1-jni-jvm-linux` for Linux * `fr.acinq.secp256k1:secp256k1-kmp-jni-jvm-linux` for Linux
* `fr.acinq.secp256k1:secp256k1-jni-jvm-darwin` for Mac OS X * `fr.acinq.secp256k1:secp256k1-kmp-jni-jvm-darwin` for Mac OS X
* `fr.acinq.secp256k1:secp256k1-jni-jvm-mingw` for Windows * `fr.acinq.secp256k1:secp256k1-kmp-jni-jvm-mingw` for Windows
* **For Android**, you must add the `fr.acinq.secp256k1:secp256k1-jni-android` dependency * **For Android**, you must add the `fr.acinq.secp256k1:secp256k1-kmp-jni-android` dependency
If you are using the JVM on an OS for which we don't provide JNI bindings (32 bits OS for example), you can use your own library native library by If you are using the JVM on an OS for which we don't provide JNI bindings (32 bits OS for example), you can use your own library native library by
adding the `fr.acinq.secp256k1:secp256k1-jni-jvm` dependency and specifying its path with `-Dfr.acinq.secp256k1.lib.path` and optionally its name with `-Dfr.acinq.secp256k1.lib.name` adding the `fr.acinq.secp256k1:secp256k1-kmp-jni-jvm` dependency and specifying its path with `-Dfr.acinq.secp256k1.lib.path` and optionally its name with `-Dfr.acinq.secp256k1.lib.name`
(if unspecified bitcoink use the standard name for your OS i.e. libsecp256k1.so on Linux, secp256k1.dll on Windows, ...). (if unspecified bitcoink use the standard name for your OS i.e. libsecp256k1.so on Linux, secp256k1.dll on Windows, ...).
To compile your own JNI bindings, have a look add the `native/build.sh` and `jni/build.sh` scripts. To compile your own JNI bindings, have a look add the `native/build.sh` and `jni/build.sh` scripts.

View File

@@ -3,8 +3,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.dokka.Platform import org.jetbrains.dokka.Platform
plugins { plugins {
kotlin("multiplatform") version "1.5.31" kotlin("multiplatform") version "1.6.21"
id("org.jetbrains.dokka") version "1.5.30" id("org.jetbrains.dokka") version "1.6.21"
`maven-publish` `maven-publish`
} }
@@ -15,14 +15,14 @@ buildscript {
} }
dependencies { dependencies {
classpath("com.android.tools.build:gradle:4.0.2") classpath("com.android.tools.build:gradle:4.2.2")
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.5.30") classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.6.21")
} }
} }
allprojects { allprojects {
group = "fr.acinq.secp256k1" group = "fr.acinq.secp256k1"
version = "0.6.2" version = "0.7.1"
repositories { repositories {
google() google()
@@ -69,7 +69,7 @@ kotlin {
} }
sourceSets.all { sourceSets.all {
languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn") languageSettings.optIn("kotlin.RequiresOptIn")
} }
} }

View File

@@ -4,14 +4,8 @@ org.gradle.parallel = true
# kotlin # kotlin
kotlin.code.style = official kotlin.code.style = official
kotlin.incremental.multiplatform = true
kotlin.parallel.tasks.in.project = true
#kotlin.mpp.enableGranularSourceSetsMetadata = true
kotlin.native.enableDependencyPropagation = false
kotlin.native.ignoreDisabledTargets = true kotlin.native.ignoreDisabledTargets = true
kotlin.mpp.enableCInteropCommonization=true
# https://github.com/gradle/gradle/issues/11412
systemProp.org.gradle.internal.publish.checksums.insecure = true
# Android # Android
android.useAndroidX = true android.useAndroidX = true

Binary file not shown.

View File

@@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

2
gradlew vendored
View File

@@ -82,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -129,6 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"` JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath

22
gradlew.bat vendored
View File

@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,28 +64,14 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell

View File

@@ -1,5 +1,3 @@
import org.jetbrains.dokka.Platform
plugins { plugins {
id("com.android.library") id("com.android.library")
kotlin("android") kotlin("android")
@@ -32,7 +30,7 @@ android {
externalNativeBuild { externalNativeBuild {
cmake { cmake {
setPath("src/main/CMakeLists.txt") path("src/main/CMakeLists.txt")
} }
} }
ndkVersion = "21.4.7075529" ndkVersion = "21.4.7075529"

View File

@@ -1,5 +1,3 @@
import org.jetbrains.dokka.Platform
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("org.jetbrains.dokka") id("org.jetbrains.dokka")
@@ -22,7 +20,7 @@ dependencies {
val generateHeaders by tasks.creating(JavaCompile::class) { val generateHeaders by tasks.creating(JavaCompile::class) {
group = "build" group = "build"
classpath = sourceSets["main"].compileClasspath classpath = sourceSets["main"].compileClasspath
destinationDir = file("${buildDir}/generated/jni") destinationDirectory.set(file("${buildDir}/generated/jni"))
source = sourceSets["main"].java source = sourceSets["main"].java
options.compilerArgs = listOf( options.compilerArgs = listOf(
"-h", file("${buildDir}/generated/jni").absolutePath, "-h", file("${buildDir}/generated/jni").absolutePath,

View File

@@ -307,9 +307,9 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
if (jseckey == NULL) return 0; if (jseckey == NULL) return 0;
CHECKRESULT((*penv)->GetArrayLength(penv, jseckey) != 32, "secret key must be 32 bytes"); CHECKRESULT((*penv)->GetArrayLength(penv, jseckey) != 32, "secret key must be 32 bytes");
seckey = (*penv)->GetByteArrayElements(penv, jseckey, 0); seckey = (*penv)->GetByteArrayElements(penv, jseckey, 0);
result = secp256k1_ec_privkey_negate(ctx, (unsigned char*)seckey); result = secp256k1_ec_seckey_negate(ctx, (unsigned char*)seckey);
(*penv)->ReleaseByteArrayElements(penv, jseckey, seckey, 0); (*penv)->ReleaseByteArrayElements(penv, jseckey, seckey, 0);
CHECKRESULT(!result, "secp256k1_ec_privkey_negate failed"); CHECKRESULT(!result, "secp256k1_ec_seckey_negate failed");
return jseckey; return jseckey;
} }
@@ -369,10 +369,10 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
CHECKRESULT((*penv)->GetArrayLength(penv, jtweak) != 32, "tweak must be 32 bytes"); CHECKRESULT((*penv)->GetArrayLength(penv, jtweak) != 32, "tweak must be 32 bytes");
seckey = (*penv)->GetByteArrayElements(penv, jseckey, 0); seckey = (*penv)->GetByteArrayElements(penv, jseckey, 0);
tweak = (*penv)->GetByteArrayElements(penv, jtweak, 0); tweak = (*penv)->GetByteArrayElements(penv, jtweak, 0);
result = secp256k1_ec_privkey_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, jseckey, seckey, 0);
(*penv)->ReleaseByteArrayElements(penv, jtweak, tweak, 0); (*penv)->ReleaseByteArrayElements(penv, jtweak, tweak, 0);
CHECKRESULT(!result, "secp256k1_ec_privkey_tweak_add failed"); CHECKRESULT(!result, "secp256k1_ec_seckey_tweak_add failed");
return jseckey; return jseckey;
} }
@@ -437,8 +437,8 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
CHECKRESULT((*penv)->GetArrayLength(penv, jtweak) != 32, "tweak must be 32 bytes"); CHECKRESULT((*penv)->GetArrayLength(penv, jtweak) != 32, "tweak must be 32 bytes");
seckey = (*penv)->GetByteArrayElements(penv, jseckey, 0); seckey = (*penv)->GetByteArrayElements(penv, jseckey, 0);
tweak = (*penv)->GetByteArrayElements(penv, jtweak, 0); tweak = (*penv)->GetByteArrayElements(penv, jtweak, 0);
result = secp256k1_ec_privkey_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_privkey_tweak_mul failed"); CHECKRESULT(!result, "secp256k1_ec_seckey_tweak_mul failed");
(*penv)->ReleaseByteArrayElements(penv, jseckey, seckey, 0); (*penv)->ReleaseByteArrayElements(penv, jseckey, seckey, 0);
(*penv)->ReleaseByteArrayElements(penv, jtweak, tweak, 0); (*penv)->ReleaseByteArrayElements(penv, jtweak, tweak, 0);
return jseckey; return jseckey;
@@ -702,7 +702,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
auxrand32 = (*penv)->GetByteArrayElements(penv, jauxrand32, 0); auxrand32 = (*penv)->GetByteArrayElements(penv, jauxrand32, 0);
} }
result = secp256k1_schnorrsig_sign(ctx, signature, (unsigned char*)msg, &keypair, auxrand32); result = secp256k1_schnorrsig_sign32(ctx, signature, (unsigned char*)msg, &keypair, auxrand32);
(*penv)->ReleaseByteArrayElements(penv, jmsg, msg, 0); (*penv)->ReleaseByteArrayElements(penv, jmsg, msg, 0);
if (auxrand32 != 0) { if (auxrand32 != 0) {
(*penv)->ReleaseByteArrayElements(penv, jauxrand32, auxrand32, 0); (*penv)->ReleaseByteArrayElements(penv, jauxrand32, auxrand32, 0);

View File

@@ -5,29 +5,29 @@ public class Secp256k1CFunctions {
* All flags' lower 8 bits indicate what they're for. Do not use directly. * All flags' lower 8 bits indicate what they're for. Do not use directly.
*/ */
public static int SECP256K1_FLAGS_TYPE_MASK = ((1 << 8) - 1); public static int SECP256K1_FLAGS_TYPE_MASK = ((1 << 8) - 1);
public static int SECP256K1_FLAGS_TYPE_CONTEXT = (1 << 0); public static final int SECP256K1_FLAGS_TYPE_CONTEXT = (1 << 0);
public static int SECP256K1_FLAGS_TYPE_COMPRESSION = (1 << 1); public static final int SECP256K1_FLAGS_TYPE_COMPRESSION = (1 << 1);
/** /**
* The higher bits contain the actual data. Do not use directly. * The higher bits contain the actual data. Do not use directly.
*/ */
public static int SECP256K1_FLAGS_BIT_CONTEXT_VERIFY = (1 << 8); public static final int SECP256K1_FLAGS_BIT_CONTEXT_VERIFY = (1 << 8);
public static int SECP256K1_FLAGS_BIT_CONTEXT_SIGN = (1 << 9); public static final int SECP256K1_FLAGS_BIT_CONTEXT_SIGN = (1 << 9);
public static int SECP256K1_FLAGS_BIT_COMPRESSION = (1 << 8); public static final int SECP256K1_FLAGS_BIT_COMPRESSION = (1 << 8);
/** /**
* Flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and * Flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and
* secp256k1_context_preallocated_create. * secp256k1_context_preallocated_create.
*/ */
public static int SECP256K1_CONTEXT_VERIFY = (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY); public static final int SECP256K1_CONTEXT_VERIFY = (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY);
public static int SECP256K1_CONTEXT_SIGN = (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN); public static final int SECP256K1_CONTEXT_SIGN = (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN);
public static int SECP256K1_CONTEXT_NONE = (SECP256K1_FLAGS_TYPE_CONTEXT); public static final int SECP256K1_CONTEXT_NONE = (SECP256K1_FLAGS_TYPE_CONTEXT);
/** /**
* Flag to pass to secp256k1_ec_pubkey_serialize. * Flag to pass to secp256k1_ec_pubkey_serialize.
*/ */
public static int SECP256K1_EC_COMPRESSED = (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION); public static final int SECP256K1_EC_COMPRESSED = (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION);
public static int SECP256K1_EC_UNCOMPRESSED = (SECP256K1_FLAGS_TYPE_COMPRESSION); public static final int SECP256K1_EC_UNCOMPRESSED = (SECP256K1_FLAGS_TYPE_COMPRESSION);
public static native long secp256k1_context_create(int flags); public static native long secp256k1_context_create(int flags);

View File

@@ -7,7 +7,7 @@ if (includeAndroid) {
} }
val currentOs = OperatingSystem.current() val currentOs = OperatingSystem.current()
val bash = if (currentOs.isWindows) "bash.exe" else "bash" val bash = "bash"
val buildSecp256k1 by tasks.creating { group = "build" } val buildSecp256k1 by tasks.creating { group = "build" }
@@ -27,7 +27,7 @@ val buildSecp256k1Host by tasks.creating(Exec::class) {
workingDir = projectDir workingDir = projectDir
environment("TARGET", target) environment("TARGET", target)
commandLine(bash, "build.sh") commandLine(bash, "-l", "build.sh")
} }
val buildSecp256k1Ios by tasks.creating(Exec::class) { val buildSecp256k1Ios by tasks.creating(Exec::class) {

42
publishing/PUBLISHING.md Normal file
View File

@@ -0,0 +1,42 @@
# Publishing secp256k1-kmp artifacts
## snapshots
Snapshots are published to the Sonatype snapshot repository (https://oss.sonatype.org/content/repositories/snapshots/).
To publish snapshot, you must add your sonatype credentials for the `ossrh` server to your local maven settings (typically in $HOME/.m2/settings.xml)
- Download `snapshot.zip` generated by the `Publish snapshot` github action
- unzip `snapshot.zip` in the `publishing` directory
- add additional JNI bindings (optional, see below)
- edit `secp256k1-kmp-snapshot-deploy.sh` and update the `VERSION` environment variable if needed
- run `secp256k1-kmp-snapshot-deploy.sh`
## releases
Releases are published to the Sonatype staging repository. If all items are valid they will be published to `maven central` repository.
You must edit `secp256k1-kmp-staging-upload.sh` and add your sonatype credentials. You must also have a valid GPG key.
- Download `release.zip` generated by the `Publish release` github action (which is triggered every time you publish a github release)
- unzip `release.zip` in the `publishing` directory
- add additional JNI bindings (optional, see below)
- edit `secp256k1-kmp-staging-upload.sh` and update the `VERSION` environment variable if needed
- sign all artifacts with a valid gpg key: `find release -type f -print -exec gpg -ab {} \;`
- run `secp256k1-kmp-staging-upload.sh`
- log into sonatype, close and publish your staging repository. Artifacts will be available on Maven Central within a few hours.
## Adding custom JNI bindings
Github CI currently generates JNI bindings for Windows x64, Linux x64 and iOS x64. But it is possible to add custom bindings to JNI packages before
they are published to maven central. This is how we add linux arm64 bindings:
- compile JNI bindings for Linux Arm64 (on a Linux Arm64 machine, cross-compilation is not supported)
- git clone --recursive https://github.com/ACINQ/secp256k1-kmp.git
- cd secp256k1-kmp
- TARGET=linux ./native/build.sh
- mkdir -p jni/jvm/build/linux
- TARGET=linux ./jni/jvm/build.sh
- JNI library is: jni/jvm/build/linux/libsecp256k1-jni.so
- copy libsecp256k1-jni.so to fr/acinq/secp256k1/jni/native/linux-aarch64/libsecp256k1-jni.so
- run `secp256k1-kmp-add-linuxarm64.sh` and specify either `release` or `snapshot` and the `VERSION` environment variable, for example:
- VERSION=0.6.4-SNAPSHOT ./secp256k1-kmp-add-linuxarm64.sh snapshot
- VERSION=0.6.3 ./secp256k1-kmp-add-linuxarm64.sh release

View File

@@ -0,0 +1,17 @@
#!/bin/bash -x
if [ $# -eq 0 ]
then
echo "specify either snapshot or release"
exit 1
fi
# add aarch64 (ARM64) library to the linux jar
if [ -e fr/acinq/secp256k1/jni/native/linux-aarch64/libsecp256k1-jni.so ]
then
jar -uf $1/fr/acinq/secp256k1/secp256k1-kmp-jni-jvm-linux/$VERSION/secp256k1-kmp-jni-jvm-linux-$VERSION.jar fr || exit
else
libsecp256k1-jni.so for arch64 is missing
exit 1
fi

View File

@@ -0,0 +1,53 @@
#!/bin/bash -x
GROUP_ID=fr.acinq.secp256k1
ARTIFACT_ID_BASE=secp256k1-kmp
VERSION=0.6.3-SNAPSHOT
cd snapshot
pushd .
cd fr/acinq/secp256k1/secp256k1-kmp/$VERSION
mvn deploy:deploy-file -DrepositoryId=ossrh -Durl=https://oss.sonatype.org/content/repositories/snapshots/ \
-DpomFile=$ARTIFACT_ID_BASE-$VERSION.pom \
-Dfile=$ARTIFACT_ID_BASE-$VERSION.jar \
-Dfiles=$ARTIFACT_ID_BASE-$VERSION.module,$ARTIFACT_ID_BASE-$VERSION-kotlin-tooling-metadata.json \
-Dtypes=module,json \
-Dclassifiers=,kotlin-tooling-metadata \
-Dsources=$ARTIFACT_ID_BASE-$VERSION-sources.jar \
-Djavadoc=$ARTIFACT_ID_BASE-$VERSION-javadoc.jar
popd
pushd .
for i in iosarm64 iosx64 jni-android jni-common jni-jvm-darwin jni-jvm-extract jni-jvm-linux jni-jvm-mingw jni-jvm jvm linux
do
cd fr/acinq/secp256k1/secp256k1-kmp-$i/$VERSION
if [ $i == iosarm64 ] || [ $i == iosx64 ] || [ $i == linux ]; then
mvn deploy:deploy-file -DrepositoryId=ossrh -Durl=https://oss.sonatype.org/content/repositories/snapshots/ \
-DpomFile=$ARTIFACT_ID_BASE-$i-$VERSION.pom \
-Dfile=$ARTIFACT_ID_BASE-$i-$VERSION.klib \
-Dfiles=$ARTIFACT_ID_BASE-$i-$VERSION.module,$ARTIFACT_ID_BASE-$i-$VERSION-cinterop-libsecp256k1.klib \
-Dtypes=module,klib \
-Dclassifiers=,cinterop-libsecp256k1 \
-Dsources=$ARTIFACT_ID_BASE-$i-$VERSION-sources.jar \
-Djavadoc=$ARTIFACT_ID_BASE-$i-$VERSION-javadoc.jar
elif [ $i == jni-android ]; then
mvn deploy:deploy-file -DrepositoryId=ossrh -Durl=https://oss.sonatype.org/content/repositories/snapshots/ \
-DpomFile=$ARTIFACT_ID_BASE-$i-$VERSION.pom \
-Dfile=$ARTIFACT_ID_BASE-$i-$VERSION.aar \
-Dfiles=$ARTIFACT_ID_BASE-$i-$VERSION.module \
-Dtypes=module \
-Dclassifiers= \
-Dsources=$ARTIFACT_ID_BASE-$i-$VERSION-sources.jar \
-Djavadoc=$ARTIFACT_ID_BASE-$i-$VERSION-javadoc.jar
else
mvn deploy:deploy-file -DrepositoryId=ossrh -Durl=https://oss.sonatype.org/content/repositories/snapshots/ \
-DpomFile=$ARTIFACT_ID_BASE-$i-$VERSION.pom \
-Dfile=$ARTIFACT_ID_BASE-$i-$VERSION.jar \
-Dfiles=$ARTIFACT_ID_BASE-$i-$VERSION.module \
-Dtypes=module \
-Dclassifiers= \
-Dsources=$ARTIFACT_ID_BASE-$i-$VERSION-sources.jar \
-Djavadoc=$ARTIFACT_ID_BASE-$i-$VERSION-javadoc.jar
fi
popd
pushd .
done

View File

@@ -0,0 +1,28 @@
#!/bin/bash -x
#
# first you must sign all files:
# find release -type f -print -exec gpg -ab {} \;
VERSION=0.6.2
for i in secp256k1-kmp \
secp256k1-kmp-iosarm64 \
secp256k1-kmp-iosx64 \
secp256k1-kmp-jni-android \
secp256k1-kmp-jni-common \
secp256k1-kmp-jni-jvm \
secp256k1-kmp-jni-jvm-darwin \
secp256k1-kmp-jni-jvm-extract \
secp256k1-kmp-jni-jvm-linux \
secp256k1-kmp-jni-jvm-mingw \
secp256k1-kmp-jvm \
secp256k1-kmp-linux
do
pushd .
cd release/fr/acinq/secp256k1/$i/$VERSION
pwd
jar -cvf bundle.jar *
# use correct sonatype credentials here
curl -v -XPOST -u USER:PASSWORD --upload-file bundle.jar https://oss.sonatype.org/service/local/staging/bundle_upload
popd
done

View File

@@ -2,7 +2,6 @@ pluginManagement {
repositories { repositories {
google() google()
gradlePluginPortal() gradlePluginPortal()
jcenter()
} }
} }
rootProject.name = "secp256k1-kmp" rootProject.name = "secp256k1-kmp"

View File

@@ -41,16 +41,16 @@ public interface Secp256k1 {
* Verify a Schnorr signature. * Verify a Schnorr signature.
* *
* @param signature 64 bytes signature. * @param signature 64 bytes signature.
* @param message message signed. * @param data message signed.
* @param pubkey signer's x-only public key (32 bytes). * @param pub signer's x-only public key (32 bytes).
*/ */
public fun verifySchnorr(signature: ByteArray, data: ByteArray, pub: ByteArray): Boolean public fun verifySchnorr(signature: ByteArray, data: ByteArray, pub: ByteArray): Boolean
/** /**
* Create a Schnorr signature. * Create a Schnorr signature.
* *
* @param message message to sign. * @param data message to sign.
* @param privkey signer's private key. * @param sec signer's private key.
* @param auxrand32 32 bytes of fresh randomness (optional). * @param auxrand32 32 bytes of fresh randomness (optional).
*/ */
public fun signSchnorr(data: ByteArray, sec: ByteArray, auxrand32: ByteArray?): ByteArray public fun signSchnorr(data: ByteArray, sec: ByteArray, auxrand32: ByteArray?): ByteArray

View File

@@ -118,7 +118,7 @@ public object Secp256k1Native : Secp256k1 {
memScoped { memScoped {
val negated = privkey.copyOf() val negated = privkey.copyOf()
val negPriv = toNat(negated) val negPriv = toNat(negated)
secp256k1_ec_privkey_negate(ctx, negPriv).requireSuccess("secp256k1_ec_privkey_negate() failed") secp256k1_ec_seckey_negate(ctx, negPriv).requireSuccess("secp256k1_ec_seckey_negate() failed")
return negated return negated
} }
} }
@@ -129,7 +129,7 @@ public object Secp256k1Native : Secp256k1 {
val added = privkey.copyOf() val added = privkey.copyOf()
val natAdd = toNat(added) val natAdd = toNat(added)
val natTweak = toNat(tweak) val natTweak = toNat(tweak)
secp256k1_ec_privkey_tweak_add(ctx, natAdd, natTweak).requireSuccess("secp256k1_ec_privkey_tweak_add() failed") secp256k1_ec_seckey_tweak_add(ctx, natAdd, natTweak).requireSuccess("secp256k1_ec_seckey_tweak_add() failed")
return added return added
} }
} }
@@ -247,7 +247,7 @@ public object Secp256k1Native : Secp256k1 {
val nSig = allocArray<UByteVar>(64) val nSig = allocArray<UByteVar>(64)
val keypair = alloc<secp256k1_keypair>() val keypair = alloc<secp256k1_keypair>()
secp256k1_keypair_create(ctx, keypair.ptr, nSec).requireSuccess("secp256k1_keypair_create() failed") secp256k1_keypair_create(ctx, keypair.ptr, nSec).requireSuccess("secp256k1_keypair_create() failed")
secp256k1_schnorrsig_sign(ctx, nSig, nData, keypair.ptr, nAuxrand32).requireSuccess("secp256k1_ecdsa_sign() failed") secp256k1_schnorrsig_sign32(ctx, nSig, nData, keypair.ptr, nAuxrand32).requireSuccess("secp256k1_ecdsa_sign() failed")
return nSig.readBytes(64) return nSig.readBytes(64)
} }
} }