commit
ab4320f8cc
|
@ -24,6 +24,10 @@ script:
|
||||||
- cargo build --verbose --features=rand
|
- cargo build --verbose --features=rand
|
||||||
- cargo test --verbose --features=rand
|
- cargo test --verbose --features=rand
|
||||||
- cargo test --verbose --features="rand serde"
|
- cargo test --verbose --features="rand serde"
|
||||||
|
- cargo build --verbose --no-default-features
|
||||||
|
- cargo build --verbose --no-default-features --features="serde"
|
||||||
|
- cargo build --verbose --no-default-features --features="rand"
|
||||||
|
- cargo build --verbose --no-default-features --features="rand serde"
|
||||||
- cargo build --verbose
|
- cargo build --verbose
|
||||||
- cargo test --verbose
|
- cargo test --verbose
|
||||||
- cargo build --release
|
- cargo build --release
|
||||||
|
|
|
@ -27,8 +27,9 @@ path = "src/lib.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
unstable = []
|
unstable = []
|
||||||
default = []
|
default = ["std"]
|
||||||
fuzztarget = []
|
fuzztarget = []
|
||||||
|
std = []
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.6"
|
rand = "0.6"
|
||||||
|
@ -38,7 +39,9 @@ serde_test = "1.0"
|
||||||
[dependencies.rand]
|
[dependencies.rand]
|
||||||
version = "0.6"
|
version = "0.6"
|
||||||
optional = true
|
optional = true
|
||||||
|
default-features = false
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
optional = true
|
optional = true
|
||||||
|
default-features = false
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//! Support for shared secret computations
|
//! Support for shared secret computations
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use std::{ops, ptr};
|
use core::{ops, ptr};
|
||||||
|
|
||||||
use key::{SecretKey, PublicKey};
|
use key::{SecretKey, PublicKey};
|
||||||
use ffi;
|
use ffi;
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
//! # FFI bindings
|
//! # FFI bindings
|
||||||
//! Direct bindings to the underlying C library functions. These should
|
//! Direct bindings to the underlying C library functions. These should
|
||||||
//! not be needed for most users.
|
//! not be needed for most users.
|
||||||
use std::mem;
|
use core::{mem, hash};
|
||||||
use std::hash;
|
use types::*;
|
||||||
use std::os::raw::{c_int, c_uchar, c_uint, c_void};
|
// use std::os::raw::{c_int, c_uchar, c_uint, c_void};
|
||||||
|
|
||||||
|
|
||||||
/// Flag for context to enable no precomputation
|
/// Flag for context to enable no precomputation
|
||||||
pub const SECP256K1_START_NONE: c_uint = 1;
|
pub const SECP256K1_START_NONE: c_uint = 1;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#[cfg(any(test, feature = "rand"))] use rand::Rng;
|
#[cfg(any(test, feature = "rand"))] use rand::Rng;
|
||||||
|
|
||||||
use std::{fmt, mem, str};
|
use core::{fmt, mem, str};
|
||||||
|
|
||||||
use super::{from_hex, Secp256k1};
|
use super::{from_hex, Secp256k1};
|
||||||
use super::Error::{self, InvalidPublicKey, InvalidSecretKey};
|
use super::Error::{self, InvalidPublicKey, InvalidSecretKey};
|
||||||
|
|
116
src/lib.rs
116
src/lib.rs
|
@ -133,18 +133,21 @@
|
||||||
#![cfg_attr(feature = "dev", feature(plugin))]
|
#![cfg_attr(feature = "dev", feature(plugin))]
|
||||||
#![cfg_attr(feature = "dev", plugin(clippy))]
|
#![cfg_attr(feature = "dev", plugin(clippy))]
|
||||||
|
|
||||||
|
#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
|
||||||
#![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 = "rand"))] pub extern crate rand;
|
#[cfg(any(test, feature = "rand"))] pub extern crate rand;
|
||||||
#[cfg(any(test))] extern crate rand_core;
|
#[cfg(any(test))] extern crate rand_core;
|
||||||
#[cfg(feature = "serde")] pub extern crate serde;
|
#[cfg(feature = "serde")] pub extern crate serde;
|
||||||
#[cfg(all(test, feature = "serde"))] extern crate serde_test;
|
#[cfg(all(test, feature = "serde"))] extern crate serde_test;
|
||||||
|
|
||||||
use std::{error, fmt, ptr, str};
|
|
||||||
#[cfg(any(test, feature = "rand"))] use rand::Rng;
|
#[cfg(any(test, feature = "rand"))] use rand::Rng;
|
||||||
|
#[cfg(any(test, feature = "std"))] extern crate core;
|
||||||
|
|
||||||
|
use core::{fmt, ptr, str};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
mod types;
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
pub mod ecdh;
|
pub mod ecdh;
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
|
@ -152,7 +155,8 @@ pub mod key;
|
||||||
|
|
||||||
pub use key::SecretKey;
|
pub use key::SecretKey;
|
||||||
pub use key::PublicKey;
|
pub use key::PublicKey;
|
||||||
use std::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
use core::ops::Deref;
|
||||||
|
|
||||||
/// A tag used for recovering the public key from a compact signature
|
/// A tag used for recovering the public key from a compact signature
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
@ -162,6 +166,13 @@ pub struct RecoveryId(i32);
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct Signature(ffi::Signature);
|
pub struct Signature(ffi::Signature);
|
||||||
|
|
||||||
|
/// A DER serialized Signature
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct SerializedSignature {
|
||||||
|
data: [u8; 72],
|
||||||
|
len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Signature {
|
impl fmt::Debug for Signature {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Display::fmt(self, f)
|
fmt::Display::fmt(self, f)
|
||||||
|
@ -228,6 +239,40 @@ pub fn to_i32(self) -> i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SerializedSignature {
|
||||||
|
/// Get a pointer to the underlying data with the specified capacity.
|
||||||
|
pub(crate) fn get_data_mut_ptr(&mut self) -> *mut u8 {
|
||||||
|
self.data.as_mut_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the capacity of the underlying data buffer.
|
||||||
|
pub fn capacity(&self) -> usize {
|
||||||
|
self.data.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the len of the used data.
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.len
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the length of the object.
|
||||||
|
pub(crate) fn set_len(&mut self, len: usize) {
|
||||||
|
self.len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert the serialized signature into the Signature struct.
|
||||||
|
/// (This DER deserializes it)
|
||||||
|
pub fn to_signature(&self) -> Result<Signature, Error> {
|
||||||
|
Signature::from_der(&self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a SerializedSignature from a Signature.
|
||||||
|
/// (this DER serializes it)
|
||||||
|
pub fn from_signature(sig: &Signature) -> SerializedSignature {
|
||||||
|
sig.serialize_der()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Signature {
|
impl Signature {
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Converts a DER-encoded byte slice to a signature
|
/// Converts a DER-encoded byte slice to a signature
|
||||||
|
@ -334,18 +379,18 @@ impl Signature {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Serializes the signature in DER format
|
/// Serializes the signature in DER format
|
||||||
pub fn serialize_der(&self) -> Vec<u8> {
|
pub fn serialize_der(&self) -> SerializedSignature {
|
||||||
let mut ret = Vec::with_capacity(72);
|
let mut ret = SerializedSignature::default();
|
||||||
let mut len: usize = ret.capacity() as usize;
|
let mut len: usize = ret.capacity();
|
||||||
unsafe {
|
unsafe {
|
||||||
let err = ffi::secp256k1_ecdsa_signature_serialize_der(
|
let err = ffi::secp256k1_ecdsa_signature_serialize_der(
|
||||||
ffi::secp256k1_context_no_precomp,
|
ffi::secp256k1_context_no_precomp,
|
||||||
ret.as_mut_ptr(),
|
ret.get_data_mut_ptr(),
|
||||||
&mut len,
|
&mut len,
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
);
|
);
|
||||||
debug_assert!(err == 1);
|
debug_assert!(err == 1);
|
||||||
ret.set_len(len as usize);
|
ret.set_len(len);
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
@ -516,17 +561,8 @@ pub enum Error {
|
||||||
InvalidTweak,
|
InvalidTweak,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passthrough Debug to Display, since errors should be user-visible
|
impl Error {
|
||||||
impl fmt::Display for Error {
|
fn as_str(&self) -> &str {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
f.write_str(error::Error::description(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for Error {
|
|
||||||
fn cause(&self) -> Option<&error::Error> { None }
|
|
||||||
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
match *self {
|
match *self {
|
||||||
Error::IncorrectSignature => "secp: signature failed verification",
|
Error::IncorrectSignature => "secp: signature failed verification",
|
||||||
Error::InvalidMessage => "secp: message was not 32 bytes (do you need to hash?)",
|
Error::InvalidMessage => "secp: message was not 32 bytes (do you need to hash?)",
|
||||||
|
@ -539,6 +575,18 @@ impl error::Error for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Passthrough Debug to Display, since errors should be user-visible
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
f.write_str(self.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl std::error::Error for Error {
|
||||||
|
fn description(&self) -> &str { self.as_str() }
|
||||||
|
}
|
||||||
|
|
||||||
/// Marker trait for indicating that an instance of `Secp256k1` can be used for signing.
|
/// Marker trait for indicating that an instance of `Secp256k1` can be used for signing.
|
||||||
pub trait Signing {}
|
pub trait Signing {}
|
||||||
|
|
||||||
|
@ -584,6 +632,36 @@ impl<C> PartialEq for Secp256k1<C> {
|
||||||
fn eq(&self, _other: &Secp256k1<C>) -> bool { true }
|
fn eq(&self, _other: &Secp256k1<C>) -> bool { true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for SerializedSignature {
|
||||||
|
fn default() -> SerializedSignature {
|
||||||
|
SerializedSignature {
|
||||||
|
data: [0u8; 72],
|
||||||
|
len: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for SerializedSignature {
|
||||||
|
fn eq(&self, other: &SerializedSignature) -> bool {
|
||||||
|
&self.data[..self.len] == &other.data[..other.len]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for SerializedSignature {
|
||||||
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
&self.data[..self.len]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for SerializedSignature {
|
||||||
|
type Target = [u8];
|
||||||
|
fn deref(&self) -> &[u8] {
|
||||||
|
&self.data[..self.len]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for SerializedSignature {}
|
||||||
|
|
||||||
impl<C> Eq for Secp256k1<C> { }
|
impl<C> Eq for Secp256k1<C> { }
|
||||||
|
|
||||||
impl<C> Drop for Secp256k1<C> {
|
impl<C> Drop for Secp256k1<C> {
|
||||||
|
|
|
@ -53,14 +53,14 @@ macro_rules! impl_array_newtype {
|
||||||
|
|
||||||
impl PartialOrd for $thing {
|
impl PartialOrd for $thing {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn partial_cmp(&self, other: &$thing) -> Option<::std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &$thing) -> Option<::core::cmp::Ordering> {
|
||||||
self[..].partial_cmp(&other[..])
|
self[..].partial_cmp(&other[..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ord for $thing {
|
impl Ord for $thing {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cmp(&self, other: &$thing) -> ::std::cmp::Ordering {
|
fn cmp(&self, other: &$thing) -> ::core::cmp::Ordering {
|
||||||
self[..].cmp(&other[..])
|
self[..].cmp(&other[..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,8 @@ macro_rules! impl_array_newtype {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> $thing {
|
fn clone(&self) -> $thing {
|
||||||
unsafe {
|
unsafe {
|
||||||
use std::intrinsics::copy_nonoverlapping;
|
use core::intrinsics::copy_nonoverlapping;
|
||||||
use std::mem;
|
use core::mem;
|
||||||
let mut ret: $thing = mem::uninitialized();
|
let mut ret: $thing = mem::uninitialized();
|
||||||
copy_nonoverlapping(self.as_ptr(),
|
copy_nonoverlapping(self.as_ptr(),
|
||||||
ret.as_mut_ptr(),
|
ret.as_mut_ptr(),
|
||||||
|
@ -80,7 +80,7 @@ macro_rules! impl_array_newtype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::ops::Index<usize> for $thing {
|
impl ::core::ops::Index<usize> for $thing {
|
||||||
type Output = $ty;
|
type Output = $ty;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -90,41 +90,41 @@ macro_rules! impl_array_newtype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::ops::Index<::std::ops::Range<usize>> for $thing {
|
impl ::core::ops::Index<::core::ops::Range<usize>> for $thing {
|
||||||
type Output = [$ty];
|
type Output = [$ty];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: ::std::ops::Range<usize>) -> &[$ty] {
|
fn index(&self, index: ::core::ops::Range<usize>) -> &[$ty] {
|
||||||
let &$thing(ref dat) = self;
|
let &$thing(ref dat) = self;
|
||||||
&dat[index]
|
&dat[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::ops::Index<::std::ops::RangeTo<usize>> for $thing {
|
impl ::core::ops::Index<::core::ops::RangeTo<usize>> for $thing {
|
||||||
type Output = [$ty];
|
type Output = [$ty];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: ::std::ops::RangeTo<usize>) -> &[$ty] {
|
fn index(&self, index: ::core::ops::RangeTo<usize>) -> &[$ty] {
|
||||||
let &$thing(ref dat) = self;
|
let &$thing(ref dat) = self;
|
||||||
&dat[index]
|
&dat[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::ops::Index<::std::ops::RangeFrom<usize>> for $thing {
|
impl ::core::ops::Index<::core::ops::RangeFrom<usize>> for $thing {
|
||||||
type Output = [$ty];
|
type Output = [$ty];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: ::std::ops::RangeFrom<usize>) -> &[$ty] {
|
fn index(&self, index: ::core::ops::RangeFrom<usize>) -> &[$ty] {
|
||||||
let &$thing(ref dat) = self;
|
let &$thing(ref dat) = self;
|
||||||
&dat[index]
|
&dat[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::ops::Index<::std::ops::RangeFull> for $thing {
|
impl ::core::ops::Index<::core::ops::RangeFull> for $thing {
|
||||||
type Output = [$ty];
|
type Output = [$ty];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, _: ::std::ops::RangeFull) -> &[$ty] {
|
fn index(&self, _: ::core::ops::RangeFull) -> &[$ty] {
|
||||||
let &$thing(ref dat) = self;
|
let &$thing(ref dat) = self;
|
||||||
&dat[..]
|
&dat[..]
|
||||||
}
|
}
|
||||||
|
@ -134,8 +134,8 @@ macro_rules! impl_array_newtype {
|
||||||
|
|
||||||
macro_rules! impl_pretty_debug {
|
macro_rules! impl_pretty_debug {
|
||||||
($thing:ident) => {
|
($thing:ident) => {
|
||||||
impl ::std::fmt::Debug for $thing {
|
impl ::core::fmt::Debug for $thing {
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||||
try!(write!(f, "{}(", stringify!($thing)));
|
try!(write!(f, "{}(", stringify!($thing)));
|
||||||
for i in self[..].iter().cloned() {
|
for i in self[..].iter().cloned() {
|
||||||
try!(write!(f, "{:02x}", i));
|
try!(write!(f, "{:02x}", i));
|
||||||
|
@ -148,8 +148,8 @@ macro_rules! impl_pretty_debug {
|
||||||
|
|
||||||
macro_rules! impl_raw_debug {
|
macro_rules! impl_raw_debug {
|
||||||
($thing:ident) => {
|
($thing:ident) => {
|
||||||
impl ::std::fmt::Debug for $thing {
|
impl ::core::fmt::Debug for $thing {
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||||
for i in self[..].iter().cloned() {
|
for i in self[..].iter().cloned() {
|
||||||
try!(write!(f, "{:02x}", i));
|
try!(write!(f, "{:02x}", i));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
pub type c_int = i32;
|
||||||
|
pub type c_uchar = u8;
|
||||||
|
pub type c_uint = u32;
|
||||||
|
|
||||||
|
/// This is an exact copy of https://doc.rust-lang.org/core/ffi/enum.c_void.html
|
||||||
|
/// It should be Equivalent to C's void type when used as a pointer.
|
||||||
|
///
|
||||||
|
/// We can replace this with `core::ffi::c_void` once we update the rustc version to >=1.30.0.
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum c_void {
|
||||||
|
#[doc(hidden)] __variant1,
|
||||||
|
#[doc(hidden)] __variant2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for c_void {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.pad("c_void")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue