[][src]Crate cashweb_secp256k1

Secp256k1

Rust bindings for Pieter Wuille's secp256k1 library, which is used for fast and accurate manipulation of ECDSA 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" feature. To de/serialize objects with serde, compile with "serde".

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 cashweb_secp256k1::rand::rngs::OsRng;
use cashweb_secp256k1::{Secp256k1, Message};
use cashweb_secp256k1::bitcoin_hashes::sha256;

let secp = Secp256k1::new();
let mut rng = OsRng::new().expect("OsRng");
let (secret_key, public_key) = secp.generate_keypair(&mut rng);
let message = Message::from_hashed_data::<sha256::Hash>("Hello World!".as_bytes());

let sig = secp.sign(&message, &secret_key);
assert!(secp.verify(&message, &sig, &public_key).is_ok());

The above code requires rust-secp256k1 to be compiled with the rand and bitcoin_hashes feature enabled, to get access to generate_keypair Alternately, keys and messages can be parsed from slices, like

use self::cashweb_secp256k1::{Secp256k1, Message, SecretKey, PublicKey};

let secp = Secp256k1::new();
let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
// This is unsafe unless the supplied byte slice is the output of a cryptographic hash function.
// See the above example for how to use this library together with bitcoin_hashes.
let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");

let sig = secp.sign(&message, &secret_key);
assert!(secp.verify(&message, &sig, &public_key).is_ok());

Users who only want to verify signatures can use a cheaper context, like so:

use cashweb_secp256k1::{Secp256k1, Message, Signature, PublicKey};

let secp = Secp256k1::verification_only();

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_slice(&[
    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,
]).expect("messages must be 32 bytes and are expected to be hashes");

let sig = 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!(secp.verify(&message, &sig, &public_key).is_ok());

Observe that the same code using, say signing_only to generate a context would simply not compile.

Re-exports

pub extern crate cashweb_secp256k1_sys;
pub extern crate rand;
pub extern crate serde;
pub use cashweb_secp256k1_sys as ffi;
pub use key::PublicKey;
pub use key::SecretKey;

Modules

constants

Constants

ecdh

ECDH

key

Public and secret keys

recovery

Recovery module

schnorrsig

schnorrsig

Structs

AllPreallocated

Represents the set of all capabilities with a user preallocated memory.

Message

A (hashed) message input to an ECDSA signature

Secp256k1

The secp256k1 engine, used to execute all signature operations

SerializedSignature

A DER serialized Signature

SignOnlyPreallocated

Represents the set of capabilities needed for signing with a user preallocated memory.

Signature

An ECDSA signature

VerifyOnlyPreallocated

Represents the set of capabilities needed for verification with a user preallocated memory.

Enums

All

Represents the set of all capabilities.

Error

An ECDSA error

SignOnly

Represents the set of capabilities needed for signing.

VerifyOnly

Represents the set of capabilities needed for verification.

Traits

Context

A trait for all kinds of Context's that Lets you define the exact flags and a function to deallocate memory. It shouldn't be possible to implement this for types outside this crate.

Signing

Marker trait for indicating that an instance of Secp256k1 can be used for signing.

ThirtyTwoByteHash

Trait describing something that promises to be a 32-byte random number; in particular, it has negligible probability of being zero or overflowing the group order. Such objects may be converted to Messages without any error paths.

Verification

Marker trait for indicating that an instance of Secp256k1 can be used for verification.