Expand description
Rust bindings for Pieter Wuille’s secp256k1 library, which is used for fast and accurate manipulation of ECDSA and Schnorr signatures on the secp256k1 curve. Such signatures are used extensively by the Bitcoin network and its derivatives.
To minimize dependencies, some functions are feature-gated. To generate
random keys or to re-randomize a context object, compile with the
rand and std features. If you are willing to use these features, we
have enabled an additional defense-in-depth sidechannel protection for
our context objects, which re-blinds certain operations on secret key
data. To de/serialize objects with serde, compile with “serde”.
Important: serde encoding is not the same as consensus
encoding!
Where possible, the bindings use the Rust type system to ensure that
API usage errors are impossible. For example, the library uses context
objects that contain precomputation tables which are created on object
construction. Since this is a slow operation (10+ milliseconds, vs ~50
microseconds for typical crypto operations, on a 2.70 Ghz i7-6820HQ)
the tables are optional, giving a performance boost for users who only
care about signing, only care about verification, or only care about
parsing. In the upstream library, if you attempt to sign a message using
a context that does not support this, it will trigger an assertion
failure and terminate the program. In rust-secp256k1, this is caught
at compile-time; in fact, it is impossible to compile code that will
trigger any assertion failures in the upstream library.
use secp256k1::rand;
use secp256k1::{ecdsa, Message};
// Our message to sign. We explicitly obtain a hash and convert it to a
// `Message`. In a real application, we would produce a signature hash
// type, e.g. `bitcoin::LegacySigHash`, which is convertible to `Message`
// and can be passed directly to `sign_ecdsa`.
const HELLO_WORLD_SHA2: [u8; 32] = [
0x31, 0x5f, 0x5b, 0xdb, 0x76, 0xd0, 0x78, 0xc4, 0x3b, 0x8a, 0xc0, 0x06, 0x4e, 0x4a, 0x01, 0x64,
0x61, 0x2b, 0x1f, 0xce, 0x77, 0xc8, 0x69, 0x34, 0x5b, 0xfc, 0x94, 0xc7, 0x58, 0x94, 0xed, 0xd3,
];
let (secret_key, public_key) = secp256k1::generate_keypair(&mut rand::rng());
let message = Message::from_digest(HELLO_WORLD_SHA2);
let sig = ecdsa::sign(message, &secret_key);
assert!(ecdsa::verify(&sig, message, &public_key).is_ok());If the “global-context” feature is enabled you have access to an alternate API.
use secp256k1::{rand, Message};
// See previous example regarding this constant.
const HELLO_WORLD_SHA2: [u8; 32] = [
0x31, 0x5f, 0x5b, 0xdb, 0x76, 0xd0, 0x78, 0xc4, 0x3b, 0x8a, 0xc0, 0x06, 0x4e, 0x4a, 0x01, 0x64,
0x61, 0x2b, 0x1f, 0xce, 0x77, 0xc8, 0x69, 0x34, 0x5b, 0xfc, 0x94, 0xc7, 0x58, 0x94, 0xed, 0xd3,
];
let (secret_key, public_key) = secp256k1::generate_keypair(&mut rand::rng());
let message = Message::from_digest(HELLO_WORLD_SHA2);
let sig = secret_key.sign_ecdsa(message);
assert!(sig.verify(message, &public_key).is_ok());The above code requires rust-secp256k1 to be compiled with the rand, hashes, and std
feature enabled, to get access to generate_keypair
Alternately, keys and messages can be parsed from slices, like
use secp256k1::{ecdsa, Message, SecretKey, PublicKey};
let secret_key = SecretKey::from_secret_bytes([0xcd; 32]).expect("32 bytes, within curve order");
let public_key = PublicKey::from_secret_key(&secret_key);
// If the supplied byte slice was *not* the output of a cryptographic hash function this would
// be cryptographically broken. It has been trivially used in the past to execute attacks.
let message = Message::from_digest(compute_hash(b"CSW is not Satoshi"));
let sig = ecdsa::sign(message, &secret_key);
assert!(ecdsa::verify(&sig, message, &public_key).is_ok());Users who only want to verify signatures can use a cheaper context, like so:
use secp256k1::{ecdsa, Message, PublicKey};
let public_key = PublicKey::from_slice(&[
0x02,
0xc6, 0x6e, 0x7d, 0x89, 0x66, 0xb5, 0xc5, 0x55,
0xaf, 0x58, 0x05, 0x98, 0x9d, 0xa9, 0xfb, 0xf8,
0xdb, 0x95, 0xe1, 0x56, 0x31, 0xce, 0x35, 0x8c,
0x3a, 0x17, 0x10, 0xc9, 0x62, 0x67, 0x90, 0x63,
]).expect("public keys must be 33 or 65 bytes, serialized according to SEC 2");
let message = Message::from_digest([
0xaa, 0xdf, 0x7d, 0xe7, 0x82, 0x03, 0x4f, 0xbe,
0x3d, 0x3d, 0xb2, 0xcb, 0x13, 0xc0, 0xcd, 0x91,
0xbf, 0x41, 0xcb, 0x08, 0xfa, 0xc7, 0xbd, 0x61,
0xd5, 0x44, 0x53, 0xcf, 0x6e, 0x82, 0xb4, 0x50,
]);
let sig = ecdsa::Signature::from_compact(&[
0xdc, 0x4d, 0xc2, 0x64, 0xa9, 0xfe, 0xf1, 0x7a,
0x3f, 0x25, 0x34, 0x49, 0xcf, 0x8c, 0x39, 0x7a,
0xb6, 0xf1, 0x6f, 0xb3, 0xd6, 0x3d, 0x86, 0x94,
0x0b, 0x55, 0x86, 0x82, 0x3d, 0xfd, 0x02, 0xae,
0x3b, 0x46, 0x1b, 0xb4, 0x33, 0x6b, 0x5e, 0xcb,
0xae, 0xfd, 0x66, 0x27, 0xaa, 0x92, 0x2e, 0xfc,
0x04, 0x8f, 0xec, 0x0c, 0x88, 0x1c, 0x10, 0xc4,
0xc9, 0x42, 0x8f, 0xca, 0x69, 0xc1, 0x32, 0xa2,
]).expect("compact signatures are 64 bytes; DER signatures are 68-72 bytes");
assert!(ecdsa::verify(&sig, message, &public_key).is_ok());Observe that the same code using, say signing_only
to generate a context would simply not compile.
§Crate features/optional dependencies
This crate provides the following opt-in Cargo features:
std- use standard Rust library, enabled by default.alloc- use theallocstandard Rust library to provide heap allocations.rand- userandlibrary to provide random generator (e.g. to generate keys).hashes- use thehasheslibrary.recovery- enable functions that can compute the public key from signature.lowmemory- optimize the library for low-memory environments.global-context- enable use of global secp256k1 context (impliesstd).serde- implements serialization and deserialization for types in this crate usingserde. Important:serdeencoding is not the same as consensus encoding!
Re-exports§
pub extern crate serde;pub use secp256k1_sys as ffi;
Modules§
- constants
- Constants related to the API and the underlying curve.
- ecdh
- Support for shared secret computations.
- ecdsa
- Structs and functionality related to the ECDSA signature algorithm.
- ellswift
- This module provides an implementation of ElligatorSwift as well as a version of x-only ECDH using it (including compatibility with BIP324).
- musig
- This module implements high-level Rust bindings for a Schnorr-based multi-signature scheme called MuSig2 paper. It is compatible with bip-schnorr.
- scalar
- Provides
Scalarand related types. - schnorr
- Support for schnorr signatures.
Macros§
- impl_
array_ newtype - Implement methods and traits for types that contain an inner array.
Structs§
- AllPreallocated
- Represents the set of all capabilities (preallocated memory).
- Invalid
Parity Value - Error returned when conversion from an integer to
Parityfails. - Keypair
- Opaque data structure that holds a keypair consisting of a secret and a public key.
- Message
- A (hashed) message input to an ECDSA signature.
- Public
Key - Public key - used to verify ECDSA signatures and to do Taproot tweaks.
- Scalar
- Positive 256-bit integer guaranteed to be less than the secp256k1 curve order.
- Secp256k1
- The secp256k1 engine, used to execute all signature operations.
- Secret
Key - Secret key - a 256-bit key used to create ECDSA and Taproot signatures.
- Sign
Only Preallocated - Represents the set of capabilities needed for signing (preallocated memory).
- Verify
Only Preallocated - Represents the set of capabilities needed for verification (preallocated memory).
- XOnly
Public Key - An x-only public key, used for verification of Taproot signatures and serialized according to BIP-340.
Enums§
- All
- Represents the set of all capabilities.
- Error
- The main error type for this library.
- Parity
- Represents the parity passed between FFI function calls.
- Sign
Only - Represents the set of capabilities needed for signing.
- Verify
Only - Represents the set of capabilities needed for verification.
Traits§
- Context
- A trait for all kinds of contexts that lets you define the exact flags and a function to deallocate memory. It isn’t possible to implement this for types outside this crate.
- Preallocated
Context - Trait marking that a particular context object internally points to
memory that must outlive
'a - Signing
- Marker trait for indicating that an instance of
Secp256k1can be used for signing. - Verification
- Marker trait for indicating that an instance of
Secp256k1can be used for verification.
Functions§
- rerandomize_
global_ context - Rerandomize the global context, using the given data as a seed.
- sort_
pubkeys - Sort public keys using lexicographic (of compressed serialization) order.
- with_
global_ context - Borrows the global context and does some operation on it.
- with_
raw_ global_ context - Borrows the global context as a raw pointer and does some operation on it.