Move recovery ffi into recovery module and feature gate C-secp recovery module
This commit is contained in:
parent
c7eecd159e
commit
16da1a854c
6
build.rs
6
build.rs
|
@ -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" {
|
||||||
|
|
94
src/ffi.rs
94
src/ffi.rs
|
@ -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,
|
||||||
|
|
|
@ -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!();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
Loading…
Reference in New Issue