18f74d5242 Clarify what does "less security" mean (Martin Habovstiak)
94c55b4d09 Fixed typos/grammar mistakes (Martin Habovštiak)
1bf05523f0 Documented features (Martin Habovstiak)

Pull request description:

  This documents the Cargo features making sure docs.rs shows warning for
  feature-gated items. They are also explicitly spelled out in the crate
  documentation.

  The PR is similar in spirit to https://github.com/rust-bitcoin/rust-bitcoin/pull/633

ACKs for top commit:
  apoelstra:
    ACK 18f74d5242

Tree-SHA512: 8aac3fc5fd8ee887d6b13606d66b3d11ce44662afb92228c4f8da6169e3f70ac6a005b328f427a91d307f8d36d091dcf24bfe4d17dfc034d02b578258719a90a
This commit is contained in:
Andrew Poelstra 2022-01-06 15:24:08 +00:00
commit 88f6baee73
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
9 changed files with 85 additions and 12 deletions

View File

@ -15,6 +15,7 @@ autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/car
# Should make docs.rs show all functions, even those behind non-default features
[package.metadata.docs.rs]
features = [ "rand", "rand-std", "serde", "recovery" ]
rustdoc-args = ["--cfg", "docsrs"]
[features]
unstable = ["recovery", "rand-std"]

View File

@ -17,6 +17,7 @@ links = "rustsecp256k1_v0_4_1"
# Should make docs.rs show all functions, even those behind non-default features
[package.metadata.docs.rs]
features = [ "recovery", "lowmemory" ]
rustdoc-args = ["--cfg", "docsrs"]
[build-dependencies]
cc = "1.0.28"

View File

