msgilligan / secp256k1-jdk

Java library providing Bitcoin-related Elliptic Curve Cryptography

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

secp256k1-jdk

secp256k1-jdk is a Java library providing Bitcoin-related Elliptic Curve Cryptography functions using the SECG curve secp256k1. It provides both ECDSA and Schnorr message signing functions.

It provides a Java API that enables multiple implementations. The proof-of-concept includes an implementation that adapts bitcoin-core/secp256k1, a native C library implementing elliptic curve operations on the secp256k1 curve. We also plan to provide an implementation using the popular Bouncy Castle library.

The library supports other JDK-based languages such as Kotlin, Groovy, Scala, and Clojure (as these languages can all use Java classes directly.) In the future, we may provide documentation, examples, and language-specific extensions for one or more additional JVM languages. (Kotlin examples are in-progress.)

WARNING

This prototype software has had limited testing and has not been reviewed. Do not use this software to store private keys for Bitcoin or any other purpose. It is provided AS-IS for experimentation and feedback.

API

The API is based on the C-language API of bitcoin-core/secp256k1, but adapted to modern, idiomatic, functional-style Java and to use Elliptic Curve types from the Java Class Library, such as ECPublicKey where appropriate.

The API is distributed as an API-only JAR (secp256k1-api-version.jar) and we expect that there will be multiple implementations of the API. The API JAR currently requires JDK 17 or later but we may backport it to an earlier version (possibly JDK 11) in a future release depending upon feedback from the community.

NOTE

At this point, we are especially interested in feedback on the API.

libsecp256k1 Panama Implementation (JDK 22+)

The provided proof-of-concept implementation uses the bitcoin-core/secp256k1 C-language library via JEP-454: Foreign Function & Memory API (known as Panama.) It is provided in a separate JAR (secp256k1-foreign-version.jar) that requires JDK 22 or later.

Panama has been available as a preview feature of Java since JDK 19, with a final release in OpenJDK 22 (March 19, 2024.) We anticipate this will be the recommended/preferred implementation for use in projects using modern JVMs.

The minimum supported JDK for this module will likely be incremented with each new JDK release, with the idea of a 1.0 release corresponding with JDK 25 (the next LTS release of the JDK.)

WARNING

This is a preliminary implementation provided for experimentation and feedback and should not be used in real applications.

Bouncy Castle Implementation

An incomplete Bouncy Castle-based submodule is included. Bouncy Castle is a well-regarded cryptography library that includes support for the secp256k1 curve and is currently used by bitcoinj and other Java-based Bitcoin implementations. We expect this implementation to be completed and made available as a pure-Java implementation for those who are unable to use the native libsecp256k1 implementation and/or Panama.

The Bouncy Castle implementation is currently targeting JDK 17, but if the API is backported to JDK 11, so will the Bouncy Castle implementation.

libsecp256k1 Implementation for older JDKs

There are currently no plans for an implementation using earlier Java-to-C adapter technologies such as JNI or JNA. However, the secp256k1-jdk API should support such an implementation. We would be supportive if someone in the community endeavours to create an implementation or adapt one of the existing implementations to use the secp256k1-jdk API.

Relation to bitcoinj

This project is hosted by the bitcoinj GitHub organization, but secp256k1-jdk does not use or require bitcoinj and (at present) bitcoinj cannot use secp256k1-jdk for its ECC implementation. bitcoinj is currently being refactored to be more modular, and we would like to have pluggable ECC implementations (and Schnorr signatures!) in the near future, but further refactoring will be required before this can happen.

For information on the in-process refactoring of bitcoinj, see the following:

Relation to Java Cryptography Architecture

secp256k1-jdk currently does not use any Java Cryptography Architecture ECC providers nor does it make itself available as a provider. It does use some of the built-in Java ECC interfaces (such as ECPublicKey) for interoperability and to avoid reinventing the wheel.

The SECG secp256K1 curve was removed from Java in the JDK 16 release (see JDK-8251547). It is possible that a secp256k1 JCA provider could be developed, but that is not currently a goal of this project.

Current Build Status

The current build requires JDK 22.

We are currently using a Nix flake to install the native libsecp256k1 and by default the build looks for it in ~/.nix-profile/lib. You can use the -PjavaPath option to Gradle to change the library path, if needed.

Building with Gradle Wrapper

Make sure you have installed the current version (0.4.1) of secp256k1 with nix profile install nixpkgs#secp256k1

  1. ./gradlew build

Running with Gradle Wrapper

(This assumes version 0.4.1 of secp256k1 was installed with nixpkgs)

  1. ./gradlew secp256k1-examples-java:run

Building with Nix

NOTE

This is currently broken after we switched from using JDK 21 in preview mode to JDK 22. We are waiting for JDK 22 support in Nixpkgs, see: NixOS/nixpkgs#271971)

  1. nix develop

  2. gradle build

Building Headers with Nix

NOTE

This is currently broken after we switched to JDK 22. We are waiting for JDK 22 support in Nixpkgs, see: NixOS/nixpkgs#271971 (JDK 22) and NixOS/nixpkgs#293102 (jextract))

NOTE

These instructions assume you are using experimental-features = nix-command flakes.

  1. nix develop

  2. ./extract-headers.sh

Reporting a vulnerability

See SECURITY.adoc (TBD)

References

secp256k1 library

Other Java/JDK Implementations

BIPS

  • BIP 340: Schnorr Signatures for secp256k1

About

Java library providing Bitcoin-related Elliptic Curve Cryptography

License:Apache License 2.0


Languages

Language:Java 96.0%Language:Kotlin 3.0%Language:Nix 0.8%Language:Shell 0.2%