bitcoin-s/docs/secp256k1/secp256k1.md
rorp c90f318fd7 Refactor crypto module to be compatible with Scala.js part 1 (#2719)
* Refactor crypto module to be compatible with Scala.js

* more changes

* some more changes

* abstract out Schnorr stuff

* abstract out adapter stuff

* cleanup

* some more cleanup

* fix build

* Removed references to ECPoint outside of .jvm scope

* remove references to ECPoint from the shared code

* cleanup

* remove cirlular dependencies

* more cleanup

* cleanup

* move SipHash to CryptoContext

* scaladoc

* scalafmt

Co-authored-by: nkohen <nadavk25@gmail.com>
2021-02-27 05:58:20 -06:00

2.9 KiB

id title
secp256k1 Secp256k1

Libsecp256k1 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
  2. linux 64 bit
  3. mac osx 64 bit
  4. windows 64 bit

Bitcoin-s uses a zero dependency library called 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

import org.bitcoin._
import org.bitcoins.crypto._

val isEnabled = org.bitcoin.Secp256k1Context.isEnabled()

println(s"Secp256k1Context.isEnabled=${isEnabled}")

If libsecp256k1 is enabled, you can use NativeSecp256k1 with static method defined in the class.

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 CryptoContext.default to return false which will make Bitcoin-S act like Secp256k1Context.isEnabled() has returned false.
  2. Call Bouncy castle methods in ECKey.

Here is an example of calling bouncy castle methods in ECKey


val privKey = ECPrivateKey.freshPrivateKey
// calls bouncy castle indirectly via CryptoContext
val publicKey = privKey.publicKey
val dataToSign = DoubleSha256Digest.empty

// calls bouncy castle indirectly via CryptoContext
val signature = privKey.sign(dataToSign.bytes)

// calls bouncy castle indirectly via CryptoContext
val verified = publicKey.verify(dataToSign.bytes, signature)

println(s"Verified with bouncy castle=${verified}")

Building libsecp256k1

See instructions here