diff --git a/src/context.rs b/src/context.rs index d38ada8..d90d332 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,5 +1,6 @@ use core::marker::PhantomData; use core::mem::ManuallyDrop; +use core::ptr::NonNull; #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] @@ -116,6 +117,7 @@ mod private { #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] mod alloc_only { use core::marker::PhantomData; + use core::ptr::NonNull; use super::private; use crate::alloc::alloc; @@ -209,7 +211,10 @@ mod alloc_only { #[allow(unused_mut)] // ctx is not mutated under some feature combinations. let mut ctx = Secp256k1 { ctx: unsafe { - ffi::secp256k1_context_preallocated_create(ptr as *mut c_void, C::FLAGS) + NonNull::new_unchecked(ffi::secp256k1_context_preallocated_create( + ptr as *mut c_void, + C::FLAGS, + )) }, phantom: PhantomData, }; @@ -261,7 +266,7 @@ mod alloc_only { impl Clone for Secp256k1 { fn clone(&self) -> Secp256k1 { - let size = unsafe { ffi::secp256k1_context_preallocated_clone_size(self.ctx as _) }; + let size = unsafe { ffi::secp256k1_context_preallocated_clone_size(self.ctx.as_ptr()) }; let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap(); let ptr = unsafe { alloc::alloc(layout) }; if ptr.is_null() { @@ -269,7 +274,10 @@ mod alloc_only { } Secp256k1 { ctx: unsafe { - ffi::secp256k1_context_preallocated_clone(self.ctx, ptr as *mut c_void) + NonNull::new_unchecked(ffi::secp256k1_context_preallocated_clone( + self.ctx.as_ptr(), + ptr as *mut c_void, + )) }, phantom: PhantomData, } @@ -321,10 +329,10 @@ impl<'buf, C: Context + 'buf> Secp256k1 { } Ok(Secp256k1 { ctx: unsafe { - ffi::secp256k1_context_preallocated_create( + NonNull::new_unchecked(ffi::secp256k1_context_preallocated_create( buf.as_mut_c_ptr() as *mut c_void, C::FLAGS, - ) + )) }, phantom: PhantomData, }) @@ -355,7 +363,7 @@ impl<'buf> Secp256k1> { pub unsafe fn from_raw_all( raw_ctx: *mut ffi::Context, ) -> ManuallyDrop>> { - ManuallyDrop::new(Secp256k1 { ctx: raw_ctx, phantom: PhantomData }) + ManuallyDrop::new(Secp256k1 { ctx: NonNull::new_unchecked(raw_ctx), phantom: PhantomData }) } } @@ -386,7 +394,7 @@ impl<'buf> Secp256k1> { pub unsafe fn from_raw_signing_only( raw_ctx: *mut ffi::Context, ) -> ManuallyDrop>> { - ManuallyDrop::new(Secp256k1 { ctx: raw_ctx, phantom: PhantomData }) + ManuallyDrop::new(Secp256k1 { ctx: NonNull::new_unchecked(raw_ctx), phantom: PhantomData }) } } @@ -417,6 +425,6 @@ impl<'buf> Secp256k1> { pub unsafe fn from_raw_verification_only( raw_ctx: *mut ffi::Context, ) -> ManuallyDrop>> { - ManuallyDrop::new(Secp256k1 { ctx: raw_ctx, phantom: PhantomData }) + ManuallyDrop::new(Secp256k1 { ctx: NonNull::new_unchecked(raw_ctx), phantom: PhantomData }) } } diff --git a/src/ecdsa/mod.rs b/src/ecdsa/mod.rs index 82aab7d..ddc7609 100644 --- a/src/ecdsa/mod.rs +++ b/src/ecdsa/mod.rs @@ -258,7 +258,7 @@ impl Secp256k1 { // an invalid signature from a valid `Message` and `SecretKey` assert_eq!( ffi::secp256k1_ecdsa_sign( - self.ctx, + self.ctx.as_ptr(), &mut ret, msg.as_c_ptr(), sk.as_c_ptr(), @@ -307,7 +307,7 @@ impl Secp256k1 { // an invalid signature from a valid `Message` and `SecretKey` assert_eq!( ffi::secp256k1_ecdsa_sign( - self.ctx, + self.ctx.as_ptr(), &mut ret, msg.as_c_ptr(), sk.as_c_ptr(), @@ -388,8 +388,12 @@ impl Secp256k1 { pk: &PublicKey, ) -> Result<(), Error> { unsafe { - if ffi::secp256k1_ecdsa_verify(self.ctx, sig.as_c_ptr(), msg.as_c_ptr(), pk.as_c_ptr()) - == 0 + if ffi::secp256k1_ecdsa_verify( + self.ctx.as_ptr(), + sig.as_c_ptr(), + msg.as_c_ptr(), + pk.as_c_ptr(), + ) == 0 { Err(Error::IncorrectSignature) } else { diff --git a/src/ecdsa/recovery.rs b/src/ecdsa/recovery.rs index c080a48..61e644a 100644 --- a/src/ecdsa/recovery.rs +++ b/src/ecdsa/recovery.rs @@ -158,7 +158,7 @@ impl Secp256k1 { // an invalid signature from a valid `Message` and `SecretKey` assert_eq!( ffi::secp256k1_ecdsa_sign_recoverable( - self.ctx, + self.ctx.as_ptr(), &mut ret, msg.as_c_ptr(), sk.as_c_ptr(), @@ -208,7 +208,12 @@ impl Secp256k1 { ) -> Result { 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 + if ffi::secp256k1_ecdsa_recover( + self.ctx.as_ptr(), + &mut pk, + sig.as_c_ptr(), + msg.as_c_ptr(), + ) != 1 { return Err(Error::InvalidSignature); } diff --git a/src/key.rs b/src/key.rs index d54c94b..10cabbe 100644 --- a/src/key.rs +++ b/src/key.rs @@ -459,7 +459,7 @@ impl PublicKey { 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()); + let res = ffi::secp256k1_ec_pubkey_create(secp.ctx.as_ptr(), &mut pk, sk.as_c_ptr()); debug_assert_eq!(res, 1); PublicKey(pk) } @@ -575,7 +575,7 @@ impl PublicKey { #[must_use = "you forgot to use the negated public key"] pub fn negate(mut self, secp: &Secp256k1) -> PublicKey { unsafe { - let res = ffi::secp256k1_ec_pubkey_negate(secp.ctx, &mut self.0); + let res = ffi::secp256k1_ec_pubkey_negate(secp.ctx.as_ptr(), &mut self.0); debug_assert_eq!(res, 1); } self @@ -593,7 +593,9 @@ impl PublicKey { tweak: &Scalar, ) -> Result { unsafe { - if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx, &mut self.0, tweak.as_c_ptr()) == 1 { + if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx.as_ptr(), &mut self.0, tweak.as_c_ptr()) + == 1 + { Ok(self) } else { Err(Error::InvalidTweak) @@ -613,7 +615,9 @@ impl PublicKey { other: &Scalar, ) -> Result { unsafe { - if ffi::secp256k1_ec_pubkey_tweak_mul(secp.ctx, &mut self.0, other.as_c_ptr()) == 1 { + if ffi::secp256k1_ec_pubkey_tweak_mul(secp.ctx.as_ptr(), &mut self.0, other.as_c_ptr()) + == 1 + { Ok(self) } else { Err(Error::InvalidTweak) @@ -817,7 +821,7 @@ impl KeyPair { pub fn from_secret_key(secp: &Secp256k1, sk: &SecretKey) -> KeyPair { unsafe { let mut kp = ffi::KeyPair::new(); - if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, sk.as_c_ptr()) == 1 { + if ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut kp, sk.as_c_ptr()) == 1 { KeyPair(kp) } else { panic!("the provided secret key is invalid: it is corrupted or was not produced by Secp256k1 library") @@ -842,7 +846,7 @@ impl KeyPair { unsafe { let mut kp = ffi::KeyPair::new(); - if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, data.as_c_ptr()) == 1 { + if ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut kp, data.as_c_ptr()) == 1 { Ok(KeyPair(kp)) } else { Err(Error::InvalidSecretKey) @@ -895,7 +899,9 @@ impl KeyPair { let mut data = crate::random_32_bytes(rng); unsafe { let mut keypair = ffi::KeyPair::new(); - while ffi::secp256k1_keypair_create(secp.ctx, &mut keypair, data.as_c_ptr()) == 0 { + while ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut keypair, data.as_c_ptr()) + == 0 + { data = crate::random_32_bytes(rng); } KeyPair(keypair) @@ -946,8 +952,11 @@ impl KeyPair { tweak: &Scalar, ) -> Result { unsafe { - let err = - ffi::secp256k1_keypair_xonly_tweak_add(secp.ctx, &mut self.0, tweak.as_c_ptr()); + let err = ffi::secp256k1_keypair_xonly_tweak_add( + secp.ctx.as_ptr(), + &mut self.0, + tweak.as_c_ptr(), + ); if err != 1 { return Err(Error::InvalidTweak); } @@ -1243,7 +1252,7 @@ impl XOnlyPublicKey { unsafe { let mut pubkey = ffi::PublicKey::new(); let mut err = ffi::secp256k1_xonly_pubkey_tweak_add( - secp.ctx, + secp.ctx.as_ptr(), &mut pubkey, self.as_c_ptr(), tweak.as_c_ptr(), @@ -1253,7 +1262,7 @@ impl XOnlyPublicKey { } err = ffi::secp256k1_xonly_pubkey_from_pubkey( - secp.ctx, + secp.ctx.as_ptr(), &mut self.0, &mut pk_parity, &pubkey, @@ -1306,7 +1315,7 @@ impl XOnlyPublicKey { let tweaked_ser = tweaked_key.serialize(); unsafe { let err = ffi::secp256k1_xonly_pubkey_tweak_add_check( - secp.ctx, + secp.ctx.as_ptr(), tweaked_ser.as_c_ptr(), tweaked_parity.to_i32(), &self.0, diff --git a/src/lib.rs b/src/lib.rs index e03c0dd..4091e8a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -180,6 +180,7 @@ pub mod schnorr; mod serde_util; use core::marker::PhantomData; +use core::ptr::NonNull; use core::{fmt, mem, str}; #[cfg(feature = "bitcoin-hashes")] @@ -369,7 +370,7 @@ impl std::error::Error for Error { /// The secp256k1 engine, used to execute all signature operations. pub struct Secp256k1 { - ctx: *mut ffi::Context, + ctx: NonNull, phantom: PhantomData, } @@ -387,9 +388,10 @@ impl Eq for Secp256k1 {} impl Drop for Secp256k1 { fn drop(&mut self) { unsafe { - let size = ffi::secp256k1_context_preallocated_clone_size(self.ctx); - ffi::secp256k1_context_preallocated_destroy(self.ctx); - C::deallocate(self.ctx as _, size); + let size = ffi::secp256k1_context_preallocated_clone_size(self.ctx.as_ptr()); + ffi::secp256k1_context_preallocated_destroy(self.ctx.as_ptr()); + + C::deallocate(self.ctx.as_ptr() as _, size); } } } @@ -405,7 +407,7 @@ impl Secp256k1 { /// shouldn't be needed with normal usage of the library. It enables /// extending the Secp256k1 with more cryptographic algorithms outside of /// this crate. - pub fn ctx(&self) -> &*mut ffi::Context { &self.ctx } + pub fn ctx(&self) -> NonNull { self.ctx } /// Returns the required memory for a preallocated context buffer in a generic manner(sign/verify/all). pub fn preallocate_size_gen() -> usize { @@ -432,7 +434,7 @@ impl Secp256k1 { /// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell. pub fn seeded_randomize(&mut self, seed: &[u8; 32]) { unsafe { - let err = ffi::secp256k1_context_randomize(self.ctx, seed.as_c_ptr()); + let err = ffi::secp256k1_context_randomize(self.ctx.as_ptr(), seed.as_c_ptr()); // This function cannot fail; it has an error return for future-proofing. // We do not expose this error since it is impossible to hit, and we have // precedent for not exposing impossible errors (for example in @@ -556,11 +558,12 @@ mod tests { let ctx_sign = unsafe { ffi::secp256k1_context_create(SignOnlyPreallocated::FLAGS) }; let ctx_vrfy = unsafe { ffi::secp256k1_context_create(VerifyOnlyPreallocated::FLAGS) }; - let full: Secp256k1 = Secp256k1 { ctx: ctx_full, phantom: PhantomData }; + let full: Secp256k1 = + Secp256k1 { ctx: unsafe { NonNull::new_unchecked(ctx_full) }, phantom: PhantomData }; let sign: Secp256k1 = - Secp256k1 { ctx: ctx_sign, phantom: PhantomData }; + Secp256k1 { ctx: unsafe { NonNull::new_unchecked(ctx_sign) }, phantom: PhantomData }; let vrfy: Secp256k1 = - Secp256k1 { ctx: ctx_vrfy, phantom: PhantomData }; + Secp256k1 { ctx: unsafe { NonNull::new_unchecked(ctx_vrfy) }, phantom: PhantomData }; let (sk, pk) = full.generate_keypair(&mut rand::thread_rng()); let msg = Message::from_slice(&[2u8; 32]).unwrap(); @@ -590,9 +593,9 @@ mod tests { let ctx_sign = Secp256k1::signing_only(); let ctx_vrfy = Secp256k1::verification_only(); - let mut full = unsafe { Secp256k1::from_raw_all(ctx_full.ctx) }; - let mut sign = unsafe { Secp256k1::from_raw_signing_only(ctx_sign.ctx) }; - let mut vrfy = unsafe { Secp256k1::from_raw_verification_only(ctx_vrfy.ctx) }; + let mut full = unsafe { Secp256k1::from_raw_all(ctx_full.ctx.as_ptr()) }; + let mut sign = unsafe { Secp256k1::from_raw_signing_only(ctx_sign.ctx.as_ptr()) }; + let mut vrfy = unsafe { Secp256k1::from_raw_verification_only(ctx_vrfy.ctx.as_ptr()) }; let (sk, pk) = full.generate_keypair(&mut rand::thread_rng()); let msg = Message::from_slice(&[2u8; 32]).unwrap(); diff --git a/src/schnorr.rs b/src/schnorr.rs index cc748a6..1a79893 100644 --- a/src/schnorr.rs +++ b/src/schnorr.rs @@ -107,7 +107,7 @@ impl Secp256k1 { assert_eq!( 1, ffi::secp256k1_schnorrsig_sign( - self.ctx, + self.ctx.as_ptr(), sig.as_mut_c_ptr(), msg.as_c_ptr(), keypair.as_c_ptr(), @@ -168,7 +168,7 @@ impl Secp256k1 { ) -> Result<(), Error> { unsafe { let ret = ffi::secp256k1_schnorrsig_verify( - self.ctx, + self.ctx.as_ptr(), sig.as_c_ptr(), msg.as_c_ptr(), 32,