Skip to content

Commit

Permalink
Implemented context create/destroy in rust
Browse files Browse the repository at this point in the history
  • Loading branch information
elichai committed Jul 13, 2019
1 parent 2a32f8c commit bf57496
Showing 1 changed file with 45 additions and 2 deletions.
47 changes: 45 additions & 2 deletions src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
//! # FFI bindings
//! Direct bindings to the underlying C library functions. These should
//! not be needed for most users.
use core::{mem, hash};
use core::{mem, hash, ptr, slice};
use types::*;

/// Flag for context to enable no precomputation
Expand Down Expand Up @@ -260,6 +260,49 @@ extern "C" {
}


#[cfg(feature = "std")]
#[no_mangle]
/// A reimplementation of the C function `secp256k1_context_create` in rust.
///
/// This function allocates memory, the pointer should be deallocated using `secp256k1_context_destroy`
/// A failure to do so will result in a memory leak.
///
/// This will create a secp256k1 raw context.
// Returns: a newly created context object.
// In: flags: which parts of the context to initialize.
pub unsafe extern "C" fn secp256k1_context_create(flags: c_uint) -> *mut Context {
assert!(mem::align_of::<usize>() >= mem::align_of::<u8>());

let size: usize = secp256k1_context_preallocated_size(flags)/mem::size_of::<usize>();

let buf = vec![0usize; size + 1].into_boxed_slice();
let ptr = Box::into_raw(buf) as *mut usize;
ptr::copy_nonoverlapping(&size, ptr, 1);
let ptr: *mut usize = ptr.offset(1);

secp256k1_context_preallocated_create(ptr as *mut c_void, flags)
}

#[cfg(feature = "std")]
#[no_mangle]
/// A reimplementation of the C function `secp256k1_context_destroy` in rust.
///
/// This function destroys and deallcates the context created by `secp256k1_context_create`.
///
/// The pointer shouldn't be used after passing to this function, consider it as passing it to `free()`.
///
pub unsafe extern "C" fn secp256k1_context_destroy(ctx: *mut Context) {
assert_eq!(ctx as usize % mem::align_of::<usize>(), 0);
secp256k1_context_preallocated_destroy(ctx);
let ctx: *mut usize = ctx as *mut usize;

let size_ptr: *mut usize = ctx.offset(-1);
let size: usize = ptr::read(size_ptr);
let slice: &mut [usize] = slice::from_raw_parts_mut(size_ptr , size+1);
let _ = Box::from_raw(slice as *mut [usize]);
}


#[no_mangle]
/// **This function is an override for the C function, this is the an edited version of the original description:**
///
Expand Down Expand Up @@ -302,7 +345,7 @@ pub unsafe extern "C" fn secp256k1_default_illegal_callback_fn(message: *const c
/// See also secp256k1_default_illegal_callback_fn.
///
pub unsafe extern "C" fn secp256k1_default_error_callback_fn(message: *const c_char, _data: *mut c_void) {
use core::{str, slice};
use core::str;
let msg_slice = slice::from_raw_parts(message as *const u8, strlen(message));
let msg = str::from_utf8_unchecked(msg_slice);
panic!("[libsecp256k1] internal consistency check failed {}", msg);
Expand Down

0 comments on commit bf57496

Please sign in to comment.