Skip to content

Commit 1c0ae7d

Browse files
committed
Added structs and functions for manual allocation
1 parent b4b52a9 commit 1c0ae7d

File tree

1 file changed

+86
-1
lines changed

1 file changed

+86
-1
lines changed

src/context.rs

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::marker::PhantomData;
2-
use {ffi, types::{c_uint, c_void}, Error, Secp256k1, };
2+
use {ffi, types::{c_uint, c_void}, Error, Secp256k1};
33

44
#[cfg(feature = "std")]
55
pub use self::std_only::*;
@@ -21,6 +21,20 @@ pub trait Signing: Context {}
2121
/// Marker trait for indicating that an instance of `Secp256k1` can be used for verification.
2222
pub trait Verification: Context {}
2323

24+
/// Represents the set of capabilities needed for signing with a user preallocated memory.
25+
pub struct SignOnlyPreallocated<'buf> {
26+
phantom: PhantomData<&'buf ()>,
27+
}
28+
29+
/// Represents the set of capabilities needed for verification with a user preallocated memory.
30+
pub struct VerifyOnlyPreallocated<'buf> {
31+
phantom: PhantomData<&'buf ()>,
32+
}
33+
34+
/// Represents the set of all capabilities with a user preallocated memory.
35+
pub struct AllPreallocated<'buf> {
36+
phantom: PhantomData<&'buf ()>,
37+
}
2438

2539
#[cfg(feature = "std")]
2640
mod std_only {
@@ -120,3 +134,74 @@ mod std_only {
120134
}
121135

122136
}
137+
138+
impl<'buf> Signing for SignOnlyPreallocated<'buf> {}
139+
impl<'buf> Signing for AllPreallocated<'buf> {}
140+
141+
impl<'buf> Verification for VerifyOnlyPreallocated<'buf> {}
142+
impl<'buf> Verification for AllPreallocated<'buf> {}
143+
144+
unsafe impl<'buf> Context for SignOnlyPreallocated<'buf> {
145+
const FLAGS: c_uint = ffi::SECP256K1_START_SIGN;
146+
const DESCRIPTION: &'static str = "signing only";
147+
148+
fn deallocate(ptr: *mut [u8]) {
149+
let _ = ptr;
150+
}
151+
}
152+
153+
unsafe impl<'buf> Context for VerifyOnlyPreallocated<'buf> {
154+
const FLAGS: c_uint = ffi::SECP256K1_START_VERIFY;
155+
const DESCRIPTION: &'static str = "verification only";
156+
157+
fn deallocate(ptr: *mut [u8]) {
158+
let _ = ptr;
159+
}
160+
}
161+
162+
unsafe impl<'buf> Context for AllPreallocated<'buf> {
163+
const FLAGS: c_uint = SignOnlyPreallocated::FLAGS | VerifyOnlyPreallocated::FLAGS;
164+
const DESCRIPTION: &'static str = "all capabilities";
165+
166+
fn deallocate(ptr: *mut [u8]) {
167+
let _ = ptr;
168+
}
169+
}
170+
171+
impl<'buf, C: Context + 'buf> Secp256k1<C> {
172+
fn preallocated_gen_new(buf: &'buf mut [u8]) -> Result<Secp256k1<C>, Error> {
173+
if buf.len() < Self::preallocate_size() {
174+
return Err(Error::NotEnoughMemory);
175+
}
176+
Ok(Secp256k1 {
177+
ctx: unsafe {
178+
ffi::secp256k1_context_preallocated_create(
179+
buf.as_mut_ptr() as *mut c_void,
180+
AllPreallocated::FLAGS)
181+
},
182+
phantom: PhantomData,
183+
buf: buf as *mut [u8],
184+
})
185+
}
186+
}
187+
188+
impl<'buf> Secp256k1<AllPreallocated<'buf>> {
189+
/// Creates a new Secp256k1 context with all capabilities
190+
pub fn preallocated_new(buf: &'buf mut [u8]) -> Result<Secp256k1<AllPreallocated<'buf>>, Error> {
191+
Secp256k1::preallocated_gen_new(buf)
192+
}
193+
}
194+
195+
impl<'buf> Secp256k1<SignOnlyPreallocated<'buf>> {
196+
/// Creates a new Secp256k1 context that can only be used for signing
197+
pub fn preallocated_new(buf: &'buf mut [u8]) -> Result<Secp256k1<SignOnlyPreallocated<'buf>>, Error> {
198+
Secp256k1::preallocated_gen_new(buf)
199+
}
200+
}
201+
202+
impl<'buf> Secp256k1<VerifyOnlyPreallocated<'buf>> {
203+
/// Creates a new Secp256k1 context that can only be used for verification
204+
pub fn preallocated_new(buf: &'buf mut [u8]) -> Result<Secp256k1<VerifyOnlyPreallocated<'buf>>, Error> {
205+
Secp256k1::preallocated_gen_new(buf)
206+
}
207+
}

0 commit comments

Comments
 (0)