* Added crypto project and decoupled BitcoinSLogger from NetworkElement Decoupled BitcoinSLogger from Factory Moved NetworkElement into crypto project Moved Factory and BitcoinSUtil (renamed to BytesUtil) to crypto project Moved MaskedToString to crypto project Added BytesUtil to imports and cleaned up CryptoUtil.recoverPoint Moved the rest of crypto stuff to the crypto project Moved crypto tests to crypto-test project * Added documentation for crypto project
2.8 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
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
- You don't trust the pre-compiled binaries we are using
- Your OS/arch is not supported
There are two ways you can circumvent libsecp256k1
- Set
DISABLE_SECP256K1=true
in your environment variables. This will forceSecp256k1Context.isEnabled()
to return false - Call Bouncy castle methods in
ECKey
.
Here is an example of calling bouncy castle methods in ECKey
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}")