From a06bf3a22b9d0dc630f80274dcf99eed90e2d29d Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Wed, 18 Mar 2020 05:51:54 -0500 Subject: [PATCH] 2020 03 17 secp256k1jni md (#1248) * First draft secp256k1.md Fix imports/names Fix nits * Address nadav's code review --- docs/secp256k1/secp256k1.md | 87 +++++++++++++++++++++++++++++++++++++ website/sidebars.json | 3 ++ 2 files changed, 90 insertions(+) create mode 100644 docs/secp256k1/secp256k1.md diff --git a/docs/secp256k1/secp256k1.md b/docs/secp256k1/secp256k1.md new file mode 100644 index 0000000000..5998e1436b --- /dev/null +++ b/docs/secp256k1/secp256k1.md @@ -0,0 +1,87 @@ +--- +id: secp256k1 +title: Secp256k1 +--- + +[Libsecp256k1](https://github.com/bitcoin-core/secp256k1) is used to preform cryptographic operations on the secp256k1 curve. +This is the curve that bitcoin uses. There is a _signficant_ speedup when using this library compared to java crypto libraries +like bouncy castle. + +In bitcoin-s, we support native binaries for libsecp256k1 + +1. [linux 32 bit](../../secp256k1jni/natives/linux_32) +2. [linux 64 bit](../../secp256k1jni/natives/linux_64) +3. [mac osx 64 bit](../../secp256k1jni/natives/osx_64) +4. [windows 64 bit](../../secp256k1jni/natives/windows_64) + +Bitcoin-s uses a zero dependency library called [`native-lib-loader`](https://github.com/scijava/native-lib-loader). +That does the appropriate loading of the library onto your classpath to be accessed. + +#### Using libsecp256k1 + +To tell if you have access to libsecp256k1 you can do the following + +```scala mdoc:invisible +import org.bitcoin._ +import org.bitcoins.core.crypto._ + +``` + +```scala mdoc:compile-only +val isEnabled = org.bitcoin.Secp256k1Context.isEnabled() + +println(s"Secp256k1Context.isEnabled=${isEnabled}") +``` + +If libsecp256k1 is enabled, you can use [NativeSecp256k1](../../secp256k1jni/src/main/java/org/bitcoin/NativeSecp256k1.java) +with static method defined in the class. + + +```scala mdoc:compile-only +val privKey = ECPrivateKey.freshPrivateKey +val pubKey = privKey.publicKey +val dataToSign = DoubleSha256Digest.empty + +val signature = NativeSecp256k1.sign(dataToSign.bytes.toArray, privKey.bytes.toArray) + +val verify = NativeSecp256k1.verify(dataToSign.bytes.toArray, signature, pubKey.bytes.toArray) + +println(s"Verified with NativeSecp256k1 signature=${verify}") + +//you can also just directly sign with the ECKey interface: +val signature2 = privKey.sign(dataToSign) + +val verified2 = pubKey.verify(dataToSign, signature2) + +println(s"Verified with NativeSecp256k1 again=${verified2}") + +``` + +### When libsecp256k1 isn't available, or you want to turn it off + +There are two reasons you wouldn't want to use libsecp256k1 + +1. You don't trust the pre-compiled binaries we are using +2. Your OS/arch is not supported + +There are two ways you can circumvent libsecp256k1 + +1. Set `DISABLE_SECP256K1=true` in your environment variables. This will force `Secp256k1Context.isEnabled()` to return false +2. Call Bouncy castle methods in `ECKey`. + +Here is an example of calling bouncy castle methods in `ECKey` + +```scala mdoc:to-string + +val privKey = ECPrivateKey.freshPrivateKey +val publicKey = privKey.publicKeyWithBouncyCastle +val dataToSign = DoubleSha256Digest.empty + +val signature = privKey.signWithBouncyCastle(dataToSign.bytes) + +val verified = publicKey.verifyWithBouncyCastle(dataToSign.bytes, signature) + +println(s"Verified with bouncy castle=${verified}") + +``` + diff --git a/website/sidebars.json b/website/sidebars.json index 13bceab207..7fb6ef64b4 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -41,6 +41,9 @@ "rpc/rpc-eclair", "rpc/rpc-bitcoind" ], + "Secp256k1": [ + "secp256k1/secp256k1" + ], "Testkit": [ "testkit/testkit" ],