Description
To investigate the library in order to provide feedback, I attempted an integration into Sparrow (actually, drongo) in which I replaced the following functions with equivalents from secp256k1-jdk, using the ffm implementation:
- Deriving a public point from a private key
- Signing ECDSA
- Verifying ECDSA signatures
- Signing Schnorr
- Verifying Schnorr signatures
- Creating an ECDH secret from a public and private key
I was able to achieve the first 5 items, with some caveats which I'll list below. I've put the changes in a branch. The secp256k1_ecdh
function was not present in secp256k1-jdk, so I wasn't able to implement the 6th item. Here are the issues I encountered:
- When distributing a client application, one cannot rely on the presence of any external libraries (like secp256k1). Generally, the approach is to package these libraries in the application jar. When the library is used, it is first extracted to a temporary location on the user's drive and loaded directly from there using
System.load(filepath)
. However, the approach used by jextract is different - it expects to be able to find the library onjava.library.path
which must be specified on application startup, since it is only read once. The problem is in the static initializer: - Grinding ECDSA signatures for low R is important, not just to reduce transaction size but to create the same signatures across different wallets (all using RFC6979). secp256k1-jdk currently has no ability to specify the RFC6979 extra ndata in
secp.ecdsaSign
. Currently, it's set to nullPointer. - I encountered the following warning when running the application - I'm not sure if anything can be done about it given it's code created by jextract, but I mention it since it's obviously not ideal to need to access to potentially unsafe operations.
WARNING: A restricted method in java.lang.foreign.AddressLayout has been called
WARNING: java.lang.foreign.AddressLayout::withTargetLayout has been called by org.bitcoinj.secp.ffm.jextract.secp256k1_h in module org.bitcoinj.secp.ffm
WARNING: Use --enable-native-access=org.bitcoinj.secp.ffm to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
Apart from these issues, everything went well. The client code was relatively easy to read/write. I did need to create two implementations (ByteArrayP256K1XOnlyPubKey
and BigIntegerP256k1PrivKey
) of the provided interfaces, which could be considered to be included in the api as I imagine they will be often required. I tested with secp256k1 v0.5.1.