Skip to content

Commit 980e30b

Browse files
committed
Randomize context on creation
If a context is created and not randomized then it is susceptible to sidechannel attacks (quoting what I've read). Currently it is easy for users to mis-use our API because they may not know that `randomize()` should be called. We can better assist users by making APIs that are hard to mis-use. If the `rand` feature is enabled we can optimistically call `randomize` when creating a context as we do for the global context. Also, add documentation highlighting the benefit of using the `rand` feature. Resolves: #225
1 parent 6b51575 commit 980e30b

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

src/context.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -166,38 +166,52 @@ mod alloc_only {
166166
}
167167

168168
impl<C: Context> Secp256k1<C> {
169-
/// Lets you create a context in a generic manner(sign/verify/all)
169+
/// Lets you create a context in a generic manner(sign/verify/all).
170+
///
171+
/// If the `rand` feature is enabled we randomize the context using `thread_rng`.
172+
#[allow(unused_mut)] // Unused when `rand` feature is not enabled.
170173
pub fn gen_new() -> Secp256k1<C> {
171174
#[cfg(target_arch = "wasm32")]
172175
ffi::types::sanity_checks_for_wasm();
173176

174177
let size = unsafe { ffi::secp256k1_context_preallocated_size(C::FLAGS) };
175178
let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap();
176179
let ptr = unsafe {alloc::alloc(layout)};
177-
Secp256k1 {
180+
let mut secp = Secp256k1 {
178181
ctx: unsafe { ffi::secp256k1_context_preallocated_create(ptr as *mut c_void, C::FLAGS) },
179182
phantom: PhantomData,
180183
size,
181-
}
184+
};
185+
186+
#[cfg(feature = "rand")]
187+
secp.randomize(&mut rand::thread_rng());
188+
189+
secp
182190
}
183191
}
184192

185193
impl Secp256k1<All> {
186-
/// Creates a new Secp256k1 context with all capabilities
194+
/// Creates a new Secp256k1 context with all capabilities.
195+
///
196+
/// If the `rand` feature is enabled we randomize the context using `thread_rng`.
187197
pub fn new() -> Secp256k1<All> {
188198
Secp256k1::gen_new()
189199
}
190200
}
191201

192202
impl Secp256k1<SignOnly> {
193-
/// Creates a new Secp256k1 context that can only be used for signing
203+
/// Creates a new Secp256k1 context that can only be used for signing.
204+
///
205+
/// If the `rand` feature is enabled we randomize the context using `thread_rng`.
194206
pub fn signing_only() -> Secp256k1<SignOnly> {
195207
Secp256k1::gen_new()
196208
}
197209
}
198210

199211
impl Secp256k1<VerifyOnly> {
200-
/// Creates a new Secp256k1 context that can only be used for verification
212+
/// Creates a new Secp256k1 context that can only be used for verification.
213+
///
214+
/// If the `rand` feature is enabled we randomize the context using `thread_rng`.
201215
pub fn verification_only() -> Secp256k1<VerifyOnly> {
202216
Secp256k1::gen_new()
203217
}

src/lib.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020
//! and its derivatives.
2121
//!
2222
//! To minimize dependencies, some functions are feature-gated. To generate
23-
//! random keys or to re-randomize a context object, compile with the "rand"
24-
//! feature. To de/serialize objects with serde, compile with "serde".
25-
//! **Important**: `serde` encoding is **not** the same as consensus encoding!
23+
//! random keys or to re-randomize a context object, compile with the `rand`
24+
//! feature. Unless you _really_ do not want the `rand` dependency consider
25+
//! using the `rand` feature, creating contexts without randomizing can leave
26+
//! you open to side channel attacks. To de/serialize objects with serde,
27+
//! compile with "serde". **Important**: `serde` encoding is **not** the same
28+
//! as consensus encoding!
2629
//!
2730
//! Where possible, the bindings use the Rust type system to ensure that
2831
//! API usage errors are impossible. For example, the library uses context
@@ -117,7 +120,7 @@
117120
//!
118121
//! * `std` - use standard Rust library, enabled by default.
119122
//! * `alloc` - use the `alloc` standard Rust library to provide heap allocations.
120-
//! * `rand` - use `rand` library to provide random generator (e.g. to generate keys).
123+
//! * `rand` - use `rand` library to provide randomness (e.g. to randomize contexts).
121124
//! * `rand-std` - use `rand` library with its `std` feature enabled. (Implies `rand`.)
122125
//! * `recovery` - enable functions that can compute the public key from signature.
123126
//! * `lowmemory` - optimize the library for low-memory environments.

0 commit comments

Comments
 (0)