@ -23,6 +23,8 @@
#![deny(unused_mut)]
#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(any(test, feature = "std"))]
extern crate core;
@ -34,6 +36,7 @@ mod macros;
pub mod types;
#[cfg(feature = "recovery")]
#[cfg_attr(docsrs, doc(cfg(feature = "recovery")))]
pub mod recovery;
use core::{slice, ptr};
@ -524,6 +527,7 @@ extern "C" {
// In: flags: which parts of the context to initialize.
#[no_mangle]
#[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))]
pub unsafe extern "C" fn rustsecp256k1_v0_4_1_context_create(flags: c_uint) -> *mut Context {
use core::mem;
use std::alloc;
@ -543,6 +547,7 @@ pub unsafe extern "C" fn rustsecp256k1_v0_4_1_context_create(flags: c_uint) -> *
}
#[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))]
pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context {
rustsecp256k1_v0_4_1_context_create(flags)
}
@ -555,6 +560,7 @@ pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context {
///
#[no_mangle]
#[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))]
pub unsafe extern "C" fn rustsecp256k1_v0_4_1_context_destroy(ctx: *mut Context) {
use std::alloc;
secp256k1_context_preallocated_destroy(ctx);
@ -565,6 +571,7 @@ pub unsafe extern "C" fn rustsecp256k1_v0_4_1_context_destroy(ctx: *mut Context)
}
#[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))]
pub unsafe fn secp256k1_context_destroy(ctx: *mut Context) {
rustsecp256k1_v0_4_1_context_destroy(ctx)
}

View File

@ -6,9 +6,11 @@ use Error;
use Secp256k1;
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
pub use self::alloc_only::*;
#[cfg(feature = "global-context-less-secure")]
#[cfg_attr(docsrs, doc(cfg(feature = "global-context-less-secure")))]
/// Module implementing a singleton pattern for a global `Secp256k1` context
pub mod global {
#[cfg(feature = "global-context")]
@ -94,6 +96,7 @@ mod private {
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
mod alloc_only {
#[cfg(feature = "std")]
use std::alloc;
@ -108,12 +111,15 @@ mod alloc_only {
const ALIGN_TO: usize = ::core::mem::align_of::<AlignedType>();
/// Represents the set of capabilities needed for signing.
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
pub enum SignOnly {}
/// Represents the set of capabilities needed for verification.
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
pub enum VerifyOnly {}
/// Represents the set of all capabilities.
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
pub enum All {}
impl Signing for SignOnly {}

View File

@ -9,6 +9,7 @@ use ffi::CPtr;
mod recovery;
#[cfg(feature = "recovery")]
#[cfg_attr(docsrs, doc(cfg(feature = "recovery")))]
pub use self::recovery::{RecoveryId, RecoverableSignature};
/// An ECDSA signature
@ -279,6 +280,7 @@ impl From<ffi::Signature> for Signature {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl ::serde::Serialize for Signature {
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
if s.is_human_readable() {
@ -290,6 +292,7 @@ impl ::serde::Serialize for Signature {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> ::serde::Deserialize<'de> for Signature {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() {

View File

@ -95,9 +95,10 @@ fn random_32_bytes<R: Rng + ?Sized>(rng: &mut R) -> [u8; 32] {
}
impl SecretKey {
/// Creates a new random secret key. Requires compilation with the "rand" feature.
/// Generates a new random secret key.
#[inline]
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub fn new<R: Rng + ?Sized>(rng: &mut R) -> SecretKey {
let mut data = random_32_bytes(rng);
unsafe {
@ -221,6 +222,7 @@ impl SecretKey {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl ::serde::Serialize for SecretKey {
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
if s.is_human_readable() {
@ -233,6 +235,7 @@ impl ::serde::Serialize for SecretKey {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> ::serde::Deserialize<'de> for SecretKey {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() {
@ -467,6 +470,7 @@ impl From<ffi::PublicKey> for PublicKey {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl ::serde::Serialize for PublicKey {
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
if s.is_human_readable() {
@ -478,6 +482,7 @@ impl ::serde::Serialize for PublicKey {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> ::serde::Deserialize<'de> for PublicKey {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<PublicKey, D::Error> {
if d.is_human_readable() {
@ -586,9 +591,10 @@ impl KeyPair {
}
}
/// Creates a new random secret key. Requires compilation with the "rand" feature.
/// Generates a new random secret key.
#[inline]
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub fn new<R: ::rand::Rng + ?Sized, C: Signing>(secp: &Secp256k1<C>, rng: &mut R) -> KeyPair {
let mut random_32_bytes = || {
let mut ret = [0u8; 32];
@ -685,6 +691,7 @@ impl str::FromStr for KeyPair {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl ::serde::Serialize for KeyPair {
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
if s.is_human_readable() {
@ -698,6 +705,7 @@ impl ::serde::Serialize for KeyPair {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> ::serde::Deserialize<'de> for KeyPair {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() {
@ -954,6 +962,7 @@ impl From<::key::PublicKey> for XOnlyPublicKey {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl ::serde::Serialize for XOnlyPublicKey {
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
if s.is_human_readable() {
@ -965,6 +974,7 @@ impl ::serde::Serialize for XOnlyPublicKey {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> ::serde::Deserialize<'de> for XOnlyPublicKey {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() {

View File

@ -110,6 +110,21 @@
//! Observe that the same code using, say [`signing_only`](struct.Secp256k1.html#method.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 the `alloc` standard Rust library to provide heap allocations.
//! * `rand` - use `rand` library to provide random generator (e.g. to generate keys).
//! * `rand-std` - use `rand` library with its `std` feature enabled. (Implies `rand`.)
//! * `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. (Implies `std`, `rand-std` and
//! `global-context-less-secure`.)
//! * `global-context-less-secure` - enables global context without extra sidechannel protection.
//! * `serde` - implements serialization and deserialization for types in this crate using `serde`.
//! * `bitcoin_hashes` - enables interaction with the `bitcoin-hashes` crate (e.g. conversions).
// Coding conventions
#![deny(non_upper_case_globals)]
@ -121,21 +136,35 @@
#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
#![cfg_attr(all(test, feature = "unstable"), feature(test))]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[macro_use]
pub extern crate secp256k1_sys;
pub use secp256k1_sys as ffi;
#[cfg(feature = "bitcoin_hashes")] pub extern crate bitcoin_hashes as hashes;
#[cfg(all(test, feature = "unstable"))] extern crate test;
#[cfg(any(test, feature = "rand"))] pub extern crate rand;
#[cfg(any(test))] extern crate rand_core;
#[cfg(feature = "serde")] pub extern crate serde;
#[cfg(all(test, feature = "serde"))] extern crate serde_test;
#[cfg(any(test, feature = "rand"))] use rand::Rng;
#[cfg(any(test, feature = "std"))] extern crate core;
#[cfg(all(test, target_arch = "wasm32"))] extern crate wasm_bindgen_test;
#[cfg(feature = "alloc")] extern crate alloc;
#[cfg(feature = "bitcoin_hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))]
pub extern crate bitcoin_hashes as hashes;
#[cfg(all(test, feature = "unstable"))]
extern crate test;
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub extern crate rand;
#[cfg(any(test))]
extern crate rand_core;
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
pub extern crate serde;
#[cfg(all(test, feature = "serde"))]
extern crate serde_test;
#[cfg(any(test, feature = "rand"))]
use rand::Rng;
#[cfg(any(test, feature = "std"))]
extern crate core;
#[cfg(all(test, target_arch = "wasm32"))]
extern crate wasm_bindgen_test;
#[cfg(feature = "alloc")]
extern crate alloc;
#[macro_use]
@ -163,6 +192,7 @@ use core::{mem, fmt, str};
use ffi::{CPtr, types::AlignedType};
#[cfg(feature = "global-context-less-secure")]
#[cfg_attr(docsrs, doc(cfg(feature = "global-context-less-secure")))]
pub use context::global::SECP256K1;
#[cfg(feature = "bitcoin_hashes")]
@ -196,6 +226,7 @@ pub trait ThirtyTwoByteHash {
}
#[cfg(feature = "bitcoin_hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))]
impl ThirtyTwoByteHash for hashes::sha256::Hash {
fn into_32(self) -> [u8; 32] {
self.into_inner()
@ -203,6 +234,7 @@ impl ThirtyTwoByteHash for hashes::sha256::Hash {
}
#[cfg(feature = "bitcoin_hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))]
impl ThirtyTwoByteHash for hashes::sha256d::Hash {
fn into_32(self) -> [u8; 32] {
self.into_inner()
@ -210,6 +242,7 @@ impl ThirtyTwoByteHash for hashes::sha256d::Hash {
}
#[cfg(feature = "bitcoin_hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))]
impl<T: hashes::sha256t::Tag> ThirtyTwoByteHash for hashes::sha256t::Hash<T> {
fn into_32(self) -> [u8; 32] {
self.into_inner()
@ -256,6 +289,7 @@ impl Message {
/// assert_eq!(m1, m2);
/// ```
#[cfg(feature = "bitcoin_hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))]
pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self {
<H as hashes::Hash>::hash(data).into()
}
@ -316,6 +350,7 @@ impl fmt::Display for Error {
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for Error {}
@ -374,6 +409,7 @@ impl<C: Context> Secp256k1<C> {
/// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell. Requires
/// compilation with "rand" feature.
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub fn randomize<R: Rng + ?Sized>(&mut self, rng: &mut R) {
let mut seed = [0u8; 32];
rng.fill_bytes(&mut seed);
@ -406,6 +442,7 @@ impl<C: Signing> Secp256k1<C> {
/// with the "rand" feature.
#[inline]
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub fn generate_keypair<R: Rng + ?Sized>(&self, rng: &mut R)
-> (key::SecretKey, key::PublicKey) {
let sk = key::SecretKey::new(rng);

View File

@ -19,6 +19,7 @@ impl_array_newtype!(Signature, u8, constants::SCHNORRSIG_SIGNATURE_SIZE);
impl_pretty_debug!(Signature);
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl ::serde::Serialize for Signature {
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
if s.is_human_readable() {
@ -30,6 +31,7 @@ impl ::serde::Serialize for Signature {
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> ::serde::Deserialize<'de> for Signature {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() {
@ -117,6 +119,7 @@ impl<C: Signing> Secp256k1<C> {
/// generator to generate the auxiliary random data.
/// Requires compilation with "rand-std" feature.
#[cfg(any(test, feature = "rand-std"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand-std")))]
#[deprecated(since = "0.21.0", note = "Use sign_schnorr instead.")]
pub fn schnorrsig_sign(&self, msg: &Message, keypair: &KeyPair) -> Signature {
self.sign_schnorr(msg, keypair)
@ -126,6 +129,7 @@ impl<C: Signing> Secp256k1<C> {
/// generator to generate the auxiliary random data.
/// Requires compilation with "rand-std" feature.
#[cfg(any(test, feature = "rand-std"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand-std")))]
pub fn sign_schnorr(&self, msg: &Message, keypair: &KeyPair) -> Signature {
let mut rng = thread_rng();
self.sign_schnorr_with_rng(msg, keypair, &mut rng)
@ -179,6 +183,7 @@ impl<C: Signing> Secp256k1<C> {
/// generate the auxiliary random data. Requires compilation with "rand"
/// feature.
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
#[deprecated(since = "0.21.0", note = "Use sign_schnorr_with_rng instead.")]
pub fn schnorrsig_sign_with_rng<R: Rng + CryptoRng>(
&self,
@ -193,6 +198,7 @@ impl<C: Signing> Secp256k1<C> {
/// generate the auxiliary random data. Requires compilation with "rand"
/// feature.
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub fn sign_schnorr_with_rng<R: Rng + CryptoRng>(
&self,
msg: &Message,
@ -250,6 +256,7 @@ impl <C: Signing> Secp256k1<C> {
/// with the "rand" feature.
#[inline]
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub fn generate_schnorrsig_keypair<R: Rng + ?Sized>(
&self,
rng: &mut R,

View File

@ -22,6 +22,7 @@ macro_rules! impl_display_secret {
// Default hasher exists only in standard library and not alloc
($thing:ident) => {
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl ::core::fmt::Debug for $thing {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use ::core::hash::Hasher;