Add an optional global, static context
This commit is contained in:
parent
a5147bbf01
commit
a959de4174
|
@ -43,6 +43,9 @@ script:
|
||||||
- cargo test --verbose --features="rand rand-std"
|
- cargo test --verbose --features="rand rand-std"
|
||||||
- cargo test --verbose --features="rand serde"
|
- cargo test --verbose --features="rand serde"
|
||||||
- cargo test --verbose --features="rand serde recovery endomorphism"
|
- cargo test --verbose --features="rand serde recovery endomorphism"
|
||||||
|
- if [ ${TRAVIS_RUST_VERSION} != "1.22.0" ]; then
|
||||||
|
cargo test --verbose --features global-context;
|
||||||
|
fi
|
||||||
- cargo build --verbose
|
- cargo build --verbose
|
||||||
- cargo test --verbose
|
- cargo test --verbose
|
||||||
- cargo build --verbose --release
|
- cargo build --verbose --release
|
||||||
|
|
|
@ -29,6 +29,7 @@ rand-std = ["rand/std"]
|
||||||
recovery = ["secp256k1-sys/recovery"]
|
recovery = ["secp256k1-sys/recovery"]
|
||||||
endomorphism = ["secp256k1-sys/endomorphism"]
|
endomorphism = ["secp256k1-sys/endomorphism"]
|
||||||
lowmemory = ["secp256k1-sys/lowmemory"]
|
lowmemory = ["secp256k1-sys/lowmemory"]
|
||||||
|
global-context = []
|
||||||
|
|
||||||
# Use this feature to not compile the bundled libsecp256k1 C symbols,
|
# Use this feature to not compile the bundled libsecp256k1 C symbols,
|
||||||
# but use external ones. Use this only if you know what you are doing!
|
# but use external ones. Use this only if you know what you are doing!
|
||||||
|
|
|
@ -9,6 +9,36 @@ use Secp256k1;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use self::std_only::*;
|
pub use self::std_only::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "global-context")]
|
||||||
|
/// Module implementing a singleton pattern for a global `Secp256k1` context
|
||||||
|
pub mod global {
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::sync::Once;
|
||||||
|
use ::{Secp256k1, All};
|
||||||
|
|
||||||
|
/// Proxy struct for global `SECP256K1` context
|
||||||
|
pub struct GlobalContext {
|
||||||
|
__private: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A global, static context to avoid repeatedly creating contexts where one can't be passed
|
||||||
|
pub static SECP256K1: &GlobalContext = &GlobalContext { __private: () };
|
||||||
|
|
||||||
|
impl Deref for GlobalContext {
|
||||||
|
type Target = Secp256k1<All>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
static ONCE: Once = Once::new();
|
||||||
|
static mut CONTEXT: Option<Secp256k1<All>> = None;
|
||||||
|
ONCE.call_once(|| unsafe {
|
||||||
|
CONTEXT = Some(Secp256k1::new());
|
||||||
|
});
|
||||||
|
unsafe { CONTEXT.as_ref().unwrap() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A trait for all kinds of Context's that Lets you define the exact flags and a function to deallocate memory.
|
/// A trait for all kinds of Context's that Lets you define the exact flags and a function to deallocate memory.
|
||||||
/// It shouldn't be possible to implement this for types outside this crate.
|
/// It shouldn't be possible to implement this for types outside this crate.
|
||||||
pub unsafe trait Context : private::Sealed {
|
pub unsafe trait Context : private::Sealed {
|
||||||
|
|
21
src/lib.rs
21
src/lib.rs
|
@ -179,6 +179,9 @@ use core::marker::PhantomData;
|
||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
use ffi::CPtr;
|
use ffi::CPtr;
|
||||||
|
|
||||||
|
#[cfg(feature = "global-context")]
|
||||||
|
pub use context::global::SECP256K1;
|
||||||
|
|
||||||
#[cfg(feature = "bitcoin_hashes")]
|
#[cfg(feature = "bitcoin_hashes")]
|
||||||
use bitcoin_hashes::Hash;
|
use bitcoin_hashes::Hash;
|
||||||
|
|
||||||
|
@ -1138,6 +1141,24 @@ mod tests {
|
||||||
assert_tokens(&sig.readable(), &[Token::BorrowedStr(SIG_STR)]);
|
assert_tokens(&sig.readable(), &[Token::BorrowedStr(SIG_STR)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "global-context")]
|
||||||
|
#[test]
|
||||||
|
fn test_global_context() {
|
||||||
|
use super::SECP256K1;
|
||||||
|
|
||||||
|
let sk_data = hex!("e6dd32f8761625f105c39a39f19370b3521d845a12456d60ce44debd0a362641");
|
||||||
|
let sk = SecretKey::from_slice(&sk_data).unwrap();
|
||||||
|
let msg_data = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
|
||||||
|
let msg = Message::from_slice(&msg_data).unwrap();
|
||||||
|
|
||||||
|
// Check usage as explicit parameter
|
||||||
|
let pk = PublicKey::from_secret_key(&SECP256K1, &sk);
|
||||||
|
|
||||||
|
// Check usage as self
|
||||||
|
let sig = SECP256K1.sign(&msg, &sk);
|
||||||
|
assert!(SECP256K1.verify(&msg, &sig, &pk).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
// For WASM, just run through our general tests in this file all at once.
|
// For WASM, just run through our general tests in this file all at once.
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
extern crate wasm_bindgen_test;
|
extern crate wasm_bindgen_test;
|
||||||
|
|
Loading…
Reference in New Issue