Secp256k1. ECDSA
(secp256k1 v0.8.0)
View Source
Module implementing ECDSA pubkey derivation and signatures
Summary
Functions
Convert uncompressed pubkey to compressed one
Derive compressed pubkey from seckey
Convert compressed pubkey to uncompressed one
Converts a compact ECDSA signature to its low-S form.
Parses a standard-sized strict DER ECDSA signature into compact 64-byte r || s form.
Derive pubkey from seckey
Serializes a compact 64-byte ECDSA signature as strict DER.
Generate an ECDSA signature of a message hash with random RFC 6979 additional data.
Generate an ECDSA signature with explicit RFC 6979 additional data.
Derive uncompressed pubkey from seckey
Check if ECDSA signature is valid.
Functions
@spec compress_pubkey(pubkey :: Secp256k1.uncompressed_pubkey()) :: Secp256k1.compressed_pubkey()
Convert uncompressed pubkey to compressed one
@spec compressed_pubkey(seckey :: Secp256k1.seckey()) :: Secp256k1.compressed_pubkey()
Derive compressed pubkey from seckey
@spec decompress_pubkey(pubkey :: Secp256k1.compressed_pubkey()) :: Secp256k1.uncompressed_pubkey()
Convert compressed pubkey to uncompressed one
@spec normalize(signature :: Secp256k1.ecdsa_sig()) :: Secp256k1.ecdsa_sig() | {:error, binary() | :allocation_failed}
Converts a compact ECDSA signature to its low-S form.
This operation is idempotent. libsecp256k1 verification rejects high-S signatures. Normalize only when the protocol deliberately accepts the mathematically equivalent high-S form: doing so accepts a malleable signature, and all subsequent identity or hashing operations must use the normalized bytes. Protocols requiring canonical low-S signatures should reject instead.
@spec parse_der(signature :: Secp256k1.ecdsa_der_sig()) :: Secp256k1.ecdsa_sig() | {:error, binary() | :allocation_failed}
Parses a standard-sized strict DER ECDSA signature into compact 64-byte r || s form.
Accepts DER signatures from 8 through 72 bytes. Wrong-sized input raises
FunctionClauseError; malformed DER within that range raises ArgumentError.
As in upstream libsecp256k1, syntactically valid DER containing out-of-range
values parses to a compact signature that cannot verify. A trailing Bitcoin
transaction sighash byte must be removed before calling this function.
@spec pubkey(seckey :: Secp256k1.seckey(), opts :: Keyword.t()) :: Secp256k1.compressed_pubkey() | Secp256k1.uncompressed_pubkey()
Derive pubkey from seckey
Options
- :compress (default true) - whether to format pubkey in compressed or uncompressed format
Examples
iex> {seckey, _} = Secp256k1.keypair(:compressed)
iex> pubkey = Secp256k1.ECDSA.pubkey(seckey)
iex> byte_size(pubkey)
33
@spec serialize_der(signature :: Secp256k1.ecdsa_sig()) :: Secp256k1.ecdsa_der_sig() | {:error, binary() | :allocation_failed}
Serializes a compact 64-byte ECDSA signature as strict DER.
The returned binary contains only the DER signature. Bitcoin transaction sighash bytes are not part of this encoding and must be handled separately.
@spec sign(msg_hash :: Secp256k1.hash(), seckey :: Secp256k1.seckey()) :: Secp256k1.ecdsa_sig()
Generate an ECDSA signature of a message hash with random RFC 6979 additional data.
Examples
iex> {seckey, _} = Secp256k1.keypair(:compressed)
iex> msg_hash = :crypto.hash(:sha256, "hello")
iex> signature = Secp256k1.ECDSA.sign(msg_hash, seckey)
iex> byte_size(signature)
64
@spec sign( msg_hash :: Secp256k1.hash(), seckey :: Secp256k1.seckey(), nonce_data :: nil | <<_::256>> ) :: Secp256k1.ecdsa_sig()
Generate an ECDSA signature with explicit RFC 6979 additional data.
Deterministic signing is for tests only
Pass nil only in tests that require reproducible signatures, such as
interoperability and test-vector checks. Use sign/2 for normal signing.
A 32-byte value is passed as libsecp256k1 ndata to derive a synthetic nonce.
@spec uncompressed_pubkey(seckey :: Secp256k1.seckey()) :: Secp256k1.uncompressed_pubkey()
Derive uncompressed pubkey from seckey
@spec valid?( signature :: Secp256k1.ecdsa_sig(), msg_hash :: Secp256k1.hash(), pubkey :: Secp256k1.compressed_pubkey() | Secp256k1.uncompressed_pubkey() ) :: boolean()
Check if ECDSA signature is valid.
High-S signatures return false. Call normalize/1 first only when the
surrounding protocol deliberately accepts malleable signature encodings.
Examples
iex> {seckey, pubkey} = Secp256k1.keypair(:compressed)
iex> msg_hash = :crypto.hash(:sha256, "hello")
iex> signature = Secp256k1.ECDSA.sign(msg_hash, seckey)
iex> Secp256k1.ECDSA.valid?(signature, msg_hash, pubkey)
true