18 Commits

Author SHA1 Message Date
Fabrice Drouin
60801787f9 Release 0.6.0 (#30) 2021-09-22 15:51:58 +02:00
Fabrice Drouin
e7644b7ddb Upgrade to kotlin 1.5 (#27)
* Upgrade to kotlin 1.5.31

* Upgrade dokka gradle plugins to 1.5.30
2021-09-22 15:22:05 +02:00
Fabrice Drouin
3a394cdddc Update secp256k1 sources to be8d9c262f (#29) 2021-09-22 15:03:20 +02:00
Fabrice Drouin
4aa4dc2a50 Set version to 0.5.3-SNASPHOT (#25)
* Set version to 0.5.3-SNAPSHOT

* Use Android API level 27
2021-08-10 09:48:31 +02:00
Fabrice Drouin
7bc3aafd08 Set version to 0.5.2 (#22) 2021-06-28 11:30:05 +02:00
Fabrice Drouin
9c1afc715a Fix Android build (#23)
* Upgrade Android NDK

* Use Android emulator 30.7.3 on macos
2021-06-28 10:31:57 +02:00
Fabrice Drouin
b544b24cc3 Fix memory leak in pubkeyCreate() (#20) 2021-06-22 16:16:08 +02:00
Fabrice Drouin
2b0254affb Update secp256k1 sources (#19)
We're now at efad350, the same commit that bitcoin core is using
2021-06-17 11:42:50 +02:00
Fabrice Drouin
b23733d5d4 Use kotlin 1.4.32, set version to 0.5.2-SNAPSHOT, remove bintray settings. (#18) 2021-04-08 10:12:36 +02:00
Fabrice Drouin
0751d7c103 Update README.md 2021-03-26 14:35:15 +01:00
Fabrice Drouin
eadd428895 Set version to 0.5.1 (#17) 2021-03-22 21:44:01 +01:00
Fabrice Drouin
ad1979c11e Update libsecp256k1 code (#16)
There are no external dependencies now
2021-03-19 19:07:05 +01:00
Romain Boisselle
a609b092be Fix CI (#15) 2021-03-12 10:35:48 +01:00
Romain Boisselle
f493edfdfb New publication configuration (#14)
* add Dokka + align POM metadatas with sonatype requirements

* update snapshot CI

* update JNI publication

* update CI scripts

* remove maven-metadata-local.xml

* add snapshot publication with maven-publish plugin
2021-03-11 17:53:50 +01:00
Salomon BRYS
7d22d835a5 Kotlin 1.4.31 (#13)
* Kotlin 1.4.31

* Updated CI add-path disabled command to new more secure environment file.

* Properly setting up Android in CI
2021-03-08 16:50:25 +01:00
sstone
bb25eb21b7 Set version to 0.4.1 2020-09-16 10:40:37 +02:00
sstone
6a67dbe9f6 signatureNormalize: relax check on signature size
Checking that the sig size is >= 64 is enough, this is just a quick check before the actual library method is called.
2020-09-10 20:21:58 +02:00
Salomon BRYS
7272a55b8a Changed deployment artifact-id to secp256k1-kmp (#12)
Co-authored-by: Salomon BRYS <salomon@kodein.net>
2020-09-09 11:00:04 +02:00
24 changed files with 348 additions and 213 deletions

View File

@@ -28,6 +28,35 @@ jobs:
path: ~/.gradle path: ~/.gradle
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
shell: bash
run: |
echo "ANDROID_HOME=$ANDROID_HOME" >> $GITHUB_ENV
echo "ANDROID_NDK_VERSION=21.4.7075529" >> $GITHUB_ENV
- name: Cached Android NDK
uses: actions/cache@v2
with:
path: ${{ format('{0}/ndk/{1}', env.ANDROID_HOME, env.ANDROID_NDK_VERSION) }}
key: ${{ runner.os }}-android-ndk-${{ env.ANDROID_NDK_VERSION }}
- name: Set up shell
if: matrix.os == 'windows-latest'
run: |
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
rm.exe "C:/WINDOWS/system32/bash.EXE"
- name: Set up JDK 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Setup Android
if: matrix.os != 'windows-latest'
shell: bash
run: |
$ANDROID_HOME/tools/bin/sdkmanager "ndk;$ANDROID_NDK_VERSION"
- name: Setup Android
if: matrix.os == 'windows-latest'
shell: bash
run: |
$ANDROID_HOME\\tools\\bin\\sdkmanager.bat "ndk;$ANDROID_NDK_VERSION"
- name: Set up JDK 11 - name: Set up JDK 11
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
@@ -35,11 +64,6 @@ jobs:
- name: Install Automake - name: Install Automake
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
run: brew install automake run: brew install automake
- name: Set up shell
if: matrix.os == 'windows-latest'
run: |
echo ::add-path::C:\msys64\usr\bin\
rm.exe "C:/WINDOWS/system32/bash.EXE"
- name: Check JVM - name: Check JVM
shell: bash shell: bash
run: ./gradlew jvmTest run: ./gradlew jvmTest
@@ -55,8 +79,10 @@ jobs:
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
uses: reactivecircus/android-emulator-runner@v2 uses: reactivecircus/android-emulator-runner@v2
with: with:
api-level: 29 api-level: 27
ndk: 21.3.6528147 emulator-build: 7425822 # workaround to emulator bug: https://github.com/ReactiveCircus/android-emulator-runner/issues/160
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
ndk: ${{ env.ANDROID_NDK_VERSION }}
cmake: 3.10.2.4988404 cmake: 3.10.2.4988404
script: ./gradlew connectedCheck script: ./gradlew connectedCheck
- name: Publish Linux - name: Publish Linux
@@ -65,24 +91,38 @@ jobs:
BINTRAY_USER: ${{ secrets.bintray_user }} BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }} BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
shell: bash shell: bash
run: ./gradlew publishLinuxPublicationToBintrayRepository :jni:jvm:linux:publishJvmPublicationToBintrayRepository # ./gradlew publishLinuxPublicationToBintrayRepository :jni:jvm:linux:publishJvmPublicationToBintrayRepository
run: ./gradlew publishLinuxPublicationToMavenLocal :jni:jvm:linux:publishJvmPublicationToMavenLocal
- name: Publish Windows - name: Publish Windows
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
env: env:
BINTRAY_USER: ${{ secrets.bintray_user }} BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }} BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
shell: bash shell: bash
run: ./gradlew :jni:jvm:mingw:publishJvmPublicationToBintrayRepository # ./gradlew :jni:jvm:mingw:publishJvmPublicationToBintrayRepository
run: ./gradlew :jni:jvm:mingw:publishToMavenLocal
- name: Publish MacOS - name: Publish MacOS
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
env: env:
BINTRAY_USER: ${{ secrets.bintray_user }} BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }} BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
shell: bash shell: bash
run: ./gradlew publish # ./gradlew publish
- name: Discard run: ./gradlew publishToMavenLocal
if: ${{ failure() || cancelled() }} - name: Copy artifact files
env: run: |
BINTRAY_USER: ${{ secrets.bintray_user }} mkdir -p maven-local/release
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }} cp -r ~/.m2/repository/* maven-local/release
run: ./gradlew postBintrayDiscard - name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: release
path: |
maven-local
!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

@@ -3,6 +3,7 @@ name: Publish snapshot
on: on:
push: push:
branches: branches:
- 'master'
- 'snapshot/*' - 'snapshot/*'
paths-ignore: paths-ignore:
- '**.md' - '**.md'
@@ -36,6 +37,35 @@ jobs:
path: ~/.gradle path: ~/.gradle
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
shell: bash
run: |
echo "ANDROID_HOME=$ANDROID_HOME" >> $GITHUB_ENV
echo "ANDROID_NDK_VERSION=21.4.7075529" >> $GITHUB_ENV
- name: Cached Android NDK
uses: actions/cache@v2
with:
path: ${{ format('{0}/ndk/{1}', env.ANDROID_HOME, env.ANDROID_NDK_VERSION) }}
key: ${{ runner.os }}-android-ndk-${{ env.ANDROID_NDK_VERSION }}
- name: Set up shell
if: matrix.os == 'windows-latest'
run: |
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
rm.exe "C:/WINDOWS/system32/bash.EXE"
- name: Set up JDK 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Setup Android
if: matrix.os != 'windows-latest'
shell: bash
run: |
$ANDROID_HOME/tools/bin/sdkmanager "ndk;$ANDROID_NDK_VERSION"
- name: Setup Android
if: matrix.os == 'windows-latest'
shell: bash
run: |
$ANDROID_HOME\\tools\\bin\\sdkmanager.bat "ndk;$ANDROID_NDK_VERSION"
- name: Set up JDK 11 - name: Set up JDK 11
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
@@ -43,11 +73,6 @@ jobs:
- name: Install Automake - name: Install Automake
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
run: brew install automake run: brew install automake
- name: Set up shell
if: matrix.os == 'windows-latest'
run: |
echo ::add-path::C:\msys64\usr\bin\
rm.exe "C:/WINDOWS/system32/bash.EXE"
- name: Check JVM - name: Check JVM
shell: bash shell: bash
run: ./gradlew jvmTest run: ./gradlew jvmTest
@@ -63,8 +88,10 @@ jobs:
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
uses: reactivecircus/android-emulator-runner@v2 uses: reactivecircus/android-emulator-runner@v2
with: with:
api-level: 29 api-level: 27
ndk: 21.3.6528147 -build: 7425822 # workaround to emulator bug: https://github.com/ReactiveCircus/android-emulator-runner/issues/160
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
ndk: ${{ env.ANDROID_NDK_VERSION }}
cmake: 3.10.2.4988404 cmake: 3.10.2.4988404
script: ./gradlew connectedCheck script: ./gradlew connectedCheck
- name: Publish Linux - name: Publish Linux
@@ -73,49 +100,63 @@ jobs:
BINTRAY_USER: ${{ secrets.bintray_user }} BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }} BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
shell: bash shell: bash
run: ./gradlew publishLinuxPublicationToBintrayRepository :jni:jvm:linux:publishJvmPublicationToBintrayRepository -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }} # ./gradlew publishLinuxPublicationToBintrayRepository :jni:jvm:linux:publishJvmPublicationToBintrayRepository -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'
env: env:
BINTRAY_USER: ${{ secrets.bintray_user }} BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }} BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
shell: bash shell: bash
run: ./gradlew :jni:jvm:mingw:publishJvmPublicationToBintrayRepository -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }} # ./gradlew :jni:jvm:mingw:publishJvmPublicationToBintrayRepository -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'
env: env:
BINTRAY_USER: ${{ secrets.bintray_user }} BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }} BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
shell: bash shell: bash
run: ./gradlew publish -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }} # ./gradlew publish -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }}
- name: Discard run: ./gradlew publishToMavenLocal -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }}
if: ${{ failure() || cancelled() }} - name: Copy artifact files
env: run: |
BINTRAY_USER: ${{ secrets.bintray_user }} mkdir -p maven-local/snapshot
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }} cp -r ~/.m2/repository/* maven-local/snapshot
run: ./gradlew postBintrayDiscard -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }} - name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: snapshot
path: |
maven-local
!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 -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }}
publish: # publish:
name: Publish # name: Publish
needs: upload # needs: upload
runs-on: ubuntu-latest # runs-on: ubuntu-latest
steps: # steps:
- name: Check out # - name: Check out
uses: actions/checkout@v2 # uses: actions/checkout@v2
with: # with:
submodules: 'true' # submodules: 'true'
- name: Cached Gradle # - name: Cached Gradle
uses: actions/cache@v2 # uses: actions/cache@v2
with: # with:
path: ~/.gradle # path: ~/.gradle
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: 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: Publish # - name: Publish
env: # env:
BINTRAY_USER: ${{ secrets.bintray_user }} # BINTRAY_USER: ${{ secrets.bintray_user }}
BINTRAY_APIKEY: ${{ secrets.bintray_apikey }} # BINTRAY_APIKEY: ${{ secrets.bintray_apikey }}
run: ./gradlew postBintrayPublish -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }} # run: ./gradlew postBintrayPublish -PsnapshotNumber=${{ github.run_number }} -PgitRef=${{ github.ref }}

View File

@@ -10,7 +10,8 @@ on:
- '!.github/workflows/test.yml' - '!.github/workflows/test.yml'
push: push:
branches: branches:
- 'master' - '!master'
- '!snapshot/*'
paths-ignore: paths-ignore:
- '**.md' - '**.md'
- '**.adoc' - '**.adoc'
@@ -42,6 +43,35 @@ jobs:
path: ~/.gradle path: ~/.gradle
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
shell: bash
run: |
echo "ANDROID_HOME=$ANDROID_HOME" >> $GITHUB_ENV
echo "ANDROID_NDK_VERSION=21.4.7075529" >> $GITHUB_ENV
- name: Cached Android NDK
uses: actions/cache@v2
with:
path: ${{ format('{0}/ndk/{1}', env.ANDROID_HOME, env.ANDROID_NDK_VERSION) }}
key: ${{ runner.os }}-android-ndk-${{ env.ANDROID_NDK_VERSION }}
- name: Set up shell
if: matrix.os == 'windows-latest'
run: |
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
rm.exe "C:/WINDOWS/system32/bash.EXE"
- name: Set up JDK 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Setup Android
if: matrix.os != 'windows-latest'
shell: bash
run: |
$ANDROID_HOME/tools/bin/sdkmanager "ndk;$ANDROID_NDK_VERSION"
- name: Setup Android
if: matrix.os == 'windows-latest'
shell: bash
run: |
$ANDROID_HOME\\tools\\bin\\sdkmanager.bat "ndk;$ANDROID_NDK_VERSION"
- name: Set up JDK 11 - name: Set up JDK 11
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
@@ -49,11 +79,6 @@ jobs:
- name: Install Automake - name: Install Automake
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
run: brew install automake run: brew install automake
- name: Set up shell
if: matrix.os == 'windows-latest'
run: |
echo ::add-path::C:\msys64\usr\bin\
rm.exe "C:/WINDOWS/system32/bash.EXE"
- name: Check JVM - name: Check JVM
shell: bash shell: bash
run: ./gradlew jvmTest run: ./gradlew jvmTest
@@ -69,7 +94,9 @@ jobs:
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
uses: reactivecircus/android-emulator-runner@v2 uses: reactivecircus/android-emulator-runner@v2
with: with:
api-level: 29 api-level: 27
ndk: 21.3.6528147 emulator-build: 7425822 # workaround to emulator bug: https://github.com/ReactiveCircus/android-emulator-runner/issues/160
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
ndk: ${{ env.ANDROID_NDK_VERSION }}
cmake: 3.10.2.4988404 cmake: 3.10.2.4988404
script: ./gradlew connectedCheck script: ./gradlew connectedCheck

View File

@@ -1,19 +1,15 @@
[![Kotlin](https://img.shields.io/badge/Kotlin-1.4.31-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*)
![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)
# Secp256k1 for Kotlin/Multiplatform # Secp256k1 for Kotlin/Multiplatform
Kotlin/Multiplatform wrapper for Bitcoin Core's secp256k1 library. Targets: JVM, Android, iOS & Linux. Kotlin/Multiplatform wrapper for Bitcoin Core's secp256k1 library. Targets: JVM, Android, iOS & Linux.
## Installation ## Installation
[ ![Download](https://api.bintray.com/packages/acinq/libs/secp256k1/images/download.svg) ](https://bintray.com/acinq/libs/secp256k1-kmp/) secp256k1-kmp is available on [maven central](https://search.maven.org/search?q=g:fr.acinq.secp256k1%20a:secp256k1-kmp*)
First, you need to add the ACINQ libraries repository:
```kotlin
// build.gradle.kts
repositories {
maven(url = "https://dl.bintray.com/acinq/libs")
}
```
Then, the actual dependency depends on your targeted platform(s): Then, the actual dependency depends on your targeted platform(s):

View File

@@ -1,35 +1,32 @@
import org.apache.http.impl.client.HttpClients
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.ContentType
import org.apache.http.entity.StringEntity
import org.apache.http.impl.auth.BasicScheme
import org.apache.http.auth.UsernamePasswordCredentials
import org.gradle.internal.os.OperatingSystem import org.gradle.internal.os.OperatingSystem
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.dokka.Platform
plugins { plugins {
kotlin("multiplatform") version "1.4.0" kotlin("multiplatform") version "1.5.31"
id("org.jetbrains.dokka") version "1.5.30"
`maven-publish` `maven-publish`
} }
buildscript { buildscript {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath("com.android.tools.build:gradle:4.0.1") classpath("com.android.tools.build:gradle:4.0.2")
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.5.30")
} }
} }
allprojects { allprojects {
group = "fr.acinq.secp256k1" group = "fr.acinq.secp256k1"
version = "0.3.0" version = "0.6.0"
repositories { repositories {
jcenter()
google() google()
mavenCentral()
} }
} }
@@ -66,7 +63,6 @@ kotlin {
ios { ios {
secp256k1CInterop("ios") secp256k1CInterop("ios")
// https://youtrack.jetbrains.com/issue/KT-39396
compilations["main"].defaultSourceSet.dependsOn(nativeMain) compilations["main"].defaultSourceSet.dependsOn(nativeMain)
// https://youtrack.jetbrains.com/issue/KT-39396 // https://youtrack.jetbrains.com/issue/KT-39396
compilations["main"].kotlinOptions.freeCompilerArgs += listOf("-include-binary", "$rootDir/native/build/ios/libsecp256k1.a") compilations["main"].kotlinOptions.freeCompilerArgs += listOf("-include-binary", "$rootDir/native/build/ios/libsecp256k1.a")
@@ -75,7 +71,6 @@ kotlin {
sourceSets.all { sourceSets.all {
languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn") languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn")
} }
} }
// Disable cross compilation // Disable cross compilation
@@ -108,41 +103,27 @@ allprojects {
} }
} }
val snapshotNumber: String? by project
val gitRef: String? by project
val eapBranch = gitRef?.split("/")?.last() ?: "dev"
val bintrayVersion = if (snapshotNumber != null) "${project.version}-$eapBranch-$snapshotNumber" else project.version.toString()
val bintrayRepo = if (snapshotNumber != null) "snapshots" else "libs"
val bintrayUsername: String? = (properties["bintrayUsername"] as String?) ?: System.getenv("BINTRAY_USER")
val bintrayApiKey: String? = (properties["bintrayApiKey"] as String?) ?: System.getenv("BINTRAY_APIKEY")
val hasBintray = bintrayUsername != null && bintrayApiKey != null
if (!hasBintray) logger.warn("Skipping bintray configuration as bintrayUsername or bintrayApiKey is not defined")
allprojects { allprojects {
val javadocJar = tasks.create<Jar>("javadocJar") {
archiveClassifier.set("javadoc")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
// Publication
plugins.withId("maven-publish") { plugins.withId("maven-publish") {
publishing { publishing {
if (hasBintray) {
repositories {
maven {
name = "bintray"
setUrl("https://api.bintray.com/maven/acinq/$bintrayRepo/${rootProject.name}/;publish=0")
credentials {
username = bintrayUsername
password = bintrayApiKey
}
}
}
}
publications.withType<MavenPublication>().configureEach { publications.withType<MavenPublication>().configureEach {
version = bintrayVersion version = project.version.toString()
artifact(javadocJar)
pom { pom {
name.set("secp256k1 for Kotlin/Multiplatform")
description.set("Bitcoin's secp256k1 library ported to Kotlin/Multiplatform for JVM, Android, iOS & Linux") description.set("Bitcoin's secp256k1 library ported to Kotlin/Multiplatform for JVM, Android, iOS & Linux")
url.set("https://github.com/ACINQ/secp256k1-kmp") url.set("https://github.com/ACINQ/secp256k1-kmp")
licenses { licenses {
name.set("Apache License v2.0") license {
url.set("https://www.apache.org/licenses/LICENSE-2.0") name.set("Apache License v2.0")
url.set("https://www.apache.org/licenses/LICENSE-2.0")
}
} }
issueManagement { issueManagement {
system.set("Github") system.set("Github")
@@ -150,35 +131,49 @@ allprojects {
} }
scm { scm {
connection.set("https://github.com/ACINQ/secp256k1-kmp.git") connection.set("https://github.com/ACINQ/secp256k1-kmp.git")
url.set("https://github.com/ACINQ/secp256k1-kmp")
}
developers {
developer {
name.set("ACINQ")
email.set("hello@acinq.co")
}
} }
} }
} }
} }
} }
}
if (hasBintray) { if (project.name !in listOf("native", "tests")) {
val postBintrayPublish by tasks.creating { afterEvaluate {
doLast { val dokkaOutputDir = buildDir.resolve("dokka")
HttpClients.createDefault().use { client ->
val post = HttpPost("https://api.bintray.com/content/acinq/$bintrayRepo/${rootProject.name}/$bintrayVersion/publish").apply {
entity = StringEntity("{}", ContentType.APPLICATION_JSON)
addHeader(BasicScheme().authenticate(UsernamePasswordCredentials(bintrayUsername, bintrayApiKey), this, null))
}
client.execute(post)
}
}
}
val postBintrayDiscard by tasks.creating { tasks.dokkaHtml {
doLast { outputDirectory.set(file(dokkaOutputDir))
HttpClients.createDefault().use { client -> dokkaSourceSets {
val post = HttpPost("https://api.bintray.com/content/acinq/$bintrayRepo/${rootProject.name}/$bintrayVersion/publish").apply { configureEach {
entity = StringEntity("{ \"discard\": true }", ContentType.APPLICATION_JSON) val platformName = when (platform.get()) {
addHeader(BasicScheme().authenticate(UsernamePasswordCredentials(bintrayUsername, bintrayApiKey), this, null)) Platform.jvm -> "jvm"
Platform.js -> "js"
Platform.native -> "native"
Platform.common -> "common"
}
displayName.set(platformName)
perPackageOption {
matchingRegex.set(".*\\.internal.*") // will match all .internal packages and sub-packages
suppress.set(true)
}
}
} }
client.execute(post)
} }
val deleteDokkaOutputDir by tasks.register<Delete>("deleteDokkaOutputDirectory") {
delete(dokkaOutputDir)
}
javadocJar.dependsOn(deleteDokkaOutputDir, tasks.dokkaHtml)
javadocJar.from(dokkaOutputDir)
} }
} }
} }

View File

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

View File

@@ -1,6 +1,9 @@
import org.jetbrains.dokka.Platform
plugins { plugins {
id("com.android.library") id("com.android.library")
kotlin("android") kotlin("android")
id("org.jetbrains.dokka")
`maven-publish` `maven-publish`
} }
@@ -32,7 +35,7 @@ android {
setPath("src/main/CMakeLists.txt") setPath("src/main/CMakeLists.txt")
} }
} }
ndkVersion = "21.3.6528147" ndkVersion = "21.4.7075529"
afterEvaluate { afterEvaluate {
tasks.withType<com.android.build.gradle.tasks.factory.AndroidUnitTest>().all { tasks.withType<com.android.build.gradle.tasks.factory.AndroidUnitTest>().all {
@@ -51,8 +54,13 @@ afterEvaluate {
publishing { publishing {
publications { publications {
create<MavenPublication>("android") { create<MavenPublication>("android") {
artifactId = "secp256k1-jni-android" artifactId = "secp256k1-kmp-jni-android"
from(components["release"]) from(components["release"])
val sourcesJar = task<Jar>("sourcesJar") {
archiveClassifier.set("sources")
from(android.sourceSets["main"].java.srcDirs)
}
artifact(sourcesJar)
} }
} }
} }

View File

@@ -1,5 +1,8 @@
import org.jetbrains.dokka.Platform
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("org.jetbrains.dokka")
`maven-publish` `maven-publish`
} }
@@ -34,8 +37,13 @@ val generateHeaders by tasks.creating(JavaCompile::class) {
publishing { publishing {
publications { publications {
create<MavenPublication>("jvm") { create<MavenPublication>("jvm") {
artifactId = "secp256k1-jni-common" artifactId = "secp256k1-kmp-jni-common"
from(components["java"]) from(components["java"])
val sourcesJar = task<Jar>("sourcesJar") {
archiveClassifier.set("sources")
from(sourceSets["main"].allSource)
}
artifact(sourcesJar)
} }
} }
} }

View File

@@ -133,11 +133,8 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
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);
jpubkey = (*penv)->NewByteArray(penv, 65);
pubkey = (*penv)->GetByteArrayElements(penv, jpubkey, 0);
result = secp256k1_ec_pubkey_create(ctx, &pub, (unsigned char*)seckey); result = secp256k1_ec_pubkey_create(ctx, &pub, (unsigned char*)seckey);
(*penv)->ReleaseByteArrayElements(penv, jseckey, seckey, 0); (*penv)->ReleaseByteArrayElements(penv, jseckey, seckey, 0);
(*penv)->ReleaseByteArrayElements(penv, jpubkey, pubkey, 0);
CHECKRESULT(!result, "secp256k1_ec_pubkey_create failed"); CHECKRESULT(!result, "secp256k1_ec_pubkey_create failed");
jpubkey = (*penv)->NewByteArray(penv, 65); jpubkey = (*penv)->NewByteArray(penv, 65);
pubkey = (*penv)->GetByteArrayElements(penv, jpubkey, 0); pubkey = (*penv)->GetByteArrayElements(penv, jpubkey, 0);

View File

@@ -1,5 +1,6 @@
plugins { plugins {
`java-library` `java-library`
id("org.jetbrains.dokka")
`maven-publish` `maven-publish`
} }
@@ -12,8 +13,12 @@ dependencies {
publishing { publishing {
publications { publications {
create<MavenPublication>("jvm") { create<MavenPublication>("jvm") {
artifactId = "secp256k1-jni-jvm" artifactId = "secp256k1-kmp-jni-jvm"
from(components["java"]) from(components["java"])
val sourcesJar = task<Jar>("sourcesJar") {
archiveClassifier.set("sources")
}
artifact(sourcesJar)
} }
} }
} }

View File

@@ -1,5 +1,6 @@
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("org.jetbrains.dokka")
`maven-publish` `maven-publish`
} }
@@ -33,8 +34,12 @@ dependencies {
publishing { publishing {
publications { publications {
create<MavenPublication>("jvm") { create<MavenPublication>("jvm") {
artifactId = "secp256k1-jni-jvm-extract" artifactId = "secp256k1-kmp-jni-jvm-extract"
from(components["java"]) from(components["java"])
val sourcesJar = task<Jar>("sourcesJar") {
archiveClassifier.set("sources")
}
artifact(sourcesJar)
} }
} }
} }

View File

@@ -14,11 +14,9 @@ JNI_HEADERS=$TARGET
if [ "$TARGET" == "linux" ]; then if [ "$TARGET" == "linux" ]; then
OUTFILE=libsecp256k1-jni.so OUTFILE=libsecp256k1-jni.so
ADD_LIB=-lgmp
CC_OPTS="-fPIC" CC_OPTS="-fPIC"
elif [ "$TARGET" == "darwin" ]; then elif [ "$TARGET" == "darwin" ]; then
OUTFILE=libsecp256k1-jni.dylib OUTFILE=libsecp256k1-jni.dylib
ADD_LIB=-lgmp
elif [ "$TARGET" == "mingw" ]; then elif [ "$TARGET" == "mingw" ]; then
OUTFILE=secp256k1-jni.dll OUTFILE=secp256k1-jni.dll
CC=x86_64-w64-mingw32-gcc CC=x86_64-w64-mingw32-gcc

View File

@@ -1,5 +1,7 @@
plugins { plugins {
kotlin("jvm") kotlin("jvm")
`java-library`
id("org.jetbrains.dokka")
`maven-publish` `maven-publish`
} }
@@ -23,8 +25,12 @@ val copyJni by tasks.creating(Sync::class) {
publishing { publishing {
publications { publications {
val pub = create<MavenPublication>("jvm") { val pub = create<MavenPublication>("jvm") {
artifactId = "secp256k1-jni-jvm-darwin" artifactId = "secp256k1-kmp-jni-jvm-darwin"
from(components["java"]) from(components["java"])
val sourcesJar = task<Jar>("sourcesJar") {
archiveClassifier.set("sources")
}
artifact(sourcesJar)
} }
if (!org.gradle.internal.os.OperatingSystem.current().isMacOsX) { if (!org.gradle.internal.os.OperatingSystem.current().isMacOsX) {
tasks.withType<AbstractPublishToMaven>().all { onlyIf { publication != pub } } tasks.withType<AbstractPublishToMaven>().all { onlyIf { publication != pub } }

View File

@@ -1,5 +1,6 @@
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("org.jetbrains.dokka")
`maven-publish` `maven-publish`
} }
@@ -23,8 +24,12 @@ val copyJni by tasks.creating(Sync::class) {
publishing { publishing {
publications { publications {
val pub = create<MavenPublication>("jvm") { val pub = create<MavenPublication>("jvm") {
artifactId = "secp256k1-jni-jvm-linux" artifactId = "secp256k1-kmp-jni-jvm-linux"
from(components["java"]) from(components["java"])
val sourcesJar = task<Jar>("sourcesJar") {
archiveClassifier.set("sources")
}
artifact(sourcesJar)
} }
if (!org.gradle.internal.os.OperatingSystem.current().isLinux) { if (!org.gradle.internal.os.OperatingSystem.current().isLinux) {
tasks.withType<AbstractPublishToMaven>().all { onlyIf { publication != pub } } tasks.withType<AbstractPublishToMaven>().all { onlyIf { publication != pub } }

View File

@@ -1,5 +1,6 @@
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("org.jetbrains.dokka")
`maven-publish` `maven-publish`
} }
@@ -23,8 +24,12 @@ val copyJni by tasks.creating(Sync::class) {
publishing { publishing {
publications { publications {
val pub = create<MavenPublication>("jvm") { val pub = create<MavenPublication>("jvm") {
artifactId = "secp256k1-jni-jvm-mingw" artifactId = "secp256k1-kmp-jni-jvm-mingw"
from(components["java"]) from(components["java"])
val sourcesJar = task<Jar>("sourcesJar") {
archiveClassifier.set("sources")
}
artifact(sourcesJar)
} }
if (!org.gradle.internal.os.OperatingSystem.current().isWindows) { if (!org.gradle.internal.os.OperatingSystem.current().isWindows) {
tasks.withType<AbstractPublishToMaven>().all { onlyIf { publication != pub } } tasks.withType<AbstractPublishToMaven>().all { onlyIf { publication != pub } }

View File

@@ -154,7 +154,7 @@ internal object OSInfo {
if (systemOsArch.startsWith("arm")) { if (systemOsArch.startsWith("arm")) {
resolveArmArchType() resolveArmArchType()
} else { } else {
val lc = systemOsArch.toLowerCase(Locale.US) val lc = systemOsArch.lowercase(Locale.US)
if (archMapping.containsKey(lc)) return archMapping[lc] if (archMapping.containsKey(lc)) return archMapping[lc]
systemOsArch systemOsArch
} }

View File

@@ -15,7 +15,6 @@ if [ "$TARGET" == "mingw" ]; then
CONF_OPTS="CFLAGS=-fPIC --host=x86_64-w64-mingw32" CONF_OPTS="CFLAGS=-fPIC --host=x86_64-w64-mingw32"
elif [ "$TARGET" == "linux" ]; then elif [ "$TARGET" == "linux" ]; then
CONF_OPTS="CFLAGS=-fPIC" CONF_OPTS="CFLAGS=-fPIC"
[ "$CROSS" == "1" ] && sudo apt -y install libgmp-dev
elif [ "$TARGET" == "darwin" ]; then elif [ "$TARGET" == "darwin" ]; then
CONF_OPTS="--host=x86_64-w64-darwin" CONF_OPTS="--host=x86_64-w64-darwin"
else else

View File

@@ -5,7 +5,7 @@ pluginManagement {
jcenter() jcenter()
} }
} }
rootProject.name = "secp256k1" rootProject.name = "secp256k1-kmp"
include( include(
":native", ":native",
@@ -17,4 +17,4 @@ include(
":jni:jvm:mingw", ":jni:jvm:mingw",
":jni:jvm:all", ":jni:jvm:all",
":tests" ":tests"
) )

View File

@@ -20,12 +20,12 @@ import java.util.*
private fun tryLoad(platform: String): Secp256k1? { private fun tryLoad(platform: String): Secp256k1? {
try { return try {
val cls = Class.forName("fr.acinq.secp256k1.jni.NativeSecp256k1${platform.capitalize(Locale.ROOT)}Loader") val cls = Class.forName("fr.acinq.secp256k1.jni.NativeSecp256k1${platform.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() }}Loader")
val load = cls.getMethod("load") val load = cls.getMethod("load")
return load.invoke(null) as Secp256k1 load.invoke(null) as Secp256k1
} catch (ex: ClassNotFoundException) { } catch (ex: ClassNotFoundException) {
return null null
} }
} }

View File

@@ -4,7 +4,7 @@ headers = secp256k1.h secp256k1_ecdh.h secp256k1_recovery.h
headerFilter = secp256k1/** secp256k1_ecdh.h secp256k1_recovery.h secp256k1.h headerFilter = secp256k1/** secp256k1_ecdh.h secp256k1_recovery.h secp256k1.h
libraryPaths.linux = c/secp256k1/build/linux/ libraryPaths.linux = c/secp256k1/build/linux/
linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -lgmp linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib
libraryPaths.ios = c/secp256k1/build/ios/ /usr/local/lib libraryPaths.ios = c/secp256k1/build/ios/ /usr/local/lib
linkerOpts.ios = -framework Security -framework Foundation linkerOpts.ios = -framework Security -framework Foundation

View File

@@ -79,7 +79,7 @@ public object Secp256k1Native : Secp256k1 {
} }
public override fun signatureNormalize(sig: ByteArray): Pair<ByteArray, Boolean> { public override fun signatureNormalize(sig: ByteArray): Pair<ByteArray, Boolean> {
require(sig.size == 64 || sig.size in 70..73) require(sig.size >= 64){ "invalid signature ${Hex.encode(sig)}" }
memScoped { memScoped {
val nSig = allocSignature(sig) val nSig = allocSignature(sig)
val isHighS = secp256k1_ecdsa_signature_normalize(ctx, nSig.ptr, nSig.ptr) val isHighS = secp256k1_ecdsa_signature_normalize(ctx, nSig.ptr, nSig.ptr)

View File

@@ -38,8 +38,8 @@ kotlin {
} }
sourceSets["androidTest"].dependencies { sourceSets["androidTest"].dependencies {
implementation(kotlin("test-junit")) implementation(kotlin("test-junit"))
implementation("androidx.test.ext:junit:1.1.1") implementation("androidx.test.ext:junit:1.1.2")
implementation("androidx.test.espresso:espresso-core:3.2.0") implementation("androidx.test.espresso:espresso-core:3.3.0")
} }
} }

View File

@@ -13,12 +13,12 @@ class Secp256k1Test {
@Test @Test
fun testVerifyPos() { fun testVerifyPos() {
var result: Boolean var result: Boolean
val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()) //sha256hash of "testing" val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".lowercase()) //sha256hash of "testing"
val sig: ByteArray = Hex.decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()) val sig: ByteArray = Hex.decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".lowercase())
val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()) val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".lowercase())
result = Secp256k1.verify(sig, data, pub) result = Secp256k1.verify(sig, data, pub)
assertTrue(result, "testVerifyPos") assertTrue(result, "testVerifyPos")
val sigCompact: ByteArray = Hex.decode("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()) val sigCompact: ByteArray = Hex.decode("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".lowercase())
result = Secp256k1.verify(sigCompact, data, pub) result = Secp256k1.verify(sigCompact, data, pub)
assertTrue(result, "testVerifyPos") assertTrue(result, "testVerifyPos")
} }
@@ -26,9 +26,9 @@ class Secp256k1Test {
@Test @Test
fun testVerifyNeg() { fun testVerifyNeg() {
var result: Boolean var result: Boolean
val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A91".toLowerCase()) //sha256hash of "testing" val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A91".lowercase()) //sha256hash of "testing"
val sig: ByteArray = Hex.decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()) val sig: ByteArray = Hex.decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".lowercase())
val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()) val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".lowercase())
result = Secp256k1.verify(sig, data, pub) result = Secp256k1.verify(sig, data, pub)
assertFalse(result, "testVerifyNeg") assertFalse(result, "testVerifyNeg")
} }
@@ -36,7 +36,7 @@ class Secp256k1Test {
@Test @Test
fun testSecKeyVerifyPos() { fun testSecKeyVerifyPos() {
var result: Boolean var result: Boolean
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
result = Secp256k1.secKeyVerify(sec) result = Secp256k1.secKeyVerify(sec)
assertTrue(result, "testSecKeyVerifyPos") assertTrue(result, "testSecKeyVerifyPos")
} }
@@ -44,16 +44,16 @@ class Secp256k1Test {
@Test @Test
fun testSecKeyVerifyNeg() { fun testSecKeyVerifyNeg() {
var result: Boolean var result: Boolean
val sec: ByteArray = Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()) val sec: ByteArray = Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".lowercase())
result = Secp256k1.secKeyVerify(sec) result = Secp256k1.secKeyVerify(sec)
assertFalse(result, "testSecKeyVerifyNeg") assertFalse(result, "testSecKeyVerifyNeg")
} }
@Test @Test
fun testPubKeyCreatePos() { fun testPubKeyCreatePos() {
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
val resultArr: ByteArray = Secp256k1.pubkeyCreate(sec) val resultArr: ByteArray = Secp256k1.pubkeyCreate(sec)
val pubkeyString: String = Hex.encode(resultArr).toUpperCase() val pubkeyString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6", "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6",
pubkeyString, pubkeyString,
@@ -63,7 +63,7 @@ class Secp256k1Test {
@Test @Test
fun testPubKeyCreateNeg() { fun testPubKeyCreateNeg() {
val sec: ByteArray = Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()) val sec: ByteArray = Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".lowercase())
assertFailsWith<Secp256k1Exception> { assertFailsWith<Secp256k1Exception> {
Secp256k1.pubkeyCreate(sec) Secp256k1.pubkeyCreate(sec)
} }
@@ -73,21 +73,21 @@ class Secp256k1Test {
fun testPubkeyCompress() { fun testPubkeyCompress() {
val pub = Hex.decode("04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6") val pub = Hex.decode("04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6")
val compressed = Secp256k1.pubKeyCompress(pub) val compressed = Secp256k1.pubKeyCompress(pub)
assertEquals("02C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D", Hex.encode(compressed).toUpperCase()) assertEquals("02C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D", Hex.encode(compressed).uppercase())
} }
@Test @Test
fun testPubKeyNegatePos() { fun testPubKeyNegatePos() {
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
val pubkey: ByteArray = Secp256k1.pubkeyCreate(sec) val pubkey: ByteArray = Secp256k1.pubkeyCreate(sec)
val pubkeyString: String = Hex.encode(pubkey).toUpperCase() val pubkeyString: String = Hex.encode(pubkey).uppercase()
assertEquals( assertEquals(
"04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6", "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6",
pubkeyString, pubkeyString,
"testPubKeyCreatePos" "testPubKeyCreatePos"
) )
val pubkey1: ByteArray = Secp256k1.pubKeyNegate(pubkey) val pubkey1: ByteArray = Secp256k1.pubKeyNegate(pubkey)
val pubkeyString1: String = Hex.encode(pubkey1).toUpperCase() val pubkeyString1: String = Hex.encode(pubkey1).uppercase()
assertEquals( assertEquals(
"04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2DDEFC12B6B8E73968536514302E69ED1DDB24B999EFEE79C12D03AB17E79E1989", "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2DDEFC12B6B8E73968536514302E69ED1DDB24B999EFEE79C12D03AB17E79E1989",
pubkeyString1, pubkeyString1,
@@ -97,9 +97,9 @@ class Secp256k1Test {
@Test @Test
fun testPubKeyParse() { fun testPubKeyParse() {
val pub: ByteArray = Hex.decode("02C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D".toLowerCase()) val pub: ByteArray = Hex.decode("02C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D".lowercase())
val resultArr: ByteArray = Secp256k1.pubkeyParse(pub) val resultArr: ByteArray = Secp256k1.pubkeyParse(pub)
val pubkeyString: String = Hex.encode(resultArr).toUpperCase() val pubkeyString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6", "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6",
pubkeyString, pubkeyString,
@@ -109,10 +109,10 @@ class Secp256k1Test {
@Test @Test
fun testPubKeyAdd() { fun testPubKeyAdd() {
val pub1: ByteArray = Hex.decode("041b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f70beaf8f588b541507fed6a642c5ab42dfdf8120a7f639de5122d47a69a8e8d1".toLowerCase()) val pub1: ByteArray = Hex.decode("041b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f70beaf8f588b541507fed6a642c5ab42dfdf8120a7f639de5122d47a69a8e8d1".lowercase())
val pub2: ByteArray = Hex.decode("044d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d07662a3eada2d0fe208b6d257ceb0f064284662e857f57b66b54c198bd310ded36d0".toLowerCase()) val pub2: ByteArray = Hex.decode("044d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d07662a3eada2d0fe208b6d257ceb0f064284662e857f57b66b54c198bd310ded36d0".lowercase())
val pub3: ByteArray = Secp256k1.pubKeyAdd(pub1, pub2) val pub3: ByteArray = Secp256k1.pubKeyAdd(pub1, pub2)
val pubkeyString: String = Hex.encode(pub3).toUpperCase() val pubkeyString: String = Hex.encode(pub3).uppercase()
assertEquals( assertEquals(
"04531FE6068134503D2723133227C867AC8FA6C83C537E9A44C3C5BDBDCB1FE3379E92C265E71E481BA82A84675A47AC705A200FCD524E92D93B0E7386F26A5458", "04531FE6068134503D2723133227C867AC8FA6C83C537E9A44C3C5BDBDCB1FE3379E92C265E71E481BA82A84675A47AC705A200FCD524E92D93B0E7386F26A5458",
pubkeyString, pubkeyString,
@@ -122,10 +122,10 @@ class Secp256k1Test {
@Test @Test
fun testSignPos() { fun testSignPos() {
val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()) //sha256hash of "testing" val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".lowercase()) //sha256hash of "testing"
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
val resultArr: ByteArray = Secp256k1.sign(data, sec) val resultArr: ByteArray = Secp256k1.sign(data, sec)
val sigString: String = Hex.encode(resultArr).toUpperCase() val sigString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A21C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9", "182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A21C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9",
sigString, sigString,
@@ -135,9 +135,9 @@ class Secp256k1Test {
@Test @Test
fun testSignatureNormalize() { fun testSignatureNormalize() {
val data: ByteArray = Hex.decode("30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9".toLowerCase()) val data: ByteArray = Hex.decode("30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9".lowercase())
val (resultArr, isHighS) = Secp256k1.signatureNormalize(data) val (resultArr, isHighS) = Secp256k1.signatureNormalize(data)
val sigString: String = Hex.encode(resultArr).toUpperCase() val sigString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A21C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9", "182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A21C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9",
sigString, sigString,
@@ -148,8 +148,8 @@ class Secp256k1Test {
@Test @Test
fun testSignNeg() { fun testSignNeg() {
val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()) //sha256hash of "testing" val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".lowercase()) //sha256hash of "testing"
val sec: ByteArray = Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()) val sec: ByteArray = Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".lowercase())
assertFailsWith<Secp256k1Exception> { assertFailsWith<Secp256k1Exception> {
Secp256k1.sign(data, sec) Secp256k1.sign(data, sec)
} }
@@ -157,10 +157,10 @@ class Secp256k1Test {
@Test @Test
fun testSignCompactPos() { fun testSignCompactPos() {
val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()) //sha256hash of "testing" val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".lowercase()) //sha256hash of "testing"
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
val resultArr: ByteArray = Secp256k1.sign(data, sec) val resultArr: ByteArray = Secp256k1.sign(data, sec)
val sigString: String = Hex.encode(resultArr).toUpperCase() val sigString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A21C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9", "182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A21C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9",
sigString, sigString,
@@ -170,11 +170,11 @@ class Secp256k1Test {
@Test @Test
fun testPrivKeyTweakNegate() { fun testPrivKeyTweakNegate() {
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
val sec1: ByteArray = Secp256k1.privKeyNegate(sec) val sec1: ByteArray = Secp256k1.privKeyNegate(sec)
assertEquals( assertEquals(
"981A9A7DD677A622518DA068D66D5F824E5F22F084B8A0E2F195B5662F300C11", "981A9A7DD677A622518DA068D66D5F824E5F22F084B8A0E2F195B5662F300C11",
Hex.encode(sec1).toUpperCase(), Hex.encode(sec1).uppercase(),
"testPrivKeyNegate" "testPrivKeyNegate"
) )
val sec2: ByteArray = Secp256k1.privKeyNegate(sec1) val sec2: ByteArray = Secp256k1.privKeyNegate(sec1)
@@ -183,10 +183,10 @@ class Secp256k1Test {
@Test @Test
fun testPrivKeyTweakAdd_1() { fun testPrivKeyTweakAdd_1() {
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
val data: ByteArray = Hex.decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()) //sha256hash of "tweak" val data: ByteArray = Hex.decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".lowercase()) //sha256hash of "tweak"
val resultArr: ByteArray = Secp256k1.privKeyTweakAdd(sec, data) val resultArr: ByteArray = Secp256k1.privKeyTweakAdd(sec, data)
val sigString: String = Hex.encode(resultArr).toUpperCase() val sigString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"A168571E189E6F9A7E2D657A4B53AE99B909F7E712D1C23CED28093CD57C88F3", "A168571E189E6F9A7E2D657A4B53AE99B909F7E712D1C23CED28093CD57C88F3",
sigString, sigString,
@@ -196,10 +196,10 @@ class Secp256k1Test {
@Test @Test
fun testPrivKeyTweakMul_1() { fun testPrivKeyTweakMul_1() {
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
val data: ByteArray = Hex.decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()) //sha256hash of "tweak" val data: ByteArray = Hex.decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".lowercase()) //sha256hash of "tweak"
val resultArr: ByteArray = Secp256k1.privKeyTweakMul(sec, data) val resultArr: ByteArray = Secp256k1.privKeyTweakMul(sec, data)
val sigString: String = Hex.encode(resultArr).toUpperCase() val sigString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"97F8184235F101550F3C71C927507651BD3F1CDB4A5A33B8986ACF0DEE20FFFC", "97F8184235F101550F3C71C927507651BD3F1CDB4A5A33B8986ACF0DEE20FFFC",
sigString, sigString,
@@ -209,10 +209,10 @@ class Secp256k1Test {
@Test @Test
fun testPrivKeyTweakAdd_2() { fun testPrivKeyTweakAdd_2() {
val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()) val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".lowercase())
val data: ByteArray = Hex.decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()) //sha256hash of "tweak" val data: ByteArray = Hex.decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".lowercase()) //sha256hash of "tweak"
val resultArr: ByteArray = Secp256k1.pubKeyTweakAdd(pub, data) val resultArr: ByteArray = Secp256k1.pubKeyTweakAdd(pub, data)
val sigString: String = Hex.encode(resultArr).toUpperCase() val sigString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"0411C6790F4B663CCE607BAAE08C43557EDC1A4D11D88DFCB3D841D0C6A941AF525A268E2A863C148555C48FB5FBA368E88718A46E205FABC3DBA2CCFFAB0796EF", "0411C6790F4B663CCE607BAAE08C43557EDC1A4D11D88DFCB3D841D0C6A941AF525A268E2A863C148555C48FB5FBA368E88718A46E205FABC3DBA2CCFFAB0796EF",
sigString, sigString,
@@ -222,10 +222,10 @@ class Secp256k1Test {
@Test @Test
fun testPrivKeyTweakMul_2() { fun testPrivKeyTweakMul_2() {
val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()) val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".lowercase())
val data: ByteArray = Hex.decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()) //sha256hash of "tweak" val data: ByteArray = Hex.decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".lowercase()) //sha256hash of "tweak"
val resultArr: ByteArray = Secp256k1.pubKeyTweakMul(pub, data) val resultArr: ByteArray = Secp256k1.pubKeyTweakMul(pub, data)
val sigString: String = Hex.encode(resultArr).toUpperCase() val sigString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"04E0FE6FE55EBCA626B98A807F6CAF654139E14E5E3698F01A9A658E21DC1D2791EC060D4F412A794D5370F672BC94B722640B5F76914151CFCA6E712CA48CC589", "04E0FE6FE55EBCA626B98A807F6CAF654139E14E5E3698F01A9A658E21DC1D2791EC060D4F412A794D5370F672BC94B722640B5F76914151CFCA6E712CA48CC589",
sigString, sigString,
@@ -235,10 +235,10 @@ class Secp256k1Test {
@Test @Test
fun testCreateECDHSecret() { fun testCreateECDHSecret() {
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()) val pub: ByteArray = Hex.decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".lowercase())
val resultArr: ByteArray = Secp256k1.ecdh(sec, pub) val resultArr: ByteArray = Secp256k1.ecdh(sec, pub)
val ecdhString: String = Hex.encode(resultArr).toUpperCase() val ecdhString: String = Hex.encode(resultArr).uppercase()
assertEquals( assertEquals(
"2A2A67007A926E6594AF3EB564FC74005B37A9C8AEF2033C4552051B5C87F043", "2A2A67007A926E6594AF3EB564FC74005B37A9C8AEF2033C4552051B5C87F043",
ecdhString, ecdhString,
@@ -248,8 +248,8 @@ class Secp256k1Test {
@Test @Test
fun testEcdsaRecover() { fun testEcdsaRecover() {
val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()) //sha256hash of "testing" val data: ByteArray = Hex.decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".lowercase()) //sha256hash of "testing"
val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()) val sec: ByteArray = Hex.decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".lowercase())
val pub: ByteArray = Secp256k1.pubkeyCreate(sec) val pub: ByteArray = Secp256k1.pubkeyCreate(sec)
val sig: ByteArray = Secp256k1.sign(data, sec) val sig: ByteArray = Secp256k1.sign(data, sec)
val pub0: ByteArray = Secp256k1.ecdsaRecover(sig, data, 0) val pub0: ByteArray = Secp256k1.ecdsaRecover(sig, data, 0)
@@ -259,11 +259,11 @@ class Secp256k1Test {
@Test @Test
fun testCompactToDER() { fun testCompactToDER() {
val sig: ByteArray = Hex.decode("182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A21C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9".toLowerCase()) //sha256hash of "testing" val sig: ByteArray = Hex.decode("182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A21C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9".lowercase()) //sha256hash of "testing"
val der: ByteArray = Secp256k1.compact2der(sig) val der: ByteArray = Secp256k1.compact2der(sig)
assertEquals( assertEquals(
"30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9", "30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9",
Hex.encode(der).toUpperCase(), Hex.encode(der).uppercase(),
) )
} }