Skip to content

Commit 68c7385

Browse files
committed
Minimise FFI in the public API
Normal users should never need to directly interact with the FFI layer. Audit and reduce the use of `ffi` types in the public API of various types. Leave only the implementation of `CPtr`, and document this clearly as not required by normal users. Done for: - PublicKey - XOnlyPublicKey - KeyPair - ecdsa::Signature - ecdsa::RecoverableSignature
1 parent 497654e commit 68c7385

File tree

6 files changed

+59
-29
lines changed

6 files changed

+59
-29
lines changed

secp256k1-sys/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -711,10 +711,12 @@ unsafe fn strlen(mut str_ptr: *const c_char) -> usize {
711711
}
712712

713713

714-
/// A trait for producing pointers that will always be valid in C. (assuming NULL pointer is a valid no-op)
715-
/// Rust doesn't promise what pointers does it give to ZST (<https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts>)
716-
/// In case the type is empty this trait will give a NULL pointer, which should be handled in C.
714+
/// A trait for producing pointers that will always be valid in C (assuming NULL pointer is a valid
715+
/// no-op).
717716
///
717+
/// Rust does not guarantee pointers to Zero Sized Types
718+
/// (<https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts>). In case the type
719+
/// is empty this trait will return a NULL pointer, which should be handled in C.
718720
pub trait CPtr {
719721
type Target;
720722
fn as_c_ptr(&self) -> *const Self::Target;

src/ecdh.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ pub fn shared_secret_point(point: &PublicKey, scalar: &SecretKey) -> [u8; 64] {
150150
ffi::secp256k1_ecdh(
151151
ffi::secp256k1_context_no_precomp,
152152
xy.as_mut_ptr(),
153-
point.as_ptr(),
153+
point.as_c_ptr(),
154154
scalar.as_ptr(),
155155
Some(c_callback),
156156
ptr::null_mut(),

src/ecdsa/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,16 @@ impl Signature {
144144

145145
/// Obtains a raw pointer suitable for use with FFI functions
146146
#[inline]
147+
#[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
147148
pub fn as_ptr(&self) -> *const ffi::Signature {
148-
&self.0
149+
self.as_c_ptr()
149150
}
150151

151152
/// Obtains a raw mutable pointer suitable for use with FFI functions
152153
#[inline]
154+
#[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")]
153155
pub fn as_mut_ptr(&mut self) -> *mut ffi::Signature {
154-
&mut self.0
156+
self.as_mut_c_ptr()
155157
}
156158

157159
#[inline]
@@ -199,11 +201,11 @@ impl CPtr for Signature {
199201
type Target = ffi::Signature;
200202

201203
fn as_c_ptr(&self) -> *const Self::Target {
202-
self.as_ptr()
204+
&self.0
203205
}
204206

205207
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
206-
self.as_mut_ptr()
208+
&mut self.0
207209
}
208210
}
209211

@@ -315,7 +317,7 @@ impl<C: Signing> Secp256k1<C> {
315317

316318
counter += 1;
317319
extra_entropy[..4].copy_from_slice(&counter.to_le_bytes());
318-
entropy_p = extra_entropy.as_ptr().cast::<ffi::types::c_void>();
320+
entropy_p = extra_entropy.as_c_ptr().cast::<ffi::types::c_void>();
319321

320322
// When fuzzing, these checks will usually spinloop forever, so just short-circuit them.
321323
#[cfg(fuzzing)]

src/ecdsa/recovery.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,16 @@ impl RecoverableSignature {
7676

7777
/// Obtains a raw pointer suitable for use with FFI functions.
7878
#[inline]
79+
#[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
7980
pub fn as_ptr(&self) -> *const ffi::RecoverableSignature {
80-
&self.0
81+
self.as_c_ptr()
8182
}
8283

8384
/// Obtains a raw mutable pointer suitable for use with FFI functions.
8485
#[inline]
86+
#[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")]
8587
pub fn as_mut_ptr(&mut self) -> *mut ffi::RecoverableSignature {
86-
&mut self.0
88+
self.as_mut_c_ptr()
8789
}
8890

8991
#[inline]
@@ -133,11 +135,11 @@ impl RecoverableSignature {
133135
impl CPtr for RecoverableSignature {
134136
type Target = ffi::RecoverableSignature;
135137
fn as_c_ptr(&self) -> *const Self::Target {
136-
self.as_ptr()
138+
&self.0
137139
}
138140

139141
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
140-
self.as_mut_ptr()
142+
&mut self.0
141143
}
142144
}
143145

src/key.rs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ impl SecretKey {
221221
let ret = ffi::secp256k1_keypair_sec(
222222
ffi::secp256k1_context_no_precomp,
223223
sk.as_mut_c_ptr(),
224-
keypair.as_ptr()
224+
keypair.as_c_ptr()
225225
);
226226
debug_assert_eq!(ret, 1);
227227
}
@@ -423,14 +423,16 @@ impl<'de> serde::Deserialize<'de> for SecretKey {
423423
impl PublicKey {
424424
/// Obtains a raw const pointer suitable for use with FFI functions.
425425
#[inline]
426+
#[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
426427
pub fn as_ptr(&self) -> *const ffi::PublicKey {
427-
&self.0
428+
self.as_c_ptr()
428429
}
429430

430431
/// Obtains a raw mutable pointer suitable for use with FFI functions.
431432
#[inline]
433+
#[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")]
432434
pub fn as_mut_ptr(&mut self) -> *mut ffi::PublicKey {
433-
&mut self.0
435+
self.as_mut_c_ptr()
434436
}
435437

436438
/// Creates a new public key from a [`SecretKey`].
@@ -507,7 +509,7 @@ impl PublicKey {
507509
let ret = ffi::secp256k1_keypair_pub(
508510
ffi::secp256k1_context_no_precomp,
509511
&mut pk,
510-
keypair.as_ptr()
512+
keypair.as_c_ptr()
511513
);
512514
debug_assert_eq!(ret, 1);
513515
PublicKey(pk)
@@ -733,7 +735,7 @@ impl PublicKey {
733735
ffi::secp256k1_context_no_precomp,
734736
&mut xonly_pk,
735737
&mut pk_parity,
736-
self.as_ptr(),
738+
self.as_c_ptr(),
737739
);
738740
debug_assert_eq!(ret, 1);
739741
let parity = Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1");
@@ -743,19 +745,26 @@ impl PublicKey {
743745
}
744746
}
745747

748+
/// This trait enables interaction with the FFI layer and even though it is part of the public API
749+
/// normal users should never need to directly interact with FFI types.
746750
impl CPtr for PublicKey {
747751
type Target = ffi::PublicKey;
752+
753+
/// Obtains a const pointer suitable for use with FFI functions.
748754
fn as_c_ptr(&self) -> *const Self::Target {
749-
self.as_ptr()
755+
&self.0
750756
}
751757

758+
/// Obtains a mutable pointer suitable for use with FFI functions.
752759
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
753-
self.as_mut_ptr()
760+
&mut self.0
754761
}
755762
}
756763

757764

758-
/// Creates a new public key from a FFI public key
765+
/// Creates a new public key from a FFI public key.
766+
///
767+
/// Note, normal users should never need to interact directly with FFI types.
759768
impl From<ffi::PublicKey> for PublicKey {
760769
#[inline]
761770
fn from(pk: ffi::PublicKey) -> PublicKey {
@@ -845,14 +854,16 @@ impl_display_secret!(KeyPair);
845854
impl KeyPair {
846855
/// Obtains a raw const pointer suitable for use with FFI functions.
847856
#[inline]
857+
#[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
848858
pub fn as_ptr(&self) -> *const ffi::KeyPair {
849-
&self.0
859+
self.as_c_ptr()
850860
}
851861

852862
/// Obtains a raw mutable pointer suitable for use with FFI functions.
853863
#[inline]
864+
#[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")]
854865
pub fn as_mut_ptr(&mut self) -> *mut ffi::KeyPair {
855-
&mut self.0
866+
self.as_mut_c_ptr()
856867
}
857868

858869
/// Creates a [`KeyPair`] directly from a Secp256k1 secret key.
@@ -1152,6 +1163,17 @@ impl<'de> serde::Deserialize<'de> for KeyPair {
11521163
}
11531164
}
11541165

1166+
impl CPtr for KeyPair {
1167+
type Target = ffi::KeyPair;
1168+
fn as_c_ptr(&self) -> *const Self::Target {
1169+
&self.0
1170+
}
1171+
1172+
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1173+
&mut self.0
1174+
}
1175+
}
1176+
11551177
/// An x-only public key, used for verification of Schnorr signatures and serialized according to BIP-340.
11561178
///
11571179
/// # Serde support
@@ -1210,14 +1232,16 @@ impl str::FromStr for XOnlyPublicKey {
12101232
impl XOnlyPublicKey {
12111233
/// Obtains a raw const pointer suitable for use with FFI functions.
12121234
#[inline]
1235+
#[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
12131236
pub fn as_ptr(&self) -> *const ffi::XOnlyPublicKey {
1214-
&self.0
1237+
self.as_c_ptr()
12151238
}
12161239

12171240
/// Obtains a raw mutable pointer suitable for use with FFI functions.
12181241
#[inline]
1242+
#[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")]
12191243
pub fn as_mut_ptr(&mut self) -> *mut ffi::XOnlyPublicKey {
1220-
&mut self.0
1244+
self.as_mut_c_ptr()
12211245
}
12221246

12231247
/// Returns the [`XOnlyPublicKey`] (and it's [`Parity`]) for `keypair`.
@@ -1230,7 +1254,7 @@ impl XOnlyPublicKey {
12301254
ffi::secp256k1_context_no_precomp,
12311255
&mut xonly_pk,
12321256
&mut pk_parity,
1233-
keypair.as_ptr(),
1257+
keypair.as_c_ptr(),
12341258
);
12351259
debug_assert_eq!(ret, 1);
12361260
let parity = Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1");
@@ -1570,11 +1594,11 @@ impl<'de> serde::Deserialize<'de> for Parity {
15701594
impl CPtr for XOnlyPublicKey {
15711595
type Target = ffi::XOnlyPublicKey;
15721596
fn as_c_ptr(&self) -> *const Self::Target {
1573-
self.as_ptr()
1597+
&self.0
15741598
}
15751599

15761600
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1577-
self.as_mut_ptr()
1601+
&mut self.0
15781602
}
15791603
}
15801604

src/schnorr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl<C: Signing> Secp256k1<C> {
112112
self.ctx,
113113
sig.as_mut_c_ptr(),
114114
msg.as_c_ptr(),
115-
keypair.as_ptr(),
115+
keypair.as_c_ptr(),
116116
nonce_data,
117117
)
118118
);

0 commit comments

Comments
 (0)