Skip to content

Commit 9186f02

Browse files
committed
Added preallocation size functions and added a test for the preallocation
1 parent 1c0ae7d commit 9186f02

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

src/context.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ mod std_only {
8484

8585
impl<C: Context> Secp256k1<C> {
8686
fn gen_new() -> Secp256k1<C> {
87-
let buf = vec![0u8; Self::preallocate_size()].into_boxed_slice();
87+
let buf = vec![0u8; Self::preallocate_size_gen()].into_boxed_slice();
8888
let ptr = Box::into_raw(buf);
8989
Secp256k1 {
9090
ctx: unsafe { ffi::secp256k1_context_preallocated_create(ptr as *mut c_void, C::FLAGS) },
@@ -170,14 +170,14 @@ unsafe impl<'buf> Context for AllPreallocated<'buf> {
170170

171171
impl<'buf, C: Context + 'buf> Secp256k1<C> {
172172
fn preallocated_gen_new(buf: &'buf mut [u8]) -> Result<Secp256k1<C>, Error> {
173-
if buf.len() < Self::preallocate_size() {
173+
if buf.len() < Self::preallocate_size_gen() {
174174
return Err(Error::NotEnoughMemory);
175175
}
176176
Ok(Secp256k1 {
177177
ctx: unsafe {
178178
ffi::secp256k1_context_preallocated_create(
179179
buf.as_mut_ptr() as *mut c_void,
180-
AllPreallocated::FLAGS)
180+
C::FLAGS)
181181
},
182182
phantom: PhantomData,
183183
buf: buf as *mut [u8],
@@ -190,18 +190,34 @@ impl<'buf> Secp256k1<AllPreallocated<'buf>> {
190190
pub fn preallocated_new(buf: &'buf mut [u8]) -> Result<Secp256k1<AllPreallocated<'buf>>, Error> {
191191
Secp256k1::preallocated_gen_new(buf)
192192
}
193+
/// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for a context
194+
pub fn preallocate_size() -> usize {
195+
Self::preallocate_size_gen()
196+
}
193197
}
194198

195199
impl<'buf> Secp256k1<SignOnlyPreallocated<'buf>> {
196200
/// 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> {
201+
pub fn preallocated_signing_only(buf: &'buf mut [u8]) -> Result<Secp256k1<SignOnlyPreallocated<'buf>>, Error> {
198202
Secp256k1::preallocated_gen_new(buf)
199203
}
204+
205+
/// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for the context
206+
#[inline]
207+
pub fn preallocate_signing_size() -> usize {
208+
Self::preallocate_size_gen()
209+
}
200210
}
201211

202212
impl<'buf> Secp256k1<VerifyOnlyPreallocated<'buf>> {
203213
/// 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> {
214+
pub fn preallocated_verification_only(buf: &'buf mut [u8]) -> Result<Secp256k1<VerifyOnlyPreallocated<'buf>>, Error> {
205215
Secp256k1::preallocated_gen_new(buf)
206216
}
217+
218+
/// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for the context
219+
#[inline]
220+
pub fn preallocate_verification_size() -> usize {
221+
Self::preallocate_size_gen()
222+
}
207223
}

src/lib.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ impl<C: Context> Secp256k1<C> {
570570
}
571571

572572
/// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for a context
573-
pub fn preallocate_size() -> usize {
573+
pub(crate) fn preallocate_size_gen() -> usize {
574574
unsafe { ffi::secp256k1_context_preallocated_size(C::FLAGS) }
575575
}
576576

@@ -695,6 +695,30 @@ mod tests {
695695
});
696696
}
697697

698+
#[test]
699+
fn test_preallocation() {
700+
let mut buf_ful = vec![0u8; Secp256k1::preallocate_size()];
701+
let mut buf_sign = vec![0u8; Secp256k1::preallocate_signing_size()];
702+
let mut buf_vfy = vec![0u8; Secp256k1::preallocate_verification_size()];
703+
//
704+
let full = Secp256k1::preallocated_new(&mut buf_ful).unwrap();
705+
let sign = Secp256k1::preallocated_signing_only(&mut buf_sign).unwrap();
706+
let vrfy = Secp256k1::preallocated_verification_only(&mut buf_vfy).unwrap();
707+
708+
// drop(buf_vfy); // The buffer can't get dropped before the context.
709+
// println!("{:?}", buf_ful[5]); // Can't even read the data thanks to the borrow checker.
710+
711+
let (sk, pk) = full.generate_keypair(&mut thread_rng());
712+
let msg = Message::from_slice(&[2u8; 32]).unwrap();
713+
// Try signing
714+
assert_eq!(sign.sign(&msg, &sk), full.sign(&msg, &sk));
715+
let sig = full.sign(&msg, &sk);
716+
717+
// Try verifying
718+
assert!(vrfy.verify(&msg, &sig, &pk).is_ok());
719+
assert!(full.verify(&msg, &sig, &pk).is_ok());
720+
}
721+
698722
#[test]
699723
fn capabilities() {
700724
let sign = Secp256k1::signing_only();

0 commit comments

Comments
 (0)