Merge pull request #19 from apoelstra/optional-deps

Make a bunch of dependencies optional, increase major version number
This commit is contained in:
Andrew Poelstra 2017-12-19 23:22:04 +00:00 committed by GitHub
commit 37f3107894
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 94 additions and 53 deletions

View File

@ -1,7 +1,7 @@
[package] [package]
name = "secp256k1" name = "secp256k1"
version = "0.7.1" version = "0.8.0"
authors = [ "Dawid Ciężarkiewicz <dpc@ucore.info>", authors = [ "Dawid Ciężarkiewicz <dpc@ucore.info>",
"Andrew Poelstra <apoelstra@wpsoftware.net>" ] "Andrew Poelstra <apoelstra@wpsoftware.net>" ]
license = "CC0-1.0" license = "CC0-1.0"
@ -23,14 +23,26 @@ path = "src/lib.rs"
[features] [features]
unstable = [] unstable = []
default = [] default = []
dev = ["clippy"]
[dependencies] [dev-dependencies]
arrayvec = "0.3"
clippy = {version = "0.0", optional = true}
rand = "0.3"
libc = "0.2"
rustc-serialize = "0.3"
serde = "1.0" serde = "1.0"
serde_json = "1.0" serde_json = "1.0"
rand = "0.3"
rustc-serialize = "0.3"
[dependencies]
libc = "0.2"
[dependencies.rand]
version = "0.3"
optional = true
[dependencies.rustc-serialize]
version = "0.3"
optional = true
[dependencies.serde]
version = "1.0"
optional = true

View File

