Move recovery ffi into recovery module and feature gate C-secp recovery module

This commit is contained in:
Jonas Nick 2019-05-21 07:37:15 +00:00
parent c7eecd159e
commit 16da1a854c
4 changed files with 131 additions and 105 deletions

View File

@ -53,8 +53,10 @@ fn main() {
.define("USE_FIELD_INV_BUILTIN", Some("1")) .define("USE_FIELD_INV_BUILTIN", Some("1"))
.define("USE_SCALAR_INV_BUILTIN", Some("1")) .define("USE_SCALAR_INV_BUILTIN", Some("1"))
.define("USE_ENDOMORPHISM", Some("1")) .define("USE_ENDOMORPHISM", Some("1"))
.define("ENABLE_MODULE_ECDH", Some("1")) .define("ENABLE_MODULE_ECDH", Some("1"));
.define("ENABLE_MODULE_RECOVERY", Some("1"));
#[cfg(feature = "recovery")]
base_config.define("ENABLE_MODULE_RECOVERY", Some("1"));
if let Ok(target_endian) = env::var("CARGO_CFG_TARGET_ENDIAN") { if let Ok(target_endian) = env::var("CARGO_CFG_TARGET_ENDIAN") {
if target_endian == "big" { if target_endian == "big" {

View File

@ -18,8 +18,6 @@
//! not be needed for most users. //! not be needed for most users.
use core::{mem, hash}; use core::{mem, hash};
use types::*; use types::*;
// use std::os::raw::{c_int, c_uchar, c_uint, c_void};
/// Flag for context to enable no precomputation /// Flag for context to enable no precomputation
pub const SECP256K1_START_NONE: c_uint = 1; pub const SECP256K1_START_NONE: c_uint = 1;
@ -93,12 +91,6 @@ pub struct Signature([c_uchar; 64]);
impl_array_newtype!(Signature, c_uchar, 64); impl_array_newtype!(Signature, c_uchar, 64);
impl_raw_debug!(Signature); impl_raw_debug!(Signature);
/// Library-internal representation of a Secp256k1 signature + recovery ID
#[repr(C)]
pub struct RecoverableSignature([c_uchar; 65]);
impl_array_newtype!(RecoverableSignature, c_uchar, 65);
impl_raw_debug!(RecoverableSignature);
impl Signature { impl Signature {
/// Create a new (zeroed) signature usable for the FFI interface /// Create a new (zeroed) signature usable for the FFI interface
pub fn new() -> Signature { Signature([0; 64]) } pub fn new() -> Signature { Signature([0; 64]) }
@ -112,19 +104,6 @@ impl Default for Signature {
} }
} }
impl RecoverableSignature {
/// Create a new (zeroed) signature usable for the FFI interface
pub fn new() -> RecoverableSignature { RecoverableSignature([0; 65]) }
/// Create a new (uninitialized) signature usable for the FFI interface
pub unsafe fn blank() -> RecoverableSignature { mem::uninitialized() }
}
impl Default for RecoverableSignature {
fn default() -> Self {
RecoverableSignature::new()
}
}
/// Library-internal representation of an ECDH shared secret /// Library-internal representation of an ECDH shared secret
#[repr(C)] #[repr(C)]
pub struct SharedSecret([c_uchar; 32]); pub struct SharedSecret([c_uchar; 32]);
@ -204,18 +183,6 @@ extern "C" {
sig: *const Signature) sig: *const Signature)
-> c_int; -> c_int;
pub fn secp256k1_ecdsa_recoverable_signature_parse_compact(cx: *const Context, sig: *mut RecoverableSignature,
input64: *const c_uchar, recid: c_int)
-> c_int;
pub fn secp256k1_ecdsa_recoverable_signature_serialize_compact(cx: *const Context, output64: *const c_uchar,
recid: *mut c_int, sig: *const RecoverableSignature)
-> c_int;
pub fn secp256k1_ecdsa_recoverable_signature_convert(cx: *const Context, sig: *mut Signature,
input: *const RecoverableSignature)
-> c_int;
pub fn secp256k1_ecdsa_signature_normalize(cx: *const Context, out_sig: *mut Signature, pub fn secp256k1_ecdsa_signature_normalize(cx: *const Context, out_sig: *mut Signature,
in_sig: *const Signature) in_sig: *const Signature)
-> c_int; -> c_int;
@ -235,20 +202,6 @@ extern "C" {
noncedata: *const c_void) noncedata: *const c_void)
-> c_int; -> c_int;
pub fn secp256k1_ecdsa_sign_recoverable(cx: *const Context,
sig: *mut RecoverableSignature,
msg32: *const c_uchar,
sk: *const c_uchar,
noncefn: NonceFn,
noncedata: *const c_void)
-> c_int;
pub fn secp256k1_ecdsa_recover(cx: *const Context,
pk: *mut PublicKey,
sig: *const RecoverableSignature,
msg32: *const c_uchar)
-> c_int;
// EC // EC
pub fn secp256k1_ec_seckey_verify(cx: *const Context, pub fn secp256k1_ec_seckey_verify(cx: *const Context,
sk: *const c_uchar) -> c_int; sk: *const c_uchar) -> c_int;
@ -463,24 +416,6 @@ mod fuzz_dummy {
1 1
} }
pub unsafe fn secp256k1_ecdsa_recoverable_signature_parse_compact(_cx: *const Context, _sig: *mut RecoverableSignature,
_input64: *const c_uchar, _recid: c_int)
-> c_int {
unimplemented!();
}
pub unsafe fn secp256k1_ecdsa_recoverable_signature_serialize_compact(_cx: *const Context, _output64: *const c_uchar,
_recid: *mut c_int, _sig: *const RecoverableSignature)
-> c_int {
unimplemented!();
}
pub unsafe fn secp256k1_ecdsa_recoverable_signature_convert(_cx: *const Context, _sig: *mut Signature,
_input: *const RecoverableSignature)
-> c_int {
unimplemented!();
}
pub unsafe fn secp256k1_ecdsa_signature_normalize(_cx: *const Context, _out_sig: *mut Signature, pub unsafe fn secp256k1_ecdsa_signature_normalize(_cx: *const Context, _out_sig: *mut Signature,
_in_sig: *const Signature) _in_sig: *const Signature)
-> c_int { -> c_int {
@ -525,35 +460,6 @@ mod fuzz_dummy {
1 1
} }
/// Sets sig to (2|3)||msg32||sk
pub unsafe fn secp256k1_ecdsa_sign_recoverable(cx: *const Context,
sig: *mut RecoverableSignature,
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; }
if *sk.offset(0) > 0x7f {
(*sig).0[0] = 2;
} else {
(*sig).0[0] = 3;
}
ptr::copy(msg32, (*sig).0[1..33].as_mut_ptr(), 32);
ptr::copy(sk, (*sig).0[33..65].as_mut_ptr(), 32);
1
}
pub unsafe fn secp256k1_ecdsa_recover(_cx: *const Context,
_pk: *mut PublicKey,
_sig: *const RecoverableSignature,
_msg32: *const c_uchar)
-> c_int {
unimplemented!();
}
// EC // EC
/// Checks that pk != 0xffff...ffff and pk[0..32] == pk[32..64] /// Checks that pk != 0xffff...ffff and pk[0..32] == pk[32..64]
pub unsafe fn test_pk_validate(cx: *const Context, pub unsafe fn test_pk_validate(cx: *const Context,

118
src/recovery/ffi.rs Normal file
View File

@ -0,0 +1,118 @@
// Bitcoin secp256k1 bindings
// Written in 2014 by
// Dawid Ciężarkiewicz
// Andrew Poelstra
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//
//! # FFI of the recovery module
use core::mem;
use types::*;
use ffi::{Context, NonceFn, PublicKey, Signature};
/// Library-internal representation of a Secp256k1 signature + recovery ID
#[repr(C)]
pub struct RecoverableSignature([c_uchar; 65]);
impl_array_newtype!(RecoverableSignature, c_uchar, 65);
impl_raw_debug!(RecoverableSignature);
impl RecoverableSignature {
/// Create a new (zeroed) signature usable for the FFI interface
pub fn new() -> RecoverableSignature { RecoverableSignature([0; 65]) }
/// Create a new (uninitialized) signature usable for the FFI interface
pub unsafe fn blank() -> RecoverableSignature { mem::uninitialized() }
}
impl Default for RecoverableSignature {
fn default() -> Self {
RecoverableSignature::new()
}
}
#[cfg(not(feature = "fuzztarget"))]
extern "C" {
pub fn secp256k1_ecdsa_recoverable_signature_parse_compact(cx: *const Context, sig: *mut RecoverableSignature,
input64: *const c_uchar, recid: c_int)
-> c_int;
pub fn secp256k1_ecdsa_recoverable_signature_serialize_compact(cx: *const Context, output64: *const c_uchar,
recid: *mut c_int, sig: *const RecoverableSignature)
-> c_int;
pub fn secp256k1_ecdsa_recoverable_signature_convert(cx: *const Context, sig: *mut Signature,
input: *const RecoverableSignature)
-> c_int;
pub fn secp256k1_ecdsa_sign_recoverable(cx: *const Context,
sig: *mut RecoverableSignature,
msg32: *const c_uchar,
sk: *const c_uchar,
noncefn: NonceFn,
noncedata: *const c_void)
-> c_int;
pub fn secp256k1_ecdsa_recover(cx: *const Context,
pk: *mut PublicKey,
sig: *const RecoverableSignature,
msg32: *const c_uchar)
-> c_int;
}
#[cfg(feature = "fuzztarget")]
mod fuzz_dummy {
pub unsafe fn secp256k1_ecdsa_recoverable_signature_parse_compact(_cx: *const Context, _sig: *mut RecoverableSignature,
_input64: *const c_uchar, _recid: c_int)
-> c_int {
unimplemented!();
}
pub unsafe fn secp256k1_ecdsa_recoverable_signature_serialize_compact(_cx: *const Context, _output64: *const c_uchar,
_recid: *mut c_int, _sig: *const RecoverableSignature)
-> c_int {
unimplemented!();
}
pub unsafe fn secp256k1_ecdsa_recoverable_signature_convert(_cx: *const Context, _sig: *mut Signature,
_input: *const RecoverableSignature)
-> c_int {
unimplemented!();
}
/// Sets sig to (2|3)||msg32||sk
pub unsafe fn secp256k1_ecdsa_sign_recoverable(cx: *const Context,
sig: *mut RecoverableSignature,
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; }
if *sk.offset(0) > 0x7f {
(*sig).0[0] = 2;
} else {
(*sig).0[0] = 3;
}
ptr::copy(msg32, (*sig).0[1..33].as_mut_ptr(), 32);
ptr::copy(sk, (*sig).0[33..65].as_mut_ptr(), 32);
1
}
pub unsafe fn secp256k1_ecdsa_recover(_cx: *const Context,
_pk: *mut PublicKey,
_sig: *const RecoverableSignature,
_msg32: *const c_uchar)
-> c_int {
unimplemented!();
}
}

View File

@ -1,4 +1,3 @@
// TODO header
// Bitcoin secp256k1 bindings // Bitcoin secp256k1 bindings
// Written in 2014 by // Written in 2014 by
// Dawid Ciężarkiewicz // Dawid Ciężarkiewicz
@ -19,12 +18,14 @@
//! signature. //! signature.
use core::ptr; use core::ptr;
use ffi;
use key; use key;
use super::{Secp256k1, Message, Error, Signature, Verification, Signing}; use super::{Secp256k1, Message, Error, Signature, Verification, Signing};
use super::ffi as super_ffi;
pub use key::SecretKey; pub use key::SecretKey;
pub use key::PublicKey; pub use key::PublicKey;
mod ffi;
/// A tag used for recovering the public key from a compact signature /// A tag used for recovering the public key from a compact signature
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct RecoveryId(i32); pub struct RecoveryId(i32);
@ -36,7 +37,6 @@ pub struct RecoverableSignature(ffi::RecoverableSignature);
impl RecoveryId { impl RecoveryId {
#[inline] #[inline]
/// Allows library users to create valid recovery IDs from i32. /// Allows library users to create valid recovery IDs from i32.
/// TODO
pub fn from_i32(id: i32) -> Result<RecoveryId, Error> { pub fn from_i32(id: i32) -> Result<RecoveryId, Error> {
match id { match id {
0 | 1 | 2 | 3 => Ok(RecoveryId(id)), 0 | 1 | 2 | 3 => Ok(RecoveryId(id)),
@ -63,7 +63,7 @@ impl RecoverableSignature {
if data.len() != 64 { if data.len() != 64 {
Err(Error::InvalidSignature) Err(Error::InvalidSignature)
} else if ffi::secp256k1_ecdsa_recoverable_signature_parse_compact( } else if ffi::secp256k1_ecdsa_recoverable_signature_parse_compact(
ffi::secp256k1_context_no_precomp, super_ffi::secp256k1_context_no_precomp,
&mut ret, &mut ret,
data.as_ptr(), data.as_ptr(),
recid.0, recid.0,
@ -89,7 +89,7 @@ impl RecoverableSignature {
let mut recid = 0i32; let mut recid = 0i32;
unsafe { unsafe {
let err = ffi::secp256k1_ecdsa_recoverable_signature_serialize_compact( let err = ffi::secp256k1_ecdsa_recoverable_signature_serialize_compact(
ffi::secp256k1_context_no_precomp, super_ffi::secp256k1_context_no_precomp,
ret.as_mut_ptr(), ret.as_mut_ptr(),
&mut recid, &mut recid,
self.as_ptr(), self.as_ptr(),
@ -103,10 +103,10 @@ impl RecoverableSignature {
/// for verification /// for verification
#[inline] #[inline]
pub fn to_standard(&self) -> Signature { pub fn to_standard(&self) -> Signature {
let mut ret = unsafe { ffi::Signature::blank() }; let mut ret = unsafe { super_ffi::Signature::blank() };
unsafe { unsafe {
let err = ffi::secp256k1_ecdsa_recoverable_signature_convert( let err = ffi::secp256k1_ecdsa_recoverable_signature_convert(
ffi::secp256k1_context_no_precomp, super_ffi::secp256k1_context_no_precomp,
&mut ret, &mut ret,
self.as_ptr(), self.as_ptr(),
); );
@ -140,7 +140,7 @@ impl<C: Signing> Secp256k1<C> {
&mut ret, &mut ret,
msg.as_ptr(), msg.as_ptr(),
sk.as_ptr(), sk.as_ptr(),
ffi::secp256k1_nonce_function_rfc6979, super_ffi::secp256k1_nonce_function_rfc6979,
ptr::null() ptr::null()
), ),
1 1
@ -157,7 +157,7 @@ impl<C: Verification> Secp256k1<C> {
pub fn recover(&self, msg: &Message, sig: &RecoverableSignature) pub fn recover(&self, msg: &Message, sig: &RecoverableSignature)
-> Result<key::PublicKey, Error> { -> Result<key::PublicKey, Error> {
let mut pk = unsafe { ffi::PublicKey::blank() }; let mut pk = unsafe { super_ffi::PublicKey::blank() };
unsafe { unsafe {
if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk, if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk,