Find your topic in the index, or refer to one of the examples below.
Module | Classes | Utilities |
---|---|---|
Secp256k1 | Context | Util |
KeyPair | ||
PublicKey | ||
XOnlyPublicKey | ||
PrivateKey | ||
SharedSecret | ||
Signature | ||
RecoverableSignature | ||
SchnorrSignature |
Context is a libsecp256k1 library context. It contains pre-computed tables and values to make ECDSA signing and verification more efficient.
KeyPair is a Secp256k1 elliptic-curve key pair.
PublicKey is a Secp256k1 public key. It can come in either compressed or uncompressed format.
XOnlyPublicKey is a Secp256k1 x-only public key.
PrivateKey is a 64-byte Secp256k1 private key.
SharedSecret A 32-byte shared secret computed from a public key (point) and private key (scalar).
Signature is an ECDSA signature of the SHA-256 message hash of a piece of data.
RecoverableSignature is a recoverable ECDSA signature of the SHA-256 message hash of a piece of data.
SchnorrSignature is a Schnorr signature of a 32-byte message.
This example demonstrates how to create a new libsecp256k1 context. This is the first step of using this library:
context = Secp256k1::Context.create
# => #<Secp256k1::Context:0x0000559b0bd8f5d0>
This example shows how to generate a new public-private key pair:
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
# => #<Secp256k1::KeyPair:0x0000559b0bc876b0>
This example shows how to generate compressed and uncompressed public keys:
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
# 1. Get the binary representation of compressed public key
key_pair.public_key.compressed
# => "\x03D\x88\xD6 3|3\x836\xCB(\x9CW%\xF4T\xB7\xCD\x8AF T\xE7\xE8\xCE\xB0\xC7c{\xE2:\xFE"
# 2. Show hex representation of compressed public key
Secp256k1::Util.bin_to_hex(key_pair.public_key.compressed)
# => "034488d620337c338336cb289c5725f454b7cd8a462054e7e8ceb0c7637be23afe"
# 3. Get the binary representation of uncompressed public key
key_pair.public_key.uncompressed
# => "\x04D\x88\xD6 3|3\x836\xCB(\x9CW%\xF4T\xB7\xCD\x8AF T\xE7\xE8\xCE\xB0\xC7c{\xE2:\xFE XRew\x1F\e\x05\xC8\xDC\xA7\xE3\x8C\xBD\x91s?\xFCW\xD5\xB3\xA8aaCCG\xD4\x94m\xA5c"
# 4. Show hex representation of uncompressed public key
Secp256k1::Util.bin_to_hex(key_pair.public_key.uncompressed)
# => "044488d620337c338336cb289c5725f454b7cd8a462054e7e8ceb0c7637be23afe20585265771f1b05c8dca7e38cbd91733ffc57d5b3a86161434347d4946da563"
This example shows how to sign a message using your private key:
require 'digest'
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
signature = context.sign(key_pair.private_key, Digest::SHA256.digest("test message"))
# => #<Secp256k1::Signature:0x0000559b0bc79358>
This example shows you how to get the DER encoded and compact encoded representations of a signature:
require 'digest'
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
signature = context.sign(key_pair.private_key, Digest::SHA256.digest("test message"))
# 1. Get the compact binary representation
signature.compact
# => "\xAB#e6_\x866\e\xAC\e\x92W\xC8a\x84N\xD4\xB6\x88\xF8\xEE\xDF\xFBC\xE8j\xB2\xF0\x10\xB8\xA0\x89\x13L\e\x9E\x91cB\xD7\xAC\x11\xF7\x02,Y&TM\xA5zp\xFD\xB3\xB1\xDCIV\xBB\\\xAF\x16@\xFC\x00"
# 2. Get the compact hex representation
Secp256k1::Util.bin_to_hex(signature.compact)
# => "ab2365365f86361bac1b9257c861844ed4b688f8eedffb43e86ab2f010b8a089134c1b9e916342d7ac11f7022c5926544da57a70fdb3b1dc4956bb5caf1640fc00"
# 3. Get the DER binary representation
signature.der_encoded
# => "0E\x02!\x00\xAB#e6_\x866\e\xAC\e\x92W\xC8a\x84N\xD4\xB6\x88\xF8\xEE\xDF\xFBC\xE8j\xB2\xF0\x10\xB8\xA0\x89\x02 \x13L\e\x9E\x91cB\xD7\xAC\x11\xF7\x02,Y&TM\xA5zp\xFD\xB3\xB1\xDCIV\xBB\\\xAF\x16@\xFC"
# 4. Get the DER hex representation
Secp256k1::Util.bin_to_hex(signature.der_encoded)
# => "3045022100ab2365365f86361bac1b9257c861844ed4b688f8eedffb43e86ab2f010b8a0890220134c1b9e916342d7ac11f7022c5926544da57a70fdb3b1dc4956bb5caf1640fc"
This example shows how to verify a signature using a public key:
require 'digest'
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
hash = Digest::SHA256.digest("test message")
signature = context.sign(key_pair.private_key, hash)
# 1. Verify signature against matching message
context.verify(signature, key_pair.public_key, hash)
# => true
# 2. Verify signature against different message
context.verify(signature, key_pair.public_key, hash)
# => false
This example shows how to load a key pair from raw binary private key data:
context = Secp256k1::Context.create
#1. Load private key alone
private_key = Secp256k1::PrivateKey.from_data("I\nX\x85\xAEz}\n\x9B\xA4\\\x81)\xD4\x9Aq\xFDH\t\xBE\x8EP\xC5.\xC6\x1F7-\x86\xA0\xCB\xF9")
# => #<Secp256k1::PrivateKey:0x00005647df1bcd30>
# 2. Load key pair from private key data
key_pair = context.key_pair_from_private_key("I\nX\x85\xAEz}\n\x9B\xA4\\\x81)\xD4\x9Aq\xFDH\t\xBE\x8EP\xC5.\xC6\x1F7-\x86\xA0\xCB\xF9")
# => #<Secp256k1::KeyPair:0x0000559b0bbf9a90>
This example shows how to load a public key from binary data:
# 1. Load public key from uncompressed pubkey
public_key = Secp256k1::PublicKey.from_data("\x04$\xA2\xE7\xBB1\xC4|tN\xE6\xE4J-\xED\x9A[\xAFf-<\x14\x84^QQ\"\x14\xC3\x91\xE4\xF2\xB5\xEEEj\xAB\xD9\xFE\b\e7Zk\xC5{k\x12\xE3\xEA\xA2\xA5\xD7\xC1\xA5&\xE5|:K\xA9 X\xA3\x90")
# => #<Secp256k1::PublicKey:0x0000559b0bdc72f0>
# 2. Load public key from compressed pubkey
public_key = Secp256k1::PublicKey.from_data("\x02$\xA2\xE7\xBB1\xC4|tN\xE6\xE4J-\xED\x9A[\xAFf-<\x14\x84^QQ\"\x14\xC3\x91\xE4\xF2\xB5")
# => #<Secp256k1::PublicKey:0x0000559b0bdd3668>
This example shows how to load signatures from binary data:
# 1. From DER encoded signature
signature = Secp256k1::Signature.from_der_encoded("0D\x02 <\xC6\x7F/\x921l\x89Z\xFBs\x89p\xEE\x18u\x8B\x92\x9D\xA6\x84\xC5Y<t\xB7\xF1\f\xEE\f\x81J\x02 \t\"\xDF]\x1D\xA7W@^\xAAokH\b\x00\xE2L\xCF\x82\xA3\x05\x1E\x00\xF9\xFC\xB19\x0F\x93|\xB1f")
# => #<Secp256k1::Signature:0x0000559b0b823d58>
# 2. From compact signature
signature = Secp256k1::Signature.from_compact("<\xC6\x7F/\x921l\x89Z\xFBs\x89p\xEE\x18u\x8B\x92\x9D\xA6\x84\xC5Y<t\xB7\xF1\f\xEE\f\x81J\t\"\xDF]\x1D\xA7W@^\xAAokH\b\x00\xE2L\xCF\x82\xA3\x05\x1E\x00\xF9\xFC\xB19\x0F\x93|\xB1f\x00")
# => #<Secp256k1::Signature:0x0000559b0bdcaa68>
To check if you have compiled the schnorr signature module into your local libsecp256k1 run the following:
Secp256k1.have_schnorr?
# => true
You can produce the tagged SHA-256 hash recommended for use with Schnorr signatures as follows:
context = Secp256k1::Context.create
context.tagged_sha256('my_test_tag', 'data')
=> "0\x85|\xC8h\x9A\x8C^\x0FoD\xDF\xD0,\x1C\x1EV}\xE8\xA8<\xC5\xA5vI\x9E`=\x9B\xC4\xA8\xAE"
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
message = context.tagged_sha256('my_test_tag', 'data')
schnorr_sig = context.sign_schnorr(key_pair, message)
=> #<Secp256k1::SchnorrSignature:0x00007f4de11e5768>
schnorr_sig.verify(message, key_pair.xonly_public_key)
=> true
schnorr_sig.serialized
=> "\x16\xEF\x04\xB0JP\xE9\x90\xC2\xB1\xE6-l\xDB\x1D\xAE\xAAc\xBF@9s\x02\xC2\xD5[\xFB\x19Q\xFAI^Hj\xD1)\xBE\xEA\xA5!a\xAD\xBEO\xCE7\x9Em\x13;\xE8R\x8A\x81$\nv\xF4\xD3\xB25\xA9\xF9\xC0"
context = Secp256k1::Context.create
schnorr_sig_raw = "\x16\xEF\x04\xB0JP\xE9\x90\xC2\xB1\xE6-l\xDB\x1D\xAE\xAAc\xBF@9s\x02\xC2\xD5[\xFB\x19Q\xFAI^Hj\xD1)\xBE\xEA\xA5!a\xAD\xBEO\xCE7\x9Em\x13;\xE8R\x8A\x81$\nv\xF4\xD3\xB25\xA9\xF9\xC0"
Secp256k1::SchnorrSignature.from_data(schnorr_sig_raw)
=> #<Secp256k1::SchnorrSignature:0x00007f4de1225818>
To check if you have compiled the recovery module into your local libsecp256k1 run the following:
Secp256k1.have_recovery?
# => true
You can sign data producing a recoverable signature as follows:
yrequire 'digest'
hash = Digest::SHA256.digest('test message')
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
signature = context.sign_recoverable(key_pair.private_key, hash)
# => #<Secp256k1::RecoverableSignature:0x000055f2ea76e548>
You can produce the compact binary serialization of a recoverable signature:
require 'digest'
hash = Digest::SHA256.digest('test message')
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
signature = context.sign_recoverable(key_pair.private_key, hash)
compact_data, recovery_id = signature.compact
# => ["D,\x9C\xA6%I\x14-\xCA\xC0\x11\x0F\xEB\x1E\xB0\xB6\\-\xE2\b\x98\xFB\xEA\xD5\x9BZ\xE6\xDF#\xC1\x1A\xEEL\xF02\xB1\xE9{\r\xEBhh<\\\xCF\xB6\x98\xEA\x8F\xF65\xF2\xBF\x84\xD8\xE5x\xF0\xA5)\xA2Wb\x9D", 1]
You can load a recoverable signature give its compact representation and recovery ID:
context = Secp256k1::Context.create
compact_data = "D,\x9C\xA6%I\x14-\xCA\xC0\x11\x0F\xEB\x1E\xB0\xB6\\-\xE2\b\x98\xFB\xEA\xD5\x9BZ\xE6\xDF#\xC1\x1A\xEEL\xF02\xB1\xE9{\r\xEBhh<\\\xCF\xB6\x98\xEA\x8F\xF65\xF2\xBF\x84\xD8\xE5x\xF0\xA5)\xA2Wb\x9D"
recovery_id = 1
signature = context.recoverable_signature_from_compact(compact_data, recovery_id)
# => #<Secp256k1::RecoverableSignature:0x000055f2ea7615c8>
You can convert a recoverable signature to a non-recoverable signature suitable for use by all methods that take a Signature object:
require 'digest'
hash = Digest::SHA256.digest('test message')
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
recoverable_signature = context.sign_recoverable(key_pair.private_key, hash)
signature = recoverable_signature.to_signature
# => #<Secp256k1::Signature:0x000055f2ea8ca4f0>
You can recover the PublicKey associated with a recoverable signature:
require 'digest'
hash = Digest::SHA256.digest('test message')
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
recoverable_signature = context.sign_recoverable(key_pair.private_key, hash)
public_key = recoverable_signature.recover_public_key(hash)
# => #<Secp256k1::PublicKey:0x000055f2ea756678>
public_key == key_pair.public_key
# => true
To check if you have compiled the ECDH module into your local libsecp256k1 run the following:
Secp256k1.have_ecdh?
# => true
To generate a shared secret run the following:
context = Secp256k1::Context.create
key_pair = context.generate_key_pair
shared_secret = context.ecdh(key_pair.public_key, key_pair.private_key)
shared_secret.data
# => "\x1FQ\x90X\xA5\xF2\xAEx;\xD7i\xB6\\T,2[\x90\xD1)a$\x1CA\x17\x8F\e\x91\xE3\x06C\x93"