#![crate_type = "lib"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![crate_name = "secp256k1_sys"]
#![cfg_attr(all(not(test), not(fuzztarget), not(feature = "std")), no_std)]
#![cfg_attr(feature = "dev", allow(unstable_features))]
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]
#[cfg(any(test, feature = "std"))]
extern crate core;
#[macro_use]
mod macros;
pub mod types;
#[cfg(feature = "recovery")]
pub mod recovery;
use core::{hash, slice, ptr};
use types::*;
pub const SECP256K1_START_NONE: c_uint = 1;
pub const SECP256K1_START_VERIFY: c_uint = 1 | (1 << 8);
pub const SECP256K1_START_SIGN: c_uint = 1 | (1 << 9);
pub const SECP256K1_SER_UNCOMPRESSED: c_uint = (1 << 1);
pub const SECP256K1_SER_COMPRESSED: c_uint = (1 << 1) | (1 << 8);
pub type NonceFn = unsafe extern "C" fn(nonce32: *mut c_uchar,
msg32: *const c_uchar,
key32: *const c_uchar,
algo16: *const c_uchar,
data: *mut c_void,
attempt: c_uint,
) -> c_int;
pub type EcdhHashFn = unsafe extern "C" fn(
output: *mut c_uchar,
x: *const c_uchar,
y: *const c_uchar,
data: *mut c_void,
) -> c_int;
#[derive(Clone, Debug)]
#[repr(C)] pub struct Context(c_int);
#[cfg(feature = "fuzztarget")]
impl Context {
pub fn flags(&self) -> u32 {
self.0 as u32
}
}
#[repr(C)]
pub struct PublicKey([c_uchar; 64]);
impl_array_newtype!(PublicKey, c_uchar, 64);
impl_raw_debug!(PublicKey);
impl PublicKey {
pub fn new() -> PublicKey { PublicKey([0; 64]) }
#[deprecated(since = "0.15.3", note = "Please use the new function instead")]
pub unsafe fn blank() -> PublicKey { PublicKey::new() }
}
impl Default for PublicKey {
fn default() -> Self {
PublicKey::new()
}
}
impl hash::Hash for PublicKey {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
state.write(&self.0)
}
}
#[repr(C)]
pub struct Signature([c_uchar; 64]);
impl_array_newtype!(Signature, c_uchar, 64);
impl_raw_debug!(Signature);
impl Signature {
pub fn new() -> Signature { Signature([0; 64]) }
#[deprecated(since = "0.15.3", note = "Please use the new function instead")]
pub unsafe fn blank() -> Signature { Signature::new() }
}
impl Default for Signature {
fn default() -> Self {
Signature::new()
}
}
#[cfg(not(feature = "fuzztarget"))]
extern "C" {
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdh_hash_function_default")]
pub static secp256k1_ecdh_hash_function_default: EcdhHashFn;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_nonce_function_rfc6979")]
pub static secp256k1_nonce_function_rfc6979: NonceFn;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_nonce_function_default")]
pub static secp256k1_nonce_function_default: NonceFn;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_context_no_precomp")]
pub static secp256k1_context_no_precomp: *const Context;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_context_preallocated_size")]
pub fn secp256k1_context_preallocated_size(flags: c_uint) -> size_t;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_context_preallocated_create")]
pub fn secp256k1_context_preallocated_create(prealloc: *mut c_void, flags: c_uint) -> *mut Context;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_context_preallocated_destroy")]
pub fn secp256k1_context_preallocated_destroy(cx: *mut Context);
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_context_preallocated_clone_size")]
pub fn secp256k1_context_preallocated_clone_size(cx: *const Context) -> size_t;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_context_preallocated_clone")]
pub fn secp256k1_context_preallocated_clone(cx: *const Context, prealloc: *mut c_void) -> *mut Context;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_context_randomize")]
pub fn secp256k1_context_randomize(cx: *mut Context,
seed32: *const c_uchar)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_pubkey_parse")]
pub fn secp256k1_ec_pubkey_parse(cx: *const Context, pk: *mut PublicKey,
input: *const c_uchar, in_len: size_t)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_pubkey_serialize")]
pub fn secp256k1_ec_pubkey_serialize(cx: *const Context, output: *mut c_uchar,
out_len: *mut size_t, pk: *const PublicKey,
compressed: c_uint)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdsa_signature_parse_der")]
pub fn secp256k1_ecdsa_signature_parse_der(cx: *const Context, sig: *mut Signature,
input: *const c_uchar, in_len: size_t)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdsa_signature_parse_compact")]
pub fn secp256k1_ecdsa_signature_parse_compact(cx: *const Context, sig: *mut Signature,
input64: *const c_uchar)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdsa_signature_parse_der_lax")]
pub fn ecdsa_signature_parse_der_lax(cx: *const Context, sig: *mut Signature,
input: *const c_uchar, in_len: size_t)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdsa_signature_serialize_der")]
pub fn secp256k1_ecdsa_signature_serialize_der(cx: *const Context, output: *mut c_uchar,
out_len: *mut size_t, sig: *const Signature)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdsa_signature_serialize_compact")]
pub fn secp256k1_ecdsa_signature_serialize_compact(cx: *const Context, output64: *mut c_uchar,
sig: *const Signature)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdsa_signature_normalize")]
pub fn secp256k1_ecdsa_signature_normalize(cx: *const Context, out_sig: *mut Signature,
in_sig: *const Signature)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdsa_verify")]
pub fn secp256k1_ecdsa_verify(cx: *const Context,
sig: *const Signature,
msg32: *const c_uchar,
pk: *const PublicKey)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdsa_sign")]
pub fn secp256k1_ecdsa_sign(cx: *const Context,
sig: *mut Signature,
msg32: *const c_uchar,
sk: *const c_uchar,
noncefn: NonceFn,
noncedata: *const c_void)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_seckey_verify")]
pub fn secp256k1_ec_seckey_verify(cx: *const Context,
sk: *const c_uchar) -> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_pubkey_create")]
pub fn secp256k1_ec_pubkey_create(cx: *const Context, pk: *mut PublicKey,
sk: *const c_uchar) -> c_int;
#[deprecated(since = "0.2.0",note = "Please use the secp256k1_ec_seckey_tweak_add function instead")]
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_privkey_negate")]
pub fn secp256k1_ec_privkey_negate(cx: *const Context,
sk: *mut c_uchar) -> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_privkey_negate")]
pub fn secp256k1_ec_seckey_negate(cx: *const Context,
sk: *mut c_uchar) -> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_pubkey_negate")]
pub fn secp256k1_ec_pubkey_negate(cx: *const Context,
pk: *mut PublicKey) -> c_int;
#[deprecated(since = "0.2.0",note = "Please use the secp256k1_ec_seckey_tweak_add function instead")]
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_privkey_tweak_add")]
pub fn secp256k1_ec_privkey_tweak_add(cx: *const Context,
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_seckey_tweak_add")]
pub fn secp256k1_ec_seckey_tweak_add(cx: *const Context,
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_pubkey_tweak_add")]
pub fn secp256k1_ec_pubkey_tweak_add(cx: *const Context,
pk: *mut PublicKey,
tweak: *const c_uchar)
-> c_int;
#[deprecated(since = "0.2.0",note = "Please use the secp256k1_ec_seckey_tweak_mul function instead")]
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_privkey_tweak_mul")]
pub fn secp256k1_ec_privkey_tweak_mul(cx: *const Context,
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_seckey_tweak_mul")]
pub fn secp256k1_ec_seckey_tweak_mul(cx: *const Context,
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_pubkey_tweak_mul")]
pub fn secp256k1_ec_pubkey_tweak_mul(cx: *const Context,
pk: *mut PublicKey,
tweak: *const c_uchar)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ec_pubkey_combine")]
pub fn secp256k1_ec_pubkey_combine(cx: *const Context,
out: *mut PublicKey,
ins: *const *const PublicKey,
n: c_int)
-> c_int;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdh")]
pub fn secp256k1_ecdh(
cx: *const Context,
output: *mut c_uchar,
pubkey: *const PublicKey,
seckey: *const c_uchar,
hashfp: EcdhHashFn,
data: *mut c_void,
) -> c_int;
}
#[no_mangle]
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
pub unsafe extern "C" fn rustsecp256k1_v0_2_0_context_create(flags: c_uint) -> *mut Context {
use std::mem;
assert!(mem::align_of::<usize>() >= mem::align_of::<u8>());
assert_eq!(mem::size_of::<usize>(), mem::size_of::<&usize>());
let word_size = mem::size_of::<usize>();
let n_words = (secp256k1_context_preallocated_size(flags) + word_size - 1) / word_size;
let buf = vec![0usize; n_words + 1].into_boxed_slice();
let ptr = Box::into_raw(buf) as *mut usize;
::core::ptr::write(ptr, n_words);
let ptr: *mut usize = ptr.offset(1);
secp256k1_context_preallocated_create(ptr as *mut c_void, flags)
}
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context {
rustsecp256k1_v0_2_0_context_create(flags)
}
#[no_mangle]
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
pub unsafe extern "C" fn rustsecp256k1_v0_2_0_context_destroy(ctx: *mut Context) {
secp256k1_context_preallocated_destroy(ctx);
let ctx: *mut usize = ctx as *mut usize;
let n_words_ptr: *mut usize = ctx.offset(-1);
let n_words: usize = ::core::ptr::read(n_words_ptr);
let slice: &mut [usize] = slice::from_raw_parts_mut(n_words_ptr , n_words+1);
let _ = Box::from_raw(slice as *mut [usize]);
}
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
pub unsafe fn secp256k1_context_destroy(ctx: *mut Context) {
rustsecp256k1_v0_2_0_context_destroy(ctx)
}
#[no_mangle]
#[cfg(not(feature = "external-symbols"))]
pub unsafe extern "C" fn rustsecp256k1_v0_2_0_default_illegal_callback_fn(message: *const c_char, _data: *mut c_void) {
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] illegal argument. {}", msg);
}
#[no_mangle]
#[cfg(not(feature = "external-symbols"))]
pub unsafe extern "C" fn rustsecp256k1_v0_2_0_default_error_callback_fn(message: *const c_char, _data: *mut c_void) {
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);
}
unsafe fn strlen(mut str_ptr: *const c_char) -> usize {
let mut ctr = 0;
while *str_ptr != '\0' as c_char {
ctr += 1;
str_ptr = str_ptr.offset(1);
}
ctr
}
pub trait CPtr {
type Target;
fn as_c_ptr(&self) -> *const Self::Target;
fn as_mut_c_ptr(&mut self) -> *mut Self::Target;
}
impl<T> CPtr for [T] {
type Target = T;
fn as_c_ptr(&self) -> *const Self::Target {
if self.is_empty() {
ptr::null()
} else {
self.as_ptr()
}
}
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
if self.is_empty() {
ptr::null::<Self::Target>() as *mut _
} else {
self.as_mut_ptr()
}
}
}
#[cfg(feature = "fuzztarget")]
mod fuzz_dummy {
extern crate std;
use self::std::{ptr, mem};
use self::std::boxed::Box;
use types::*;
use ::{Signature, Context, NonceFn, EcdhHashFn, PublicKey,
SECP256K1_START_NONE, SECP256K1_START_VERIFY, SECP256K1_START_SIGN,
SECP256K1_SER_COMPRESSED, SECP256K1_SER_UNCOMPRESSED};
#[allow(non_upper_case_globals)]
pub static secp256k1_context_no_precomp: &Context = &Context(0);
extern "C" {
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_ecdh_hash_function_default")]
pub static secp256k1_ecdh_hash_function_default: EcdhHashFn;
#[cfg_attr(not(feature = "external-symbols"), link_name = "rustsecp256k1_v0_2_0_nonce_function_rfc6979")]
pub static secp256k1_nonce_function_rfc6979: NonceFn;
}
pub unsafe fn secp256k1_context_preallocated_create(_ptr: *mut c_void, flags: c_uint) -> *mut Context {
let b = Box::new(Context(flags as i32));
Box::into_raw(b)
}
pub unsafe fn secp256k1_context_preallocated_size(_flags: c_uint) -> size_t {
mem::size_of::<Context>()
}
pub unsafe fn secp256k1_context_preallocated_clone_size(_cx: *mut Context) -> size_t {
mem::size_of::<Context>()
}
pub unsafe fn secp256k1_context_preallocated_clone(cx: *const Context, prealloc: *mut c_void) -> *mut Context {
let ret = prealloc as *mut Context;
*ret = (*cx).clone();
ret
}
pub unsafe fn secp256k1_context_preallocated_destroy(cx: *mut Context) {
(*cx).0 = 0;
}
pub unsafe fn secp256k1_context_randomize(cx: *mut Context,
_seed32: *const c_uchar)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
1
}
pub unsafe fn secp256k1_ec_pubkey_parse(cx: *const Context, pk: *mut PublicKey,
input: *const c_uchar, in_len: size_t)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
match in_len {
33 => {
if (*input.offset(1) > 0x7f && *input != 2) || (*input.offset(1) <= 0x7f && *input != 3) {
0
} else {
ptr::copy(input.offset(1), (*pk).0[0..32].as_mut_ptr(), 32);
ptr::copy(input.offset(1), (*pk).0[32..64].as_mut_ptr(), 32);
test_pk_validate(cx, pk)
}
},
65 => {
if *input != 4 && *input != 6 && *input != 7 {
0
} else {
ptr::copy(input.offset(1), (*pk).0.as_mut_ptr(), 64);
test_pk_validate(cx, pk)
}
},
_ => 0
}
}
pub unsafe fn secp256k1_ec_pubkey_serialize(cx: *const Context, output: *mut c_uchar,
out_len: *mut size_t, pk: *const PublicKey,
compressed: c_uint)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if test_pk_validate(cx, pk) != 1 { return 0; }
if compressed == SECP256K1_SER_COMPRESSED {
assert_eq!(*out_len, 33);
if (*pk).0[0] > 0x7f {
*output = 2;
} else {
*output = 3;
}
ptr::copy((*pk).0.as_ptr(), output.offset(1), 32);
} else if compressed == SECP256K1_SER_UNCOMPRESSED {
assert_eq!(*out_len, 65);
*output = 4;
ptr::copy((*pk).0.as_ptr(), output.offset(1), 64);
} else {
panic!("Bad flags");
}
1
}
pub unsafe fn secp256k1_ecdsa_signature_parse_der(_cx: *const Context, _sig: *mut Signature,
_input: *const c_uchar, _in_len: size_t)
-> c_int {
unimplemented!();
}
pub unsafe fn secp256k1_ecdsa_signature_parse_compact(cx: *const Context, sig: *mut Signature,
input64: *const c_uchar)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, input64.offset(32)) != 1 { return 0; }
ptr::copy(input64, (*sig).0[..].as_mut_ptr(), 64);
1
}
pub unsafe fn ecdsa_signature_parse_der_lax(_cx: *const Context, _sig: *mut Signature,
_input: *const c_uchar, _in_len: size_t)
-> c_int {
unimplemented!();
}
pub unsafe fn secp256k1_ecdsa_signature_serialize_der(cx: *const Context, output: *mut c_uchar,
out_len: *mut size_t, sig: *const Signature)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
let mut len_r = 33;
if *(*sig).0.as_ptr().offset(0) < 0x80 {
len_r -= 1;
}
let mut len_s = 33;
if *(*sig).0.as_ptr().offset(32) < 0x80 {
len_s -= 1;
}
assert!(*out_len >= (6 + len_s + len_r) as usize);
*output.offset(0) = 0x30;
*output.offset(1) = 4 + len_r + len_s;
*output.offset(2) = 0x02;
*output.offset(3) = len_r;
if len_r == 33 {
*output.offset(4) = 0;
ptr::copy((*sig).0[..].as_ptr(), output.offset(5), 32);
} else {
ptr::copy((*sig).0[..].as_ptr(), output.offset(4), 32);
}
*output.offset(4 + len_r as isize) = 0x02;
*output.offset(5 + len_r as isize) = len_s;
if len_s == 33 {
*output.offset(6 + len_r as isize) = 0;
ptr::copy((*sig).0[..].as_ptr().offset(32), output.offset(7 + len_r as isize), 32);
} else {
ptr::copy((*sig).0[..].as_ptr().offset(32), output.offset(6 + len_r as isize), 32);
}
1
}
pub unsafe fn secp256k1_ecdsa_signature_serialize_compact(cx: *const Context, output64: *mut c_uchar,
sig: *const Signature)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
ptr::copy((*sig).0[..].as_ptr(), output64, 64);
1
}
pub unsafe fn secp256k1_ecdsa_signature_normalize(_cx: *const Context, _out_sig: *mut Signature,
_in_sig: *const Signature)
-> c_int {
unimplemented!();
}
pub unsafe fn secp256k1_ecdsa_verify(cx: *const Context,
sig: *const Signature,
msg32: *const c_uchar,
pk: *const PublicKey)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
assert!((*cx).0 as u32 & SECP256K1_START_VERIFY == SECP256K1_START_VERIFY);
if test_pk_validate(cx, pk) != 1 { return 0; }
for i in 0..32 {
if (*sig).0[i] != *msg32.offset(i as isize) {
return 0;
}
}
if (*sig).0[32..64] != (*pk).0[0..32] {
0
} else {
1
}
}
pub unsafe fn secp256k1_ecdsa_sign(cx: *const Context,
sig: *mut Signature,
msg32: *const c_uchar,
sk: *const c_uchar,
_noncefn: NonceFn,
_noncedata: *const c_void)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
assert!((*cx).0 as u32 & SECP256K1_START_SIGN == SECP256K1_START_SIGN);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
ptr::copy(msg32, (*sig).0[0..32].as_mut_ptr(), 32);
ptr::copy(sk, (*sig).0[32..64].as_mut_ptr(), 32);
1
}
pub unsafe fn test_pk_validate(cx: *const Context,
pk: *const PublicKey) -> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if (*pk).0[0..32] != (*pk).0[32..64] || secp256k1_ec_seckey_verify(cx, (*pk).0[0..32].as_ptr()) == 0 {
0
} else {
1
}
}
pub unsafe fn secp256k1_ec_seckey_verify(cx: *const Context,
sk: *const c_uchar) -> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
let mut res = 0;
for i in 0..32 {
if *sk.offset(i as isize) != 0xff { res = 1 };
}
res
}
pub unsafe fn secp256k1_ec_pubkey_create(cx: *const Context, pk: *mut PublicKey,
sk: *const c_uchar) -> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
ptr::copy(sk, (*pk).0[0..32].as_mut_ptr(), 32);
ptr::copy(sk, (*pk).0[32..64].as_mut_ptr(), 32);
1
}
#[deprecated(since = "0.2.0",note = "Please use the secp256k1_ec_seckey_negate function instead")]
pub unsafe fn secp256k1_ec_privkey_negate(cx: *const Context,
sk: *mut c_uchar) -> c_int {
secp256k1_ec_seckey_negate(cx, sk)
}
pub unsafe fn secp256k1_ec_seckey_negate(cx: *const Context,
sk: *mut c_uchar) -> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
1
}
pub unsafe fn secp256k1_ec_pubkey_negate(cx: *const Context,
pk: *mut PublicKey) -> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if test_pk_validate(cx, pk) != 1 { return 0; }
1
}
pub unsafe fn secp256k1_ec_privkey_tweak_add(cx: *const Context,
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int {
secp256k1_ec_seckey_tweak_add(cx, sk, tweak)
}
pub unsafe fn secp256k1_ec_seckey_tweak_add(cx: *const Context,
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
ptr::copy(tweak.offset(16), sk.offset(16), 16);
*sk.offset(24) = 0x7f;
1
}
pub unsafe fn secp256k1_ec_pubkey_tweak_add(cx: *const Context,
pk: *mut PublicKey,
tweak: *const c_uchar)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if test_pk_validate(cx, pk) != 1 { return 0; }
ptr::copy(tweak.offset(16), (*pk).0[16..32].as_mut_ptr(), 16);
ptr::copy(tweak.offset(16), (*pk).0[16+32..64].as_mut_ptr(), 16);
(*pk).0[24] = 0x7f;
(*pk).0[24+32] = 0x7f;
1
}
pub unsafe fn secp256k1_ec_privkey_tweak_mul(cx: *const Context,
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int {
secp256k1_ec_seckey_tweak_mul(cx, sk, tweak)
}
pub unsafe fn secp256k1_ec_seckey_tweak_mul(cx: *const Context,
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
ptr::copy(tweak.offset(16), sk.offset(16), 16);
*sk.offset(24) = 0x00;
1
}
pub unsafe fn secp256k1_ec_pubkey_tweak_mul(cx: *const Context,
pk: *mut PublicKey,
tweak: *const c_uchar)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if test_pk_validate(cx, pk) != 1 { return 0; }
ptr::copy(tweak.offset(16), (*pk).0[16..32].as_mut_ptr(), 16);
ptr::copy(tweak.offset(16), (*pk).0[16+32..64].as_mut_ptr(), 16);
(*pk).0[24] = 0x00;
(*pk).0[24+32] = 0x00;
1
}
pub unsafe fn secp256k1_ec_pubkey_combine(cx: *const Context,
out: *mut PublicKey,
ins: *const *const PublicKey,
n: c_int)
-> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
assert!(n <= 32 && n >= 0);
for i in 0..n {
if test_pk_validate(cx, *ins.offset(i as isize)) != 1 { return 0; }
(*out).0[(i*32/n) as usize..((i+1)*32/n) as usize].copy_from_slice(&(**ins.offset(i as isize)).0[(i*32/n) as usize..((i+1)*32/n) as usize]);
}
ptr::copy((*out).0[0..32].as_ptr(), (*out).0[32..64].as_mut_ptr(), 32);
(*out).0[24] = 0x7f;
(*out).0[24+32] = 0x7f;
test_pk_validate(cx, out)
}
pub unsafe fn secp256k1_ecdh(
cx: *const Context,
out: *mut c_uchar,
point: *const PublicKey,
scalar: *const c_uchar,
_hashfp: EcdhHashFn,
_data: *mut c_void,
) -> c_int {
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, scalar) != 1 { return 0; }
let mut scalar_prefix = [0; 16];
ptr::copy(scalar, scalar_prefix[..].as_mut_ptr(), 16);
if (*point).0[0..16] > scalar_prefix[0..16] {
ptr::copy((*point).as_ptr(), out, 16);
ptr::copy(scalar, out.offset(16), 16);
} else {
ptr::copy(scalar, out, 16);
ptr::copy((*point).as_ptr(), out.offset(16), 16);
}
(*out.offset(16)) = 0x00;
1
}
}
#[cfg(feature = "fuzztarget")]
pub use self::fuzz_dummy::*;
#[cfg(test)]
mod tests {
use std::ffi::CString;
use super::strlen;
#[test]
fn test_strlen() {
let orig = "test strlen \t \n";
let test = CString::new(orig).unwrap();
assert_eq!(orig.len(), unsafe {strlen(test.as_ptr())});
}
}