Add secp256k1-sys

This commit is contained in:
Steven Roose 2019-10-21 14:15:19 +02:00
parent 9bd088233b
commit 724c49fff9
No known key found for this signature in database
GPG Key ID: 2F2A88D7F8D68E87
102 changed files with 252 additions and 171 deletions

View File

@ -11,17 +11,12 @@ 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." 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" ] keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin" ]
readme = "README.md" readme = "README.md"
build = "build.rs"
links = "secp256k1"
autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/cargo/issues/5330 autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/cargo/issues/5330
# Should make docs.rs show all functions, even those behind non-default features # Should make docs.rs show all functions, even those behind non-default features
[package.metadata.docs.rs] [package.metadata.docs.rs]
features = [ "rand", "rand-std", "serde", "recovery", "endomorphism" ] features = [ "rand", "rand-std", "serde", "recovery", "endomorphism" ]
[build-dependencies]
cc = ">= 1.0.28, < 1.0.42"
[lib] [lib]
name = "secp256k1" name = "secp256k1"
path = "src/lib.rs" path = "src/lib.rs"
@ -29,16 +24,19 @@ path = "src/lib.rs"
[features] [features]
unstable = [] unstable = []
default = ["std"] default = ["std"]
std = [] std = ["secp256k1-sys/std"]
rand-std = ["rand/std"] rand-std = ["rand/std"]
recovery = [] recovery = ["secp256k1-sys/recovery"]
endomorphism = [] endomorphism = ["secp256k1-sys/endomorphism"]
lowmemory = [] lowmemory = ["secp256k1-sys/lowmemory"]
# Do not use this feature! HAZMAT. (meant for Bitcoin Core only) # Do not use this feature! HAZMAT. (meant for Bitcoin Core only)
dont_replace_c_symbols = [] dont_replace_c_symbols = ["secp256k1-sys/dont_replace_c_symbols"]
# Do not use this feature! HAZMAT. (meant for Fuzzing only. this is *BROKEN CRYPTOGRAPHY*) # Do not use this feature! HAZMAT. (meant for Fuzzing only. this is *BROKEN CRYPTOGRAPHY*)
fuzztarget = [] fuzztarget = ["secp256k1-sys/fuzztarget"]
[dependencies]
secp256k1-sys = { version = "0.1.0", default-features = false, path = "./secp256k1-sys" }
[dev-dependencies] [dev-dependencies]
rand = "0.6" rand = "0.6"

38
secp256k1-sys/Cargo.toml Normal file
View File

@ -0,0 +1,38 @@
[package]
name = "secp256k1-sys"
version = "0.1.0"
authors = [ "Dawid Ciężarkiewicz <dpc@ucore.info>",
"Andrew Poelstra <apoelstra@wpsoftware.net>",
"Steven Roose <steven@stevenroose.org>" ]
license = "CC0-1.0"
homepage = "https://github.com/rust-bitcoin/rust-secp256k1/"
repository = "https://github.com/rust-bitcoin/rust-secp256k1/"
documentation = "https://docs.rs/secp256k1-sys/"
description = "FFI for Pieter Wuille's `libsecp256k1` library."
keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin", "ffi" ]
readme = "README.md"
build = "build.rs"
links = "secp256k1"
# Should make docs.rs show all functions, even those behind non-default features
[package.metadata.docs.rs]
features = [ "recovery", "endomorphism", "lowmemory" ]
[build-dependencies]
cc = ">= 1.0.28, <= 1.0.41"
[lib]
name = "secp256k1_sys"
path = "src/lib.rs"
[features]
default = ["std"]
recovery = []
endomorphism = []
lowmemory = []
std = []
# Do not use this feature! HAZMAT. (meant for Bitcoin Core only)
dont_replace_c_symbols = []
# Do not use this feature! HAZMAT. (meant for Fuzzing only. this is *BROKEN CRYPTOGRAPHY*)
fuzztarget = []

View File