@ -24,7 +24,7 @@
extern crate gcc; extern crate gcc;
fn main() { fn main() {
let mut base_config = gcc::Config::new(); let mut base_config = gcc::Build::new();
base_config.include("depend/secp256k1/") base_config.include("depend/secp256k1/")
.include("depend/secp256k1/include") .include("depend/secp256k1/include")
.include("depend/secp256k1/src") .include("depend/secp256k1/src")

View File

@ -22,16 +22,12 @@ pub const MESSAGE_SIZE: usize = 32;
/// The size (in bytes) of a secret key /// The size (in bytes) of a secret key
pub const SECRET_KEY_SIZE: usize = 32; pub const SECRET_KEY_SIZE: usize = 32;
/// The size (in bytes) of a public key array. This only needs to be 65 /// The size (in bytes) of a serialized public key.
/// but must be 72 for compatibility with the `ArrayVec` library. pub const PUBLIC_KEY_SIZE: usize = 33;
pub const PUBLIC_KEY_SIZE: usize = 72;
/// The size (in bytes) of an uncompressed public key /// The size (in bytes) of an serialized uncompressed public key
pub const UNCOMPRESSED_PUBLIC_KEY_SIZE: usize = 65; pub const UNCOMPRESSED_PUBLIC_KEY_SIZE: usize = 65;
/// The size (in bytes) of a compressed public key
pub const COMPRESSED_PUBLIC_KEY_SIZE: usize = 33;
/// The maximum size of a signature /// The maximum size of a signature
pub const MAX_SIGNATURE_SIZE: usize = 72; pub const MAX_SIGNATURE_SIZE: usize = 72;

View File

@ -140,7 +140,7 @@ extern "C" {
input: *const c_uchar, in_len: size_t) input: *const c_uchar, in_len: size_t)
-> c_int; -> c_int;
pub fn secp256k1_ec_pubkey_serialize(cx: *const Context, output: *const c_uchar, pub fn secp256k1_ec_pubkey_serialize(cx: *const Context, output: *mut c_uchar,
out_len: *mut size_t, pk: *const PublicKey out_len: *mut size_t, pk: *const PublicKey
, compressed: c_uint) , compressed: c_uint)
-> c_int; -> c_int;

View File

@ -15,11 +15,10 @@
//! # Public and secret keys //! # Public and secret keys
use std::marker; #[cfg(any(test, feature = "serde"))] use std::marker;
use arrayvec::ArrayVec; #[cfg(any(test, feature = "rand"))] use rand::Rng;
use rand::Rng; #[cfg(any(test, feature = "rustc-serialize"))] use serialize::{Decoder, Decodable, Encoder, Encodable};
use serialize::{Decoder, Decodable, Encoder, Encodable}; #[cfg(any(test, feature = "serde"))] use serde::{Serialize, Deserialize, Serializer, Deserializer};
use serde::{Serialize, Deserialize, Serializer, Deserializer};
use super::{Secp256k1, ContextFlag}; use super::{Secp256k1, ContextFlag};
use super::Error::{self, IncapableContext, InvalidPublicKey, InvalidSecretKey}; use super::Error::{self, IncapableContext, InvalidPublicKey, InvalidSecretKey};
@ -55,6 +54,7 @@ pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
pub struct PublicKey(ffi::PublicKey); pub struct PublicKey(ffi::PublicKey);
#[cfg(any(test, feature = "rand"))]
fn random_32_bytes<R: Rng>(rng: &mut R) -> [u8; 32] { fn random_32_bytes<R: Rng>(rng: &mut R) -> [u8; 32] {
let mut ret = [0u8; 32]; let mut ret = [0u8; 32];
rng.fill_bytes(&mut ret); rng.fill_bytes(&mut ret);
@ -64,6 +64,7 @@ fn random_32_bytes<R: Rng>(rng: &mut R) -> [u8; 32] {
impl SecretKey { impl SecretKey {
/// Creates a new random secret key /// Creates a new random secret key
#[inline] #[inline]
#[cfg(any(test, feature = "rand"))]
pub fn new<R: Rng>(secp: &Secp256k1, rng: &mut R) -> SecretKey { pub fn new<R: Rng>(secp: &Secp256k1, rng: &mut R) -> SecretKey {
let mut data = random_32_bytes(rng); let mut data = random_32_bytes(rng);
unsafe { unsafe {
@ -179,17 +180,41 @@ impl PublicKey {
/// Serialize the key as a byte-encoded pair of values. In compressed form /// Serialize the key as a byte-encoded pair of values. In compressed form
/// the y-coordinate is represented by only a single bit, as x determines /// the y-coordinate is represented by only a single bit, as x determines
/// it up to one bit. /// it up to one bit.
pub fn serialize_vec(&self, secp: &Secp256k1, compressed: bool) -> ArrayVec<[u8; constants::PUBLIC_KEY_SIZE]> { pub fn serialize(&self) -> [u8; constants::PUBLIC_KEY_SIZE] {
let mut ret = ArrayVec::new(); let secp = Secp256k1::with_caps(ContextFlag::None);
let mut ret = [0; constants::PUBLIC_KEY_SIZE];
unsafe { unsafe {
let mut ret_len = constants::PUBLIC_KEY_SIZE as ::libc::size_t; let mut ret_len = constants::PUBLIC_KEY_SIZE as ::libc::size_t;
let compressed = if compressed { ffi::SECP256K1_SER_COMPRESSED } else { ffi::SECP256K1_SER_UNCOMPRESSED }; let err = ffi::secp256k1_ec_pubkey_serialize(
let err = ffi::secp256k1_ec_pubkey_serialize(secp.ctx, ret.as_ptr(), secp.ctx,
&mut ret_len, self.as_ptr(), ret.as_mut_ptr(),
compressed); &mut ret_len,
self.as_ptr(),
ffi::SECP256K1_SER_COMPRESSED,
);
debug_assert_eq!(err, 1); debug_assert_eq!(err, 1);
ret.set_len(ret_len as usize); debug_assert_eq!(ret_len, ret.len());
}
ret
}
/// Serialize the key as a byte-encoded pair of values, in uncompressed form
pub fn serialize_uncompressed(&self) -> [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE] {
let secp = Secp256k1::with_caps(ContextFlag::None);
let mut ret = [0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE];
unsafe {
let mut ret_len = constants::UNCOMPRESSED_PUBLIC_KEY_SIZE as ::libc::size_t;
let err = ffi::secp256k1_ec_pubkey_serialize(
secp.ctx,
ret.as_mut_ptr(),
&mut ret_len,
self.as_ptr(),
ffi::SECP256K1_SER_UNCOMPRESSED,
);
debug_assert_eq!(err, 1);
debug_assert_eq!(ret_len, ret.len());
} }
ret ret
} }
@ -229,6 +254,7 @@ impl PublicKey {
} }
} }
#[cfg(any(test, feature = "rustc-serialize"))]
impl Decodable for PublicKey { impl Decodable for PublicKey {
fn decode<D: Decoder>(d: &mut D) -> Result<PublicKey, D::Error> { fn decode<D: Decoder>(d: &mut D) -> Result<PublicKey, D::Error> {
d.read_seq(|d, len| { d.read_seq(|d, len| {
@ -242,10 +268,10 @@ impl Decodable for PublicKey {
} }
PublicKey::from_slice(&s, &ret).map_err(|_| d.error("invalid public key")) PublicKey::from_slice(&s, &ret).map_err(|_| d.error("invalid public key"))
} }
} else if len == constants::COMPRESSED_PUBLIC_KEY_SIZE { } else if len == constants::PUBLIC_KEY_SIZE {
unsafe { unsafe {
use std::mem; use std::mem;
let mut ret: [u8; constants::COMPRESSED_PUBLIC_KEY_SIZE] = mem::uninitialized(); let mut ret: [u8; constants::PUBLIC_KEY_SIZE] = mem::uninitialized();
for i in 0..len { for i in 0..len {
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
} }
@ -267,13 +293,14 @@ impl From<ffi::PublicKey> for PublicKey {
} }
#[cfg(any(test, feature = "rustc-serialize"))]
impl Encodable for PublicKey { impl Encodable for PublicKey {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
let secp = Secp256k1::with_caps(::ContextFlag::None); self.serialize().encode(s)
self.serialize_vec(&secp, true).encode(s)
} }
} }
#[cfg(any(test, feature = "serde"))]
impl<'de> Deserialize<'de> for PublicKey { impl<'de> Deserialize<'de> for PublicKey {
fn deserialize<D>(d: D) -> Result<PublicKey, D::Error> fn deserialize<D>(d: D) -> Result<PublicKey, D::Error>
where D: Deserializer<'de> where D: Deserializer<'de>
@ -289,7 +316,7 @@ impl<'de> Deserialize<'de> for PublicKey {
fn visit_seq<A>(self, mut a: A) -> Result<PublicKey, A::Error> fn visit_seq<A>(self, mut a: A) -> Result<PublicKey, A::Error>
where A: de::SeqAccess<'de> where A: de::SeqAccess<'de>
{ {
debug_assert!(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE >= constants::COMPRESSED_PUBLIC_KEY_SIZE); debug_assert!(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE >= constants::PUBLIC_KEY_SIZE);
let s = Secp256k1::with_caps(::ContextFlag::None); let s = Secp256k1::with_caps(::ContextFlag::None);
unsafe { unsafe {
@ -311,7 +338,7 @@ impl<'de> Deserialize<'de> for PublicKey {
} }
match read_len { match read_len {
constants::UNCOMPRESSED_PUBLIC_KEY_SIZE | constants::COMPRESSED_PUBLIC_KEY_SIZE constants::UNCOMPRESSED_PUBLIC_KEY_SIZE | constants::PUBLIC_KEY_SIZE
=> PublicKey::from_slice(&s, &ret[..read_len]).map_err( => PublicKey::from_slice(&s, &ret[..read_len]).map_err(
|e| match e { |e| match e {
InvalidPublicKey => de::Error::invalid_value(de::Unexpected::Seq, &self), InvalidPublicKey => de::Error::invalid_value(de::Unexpected::Seq, &self),
@ -325,7 +352,7 @@ impl<'de> Deserialize<'de> for PublicKey {
fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "a sequence of {} or {} bytes representing a valid compressed or uncompressed public key", write!(f, "a sequence of {} or {} bytes representing a valid compressed or uncompressed public key",
constants::COMPRESSED_PUBLIC_KEY_SIZE, constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) constants::PUBLIC_KEY_SIZE, constants::UNCOMPRESSED_PUBLIC_KEY_SIZE)
} }
} }
@ -334,12 +361,12 @@ impl<'de> Deserialize<'de> for PublicKey {
} }
} }
#[cfg(any(test, feature = "serde"))]
impl Serialize for PublicKey { impl Serialize for PublicKey {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where S: Serializer where S: Serializer
{ {
let secp = Secp256k1::with_caps(::ContextFlag::None); self.serialize().serialize(s)
(&self.serialize_vec(&secp, true)[..]).serialize(s)
} }
} }
@ -381,8 +408,8 @@ mod test {
let (sk1, pk1) = s.generate_keypair(&mut thread_rng()).unwrap(); let (sk1, pk1) = s.generate_keypair(&mut thread_rng()).unwrap();
assert_eq!(SecretKey::from_slice(&s, &sk1[..]), Ok(sk1)); assert_eq!(SecretKey::from_slice(&s, &sk1[..]), Ok(sk1));
assert_eq!(PublicKey::from_slice(&s, &pk1.serialize_vec(&s, true)[..]), Ok(pk1)); assert_eq!(PublicKey::from_slice(&s, &pk1.serialize()[..]), Ok(pk1));
assert_eq!(PublicKey::from_slice(&s, &pk1.serialize_vec(&s, false)[..]), Ok(pk1)); assert_eq!(PublicKey::from_slice(&s, &pk1.serialize_uncompressed()[..]), Ok(pk1));
} }
#[test] #[test]
@ -597,9 +624,9 @@ mod test {
fn test_pubkey_from_bad_slice() { fn test_pubkey_from_bad_slice() {
let s = Secp256k1::new(); let s = Secp256k1::new();
// Bad sizes // Bad sizes
assert_eq!(PublicKey::from_slice(&s, &[0; constants::COMPRESSED_PUBLIC_KEY_SIZE - 1]), assert_eq!(PublicKey::from_slice(&s, &[0; constants::PUBLIC_KEY_SIZE - 1]),
Err(InvalidPublicKey)); Err(InvalidPublicKey));
assert_eq!(PublicKey::from_slice(&s, &[0; constants::COMPRESSED_PUBLIC_KEY_SIZE + 1]), assert_eq!(PublicKey::from_slice(&s, &[0; constants::PUBLIC_KEY_SIZE + 1]),
Err(InvalidPublicKey)); Err(InvalidPublicKey));
assert_eq!(PublicKey::from_slice(&s, &[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE - 1]), assert_eq!(PublicKey::from_slice(&s, &[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE - 1]),
Err(InvalidPublicKey)); Err(InvalidPublicKey));
@ -609,7 +636,7 @@ mod test {
// Bad parse // Bad parse
assert_eq!(PublicKey::from_slice(&s, &[0xff; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]), assert_eq!(PublicKey::from_slice(&s, &[0xff; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]),
Err(InvalidPublicKey)); Err(InvalidPublicKey));
assert_eq!(PublicKey::from_slice(&s, &[0x55; constants::COMPRESSED_PUBLIC_KEY_SIZE]), assert_eq!(PublicKey::from_slice(&s, &[0x55; constants::PUBLIC_KEY_SIZE]),
Err(InvalidPublicKey)); Err(InvalidPublicKey));
} }
@ -642,9 +669,9 @@ mod test {
let s = Secp256k1::new(); let s = Secp256k1::new();
let (_, pk1) = s.generate_keypair(&mut DumbRng(0)).unwrap(); let (_, pk1) = s.generate_keypair(&mut DumbRng(0)).unwrap();
assert_eq!(&pk1.serialize_vec(&s, false)[..], assert_eq!(&pk1.serialize_uncompressed()[..],
&[4, 149, 16, 196, 140, 38, 92, 239, 179, 65, 59, 224, 230, 183, 91, 238, 240, 46, 186, 252, 175, 102, 52, 249, 98, 178, 123, 72, 50, 171, 196, 254, 236, 1, 189, 143, 242, 227, 16, 87, 247, 183, 162, 68, 237, 140, 92, 205, 151, 129, 166, 58, 111, 96, 123, 64, 180, 147, 51, 12, 209, 89, 236, 213, 206][..]); &[4, 149, 16, 196, 140, 38, 92, 239, 179, 65, 59, 224, 230, 183, 91, 238, 240, 46, 186, 252, 175, 102, 52, 249, 98, 178, 123, 72, 50, 171, 196, 254, 236, 1, 189, 143, 242, 227, 16, 87, 247, 183, 162, 68, 237, 140, 92, 205, 151, 129, 166, 58, 111, 96, 123, 64, 180, 147, 51, 12, 209, 89, 236, 213, 206][..]);
assert_eq!(&pk1.serialize_vec(&s, true)[..], assert_eq!(&pk1.serialize()[..],
&[2, 149, 16, 196, 140, 38, 92, 239, 179, 65, 59, 224, 230, 183, 91, 238, 240, 46, 186, 252, 175, 102, 52, 249, 98, 178, 123, 72, 50, 171, 196, 254, 236][..]); &[2, 149, 16, 196, 140, 38, 92, 239, 179, 65, 59, 224, 230, 183, 91, 238, 240, 46, 186, 252, 175, 102, 52, 249, 98, 178, 123, 72, 50, 171, 196, 254, 236][..]);
} }

View File

@ -38,18 +38,16 @@
#![cfg_attr(all(test, feature = "unstable"), feature(test))] #![cfg_attr(all(test, feature = "unstable"), feature(test))]
#[cfg(all(test, feature = "unstable"))] extern crate test; #[cfg(all(test, feature = "unstable"))] extern crate test;
#[cfg(any(test, feature = "serde"))] extern crate serde;
extern crate arrayvec; #[cfg(test)] extern crate serde_json as json;
extern crate rustc_serialize as serialize; #[cfg(any(test, feature = "rand"))] extern crate rand;
extern crate serde; #[cfg(any(test, feature = "rustc-serialize"))] extern crate rustc_serialize as serialize;
extern crate serde_json as json;
extern crate libc; extern crate libc;
extern crate rand;
use libc::size_t; use libc::size_t;
use std::{error, fmt, ops, ptr}; use std::{error, fmt, ops, ptr};
use rand::Rng; #[cfg(any(test, feature = "rand"))] use rand::Rng;
#[macro_use] #[macro_use]
mod macros; mod macros;
@ -202,6 +200,7 @@ impl Signature {
} }
} }
#[cfg(any(test, feature = "serde"))]
impl serde::Serialize for Signature { impl serde::Serialize for Signature {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer where S: serde::Serializer
@ -211,6 +210,7 @@ impl serde::Serialize for Signature {
} }
} }
#[cfg(any(test, feature = "serde"))]
impl<'de> serde::Deserialize<'de> for Signature { impl<'de> serde::Deserialize<'de> for Signature {
fn deserialize<D>(d: D) -> Result<Signature, D::Error> fn deserialize<D>(d: D) -> Result<Signature, D::Error>
where D: serde::Deserializer<'de> where D: serde::Deserializer<'de>
@ -520,6 +520,7 @@ impl Secp256k1 {
/// (Re)randomizes the Secp256k1 context for cheap sidechannel resistence; /// (Re)randomizes the Secp256k1 context for cheap sidechannel resistence;
/// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell /// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell
#[cfg(any(test, feature = "rand"))]
pub fn randomize<R: Rng>(&mut self, rng: &mut R) { pub fn randomize<R: Rng>(&mut self, rng: &mut R) {
let mut seed = [0; 32]; let mut seed = [0; 32];
rng.fill_bytes(&mut seed); rng.fill_bytes(&mut seed);
@ -541,6 +542,7 @@ impl Secp256k1 {
/// and `key::PublicKey::from_secret_key`; call those functions directly for /// 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.
#[inline] #[inline]
#[cfg(any(test, feature = "rand"))]
pub fn generate_keypair<R: Rng>(&self, rng: &mut R) pub fn generate_keypair<R: Rng>(&self, rng: &mut R)
-> Result<(key::SecretKey, key::PublicKey), Error> { -> Result<(key::SecretKey, key::PublicKey), Error> {
let sk = key::SecretKey::new(self, rng); let sk = key::SecretKey::new(self, rng);
@ -690,7 +692,7 @@ mod tests {
assert_eq!(full.recover(&msg, &sigr), Ok(pk)); assert_eq!(full.recover(&msg, &sigr), Ok(pk));
// Check that we can produce keys from slices with no precomputation // Check that we can produce keys from slices with no precomputation
let (pk_slice, sk_slice) = (&pk.serialize_vec(&none, true), &sk[..]); let (pk_slice, sk_slice) = (&pk.serialize(), &sk[..]);
let new_pk = PublicKey::from_slice(&none, pk_slice).unwrap(); let new_pk = PublicKey::from_slice(&none, pk_slice).unwrap();
let new_sk = SecretKey::from_slice(&none, sk_slice).unwrap(); let new_sk = SecretKey::from_slice(&none, sk_slice).unwrap();
assert_eq!(sk, new_sk); assert_eq!(sk, new_sk);

View File

@ -116,6 +116,7 @@ macro_rules! impl_array_newtype {
} }
} }
#[cfg(any(test, feature = "rustc-serialize"))]
impl ::serialize::Decodable for $thing { impl ::serialize::Decodable for $thing {
fn decode<D: ::serialize::Decoder>(d: &mut D) -> Result<$thing, D::Error> { fn decode<D: ::serialize::Decoder>(d: &mut D) -> Result<$thing, D::Error> {
use serialize::Decodable; use serialize::Decodable;
@ -137,6 +138,7 @@ macro_rules! impl_array_newtype {
} }
} }
#[cfg(any(test, feature = "rustc-serialize"))]
impl ::serialize::Encodable for $thing { impl ::serialize::Encodable for $thing {
fn encode<S: ::serialize::Encoder>(&self, s: &mut S) fn encode<S: ::serialize::Encoder>(&self, s: &mut S)
-> Result<(), S::Error> { -> Result<(), S::Error> {
@ -144,6 +146,7 @@ macro_rules! impl_array_newtype {
} }
} }
#[cfg(any(test, feature = "serde"))]
impl<'de> ::serde::Deserialize<'de> for $thing { impl<'de> ::serde::Deserialize<'de> for $thing {
fn deserialize<D>(d: D) -> Result<$thing, D::Error> fn deserialize<D>(d: D) -> Result<$thing, D::Error>
where D: ::serde::Deserializer<'de> where D: ::serde::Deserializer<'de>
@ -188,6 +191,7 @@ macro_rules! impl_array_newtype {
} }
} }
#[cfg(any(test, feature = "serde"))]
impl ::serde::Serialize for $thing { impl ::serde::Serialize for $thing {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where S: ::serde::Serializer where S: ::serde::Serializer