File tree Expand file tree Collapse file tree 4 files changed +57
-0
lines changed Expand file tree Collapse file tree 4 files changed +57
-0
lines changed Original file line number Diff line number Diff line change @@ -43,6 +43,9 @@ script:
4343 - cargo test --verbose --features="rand rand-std"
4444 - cargo test --verbose --features="rand serde"
4545 - cargo test --verbose --features="rand serde recovery endomorphism"
46+ - if [ ${TRAVIS_RUST_VERSION} != "1.22.0" ]; then
47+ cargo test --verbose --features global-context;
48+ fi
4649 - cargo build --verbose
4750 - cargo test --verbose
4851 - cargo build --verbose --release
Original file line number Diff line number Diff line change @@ -29,6 +29,7 @@ rand-std = ["rand/std"]
2929recovery = [" secp256k1-sys/recovery" ]
3030endomorphism = [" secp256k1-sys/endomorphism" ]
3131lowmemory = [" secp256k1-sys/lowmemory" ]
32+ global-context = [" std" , " rand" ]
3233
3334# Use this feature to not compile the bundled libsecp256k1 C symbols,
3435# but use external ones. Use this only if you know what you are doing!
Original file line number Diff line number Diff line change @@ -9,6 +9,38 @@ use Secp256k1;
99#[ cfg( feature = "std" ) ]
1010pub use self :: std_only:: * ;
1111
12+ #[ cfg( feature = "global-context" ) ]
13+ /// Module implementing a singleton pattern for a global `Secp256k1` context
14+ pub mod global {
15+ use std:: ops:: Deref ;
16+ use std:: sync:: Once ;
17+ use :: { Secp256k1 , All } ;
18+
19+ /// Proxy struct for global `SECP256K1` context
20+ pub struct GlobalContext {
21+ __private : ( ) ,
22+ }
23+
24+ /// A global, static context to avoid repeatedly creating contexts where one can't be passed
25+ pub static SECP256K1 : & GlobalContext = & GlobalContext { __private : ( ) } ;
26+
27+ impl Deref for GlobalContext {
28+ type Target = Secp256k1 < All > ;
29+
30+ fn deref ( & self ) -> & Self :: Target {
31+ static ONCE : Once = Once :: new ( ) ;
32+ static mut CONTEXT : Option < Secp256k1 < All > > = None ;
33+ ONCE . call_once ( || unsafe {
34+ let mut ctx = Secp256k1 :: new ( ) ;
35+ ctx. randomize ( & mut rand:: thread_rng ( ) ) ;
36+ CONTEXT = Some ( ctx) ;
37+ } ) ;
38+ unsafe { CONTEXT . as_ref ( ) . unwrap ( ) }
39+ }
40+ }
41+ }
42+
43+
1244/// A trait for all kinds of Context's that Lets you define the exact flags and a function to deallocate memory.
1345/// It shouldn't be possible to implement this for types outside this crate.
1446pub unsafe trait Context : private:: Sealed {
Original file line number Diff line number Diff line change @@ -179,6 +179,9 @@ use core::marker::PhantomData;
179179use core:: ops:: Deref ;
180180use ffi:: CPtr ;
181181
182+ #[ cfg( feature = "global-context" ) ]
183+ pub use context:: global:: SECP256K1 ;
184+
182185#[ cfg( feature = "bitcoin_hashes" ) ]
183186use bitcoin_hashes:: Hash ;
184187
@@ -1138,6 +1141,24 @@ mod tests {
11381141 assert_tokens ( & sig. readable ( ) , & [ Token :: BorrowedStr ( SIG_STR ) ] ) ;
11391142 }
11401143
1144+ #[ cfg( feature = "global-context" ) ]
1145+ #[ test]
1146+ fn test_global_context ( ) {
1147+ use super :: SECP256K1 ;
1148+
1149+ let sk_data = hex ! ( "e6dd32f8761625f105c39a39f19370b3521d845a12456d60ce44debd0a362641" ) ;
1150+ let sk = SecretKey :: from_slice ( & sk_data) . unwrap ( ) ;
1151+ let msg_data = hex ! ( "a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d" ) ;
1152+ let msg = Message :: from_slice ( & msg_data) . unwrap ( ) ;
1153+
1154+ // Check usage as explicit parameter
1155+ let pk = PublicKey :: from_secret_key ( & SECP256K1 , & sk) ;
1156+
1157+ // Check usage as self
1158+ let sig = SECP256K1 . sign ( & msg, & sk) ;
1159+ assert ! ( SECP256K1 . verify( & msg, & sig, & pk) . is_ok( ) ) ;
1160+ }
1161+
11411162 // For WASM, just run through our general tests in this file all at once.
11421163 #[ cfg( target_arch = "wasm32" ) ]
11431164 extern crate wasm_bindgen_test;
You can’t perform that action at this time.
0 commit comments