@ -12,11 +12,31 @@
// along with this software. // along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. // If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
// //
//! # secp256k1-sys 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 core::{mem, hash, slice, ptr};
#![crate_type = "lib"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![crate_name = "secp256k1_sys"]
#![cfg_attr(all(not(test), not(fuzztarget), not(feature = "std")), no_std)]
#![cfg_attr(feature = "dev", allow(unstable_features))]
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]
#[cfg(any(test, feature = "std"))]
extern crate core;
#[macro_use]
mod macros;
pub mod types;
#[cfg(feature = "recovery")]
pub mod recovery;
use core::{hash, slice, ptr};
use types::*; use types::*;
/// Flag for context to enable no precomputation /// Flag for context to enable no precomputation
@ -268,6 +288,7 @@ extern "C" {
// Returns: a newly created context object. // Returns: a newly created context object.
// In: flags: which parts of the context to initialize. // In: flags: which parts of the context to initialize.
pub unsafe extern "C" fn secp256k1_context_create(flags: c_uint) -> *mut Context { pub unsafe extern "C" fn secp256k1_context_create(flags: c_uint) -> *mut Context {
use std::mem;
assert!(mem::align_of::<usize>() >= mem::align_of::<u8>()); assert!(mem::align_of::<usize>() >= mem::align_of::<u8>());
assert_eq!(mem::size_of::<usize>(), mem::size_of::<&usize>()); assert_eq!(mem::size_of::<usize>(), mem::size_of::<&usize>());
@ -366,7 +387,7 @@ unsafe fn strlen(mut str_ptr: *const c_char) -> usize {
/// Rust doesn't promise what pointers does it give to ZST (https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts) /// Rust doesn't promise what pointers does it give to ZST (https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts)
/// In case the type is empty this trait will give a NULL pointer, which should be handled in C. /// In case the type is empty this trait will give a NULL pointer, which should be handled in C.
/// ///
pub(crate) trait CPtr { pub trait CPtr {
type Target; type Target;
fn as_c_ptr(&self) -> *const Self::Target; fn as_c_ptr(&self) -> *const Self::Target;
fn as_mut_c_ptr(&mut self) -> *mut Self::Target; fn as_mut_c_ptr(&mut self) -> *mut Self::Target;
@ -397,10 +418,12 @@ impl<T> CPtr for [T] {
#[cfg(feature = "fuzztarget")] #[cfg(feature = "fuzztarget")]
mod fuzz_dummy { mod fuzz_dummy {
extern crate std; extern crate std;
use types::*;
use ffi::*;
use self::std::{ptr, mem}; use self::std::{ptr, mem};
use self::std::boxed::Box; use self::std::boxed::Box;
use types::*;
use ::{Signature, Context, NonceFn, EcdhHashFn, PublicKey, SharedSecret,
SECP256K1_START_NONE, SECP256K1_START_VERIFY, SECP256K1_START_SIGN,
SECP256K1_SER_COMPRESSED, SECP256K1_SER_UNCOMPRESSED};
extern "C" { extern "C" {
pub static secp256k1_ecdh_hash_function_default: EcdhHashFn; pub static secp256k1_ecdh_hash_function_default: EcdhHashFn;
@ -421,7 +444,7 @@ mod fuzz_dummy {
} }
/// Return dummy size of context struct. /// Return dummy size of context struct.
pub unsafe fn secp256k1_context_preallocated_clone_size(cx: *mut Context) -> usize { pub unsafe fn secp256k1_context_preallocated_clone_size(_cx: *mut Context) -> usize {
mem::size_of::<Context>() mem::size_of::<Context>()
} }
@ -767,3 +790,4 @@ mod tests {
assert_eq!(orig.len(), unsafe {strlen(test.as_ptr())}); assert_eq!(orig.len(), unsafe {strlen(test.as_ptr())});
} }
} }

158
secp256k1-sys/src/macros.rs Normal file
View File

@ -0,0 +1,158 @@
// Bitcoin secp256k1 bindings
// Written in 2014 by
// Dawid Ciężarkiewicz
// Andrew Poelstra
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//
// This is a macro that routinely comes in handy
#[macro_export]
macro_rules! impl_array_newtype {
($thing:ident, $ty:ty, $len:expr) => {
impl Copy for $thing {}
impl $thing {
#[inline]
/// Converts the object to a raw pointer for FFI interfacing
pub fn as_ptr(&self) -> *const $ty {
let &$thing(ref dat) = self;
dat.as_ptr()
}
#[inline]
/// Converts the object to a mutable raw pointer for FFI interfacing
pub fn as_mut_ptr(&mut self) -> *mut $ty {
let &mut $thing(ref mut dat) = self;
dat.as_mut_ptr()
}
#[inline]
/// Returns the length of the object as an array
pub fn len(&self) -> usize { $len }
#[inline]
/// Returns whether the object as an array is empty
pub fn is_empty(&self) -> bool { false }
}
impl PartialEq for $thing {
#[inline]
fn eq(&self, other: &$thing) -> bool {
&self[..] == &other[..]
}
}
impl Eq for $thing {}
impl PartialOrd for $thing {
#[inline]
fn partial_cmp(&self, other: &$thing) -> Option<::core::cmp::Ordering> {
self[..].partial_cmp(&other[..])
}
}
impl Ord for $thing {
#[inline]
fn cmp(&self, other: &$thing) -> ::core::cmp::Ordering {
self[..].cmp(&other[..])
}
}
impl Clone for $thing {
#[inline]
fn clone(&self) -> $thing {
let &$thing(ref dat) = self;
$thing(dat.clone())
}
}
impl ::core::ops::Index<usize> for $thing {
type Output = $ty;
#[inline]
fn index(&self, index: usize) -> &$ty {
let &$thing(ref dat) = self;
&dat[index]
}
}
impl ::core::ops::Index<::core::ops::Range<usize>> for $thing {
type Output = [$ty];
#[inline]
fn index(&self, index: ::core::ops::Range<usize>) -> &[$ty] {
let &$thing(ref dat) = self;
&dat[index]
}
}
impl ::core::ops::Index<::core::ops::RangeTo<usize>> for $thing {
type Output = [$ty];
#[inline]
fn index(&self, index: ::core::ops::RangeTo<usize>) -> &[$ty] {
let &$thing(ref dat) = self;
&dat[index]
}
}
impl ::core::ops::Index<::core::ops::RangeFrom<usize>> for $thing {
type Output = [$ty];
#[inline]
fn index(&self, index: ::core::ops::RangeFrom<usize>) -> &[$ty] {
let &$thing(ref dat) = self;
&dat[index]
}
}
impl ::core::ops::Index<::core::ops::RangeFull> for $thing {
type Output = [$ty];
#[inline]
fn index(&self, _: ::core::ops::RangeFull) -> &[$ty] {
let &$thing(ref dat) = self;
&dat[..]
}
}
impl ::CPtr for $thing {
type Target = $ty;
fn as_c_ptr(&self) -> *const Self::Target {
if self.is_empty() {
::core::ptr::null()
} else {
self.as_ptr()
}
}
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
if self.is_empty() {
::core::ptr::null::<Self::Target>() as *mut _
} else {
self.as_mut_ptr()
}
}
}
}
}
macro_rules! impl_raw_debug {
($thing:ident) => {
impl ::core::fmt::Debug for $thing {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
for i in self[..].iter().cloned() {
write!(f, "{:02x}", i)?;
}
Ok(())
}
}
}
}

View File

@ -15,9 +15,9 @@
//! # FFI of the recovery module //! # FFI of the recovery module
use core::mem; use ::types::*;
use types::*; #[cfg(not(feature = "fuzztarget"))]
use ffi::{Context, NonceFn, PublicKey, Signature, CPtr}; use ::{Context, Signature, NonceFn, PublicKey};
/// Library-internal representation of a Secp256k1 signature + recovery ID /// Library-internal representation of a Secp256k1 signature + recovery ID
#[repr(C)] #[repr(C)]
@ -71,10 +71,11 @@ extern "C" {
#[cfg(feature = "fuzztarget")] #[cfg(feature = "fuzztarget")]
mod fuzz_dummy { mod fuzz_dummy {
extern crate std; extern crate std;
use types::*;
use ffi::*;
use self::std::ptr; use self::std::ptr;
use super::RecoverableSignature; use super::RecoverableSignature;
use types::*;
use ::{Signature, Context, PublicKey, NonceFn, secp256k1_ec_seckey_verify,
SECP256K1_START_NONE, SECP256K1_START_VERIFY, SECP256K1_START_SIGN};
pub unsafe fn secp256k1_ecdsa_recoverable_signature_parse_compact(_cx: *const Context, _sig: *mut RecoverableSignature, pub unsafe fn secp256k1_ecdsa_recoverable_signature_parse_compact(_cx: *const Context, _sig: *mut RecoverableSignature,
_input64: *const c_uchar, _recid: c_int) _input64: *const c_uchar, _recid: c_int)
@ -125,3 +126,4 @@ mod fuzz_dummy {
} }
#[cfg(feature = "fuzztarget")] #[cfg(feature = "fuzztarget")]
pub use self::fuzz_dummy::*; pub use self::fuzz_dummy::*;

View File

@ -38,4 +38,4 @@ mod tests {
assert_eq!(TypeId::of::<types::c_uint>(), TypeId::of::<raw::c_uint>()); assert_eq!(TypeId::of::<types::c_uint>(), TypeId::of::<raw::c_uint>());
assert_eq!(TypeId::of::<types::c_char>(), TypeId::of::<raw::c_char>()); assert_eq!(TypeId::of::<types::c_char>(), TypeId::of::<raw::c_char>());
} }
} }

View File

@ -1,7 +1,7 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use ptr; use ptr;
use ffi::{self, CPtr}; use ffi::{self, CPtr};
use types::{c_uint, c_void}; use ffi::types::{c_uint, c_void};
use Error; use Error;
use Secp256k1; use Secp256k1;

View File

@ -139,8 +139,14 @@
#![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(fuzztarget), not(feature = "std")), no_std)] #![cfg_attr(all(not(test), not(fuzztarget), not(feature = "std")), no_std)]
#![cfg_attr(all(test, feature = "unstable"), feature(test))] #![cfg_attr(all(test, feature = "unstable"), feature(test))]
#[macro_use]
pub extern crate secp256k1_sys;
pub use secp256k1_sys as ffi;
#[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;
@ -153,11 +159,9 @@ use core::{fmt, ptr, str};
#[macro_use] #[macro_use]
mod macros; mod macros;
mod types;
mod context; mod context;
pub mod constants; pub mod constants;
pub mod ecdh; pub mod ecdh;
pub mod ffi;
pub mod key; pub mod key;
#[cfg(feature = "recovery")] #[cfg(feature = "recovery")]
pub mod recovery; pub mod recovery;

Some files were not shown because too many files have changed in this diff Show More