Secp256k1 (secp256k1 v0.6.1)

View Source

This is unified API for all secp256k1 functions this library provides

Examples

Generate new keypair

iex> {_seckey, _pubkey} = Secp256k1.keypair(:xonly)

Derive pubkey from your awesome seckey

iex> seckey = <<0x1111111111111111111111111111111111111111111111111111111111111111::256>>
iex> pubkey = Secp256k1.pubkey(seckey, :compressed)
iex> Base.encode16(pubkey, case: :lower)
"034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa"

Calculate ECDSA signature

iex> # your keypair
iex> {seckey, pubkey} = Secp256k1.keypair(:compressed)
iex> # prepare your message hash
iex> msg_hash = :crypto.hash(:sha256, "My awesome message")
iex> # generate signature
iex> sig = Secp256k1.ecdsa_sign(msg_hash, seckey)
iex> # validate your signature
iex> Secp256k1.ecdsa_valid?(sig, msg_hash, pubkey)
true

Calculate Schnorr signature

iex> # your keypair
iex> {seckey, pubkey} = Secp256k1.keypair(:xonly)
iex> # prepare your message hash
iex> msg_hash = :crypto.hash(:sha256, "My awesome message")
iex> # generate signature
iex> sig = Secp256k1.schnorr_sign(msg_hash, seckey)
iex> # validate your signature
iex> Secp256k1.schnorr_valid?(sig, msg_hash, pubkey)
true

Summary

Types

Compressed pubkey is binary of 33 byte length

Serialized compressed ECDSA signature is 64 bytes long binary

Hash is 32 bytes long binary

Pubkey is binary of 32, 33 or 65 byte length

Pubkey can be parsed in compressed (33 bytes), uncompressed (65 bytes) or xonly (32 bytes) format

Schnorr signature is 64 bytes long binary

EC secp256k1 seckey is 32 bytes long binary

ECDH shared secret is 32 bytes long binary

Uncompressed pubkey is binary of 65 byte length

X-only pubkey is binary of 32 byte length

Functions

Create an ECDSA signature

Generate new secp256k1 keypair

Generate new secp256k1 keypair from provided seckey

Derive pubkey from provided seckey

Calculate Schnorr signature according to BIP 340

Validate Schnorr signature

Types

compressed_pubkey()

@type compressed_pubkey() :: <<_::264>>

Compressed pubkey is binary of 33 byte length

ecdsa_sig()

@type ecdsa_sig() :: <<_::512>>

Serialized compressed ECDSA signature is 64 bytes long binary

hash()

@type hash() :: <<_::256>>

Hash is 32 bytes long binary

pubkey()

@type pubkey() :: xonly_pubkey() | compressed_pubkey() | uncompressed_pubkey()

Pubkey is binary of 32, 33 or 65 byte length

pubkey_type()

@type pubkey_type() :: :compressed | :uncompressed | :xonly

Pubkey can be parsed in compressed (33 bytes), uncompressed (65 bytes) or xonly (32 bytes) format

schnorr_sig()

@type schnorr_sig() :: <<_::512>>

Schnorr signature is 64 bytes long binary

seckey()

@type seckey() :: <<_::256>>

EC secp256k1 seckey is 32 bytes long binary

shared_secret()

@type shared_secret() :: <<_::256>>

ECDH shared secret is 32 bytes long binary

uncompressed_pubkey()

@type uncompressed_pubkey() :: <<_::520>>

Uncompressed pubkey is binary of 65 byte length

xonly_pubkey()

@type xonly_pubkey() :: <<_::256>>

X-only pubkey is binary of 32 byte length

Functions

ecdsa_sign(msg_hash, seckey)

@spec ecdsa_sign(msg_hash :: hash(), seckey :: seckey()) :: ecdsa_sig()

Create an ECDSA signature

Inputs

  • msg_hash 32 byte long message hash to sign
  • seckey 32 byte long binary

Output

  • signature ECDSA signature serialized in compressed format (64 byte binary)

ecdsa_valid?(signature, msg_hash, pubkey)

@spec ecdsa_valid?(
  signature :: ecdsa_sig(),
  msg_hash :: hash(),
  pubkey :: compressed_pubkey()
) ::
  boolean()

Validate ECDSA signature

Inputs

  • signature 64 byte long binary
  • msg_hash 32 byte long message hash that was signed
  • pubkey compressed pubkey (33 byte long binary)

keypair(type)

@spec keypair(type :: pubkey_type()) :: {seckey(), pubkey()}

Generate new secp256k1 keypair

Input

Output

  • 2-tuple with seckey on the first place and pubkey on the second place

keypair(seckey, type)

@spec keypair(seckey :: seckey(), type :: pubkey_type()) :: {seckey(), pubkey()}

Generate new secp256k1 keypair from provided seckey

For options see pubkey/2

pubkey(seckey, atom)

@spec pubkey(seckey :: seckey(), type :: pubkey_type()) :: pubkey()

Derive pubkey from provided seckey

Inputs

  • seckey 32 byte long binary
  • type one of :xonly, :compressed or :uncompressed

Output

  • pubkey serialization type depends on the type provided

schnorr_sign(message, seckey)

@spec schnorr_sign(message :: binary(), seckey :: seckey()) :: schnorr_sig()

Calculate Schnorr signature according to BIP 340

Inputs

  • message can accept arbitrary long binary but only 32 byte long hash is the only option strictly according to specification
  • seckey 32 byte long binary

Output

  • signature Schnorr signature is 64 byte long binary

Note: automatic random nonce is added to every run so generated signature is not deterministic

schnorr_valid?(signature, message, pubkey)

@spec schnorr_valid?(
  signature :: schnorr_sig(),
  message :: binary(),
  pubkey :: xonly_pubkey()
) :: boolean()

Validate Schnorr signature

Inputs

  • signature 64 byte long binary
  • message arbitrary long binary
  • pubkey xonly pubkey (32 byte long binary)