improve documentation

This commit is contained in:
Andrew Poelstra 2018-07-31 15:55:58 +00:00
parent fa670a0c2a
commit 93d8249028
3 changed files with 109 additions and 4 deletions

View File

@ -11,8 +11,14 @@ documentation = "https://docs.rs/secp256k1/"
description = "Rust bindings for Pieter Wuille's `libsecp256k1` library. Implements ECDSA for the SECG elliptic curve group secp256k1 and related utilities."
keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin" ]
readme = "README.md"
build = "build.rs"
# Should make docs.rs show all functions, even those behind non-default features
[package.metadata.docs.rs]
rustdoc-args = [
"--features \"rand serde\""
]
[build-dependencies]
cc = "1.0"

View File

@ -62,7 +62,7 @@ fn random_32_bytes<R: Rng>(rng: &mut R) -> [u8; 32] {
}
impl SecretKey {
/// Creates a new random secret key
/// Creates a new random secret key. Requires compilation with the "rand" feature.
#[inline]
#[cfg(any(test, feature = "rand"))]
pub fn new<R: Rng, C>(secp: &Secp256k1<C>, rng: &mut R) -> SecretKey {

View File

@ -19,6 +19,103 @@
//! 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.
//!
//! ```rust
//! extern crate secp256k1;
//! # #[cfg(feature="rand")]
//! extern crate rand;
//!
//! #
//! # fn main() {
//! # #[cfg(feature="rand")] {
//! use rand::OsRng;
//! use secp256k1::{Secp256k1, Message};
//!
//! 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_slice(&[0xab; 32]).expect("32 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`
//! feature enabled, to get access to [`generate_keypair`](struct.Secp256k1.html#method.generate_keypair)
//! Alternately, keys can be parsed from slices, like
//!
//! ```rust
//! # fn main() {
//! use self::secp256k1::{Secp256k1, Message, SecretKey, PublicKey};
//!
//! let secp = Secp256k1::new();
//! let secret_key = SecretKey::from_slice(&secp, &[0xcd; 32]).expect("32 bytes, within curve order");
//! let public_key = PublicKey::from_secret_key(&secp, &secret_key);
//! 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:
//!
//! ```rust
//! # fn main() {
//! use secp256k1::{Secp256k1, Message, Signature, PublicKey};
//!
//! let secp = Secp256k1::verification_only();
//!
//! let public_key = PublicKey::from_slice(&secp, &[
//! 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(&secp, &[
//! 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`](struct.Secp256k1.html#method.signing_only)
//! to generate a context would simply not compile.
//!
#![crate_type = "lib"]
#![crate_type = "rlib"]
@ -480,7 +577,8 @@ impl Secp256k1<VerifyOnly> {
impl<C> Secp256k1<C> {
/// (Re)randomizes the Secp256k1 context for cheap sidechannel resistance;
/// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell
/// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell. Requires
/// compilation with "rand" feature.
#[cfg(any(test, feature = "rand"))]
pub fn randomize<R: Rng>(&mut self, rng: &mut R) {
let mut seed = [0; 32];
@ -539,7 +637,8 @@ impl<C: Signing> Secp256k1<C> {
/// Generates a random keypair. Convenience function for `key::SecretKey::new`
/// and `key::PublicKey::from_secret_key`; call those functions directly for
/// batch key generation. Requires a signing-capable context.
/// batch key generation. Requires a signing-capable context. Requires compilation
/// with the "rand" feature.
#[inline]
#[cfg(any(test, feature = "rand"))]
pub fn generate_keypair<R: Rng>(&self, rng: &mut R)