diff --git a/Cargo.toml b/Cargo.toml index f847d05..f1b580f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,8 @@ features = [ "rand", "rand-std", "serde", "recovery" ] unstable = ["recovery", "rand-std"] default = ["std"] std = ["secp256k1-sys/std"] +# allow use of Secp256k1::new and related API that requires an allocator +alloc = [] rand-std = ["rand/std"] recovery = ["secp256k1-sys/recovery"] lowmemory = ["secp256k1-sys/lowmemory"] diff --git a/contrib/test.sh b/contrib/test.sh index 7869499..dc936ab 100755 --- a/contrib/test.sh +++ b/contrib/test.sh @@ -76,6 +76,7 @@ if [ "$DO_ASAN" = true ]; then RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins -Cforce-frame-pointers=yes' \ cargo test --lib --all --features="$FEATURES" -Zbuild-std --target x86_64-unknown-linux-gnu && cargo run --release --manifest-path=./no_std_test/Cargo.toml | grep -q "Verified Successfully" + cargo run --release --features=alloc --manifest-path=./no_std_test/Cargo.toml | grep -q "Verified alloc Successfully" fi # Test if panic in C code aborts the process (either with a real panic or with SIGILL) diff --git a/no_std_test/Cargo.toml b/no_std_test/Cargo.toml index 9ab53af..d365235 100644 --- a/no_std_test/Cargo.toml +++ b/no_std_test/Cargo.toml @@ -3,7 +3,11 @@ name = "no_std_test" version = "0.1.0" authors = ["Elichai Turkel "] +[features] +alloc = ["secp256k1/alloc", "wee_alloc"] + [dependencies] +wee_alloc = { version = "0.4.5", optional = true } secp256k1 = { path = "../", default-features = false, features = ["serde", "rand", "recovery"] } libc = { version = "0.2", default-features = false } serde_cbor = { version = "0.10", default-features = false } # A random serializer that supports no-std. diff --git a/no_std_test/src/main.rs b/no_std_test/src/main.rs index 9586aed..f6ecd95 100644 --- a/no_std_test/src/main.rs +++ b/no_std_test/src/main.rs @@ -43,11 +43,24 @@ #![feature(start)] #![feature(core_intrinsics)] #![feature(panic_info_message)] +#![feature(alloc_error_handler)] #![no_std] extern crate libc; extern crate secp256k1; extern crate serde_cbor; +#[cfg(feature = "alloc")] +extern crate alloc; + +use core::alloc::Layout; + +#[cfg(feature = "alloc")] +extern crate wee_alloc; + +#[cfg(feature = "alloc")] +#[global_allocator] +static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; + use core::fmt::{self, write, Write}; use core::intrinsics; use core::panic::PanicInfo; @@ -120,6 +133,17 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize { assert_ne!(x_arr, [0u8; 32]); assert_ne!(&y_arr[..], &[0u8; 32][..]); + #[cfg(feature = "alloc")] + { + let secp_alloc = Secp256k1::new(); + let public_key = PublicKey::from_secret_key(&secp_alloc, &secret_key); + let message = Message::from_slice(&[0xab; 32]).expect("32 bytes"); + + let sig = secp_alloc.sign(&message, &secret_key); + assert!(secp_alloc.verify(&message, &sig, &public_key).is_ok()); + unsafe { libc::printf("Verified alloc Successfully!\n\0".as_ptr() as _) }; + } + unsafe { libc::printf("Verified Successfully!\n\0".as_ptr() as _) }; 0 } @@ -171,3 +195,9 @@ fn panic(info: &PanicInfo) -> ! { buf.print(); intrinsics::abort() } + +#[alloc_error_handler] +fn alloc_error(_layout: Layout) -> ! { + unsafe { libc::printf("alloc shi1\n\0".as_ptr() as _) }; + intrinsics::abort() +} diff --git a/src/context.rs b/src/context.rs index 557a057..ec8b193 100644 --- a/src/context.rs +++ b/src/context.rs @@ -5,8 +5,8 @@ use ffi::types::{c_uint, c_void}; use Error; use Secp256k1; -#[cfg(feature = "std")] -pub use self::std_only::*; +#[cfg(any(feature = "std", feature = "alloc"))] +pub use self::alloc_only::*; #[cfg(feature = "global-context-less-secure")] /// Module implementing a singleton pattern for a global `Secp256k1` context @@ -93,14 +93,18 @@ mod private { impl<'buf> Sealed for SignOnlyPreallocated<'buf> {} } -#[cfg(feature = "std")] -mod std_only { +#[cfg(any(feature = "std", feature = "alloc"))] +mod alloc_only { + #[cfg(feature = "std")] + use std::alloc; + #[cfg(not(feature = "std"))] + use alloc::alloc; + impl private::Sealed for SignOnly {} impl private::Sealed for All {} impl private::Sealed for VerifyOnly {} use super::*; - use std::alloc; const ALIGN_TO: usize = mem::align_of::(); /// Represents the set of capabilities needed for signing. diff --git a/src/lib.rs b/src/lib.rs index 1a88062..a32a2af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -135,6 +135,7 @@ pub use secp256k1_sys as ffi; #[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; use core::{fmt, ptr, str};