make `ffi::Type::new` functions all unsafe, expand documentation
This commit is contained in:
parent
be9a78f39e
commit
12b0abbcf8
|
@ -106,13 +106,32 @@ impl_array_newtype!(PublicKey, c_uchar, 64);
|
|||
impl_raw_debug!(PublicKey);
|
||||
|
||||
impl PublicKey {
|
||||
/// Create a new (zeroed) public key usable for the FFI interface
|
||||
pub fn new() -> PublicKey { PublicKey([0; 64]) }
|
||||
/// Creates an "uninitialized" FFI public key which is zeroed out
|
||||
///
|
||||
/// If you pass this to any FFI functions, except as an out-pointer,
|
||||
/// the result is likely to be an assertation failure and process
|
||||
/// termination.
|
||||
pub unsafe fn new() -> Self {
|
||||
Self::from_array_unchecked([0; 64])
|
||||
}
|
||||
|
||||
impl Default for PublicKey {
|
||||
fn default() -> Self {
|
||||
PublicKey::new()
|
||||
/// Create a new public key usable for the FFI interface from raw bytes
|
||||
///
|
||||
/// Does not check the validity of the underlying representation. If it is
|
||||
/// invalid the result may be assertation failures (and process aborts) from
|
||||
/// the underlying library. You should not use this method except with data
|
||||
/// that you obtained from the FFI interface of the same version of this
|
||||
/// library.
|
||||
pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self {
|
||||
PublicKey(data)
|
||||
}
|
||||
|
||||
/// Returns the underlying FFI opaque representation of the public key
|
||||
///
|
||||
/// You should not use this unless you really know what you are doing. It is
|
||||
/// essentially only useful for extending the FFI interface itself.
|
||||
pub fn underlying_bytes(self) -> [c_uchar; 64] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,13 +148,32 @@ impl_array_newtype!(Signature, c_uchar, 64);
|
|||
impl_raw_debug!(Signature);
|
||||
|
||||
impl Signature {
|
||||
/// Create a new (zeroed) signature usable for the FFI interface
|
||||
pub fn new() -> Signature { Signature([0; 64]) }
|
||||
/// Creates an "uninitialized" FFI signature which is zeroed out
|
||||
///
|
||||
/// If you pass this to any FFI functions, except as an out-pointer,
|
||||
/// the result is likely to be an assertation failure and process
|
||||
/// termination.
|
||||
pub unsafe fn new() -> Self {
|
||||
Self::from_array_unchecked([0; 64])
|
||||
}
|
||||
|
||||
impl Default for Signature {
|
||||
fn default() -> Self {
|
||||
Signature::new()
|
||||
/// Create a new signature usable for the FFI interface from raw bytes
|
||||
///
|
||||
/// Does not check the validity of the underlying representation. If it is
|
||||
/// invalid the result may be assertation failures (and process aborts) from
|
||||
/// the underlying library. You should not use this method except with data
|
||||
/// that you obtained from the FFI interface of the same version of this
|
||||
/// library.
|
||||
pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self {
|
||||
Signature(data)
|
||||
}
|
||||
|
||||
/// Returns the underlying FFI opaque representation of the signature
|
||||
///
|
||||
/// You should not use this unless you really know what you are doing. It is
|
||||
/// essentially only useful for extending the FFI interface itself.
|
||||
pub fn underlying_bytes(self) -> [c_uchar; 64] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,11 +183,33 @@ impl_array_newtype!(XOnlyPublicKey, c_uchar, 64);
|
|||
impl_raw_debug!(XOnlyPublicKey);
|
||||
|
||||
impl XOnlyPublicKey {
|
||||
/// Create a new (zeroed) x-only public key usable for the FFI interface
|
||||
pub fn new() -> XOnlyPublicKey { XOnlyPublicKey([0; 64]) }
|
||||
pub fn from_array(data: [c_uchar; 64]) -> XOnlyPublicKey {
|
||||
/// Creates an "uninitialized" FFI x-only public key which is zeroed out
|
||||
///
|
||||
/// If you pass this to any FFI functions, except as an out-pointer,
|
||||
/// the result is likely to be an assertation failure and process
|
||||
/// termination.
|
||||
pub unsafe fn new() -> Self {
|
||||
Self::from_array_unchecked([0; 64])
|
||||
}
|
||||
|
||||
/// Create a new x-only public key usable for the FFI interface from raw bytes
|
||||
///
|
||||
/// Does not check the validity of the underlying representation. If it is
|
||||
/// invalid the result may be assertation failures (and process aborts) from
|
||||
/// the underlying library. You should not use this method except with data
|
||||
/// that you obtained from the FFI interface of the same version of this
|
||||
/// library.
|
||||
pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self {
|
||||
XOnlyPublicKey(data)
|
||||
}
|
||||
|
||||
/// Returns the underlying FFI opaque representation of the x-only public key
|
||||
///
|
||||
/// You should not use this unless you really know what you are doing. It is
|
||||
/// essentially only useful for extending the FFI interface itself.
|
||||
pub fn underlying_bytes(self) -> [c_uchar; 64] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl hash::Hash for XOnlyPublicKey {
|
||||
|
@ -158,23 +218,39 @@ impl hash::Hash for XOnlyPublicKey {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for XOnlyPublicKey {
|
||||
fn default() -> Self {
|
||||
XOnlyPublicKey::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct KeyPair([c_uchar; 96]);
|
||||
impl_array_newtype!(KeyPair, c_uchar, 96);
|
||||
impl_raw_debug!(KeyPair);
|
||||
|
||||
impl KeyPair {
|
||||
/// Create a new (zeroed) key pair usable for the FFI interface
|
||||
pub fn new() -> KeyPair { KeyPair([0; 96]) }
|
||||
pub fn from_array(data: [c_uchar; 96]) -> KeyPair {
|
||||
/// Creates an "uninitialized" FFI keypair which is zeroed out
|
||||
///
|
||||
/// If you pass this to any FFI functions, except as an out-pointer,
|
||||
/// the result is likely to be an assertation failure and process
|
||||
/// termination.
|
||||
pub unsafe fn new() -> Self {
|
||||
Self::from_array_unchecked([0; 96])
|
||||
}
|
||||
|
||||
/// Create a new keypair usable for the FFI interface from raw bytes
|
||||
///
|
||||
/// Does not check the validity of the underlying representation. If it is
|
||||
/// invalid the result may be assertation failures (and process aborts) from
|
||||
/// the underlying library. You should not use this method except with data
|
||||
/// that you obtained from the FFI interface of the same version of this
|
||||
/// library.
|
||||
pub unsafe fn from_array_unchecked(data: [c_uchar; 96]) -> Self {
|
||||
KeyPair(data)
|
||||
}
|
||||
|
||||
/// Returns the underlying FFI opaque representation of the x-only public key
|
||||
///
|
||||
/// You should not use this unless you really know what you are doing. It is
|
||||
/// essentially only useful for extending the FFI interface itself.
|
||||
pub fn underlying_bytes(self) -> [c_uchar; 96] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl hash::Hash for KeyPair {
|
||||
|
@ -183,12 +259,6 @@ impl hash::Hash for KeyPair {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for KeyPair {
|
||||
fn default() -> Self {
|
||||
KeyPair::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "fuzztarget"))]
|
||||
extern "C" {
|
||||
/// Default ECDH hash function
|
||||
|
|
|
@ -233,23 +233,23 @@ impl PublicKey {
|
|||
pub fn from_secret_key<C: Signing>(secp: &Secp256k1<C>,
|
||||
sk: &SecretKey)
|
||||
-> PublicKey {
|
||||
let mut pk = ffi::PublicKey::new();
|
||||
unsafe {
|
||||
let mut pk = ffi::PublicKey::new();
|
||||
// We can assume the return value because it's not possible to construct
|
||||
// an invalid `SecretKey` without transmute trickery or something
|
||||
let res = ffi::secp256k1_ec_pubkey_create(secp.ctx, &mut pk, sk.as_c_ptr());
|
||||
debug_assert_eq!(res, 1);
|
||||
}
|
||||
PublicKey(pk)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a public key directly from a slice
|
||||
#[inline]
|
||||
pub fn from_slice(data: &[u8]) -> Result<PublicKey, Error> {
|
||||
if data.is_empty() {return Err(Error::InvalidPublicKey);}
|
||||
|
||||
let mut pk = ffi::PublicKey::new();
|
||||
unsafe {
|
||||
let mut pk = ffi::PublicKey::new();
|
||||
if ffi::secp256k1_ec_pubkey_parse(
|
||||
ffi::secp256k1_context_no_precomp,
|
||||
&mut pk,
|
||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -269,9 +269,8 @@ impl Signature {
|
|||
pub fn from_der(data: &[u8]) -> Result<Signature, Error> {
|
||||
if data.is_empty() {return Err(Error::InvalidSignature);}
|
||||
|
||||
let mut ret = ffi::Signature::new();
|
||||
|
||||
unsafe {
|
||||
let mut ret = ffi::Signature::new();
|
||||
if ffi::secp256k1_ecdsa_signature_parse_der(
|
||||
ffi::secp256k1_context_no_precomp,
|
||||
&mut ret,
|
||||
|
@ -288,12 +287,12 @@ impl Signature {
|
|||
|
||||
/// Converts a 64-byte compact-encoded byte slice to a signature
|
||||
pub fn from_compact(data: &[u8]) -> Result<Signature, Error> {
|
||||
let mut ret = ffi::Signature::new();
|
||||
if data.len() != 64 {
|
||||
return Err(Error::InvalidSignature)
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mut ret = ffi::Signature::new();
|
||||
if ffi::secp256k1_ecdsa_signature_parse_compact(
|
||||
ffi::secp256k1_context_no_precomp,
|
||||
&mut ret,
|
||||
|
@ -661,17 +660,16 @@ impl<C: Signing> Secp256k1<C> {
|
|||
pub fn sign(&self, msg: &Message, sk: &key::SecretKey)
|
||||
-> Signature {
|
||||
|
||||
let mut ret = ffi::Signature::new();
|
||||
unsafe {
|
||||
let mut ret = ffi::Signature::new();
|
||||
// We can assume the return value because it's not possible to construct
|
||||
// an invalid signature from a valid `Message` and `SecretKey`
|
||||
assert_eq!(ffi::secp256k1_ecdsa_sign(self.ctx, &mut ret, msg.as_c_ptr(),
|
||||
sk.as_c_ptr(), ffi::secp256k1_nonce_function_rfc6979,
|
||||
ptr::null()), 1);
|
||||
}
|
||||
|
||||
Signature::from(ret)
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates a random keypair. Convenience function for `key::SecretKey::new`
|
||||
/// and `key::PublicKey::from_secret_key`; call those functions directly for
|
||||
|
|
|
@ -112,18 +112,18 @@ impl RecoverableSignature {
|
|||
/// for verification
|
||||
#[inline]
|
||||
pub fn to_standard(&self) -> Signature {
|
||||
let mut ret = super_ffi::Signature::new();
|
||||
unsafe {
|
||||
let mut ret = super_ffi::Signature::new();
|
||||
let err = ffi::secp256k1_ecdsa_recoverable_signature_convert(
|
||||
super_ffi::secp256k1_context_no_precomp,
|
||||
&mut ret,
|
||||
self.as_c_ptr(),
|
||||
);
|
||||
assert!(err == 1);
|
||||
}
|
||||
Signature(ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl CPtr for RecoverableSignature {
|
||||
|
@ -178,17 +178,16 @@ impl<C: Verification> Secp256k1<C> {
|
|||
pub fn recover(&self, msg: &Message, sig: &RecoverableSignature)
|
||||
-> Result<key::PublicKey, Error> {
|
||||
|
||||
let mut pk = super_ffi::PublicKey::new();
|
||||
|
||||
unsafe {
|
||||
let mut pk = super_ffi::PublicKey::new();
|
||||
if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk,
|
||||
sig.as_c_ptr(), msg.as_c_ptr()) != 1 {
|
||||
return Err(Error::InvalidSignature);
|
||||
}
|
||||
};
|
||||
Ok(key::PublicKey::from(pk))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -123,8 +123,8 @@ impl KeyPair {
|
|||
return Err(InvalidPublicKey);
|
||||
}
|
||||
|
||||
let mut kp = ffi::KeyPair::new();
|
||||
unsafe {
|
||||
let mut kp = ffi::KeyPair::new();
|
||||
if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, data.as_c_ptr()) == 1 {
|
||||
Ok(KeyPair(kp))
|
||||
} else {
|
||||
|
@ -155,14 +155,14 @@ impl KeyPair {
|
|||
ret
|
||||
};
|
||||
let mut data = random_32_bytes();
|
||||
let mut keypair = ffi::KeyPair::new();
|
||||
unsafe {
|
||||
let mut keypair = ffi::KeyPair::new();
|
||||
while ffi::secp256k1_keypair_create(secp.ctx, &mut keypair, data.as_c_ptr()) == 0 {
|
||||
data = random_32_bytes();
|
||||
}
|
||||
}
|
||||
KeyPair(keypair)
|
||||
}
|
||||
}
|
||||
|
||||
/// Tweak a keypair by adding the given tweak to the secret key and updating the
|
||||
/// public key accordingly.
|
||||
|
@ -210,9 +210,9 @@ impl PublicKey {
|
|||
/// Creates a new Schnorr public key from a Schnorr key pair
|
||||
#[inline]
|
||||
pub fn from_keypair<C: Signing>(secp: &Secp256k1<C>, keypair: &KeyPair) -> PublicKey {
|
||||
let mut xonly_pk = ffi::XOnlyPublicKey::new();
|
||||
let mut pk_parity = 0;
|
||||
unsafe {
|
||||
let mut xonly_pk = ffi::XOnlyPublicKey::new();
|
||||
let ret = ffi::secp256k1_keypair_xonly_pub(
|
||||
secp.ctx,
|
||||
&mut xonly_pk,
|
||||
|
@ -220,9 +220,9 @@ impl PublicKey {
|
|||
keypair.as_ptr(),
|
||||
);
|
||||
debug_assert_eq!(ret, 1);
|
||||
}
|
||||
PublicKey(xonly_pk)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a Schnorr public key directly from a slice
|
||||
#[inline]
|
||||
|
@ -231,8 +231,8 @@ impl PublicKey {
|
|||
return Err(InvalidPublicKey);
|
||||
}
|
||||
|
||||
let mut pk = ffi::XOnlyPublicKey::new();
|
||||
unsafe {
|
||||
let mut pk = ffi::XOnlyPublicKey::new();
|
||||
if ffi::secp256k1_xonly_pubkey_parse(
|
||||
ffi::secp256k1_context_no_precomp,
|
||||
&mut pk,
|
||||
|
@ -326,9 +326,8 @@ impl From<ffi::XOnlyPublicKey> for PublicKey {
|
|||
|
||||
impl From<::key::PublicKey> for PublicKey {
|
||||
fn from(src: ::key::PublicKey) -> PublicKey {
|
||||
let mut pk = ffi::XOnlyPublicKey::new();
|
||||
|
||||
unsafe {
|
||||
let mut pk = ffi::XOnlyPublicKey::new();
|
||||
assert_eq!(
|
||||
1,
|
||||
ffi::secp256k1_xonly_pubkey_from_pubkey(
|
||||
|
@ -338,11 +337,10 @@ impl From<::key::PublicKey> for PublicKey {
|
|||
src.as_c_ptr(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
PublicKey(pk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serde_impl_from_slice!(PublicKey);
|
||||
|
||||
|
|
Loading…
Reference in New Issue