secp256k1_sys/
lib.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! # secp256k1-sys FFI bindings
4//! Direct bindings to the underlying C library functions. These should
5//! not be needed for most users.
6
7// Coding conventions
8#![deny(non_upper_case_globals, non_camel_case_types, non_snake_case, unused_mut)]
9#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
10#![cfg_attr(docsrs, feature(doc_auto_cfg))]
11
12#[cfg(any(test, feature = "std"))]
13extern crate core;
14
15#[cfg(feature = "alloc")]
16extern crate alloc;
17
18#[cfg(secp256k1_fuzz)]
19const THIS_UNUSED_CONSTANT_IS_YOUR_WARNING_THAT_ALL_THE_CRYPTO_IN_THIS_LIB_IS_DISABLED_FOR_FUZZING: usize = 0;
20
21mod macros;
22pub mod types;
23
24#[cfg(feature = "recovery")]
25pub mod recovery;
26
27use core::ptr::NonNull;
28use core::{ptr, slice};
29
30use types::*;
31
32/// Flag for context to enable no precomputation
33pub const SECP256K1_START_NONE: c_uint = 1;
34/// Flag for context to enable verification precomputation
35pub const SECP256K1_START_VERIFY: c_uint = 1 | (1 << 8);
36/// Flag for context to enable signing precomputation
37pub const SECP256K1_START_SIGN: c_uint = 1 | (1 << 9);
38/// Flag for keys to indicate uncompressed serialization format
39#[allow(unused_parens)]
40pub const SECP256K1_SER_UNCOMPRESSED: c_uint = (1 << 1);
41/// Flag for keys to indicate compressed serialization format
42pub const SECP256K1_SER_COMPRESSED: c_uint = (1 << 1) | (1 << 8);
43
44/// A nonce generation function.
45///
46/// Ordinary users of the library never need to see this type; the default
47/// nonce generation function should be sufficient for almost all usecases.
48///
49/// To use this type, you must write your own (unsafe) wrapper. It is unsafe
50/// because any secure implementation must dereference the passed-in raw
51/// pointers and/or call FFI functions.
52pub type NonceFn = Option<
53    unsafe extern "C" fn(
54        nonce32: *mut c_uchar,
55        msg32: *const c_uchar,
56        key32: *const c_uchar,
57        algo16: *const c_uchar,
58        data: *mut c_void,
59        attempt: c_uint,
60    ) -> c_int,
61>;
62
63/// Hash function to use to post-process an ECDH point to get
64/// a shared secret.
65pub type EcdhHashFn = Option<
66    unsafe extern "C" fn(
67        output: *mut c_uchar,
68        x: *const c_uchar,
69        y: *const c_uchar,
70        data: *mut c_void,
71    ) -> c_int,
72>;
73
74/// Same as [`NonceFn`], but accepts an additional pubkey argument and does not
75/// accept an attempt argument.
76///
77/// The pubkey argument will protect signature schemes with tweaked keys from
78/// reusing the nonce when signing with a different precomputed pubkey, which
79/// for BIP 340 signatures is just as bad as reusing a nonce across different
80/// messages.
81///
82/// As with [`NonceFn`] ordinary users should never need to touch this type.
83pub type SchnorrNonceFn = Option<
84    unsafe extern "C" fn(
85        nonce32: *mut c_uchar,
86        msg32: *const c_uchar,
87        msg_len: size_t,
88        key32: *const c_uchar,
89        xonly_pk32: *const c_uchar,
90        algo16: *const c_uchar,
91        algo_len: size_t,
92        data: *mut c_void,
93    ) -> c_int,
94>;
95
96/// A hash function used by `ellswift_ecdh` to hash the final ECDH shared secret.
97pub type EllswiftEcdhHashFn = Option<
98    unsafe extern "C" fn(
99        output: *mut c_uchar,
100        x32: *const c_uchar,
101        ell_a64: *const c_uchar,
102        ell_b64: *const c_uchar,
103        data: *mut c_void,
104    ) -> c_int,
105>;
106
107/// Data structure that contains additional arguments for schnorrsig_sign_custom.
108#[repr(C)]
109pub struct SchnorrSigExtraParams {
110    magic: [c_uchar; 4],
111    nonce_fp: SchnorrNonceFn,
112    ndata: *const c_void,
113}
114
115impl SchnorrSigExtraParams {
116    /// Create a new SchnorrSigExtraParams properly initialized.
117    ///
118    /// `nonce_fp`: pointer to a nonce generation function. If NULL
119    /// rustsecp256k1_v0_5_0_nonce_function_bip340 is used
120    ///
121    /// `ndata`: pointer to arbitrary data used by the nonce generation function
122    /// (can be NULL). If it is non-NULL and
123    /// rustsecp256k1_v0_5_0_nonce_function_bip340 is used,
124    /// then ndata must be a pointer to 32-byte auxiliary randomness as per
125    /// BIP-340.
126    pub fn new(nonce_fp: SchnorrNonceFn, ndata: *const c_void) -> Self {
127        SchnorrSigExtraParams { magic: [0xda, 0x6f, 0xb3, 0x8c], nonce_fp, ndata }
128    }
129}
130
131/// An opaque Secp256k1 context.
132///
133/// Currently this object contains a blinding factor used internally to
134/// randomize computations to protect against sidechannel attacks. In the
135/// past it has contained precomputation tables to speed up crypto operations.
136///
137/// It should be assumed to be expensive to create and therefore should be
138/// reused when possible.
139///
140/// If you create one of these with `secp256k1_context_create` you must
141/// destroy it with `secp256k1_context_destroy`. (Failure to destroy it is
142/// a memory leak; destroying it using any other allocator is undefined
143/// behavior.)
144#[derive(Clone, Debug)]
145#[repr(C)]
146pub struct Context(c_int);
147
148/// Library-internal representation of a Secp256k1 public key
149#[repr(C)]
150#[derive(Copy, Clone)]
151#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
152pub struct PublicKey([c_uchar; 64]);
153impl_array_newtype!(PublicKey, c_uchar, 64);
154impl_raw_debug!(PublicKey);
155
156impl PublicKey {
157    /// Creates an "uninitialized" FFI public key which is zeroed out
158    ///
159    /// # Safety
160    ///
161    /// If you pass this to any FFI functions, except as an out-pointer,
162    /// the result is likely to be an assertation failure and process
163    /// termination.
164    pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 64]) }
165
166    /// Create a new public key usable for the FFI interface from raw bytes
167    ///
168    /// # Safety
169    ///
170    /// Does not check the validity of the underlying representation. If it is
171    /// invalid the result may be assertation failures (and process aborts) from
172    /// the underlying library. You should not use this method except with data
173    /// that you obtained from the FFI interface of the same version of this
174    /// library.
175    pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self { PublicKey(data) }
176
177    /// Returns the underlying FFI opaque representation of the public key
178    ///
179    /// You should not use this unless you really know what you are doing. It is
180    /// essentially only useful for extending the FFI interface itself.
181    pub fn underlying_bytes(self) -> [c_uchar; 64] { self.0 }
182
183    /// Serializes this public key as a byte-encoded pair of values, in compressed form.
184    fn serialize(&self) -> [u8; 33] {
185        let mut buf = [0u8; 33];
186        let mut len = 33;
187        unsafe {
188            let ret = secp256k1_ec_pubkey_serialize(
189                secp256k1_context_no_precomp,
190                buf.as_mut_c_ptr(),
191                &mut len,
192                self,
193                SECP256K1_SER_COMPRESSED,
194            );
195            debug_assert_eq!(ret, 1);
196            debug_assert_eq!(len, 33);
197        };
198        buf
199    }
200}
201
202#[cfg(not(secp256k1_fuzz))]
203impl PartialOrd for PublicKey {
204    fn partial_cmp(&self, other: &PublicKey) -> Option<core::cmp::Ordering> {
205        Some(self.cmp(other))
206    }
207}
208
209#[cfg(not(secp256k1_fuzz))]
210impl Ord for PublicKey {
211    fn cmp(&self, other: &PublicKey) -> core::cmp::Ordering {
212        let ret = unsafe { secp256k1_ec_pubkey_cmp(secp256k1_context_no_precomp, self, other) };
213        ret.cmp(&0i32)
214    }
215}
216
217#[cfg(not(secp256k1_fuzz))]
218impl PartialEq for PublicKey {
219    fn eq(&self, other: &Self) -> bool { self.cmp(other) == core::cmp::Ordering::Equal }
220}
221
222#[cfg(not(secp256k1_fuzz))]
223impl Eq for PublicKey {}
224
225#[cfg(not(secp256k1_fuzz))]
226impl core::hash::Hash for PublicKey {
227    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
228        let ser = self.serialize();
229        ser.hash(state);
230    }
231}
232
233/// Library-internal representation of a Secp256k1 signature
234#[repr(C)]
235#[derive(Copy, Clone)]
236#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
237pub struct Signature([c_uchar; 64]);
238impl_array_newtype!(Signature, c_uchar, 64);
239impl_raw_debug!(Signature);
240
241impl Signature {
242    /// Creates an "uninitialized" FFI signature which is zeroed out
243    ///
244    /// # Safety
245    ///
246    /// If you pass this to any FFI functions, except as an out-pointer,
247    /// the result is likely to be an assertation failure and process
248    /// termination.
249    pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 64]) }
250
251    /// Create a new signature usable for the FFI interface from raw bytes
252    ///
253    /// # Safety
254    ///
255    /// Does not check the validity of the underlying representation. If it is
256    /// invalid the result may be assertation failures (and process aborts) from
257    /// the underlying library. You should not use this method except with data
258    /// that you obtained from the FFI interface of the same version of this
259    /// library.
260    pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self { Signature(data) }
261
262    /// Returns the underlying FFI opaque representation of the signature
263    ///
264    /// You should not use this unless you really know what you are doing. It is
265    /// essentially only useful for extending the FFI interface itself.
266    pub fn underlying_bytes(self) -> [c_uchar; 64] { self.0 }
267
268    /// Serializes the signature in compact format.
269    fn serialize(&self) -> [u8; 64] {
270        let mut buf = [0u8; 64];
271        unsafe {
272            let ret = secp256k1_ecdsa_signature_serialize_compact(
273                secp256k1_context_no_precomp,
274                buf.as_mut_c_ptr(),
275                self,
276            );
277            debug_assert!(ret == 1);
278        }
279        buf
280    }
281}
282
283#[cfg(not(secp256k1_fuzz))]
284impl PartialOrd for Signature {
285    fn partial_cmp(&self, other: &Signature) -> Option<core::cmp::Ordering> {
286        Some(self.cmp(other))
287    }
288}
289
290#[cfg(not(secp256k1_fuzz))]
291impl Ord for Signature {
292    fn cmp(&self, other: &Signature) -> core::cmp::Ordering {
293        let this = self.serialize();
294        let that = other.serialize();
295        this.cmp(&that)
296    }
297}
298
299#[cfg(not(secp256k1_fuzz))]
300impl PartialEq for Signature {
301    fn eq(&self, other: &Self) -> bool { self.cmp(other) == core::cmp::Ordering::Equal }
302}
303
304#[cfg(not(secp256k1_fuzz))]
305impl Eq for Signature {}
306
307#[cfg(not(secp256k1_fuzz))]
308impl core::hash::Hash for Signature {
309    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
310        let ser = self.serialize();
311        ser.hash(state);
312    }
313}
314
315#[repr(C)]
316#[derive(Copy, Clone)]
317#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
318pub struct XOnlyPublicKey([c_uchar; 64]);
319impl_array_newtype!(XOnlyPublicKey, c_uchar, 64);
320impl_raw_debug!(XOnlyPublicKey);
321
322impl XOnlyPublicKey {
323    /// Creates an "uninitialized" FFI x-only public key which is zeroed out
324    ///
325    /// # Safety
326    ///
327    /// If you pass this to any FFI functions, except as an out-pointer,
328    /// the result is likely to be an assertation failure and process
329    /// termination.
330    pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 64]) }
331
332    /// Create a new x-only public key usable for the FFI interface from raw bytes
333    ///
334    /// # Safety
335    ///
336    /// Does not check the validity of the underlying representation. If it is
337    /// invalid the result may be assertation failures (and process aborts) from
338    /// the underlying library. You should not use this method except with data
339    /// that you obtained from the FFI interface of the same version of this
340    /// library.
341    pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self { XOnlyPublicKey(data) }
342
343    /// Returns the underlying FFI opaque representation of the x-only public key
344    ///
345    /// You should not use this unless you really know what you are doing. It is
346    /// essentially only useful for extending the FFI interface itself.
347    pub fn underlying_bytes(self) -> [c_uchar; 64] { self.0 }
348
349    /// Serializes this key as a byte-encoded x coordinate value (32 bytes).
350    fn serialize(&self) -> [u8; 32] {
351        let mut buf = [0u8; 32];
352        unsafe {
353            let ret = secp256k1_xonly_pubkey_serialize(
354                secp256k1_context_no_precomp,
355                buf.as_mut_c_ptr(),
356                self,
357            );
358            assert_eq!(ret, 1);
359        };
360        buf
361    }
362}
363
364#[cfg(not(secp256k1_fuzz))]
365impl PartialOrd for XOnlyPublicKey {
366    fn partial_cmp(&self, other: &XOnlyPublicKey) -> Option<core::cmp::Ordering> {
367        Some(self.cmp(other))
368    }
369}
370
371#[cfg(not(secp256k1_fuzz))]
372impl Ord for XOnlyPublicKey {
373    fn cmp(&self, other: &XOnlyPublicKey) -> core::cmp::Ordering {
374        let ret = unsafe { secp256k1_xonly_pubkey_cmp(secp256k1_context_no_precomp, self, other) };
375        ret.cmp(&0i32)
376    }
377}
378
379#[cfg(not(secp256k1_fuzz))]
380impl PartialEq for XOnlyPublicKey {
381    fn eq(&self, other: &Self) -> bool { self.cmp(other) == core::cmp::Ordering::Equal }
382}
383
384#[cfg(not(secp256k1_fuzz))]
385impl Eq for XOnlyPublicKey {}
386
387#[cfg(not(secp256k1_fuzz))]
388impl core::hash::Hash for XOnlyPublicKey {
389    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
390        let ser = self.serialize();
391        ser.hash(state);
392    }
393}
394
395#[repr(C)]
396#[derive(Copy, Clone)]
397#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
398pub struct Keypair([c_uchar; 96]);
399impl_array_newtype!(Keypair, c_uchar, 96);
400impl_raw_debug!(Keypair);
401
402impl Keypair {
403    /// Creates an "uninitialized" FFI keypair which is zeroed out
404    ///
405    /// # Safety
406    ///
407    /// If you pass this to any FFI functions, except as an out-pointer,
408    /// the result is likely to be an assertation failure and process
409    /// termination.
410    pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 96]) }
411
412    /// Create a new keypair usable for the FFI interface from raw bytes
413    ///
414    /// # Safety
415    ///
416    /// Does not check the validity of the underlying representation. If it is
417    /// invalid the result may be assertation failures (and process aborts) from
418    /// the underlying library. You should not use this method except with data
419    /// that you obtained from the FFI interface of the same version of this
420    /// library.
421    pub unsafe fn from_array_unchecked(data: [c_uchar; 96]) -> Self { Keypair(data) }
422
423    /// Returns the underlying FFI opaque representation of the x-only public key
424    ///
425    /// You should not use this unless you really know what you are doing. It is
426    /// essentially only useful for extending the FFI interface itself.
427    pub fn underlying_bytes(self) -> [c_uchar; 96] { self.0 }
428
429    /// Creates a new compressed public key from this key pair.
430    fn public_key(&self) -> PublicKey {
431        unsafe {
432            let mut pk = PublicKey::new();
433            let ret = secp256k1_keypair_pub(secp256k1_context_no_precomp, &mut pk, self);
434            debug_assert_eq!(ret, 1);
435            pk
436        }
437    }
438
439    /// Attempts to erase the contents of the underlying array.
440    ///
441    /// Note, however, that the compiler is allowed to freely copy or move the
442    /// contents of this array to other places in memory. Preventing this behavior
443    /// is very subtle. For more discussion on this, please see the documentation
444    /// of the [`zeroize`](https://docs.rs/zeroize) crate.
445    #[inline]
446    pub fn non_secure_erase(&mut self) { non_secure_erase_impl(&mut self.0, DUMMY_KEYPAIR); }
447}
448
449// DUMMY_KEYPAIR is the internal repr of a valid key pair with secret key `[1u8; 32]`
450#[cfg(target_endian = "little")]
451const DUMMY_KEYPAIR: [c_uchar; 96] = [
452    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
453    143, 7, 221, 213, 233, 245, 23, 156, 255, 25, 72, 96, 52, 24, 30, 215, 101, 5, 186, 170, 213,
454    62, 93, 153, 64, 100, 18, 123, 86, 197, 132, 27, 209, 232, 168, 105, 122, 212, 34, 81, 222, 57,
455    246, 167, 32, 129, 223, 223, 66, 171, 197, 66, 166, 214, 254, 7, 21, 84, 139, 88, 143, 175,
456    190, 112,
457];
458#[cfg(all(target_endian = "big", target_pointer_width = "32"))]
459const DUMMY_KEYPAIR: [c_uchar; 96] = [
460    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
461    213, 221, 7, 143, 156, 23, 245, 233, 96, 72, 25, 255, 215, 30, 24, 52, 170, 186, 5, 101, 153,
462    93, 62, 213, 123, 18, 100, 64, 27, 132, 197, 86, 105, 168, 232, 209, 81, 34, 212, 122, 167,
463    246, 57, 222, 223, 223, 129, 32, 66, 197, 171, 66, 7, 254, 214, 166, 88, 139, 84, 21, 112, 190,
464    175, 143,
465];
466#[cfg(all(target_endian = "big", target_pointer_width = "64"))]
467const DUMMY_KEYPAIR: [c_uchar; 96] = [
468    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
469    156, 23, 245, 233, 213, 221, 7, 143, 215, 30, 24, 52, 96, 72, 25, 255, 153, 93, 62, 213, 170,
470    186, 5, 101, 27, 132, 197, 86, 123, 18, 100, 64, 81, 34, 212, 122, 105, 168, 232, 209, 223,
471    223, 129, 32, 167, 246, 57, 222, 7, 254, 214, 166, 66, 197, 171, 66, 112, 190, 175, 143, 88,
472    139, 84, 21,
473];
474
475/// Does a best attempt at secure erasure using Rust intrinsics.
476///
477/// The implementation is based on the approach used by the [`zeroize`](https://docs.rs/zeroize) crate.
478#[inline(always)]
479pub fn non_secure_erase_impl<T>(dst: &mut T, src: T) {
480    use core::sync::atomic;
481    // overwrite using volatile value
482    unsafe {
483        ptr::write_volatile(dst, src);
484    }
485
486    // prevent future accesses from being reordered to before erasure
487    atomic::compiler_fence(atomic::Ordering::SeqCst);
488}
489
490#[cfg(not(secp256k1_fuzz))]
491impl PartialOrd for Keypair {
492    fn partial_cmp(&self, other: &Keypair) -> Option<core::cmp::Ordering> { Some(self.cmp(other)) }
493}
494
495#[cfg(not(secp256k1_fuzz))]
496impl Ord for Keypair {
497    fn cmp(&self, other: &Keypair) -> core::cmp::Ordering {
498        let this = self.public_key();
499        let that = other.public_key();
500        this.cmp(&that)
501    }
502}
503
504#[cfg(not(secp256k1_fuzz))]
505impl PartialEq for Keypair {
506    fn eq(&self, other: &Self) -> bool { self.cmp(other) == core::cmp::Ordering::Equal }
507}
508
509#[cfg(not(secp256k1_fuzz))]
510impl Eq for Keypair {}
511
512#[cfg(not(secp256k1_fuzz))]
513impl core::hash::Hash for Keypair {
514    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
515        // To hash the key pair we just hash the serialized public key. Since any change to the
516        // secret key would also be a change to the public key this is a valid one way function from
517        // the key pair to the digest.
518        let pk = self.public_key();
519        let ser = pk.serialize();
520        ser.hash(state);
521    }
522}
523
524/// Library-internal representation of a ElligatorSwift encoded group element.
525#[repr(C)]
526#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
527pub struct ElligatorSwift([u8; 64]);
528
529impl ElligatorSwift {
530    pub fn from_array(arr: [u8; 64]) -> Self { ElligatorSwift(arr) }
531    pub fn to_array(self) -> [u8; 64] { self.0 }
532}
533
534impl_array_newtype!(ElligatorSwift, u8, 64);
535impl_raw_debug!(ElligatorSwift);
536
537extern "C" {
538    /// Default ECDH hash function
539    #[cfg_attr(
540        not(rust_secp_no_symbol_renaming),
541        link_name = "rustsecp256k1_v0_12_ecdh_hash_function_default"
542    )]
543    pub static secp256k1_ecdh_hash_function_default: EcdhHashFn;
544
545    /// Default ECDH hash function for BIP324 key establishment
546    #[cfg_attr(
547        not(rust_secp_no_symbol_renaming),
548        link_name = "rustsecp256k1_v0_12_ellswift_xdh_hash_function_bip324"
549    )]
550    pub static secp256k1_ellswift_xdh_hash_function_bip324: EllswiftEcdhHashFn;
551
552    #[cfg_attr(
553        not(rust_secp_no_symbol_renaming),
554        link_name = "rustsecp256k1_v0_12_nonce_function_rfc6979"
555    )]
556    pub static secp256k1_nonce_function_rfc6979: NonceFn;
557
558    #[cfg_attr(
559        not(rust_secp_no_symbol_renaming),
560        link_name = "rustsecp256k1_v0_12_nonce_function_default"
561    )]
562    pub static secp256k1_nonce_function_default: NonceFn;
563
564    #[cfg_attr(
565        not(rust_secp_no_symbol_renaming),
566        link_name = "rustsecp256k1_v0_12_nonce_function_bip340"
567    )]
568    pub static secp256k1_nonce_function_bip340: SchnorrNonceFn;
569
570    #[cfg_attr(
571        not(rust_secp_no_symbol_renaming),
572        link_name = "rustsecp256k1_v0_12_context_no_precomp"
573    )]
574    pub static secp256k1_context_no_precomp: *const Context;
575
576    // Contexts
577    #[cfg_attr(
578        not(rust_secp_no_symbol_renaming),
579        link_name = "rustsecp256k1_v0_12_context_preallocated_destroy"
580    )]
581    pub fn secp256k1_context_preallocated_destroy(cx: NonNull<Context>);
582
583    // Signatures
584    #[cfg_attr(
585        not(rust_secp_no_symbol_renaming),
586        link_name = "rustsecp256k1_v0_12_ecdsa_signature_parse_der"
587    )]
588    pub fn secp256k1_ecdsa_signature_parse_der(
589        cx: *const Context,
590        sig: *mut Signature,
591        input: *const c_uchar,
592        in_len: size_t,
593    ) -> c_int;
594
595    #[cfg_attr(
596        not(rust_secp_no_symbol_renaming),
597        link_name = "rustsecp256k1_v0_12_ecdsa_signature_parse_compact"
598    )]
599    pub fn secp256k1_ecdsa_signature_parse_compact(
600        cx: *const Context,
601        sig: *mut Signature,
602        input64: *const c_uchar,
603    ) -> c_int;
604
605    #[cfg_attr(
606        not(rust_secp_no_symbol_renaming),
607        link_name = "rustsecp256k1_v0_12_ecdsa_signature_parse_der_lax"
608    )]
609    pub fn ecdsa_signature_parse_der_lax(
610        cx: *const Context,
611        sig: *mut Signature,
612        input: *const c_uchar,
613        in_len: size_t,
614    ) -> c_int;
615
616    #[cfg_attr(
617        not(rust_secp_no_symbol_renaming),
618        link_name = "rustsecp256k1_v0_12_ecdsa_signature_serialize_der"
619    )]
620    pub fn secp256k1_ecdsa_signature_serialize_der(
621        cx: *const Context,
622        output: *mut c_uchar,
623        out_len: *mut size_t,
624        sig: *const Signature,
625    ) -> c_int;
626
627    #[cfg_attr(
628        not(rust_secp_no_symbol_renaming),
629        link_name = "rustsecp256k1_v0_12_ecdsa_signature_serialize_compact"
630    )]
631    pub fn secp256k1_ecdsa_signature_serialize_compact(
632        cx: *const Context,
633        output64: *mut c_uchar,
634        sig: *const Signature,
635    ) -> c_int;
636
637    #[cfg_attr(
638        not(rust_secp_no_symbol_renaming),
639        link_name = "rustsecp256k1_v0_12_ecdsa_signature_normalize"
640    )]
641    pub fn secp256k1_ecdsa_signature_normalize(
642        cx: *const Context,
643        out_sig: *mut Signature,
644        in_sig: *const Signature,
645    ) -> c_int;
646
647    // Secret Keys
648    #[cfg_attr(
649        not(rust_secp_no_symbol_renaming),
650        link_name = "rustsecp256k1_v0_12_ec_seckey_verify"
651    )]
652    pub fn secp256k1_ec_seckey_verify(cx: *const Context, sk: *const c_uchar) -> c_int;
653
654    #[cfg_attr(
655        not(rust_secp_no_symbol_renaming),
656        link_name = "rustsecp256k1_v0_12_ec_seckey_negate"
657    )]
658    pub fn secp256k1_ec_seckey_negate(cx: *const Context, sk: *mut c_uchar) -> c_int;
659
660    #[cfg_attr(
661        not(rust_secp_no_symbol_renaming),
662        link_name = "rustsecp256k1_v0_12_ec_seckey_tweak_add"
663    )]
664    pub fn secp256k1_ec_seckey_tweak_add(
665        cx: *const Context,
666        sk: *mut c_uchar,
667        tweak: *const c_uchar,
668    ) -> c_int;
669    #[cfg_attr(
670        not(rust_secp_no_symbol_renaming),
671        link_name = "rustsecp256k1_v0_12_ec_seckey_tweak_mul"
672    )]
673    pub fn secp256k1_ec_seckey_tweak_mul(
674        cx: *const Context,
675        sk: *mut c_uchar,
676        tweak: *const c_uchar,
677    ) -> c_int;
678
679    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_keypair_sec")]
680    pub fn secp256k1_keypair_sec(
681        cx: *const Context,
682        output_seckey: *mut c_uchar,
683        keypair: *const Keypair,
684    ) -> c_int;
685
686    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_keypair_pub")]
687    pub fn secp256k1_keypair_pub(
688        cx: *const Context,
689        output_pubkey: *mut PublicKey,
690        keypair: *const Keypair,
691    ) -> c_int;
692    // Elligator Swift
693    #[cfg_attr(
694        not(rust_secp_no_symbol_renaming),
695        link_name = "rustsecp256k1_v0_12_ellswift_encode"
696    )]
697    pub fn secp256k1_ellswift_encode(
698        ctx: *const Context,
699        ell64: *mut c_uchar,
700        pubkey: *const PublicKey,
701        rnd32: *const c_uchar,
702    ) -> c_int;
703    #[cfg_attr(
704        not(rust_secp_no_symbol_renaming),
705        link_name = "rustsecp256k1_v0_12_ellswift_decode"
706    )]
707    pub fn secp256k1_ellswift_decode(
708        ctx: *const Context,
709        pubkey: *mut u8,
710        ell64: *const c_uchar,
711    ) -> c_int;
712    #[cfg_attr(
713        not(rust_secp_no_symbol_renaming),
714        link_name = "rustsecp256k1_v0_12_ellswift_create"
715    )]
716    pub fn secp256k1_ellswift_create(
717        ctx: *const Context,
718        ell64: *mut c_uchar,
719        seckey32: *const c_uchar,
720        aux_rand32: *const c_uchar,
721    ) -> c_int;
722    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ellswift_xdh")]
723    pub fn secp256k1_ellswift_xdh(
724        ctx: *const Context,
725        output: *mut c_uchar,
726        ell_a64: *const c_uchar,
727        ell_b64: *const c_uchar,
728        seckey32: *const c_uchar,
729        party: c_int,
730        hashfp: EllswiftEcdhHashFn,
731        data: *mut c_void,
732    ) -> c_int;
733
734    #[cfg_attr(
735        not(rust_secp_no_symbol_renaming),
736        link_name = "rustsecp256k1_v0_12_musig_pubnonce_parse"
737    )]
738    pub fn secp256k1_musig_pubnonce_parse(
739        cx: *const Context,
740        nonce: *mut MusigPubNonce,
741        in66: *const c_uchar,
742    ) -> c_int;
743
744    #[cfg_attr(
745        not(rust_secp_no_symbol_renaming),
746        link_name = "rustsecp256k1_v0_12_musig_pubnonce_serialize"
747    )]
748    pub fn secp256k1_musig_pubnonce_serialize(
749        cx: *const Context,
750        out66: *mut c_uchar,
751        nonce: *const MusigPubNonce,
752    ) -> c_int;
753
754    #[cfg_attr(
755        not(rust_secp_no_symbol_renaming),
756        link_name = "rustsecp256k1_v0_12_musig_aggnonce_parse"
757    )]
758    pub fn secp256k1_musig_aggnonce_parse(
759        cx: *const Context,
760        nonce: *mut MusigAggNonce,
761        in66: *const c_uchar,
762    ) -> c_int;
763
764    #[cfg_attr(
765        not(rust_secp_no_symbol_renaming),
766        link_name = "rustsecp256k1_v0_12_musig_aggnonce_serialize"
767    )]
768    pub fn secp256k1_musig_aggnonce_serialize(
769        cx: *const Context,
770        out66: *mut c_uchar,
771        nonce: *const MusigAggNonce,
772    ) -> c_int;
773
774    #[cfg_attr(
775        not(rust_secp_no_symbol_renaming),
776        link_name = "rustsecp256k1_v0_12_musig_partial_sig_parse"
777    )]
778    pub fn secp256k1_musig_partial_sig_parse(
779        cx: *const Context,
780        sig: *mut MusigPartialSignature,
781        in32: *const c_uchar,
782    ) -> c_int;
783
784    #[cfg_attr(
785        not(rust_secp_no_symbol_renaming),
786        link_name = "rustsecp256k1_v0_12_musig_partial_sig_serialize"
787    )]
788    pub fn secp256k1_musig_partial_sig_serialize(
789        cx: *const Context,
790        out32: *mut c_uchar,
791        sig: *const MusigPartialSignature,
792    ) -> c_int;
793
794    #[cfg_attr(
795        not(rust_secp_no_symbol_renaming),
796        link_name = "rustsecp256k1_v0_12_musig_pubkey_agg"
797    )]
798    pub fn secp256k1_musig_pubkey_agg(
799        cx: *const Context,
800        agg_pk: *mut XOnlyPublicKey,
801        keyagg_cache: *mut MusigKeyAggCache,
802        pubkeys: *const *const PublicKey,
803        n_pubkeys: size_t,
804    ) -> c_int;
805
806    #[cfg_attr(
807        not(rust_secp_no_symbol_renaming),
808        link_name = "rustsecp256k1_v0_12_musig_pubkey_get"
809    )]
810    pub fn secp256k1_musig_pubkey_get(
811        cx: *const Context,
812        agg_pk: *mut PublicKey,
813        keyagg_cache: *const MusigKeyAggCache,
814    ) -> c_int;
815
816    #[cfg_attr(
817        not(rust_secp_no_symbol_renaming),
818        link_name = "rustsecp256k1_v0_12_musig_pubkey_ec_tweak_add"
819    )]
820    pub fn secp256k1_musig_pubkey_ec_tweak_add(
821        cx: *const Context,
822        output_pubkey: *mut PublicKey,
823        keyagg_cache: *mut MusigKeyAggCache,
824        tweak32: *const c_uchar,
825    ) -> c_int;
826
827    #[cfg_attr(
828        not(rust_secp_no_symbol_renaming),
829        link_name = "rustsecp256k1_v0_12_musig_pubkey_xonly_tweak_add"
830    )]
831    pub fn secp256k1_musig_pubkey_xonly_tweak_add(
832        cx: *const Context,
833        output_pubkey: *mut PublicKey,
834        keyagg_cache: *mut MusigKeyAggCache,
835        tweak32: *const c_uchar,
836    ) -> c_int;
837
838    #[cfg_attr(
839        not(rust_secp_no_symbol_renaming),
840        link_name = "rustsecp256k1_v0_12_musig_nonce_gen"
841    )]
842    pub fn secp256k1_musig_nonce_gen(
843        cx: *const Context,
844        secnonce: *mut MusigSecNonce,
845        pubnonce: *mut MusigPubNonce,
846        session_secrand32: *mut c_uchar,
847        seckey: *const c_uchar,
848        pubkey: *const PublicKey,
849        msg32: *const c_uchar,
850        keyagg_cache: *const MusigKeyAggCache,
851        extra_input32: *const c_uchar,
852    ) -> c_int;
853
854    #[cfg_attr(
855        not(rust_secp_no_symbol_renaming),
856        link_name = "rustsecp256k1_v0_12_musig_nonce_agg"
857    )]
858    pub fn secp256k1_musig_nonce_agg(
859        cx: *const Context,
860        aggnonce: *mut MusigAggNonce,
861        pubnonces: *const *const MusigPubNonce,
862        n_pubnonces: size_t,
863    ) -> c_int;
864
865    #[cfg_attr(
866        not(rust_secp_no_symbol_renaming),
867        link_name = "rustsecp256k1_v0_12_musig_nonce_process"
868    )]
869    pub fn secp256k1_musig_nonce_process(
870        cx: *const Context,
871        session: *mut MusigSession,
872        aggnonce: *const MusigAggNonce,
873        msg32: *const c_uchar,
874        keyagg_cache: *const MusigKeyAggCache,
875    ) -> c_int;
876
877    #[cfg_attr(
878        not(rust_secp_no_symbol_renaming),
879        link_name = "rustsecp256k1_v0_12_musig_partial_sign"
880    )]
881    pub fn secp256k1_musig_partial_sign(
882        cx: *const Context,
883        partial_sig: *mut MusigPartialSignature,
884        secnonce: *mut MusigSecNonce,
885        keypair: *const Keypair,
886        keyagg_cache: *const MusigKeyAggCache,
887        session: *const MusigSession,
888    ) -> c_int;
889
890    #[cfg_attr(
891        not(rust_secp_no_symbol_renaming),
892        link_name = "rustsecp256k1_v0_12_musig_partial_sig_verify"
893    )]
894    pub fn secp256k1_musig_partial_sig_verify(
895        cx: *const Context,
896        partial_sig: *const MusigPartialSignature,
897        pubnonce: *const MusigPubNonce,
898        pubkey: *const PublicKey,
899        keyagg_cache: *const MusigKeyAggCache,
900        session: *const MusigSession,
901    ) -> c_int;
902
903    #[cfg_attr(
904        not(rust_secp_no_symbol_renaming),
905        link_name = "rustsecp256k1_v0_12_musig_partial_sig_agg"
906    )]
907    pub fn secp256k1_musig_partial_sig_agg(
908        cx: *const Context,
909        sig64: *mut c_uchar,
910        session: *const MusigSession,
911        partial_sigs: *const *const MusigPartialSignature,
912        n_sigs: size_t,
913    ) -> c_int;
914
915    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ec_pubkey_sort")]
916    pub fn secp256k1_ec_pubkey_sort(
917        ctx: *const Context,
918        pubkeys: *mut *const PublicKey,
919        n_pubkeys: size_t,
920    ) -> c_int;
921}
922
923#[cfg(not(secp256k1_fuzz))]
924extern "C" {
925    // Contexts
926    #[cfg_attr(
927        not(rust_secp_no_symbol_renaming),
928        link_name = "rustsecp256k1_v0_12_context_preallocated_size"
929    )]
930    pub fn secp256k1_context_preallocated_size(flags: c_uint) -> size_t;
931
932    #[cfg_attr(
933        not(rust_secp_no_symbol_renaming),
934        link_name = "rustsecp256k1_v0_12_context_preallocated_create"
935    )]
936    pub fn secp256k1_context_preallocated_create(
937        prealloc: NonNull<c_void>,
938        flags: c_uint,
939    ) -> NonNull<Context>;
940
941    #[cfg_attr(
942        not(rust_secp_no_symbol_renaming),
943        link_name = "rustsecp256k1_v0_12_context_preallocated_clone_size"
944    )]
945    pub fn secp256k1_context_preallocated_clone_size(cx: *const Context) -> size_t;
946
947    #[cfg_attr(
948        not(rust_secp_no_symbol_renaming),
949        link_name = "rustsecp256k1_v0_12_context_preallocated_clone"
950    )]
951    pub fn secp256k1_context_preallocated_clone(
952        cx: *const Context,
953        prealloc: NonNull<c_void>,
954    ) -> NonNull<Context>;
955
956    #[cfg_attr(
957        not(rust_secp_no_symbol_renaming),
958        link_name = "rustsecp256k1_v0_12_context_randomize"
959    )]
960    pub fn secp256k1_context_randomize(cx: NonNull<Context>, seed32: *const c_uchar) -> c_int;
961    // Pubkeys
962    #[cfg_attr(
963        not(rust_secp_no_symbol_renaming),
964        link_name = "rustsecp256k1_v0_12_ec_pubkey_parse"
965    )]
966    pub fn secp256k1_ec_pubkey_parse(
967        cx: *const Context,
968        pk: *mut PublicKey,
969        input: *const c_uchar,
970        in_len: size_t,
971    ) -> c_int;
972
973    #[cfg_attr(
974        not(rust_secp_no_symbol_renaming),
975        link_name = "rustsecp256k1_v0_12_ec_pubkey_serialize"
976    )]
977    pub fn secp256k1_ec_pubkey_serialize(
978        cx: *const Context,
979        output: *mut c_uchar,
980        out_len: *mut size_t,
981        pk: *const PublicKey,
982        compressed: c_uint,
983    ) -> c_int;
984
985    // EC
986    #[cfg_attr(
987        not(rust_secp_no_symbol_renaming),
988        link_name = "rustsecp256k1_v0_12_ec_pubkey_create"
989    )]
990    pub fn secp256k1_ec_pubkey_create(
991        cx: *const Context,
992        pk: *mut PublicKey,
993        sk: *const c_uchar,
994    ) -> c_int;
995
996    #[cfg_attr(
997        not(rust_secp_no_symbol_renaming),
998        link_name = "rustsecp256k1_v0_12_ec_pubkey_negate"
999    )]
1000    pub fn secp256k1_ec_pubkey_negate(cx: *const Context, pk: *mut PublicKey) -> c_int;
1001
1002    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ec_pubkey_cmp")]
1003    pub fn secp256k1_ec_pubkey_cmp(
1004        cx: *const Context,
1005        pubkey1: *const PublicKey,
1006        pubkey2: *const PublicKey,
1007    ) -> c_int;
1008
1009    #[cfg_attr(
1010        not(rust_secp_no_symbol_renaming),
1011        link_name = "rustsecp256k1_v0_12_ec_pubkey_tweak_add"
1012    )]
1013    pub fn secp256k1_ec_pubkey_tweak_add(
1014        cx: *const Context,
1015        pk: *mut PublicKey,
1016        tweak: *const c_uchar,
1017    ) -> c_int;
1018
1019    #[cfg_attr(
1020        not(rust_secp_no_symbol_renaming),
1021        link_name = "rustsecp256k1_v0_12_ec_pubkey_tweak_mul"
1022    )]
1023    pub fn secp256k1_ec_pubkey_tweak_mul(
1024        cx: *const Context,
1025        pk: *mut PublicKey,
1026        tweak: *const c_uchar,
1027    ) -> c_int;
1028
1029    #[cfg_attr(
1030        not(rust_secp_no_symbol_renaming),
1031        link_name = "rustsecp256k1_v0_12_ec_pubkey_combine"
1032    )]
1033    pub fn secp256k1_ec_pubkey_combine(
1034        cx: *const Context,
1035        out: *mut PublicKey,
1036        ins: *const *const PublicKey,
1037        n: size_t,
1038    ) -> c_int;
1039
1040    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ecdh")]
1041    pub fn secp256k1_ecdh(
1042        cx: *const Context,
1043        output: *mut c_uchar,
1044        pubkey: *const PublicKey,
1045        seckey: *const c_uchar,
1046        hashfp: EcdhHashFn,
1047        data: *mut c_void,
1048    ) -> c_int;
1049
1050    // ECDSA
1051    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ecdsa_verify")]
1052    pub fn secp256k1_ecdsa_verify(
1053        cx: *const Context,
1054        sig: *const Signature,
1055        msg32: *const c_uchar,
1056        pk: *const PublicKey,
1057    ) -> c_int;
1058
1059    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ecdsa_sign")]
1060    pub fn secp256k1_ecdsa_sign(
1061        cx: *const Context,
1062        sig: *mut Signature,
1063        msg32: *const c_uchar,
1064        sk: *const c_uchar,
1065        noncefn: NonceFn,
1066        noncedata: *const c_void,
1067    ) -> c_int;
1068
1069    // Schnorr Signatures
1070    #[cfg_attr(
1071        not(rust_secp_no_symbol_renaming),
1072        link_name = "rustsecp256k1_v0_12_schnorrsig_sign"
1073    )]
1074    pub fn secp256k1_schnorrsig_sign(
1075        cx: *const Context,
1076        sig: *mut c_uchar,
1077        msg32: *const c_uchar,
1078        keypair: *const Keypair,
1079        aux_rand32: *const c_uchar,
1080    ) -> c_int;
1081
1082    // Schnorr Signatures with extra parameters (see [`SchnorrSigExtraParams`])
1083    #[cfg_attr(
1084        not(rust_secp_no_symbol_renaming),
1085        link_name = "rustsecp256k1_v0_12_schnorrsig_sign_custom"
1086    )]
1087    pub fn secp256k1_schnorrsig_sign_custom(
1088        cx: *const Context,
1089        sig: *mut c_uchar,
1090        msg: *const c_uchar,
1091        msg_len: size_t,
1092        keypair: *const Keypair,
1093        extra_params: *const SchnorrSigExtraParams,
1094    ) -> c_int;
1095
1096    #[cfg_attr(
1097        not(rust_secp_no_symbol_renaming),
1098        link_name = "rustsecp256k1_v0_12_schnorrsig_verify"
1099    )]
1100    pub fn secp256k1_schnorrsig_verify(
1101        cx: *const Context,
1102        sig64: *const c_uchar,
1103        msg32: *const c_uchar,
1104        msglen: size_t,
1105        pubkey: *const XOnlyPublicKey,
1106    ) -> c_int;
1107
1108    // Extra keys
1109    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_keypair_create")]
1110    pub fn secp256k1_keypair_create(
1111        cx: *const Context,
1112        keypair: *mut Keypair,
1113        seckey: *const c_uchar,
1114    ) -> c_int;
1115
1116    #[cfg_attr(
1117        not(rust_secp_no_symbol_renaming),
1118        link_name = "rustsecp256k1_v0_12_xonly_pubkey_parse"
1119    )]
1120    pub fn secp256k1_xonly_pubkey_parse(
1121        cx: *const Context,
1122        pubkey: *mut XOnlyPublicKey,
1123        input32: *const c_uchar,
1124    ) -> c_int;
1125
1126    #[cfg_attr(
1127        not(rust_secp_no_symbol_renaming),
1128        link_name = "rustsecp256k1_v0_12_xonly_pubkey_serialize"
1129    )]
1130    pub fn secp256k1_xonly_pubkey_serialize(
1131        cx: *const Context,
1132        output32: *mut c_uchar,
1133        pubkey: *const XOnlyPublicKey,
1134    ) -> c_int;
1135
1136    #[cfg_attr(
1137        not(rust_secp_no_symbol_renaming),
1138        link_name = "rustsecp256k1_v0_12_xonly_pubkey_from_pubkey"
1139    )]
1140    pub fn secp256k1_xonly_pubkey_from_pubkey(
1141        cx: *const Context,
1142        xonly_pubkey: *mut XOnlyPublicKey,
1143        pk_parity: *mut c_int,
1144        pubkey: *const PublicKey,
1145    ) -> c_int;
1146
1147    #[cfg_attr(
1148        not(rust_secp_no_symbol_renaming),
1149        link_name = "rustsecp256k1_v0_12_xonly_pubkey_cmp"
1150    )]
1151    pub fn secp256k1_xonly_pubkey_cmp(
1152        cx: *const Context,
1153        pubkey1: *const XOnlyPublicKey,
1154        pubkey2: *const XOnlyPublicKey,
1155    ) -> c_int;
1156
1157    #[cfg_attr(
1158        not(rust_secp_no_symbol_renaming),
1159        link_name = "rustsecp256k1_v0_12_xonly_pubkey_tweak_add"
1160    )]
1161    pub fn secp256k1_xonly_pubkey_tweak_add(
1162        cx: *const Context,
1163        output_pubkey: *mut PublicKey,
1164        internal_pubkey: *const XOnlyPublicKey,
1165        tweak32: *const c_uchar,
1166    ) -> c_int;
1167
1168    #[cfg_attr(
1169        not(rust_secp_no_symbol_renaming),
1170        link_name = "rustsecp256k1_v0_12_keypair_xonly_pub"
1171    )]
1172    pub fn secp256k1_keypair_xonly_pub(
1173        cx: *const Context,
1174        pubkey: *mut XOnlyPublicKey,
1175        pk_parity: *mut c_int,
1176        keypair: *const Keypair,
1177    ) -> c_int;
1178
1179    #[cfg_attr(
1180        not(rust_secp_no_symbol_renaming),
1181        link_name = "rustsecp256k1_v0_12_keypair_xonly_tweak_add"
1182    )]
1183    pub fn secp256k1_keypair_xonly_tweak_add(
1184        cx: *const Context,
1185        keypair: *mut Keypair,
1186        tweak32: *const c_uchar,
1187    ) -> c_int;
1188
1189    #[cfg_attr(
1190        not(rust_secp_no_symbol_renaming),
1191        link_name = "rustsecp256k1_v0_12_xonly_pubkey_tweak_add_check"
1192    )]
1193    pub fn secp256k1_xonly_pubkey_tweak_add_check(
1194        cx: *const Context,
1195        tweaked_pubkey32: *const c_uchar,
1196        tweaked_pubkey_parity: c_int,
1197        internal_pubkey: *const XOnlyPublicKey,
1198        tweak32: *const c_uchar,
1199    ) -> c_int;
1200}
1201
1202/// A reimplementation of the C function `secp256k1_context_create` in rust.
1203///
1204/// This function allocates memory, the pointer should be deallocated using
1205/// `secp256k1_context_destroy`. Failure to do so will result in a memory leak.
1206///
1207/// Input `flags` control which parts of the context to initialize.
1208///
1209/// # Safety
1210///
1211/// This function is unsafe because it calls unsafe functions however (assuming no bugs) no
1212/// undefined behavior is possible.
1213///
1214/// # Returns
1215///
1216/// The newly created secp256k1 raw context.
1217#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
1218pub unsafe fn secp256k1_context_create(flags: c_uint) -> NonNull<Context> {
1219    rustsecp256k1_v0_12_context_create(flags)
1220}
1221
1222/// A reimplementation of the C function `secp256k1_context_create` in rust.
1223///
1224/// See [`secp256k1_context_create`] for documentation and safety constraints.
1225#[no_mangle]
1226#[allow(clippy::missing_safety_doc)] // Documented above.
1227#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
1228pub unsafe extern "C" fn rustsecp256k1_v0_12_context_create(flags: c_uint) -> NonNull<Context> {
1229    use core::mem;
1230
1231    use crate::alloc::alloc;
1232    assert!(ALIGN_TO >= mem::align_of::<usize>());
1233    assert!(ALIGN_TO >= mem::align_of::<&usize>());
1234    assert!(ALIGN_TO >= mem::size_of::<usize>());
1235
1236    // We need to allocate `ALIGN_TO` more bytes in order to write the amount of bytes back.
1237    let bytes = secp256k1_context_preallocated_size(flags) + ALIGN_TO;
1238    let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
1239    let ptr = alloc::alloc(layout);
1240    if ptr.is_null() {
1241        alloc::handle_alloc_error(layout);
1242    }
1243    (ptr as *mut usize).write(bytes);
1244    // We must offset a whole ALIGN_TO in order to preserve the same alignment
1245    // this means we "lose" ALIGN_TO-size_of(usize) for padding.
1246    let ptr = ptr.add(ALIGN_TO);
1247    let ptr = NonNull::new_unchecked(ptr as *mut c_void); // Checked above.
1248    secp256k1_context_preallocated_create(ptr, flags)
1249}
1250
1251/// A reimplementation of the C function `secp256k1_context_destroy` in rust.
1252///
1253/// This function destroys and deallcates the context created by `secp256k1_context_create`.
1254///
1255/// The pointer shouldn't be used after passing to this function, consider it as passing it to `free()`.
1256///
1257/// # Safety
1258///
1259///  `ctx` must be a valid pointer to a block of memory created using [`secp256k1_context_create`].
1260#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
1261pub unsafe fn secp256k1_context_destroy(ctx: NonNull<Context>) {
1262    rustsecp256k1_v0_12_context_destroy(ctx)
1263}
1264
1265#[no_mangle]
1266#[allow(clippy::missing_safety_doc)] // Documented above.
1267#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
1268pub unsafe extern "C" fn rustsecp256k1_v0_12_context_destroy(mut ctx: NonNull<Context>) {
1269    use crate::alloc::alloc;
1270    secp256k1_context_preallocated_destroy(ctx);
1271    let ctx: *mut Context = ctx.as_mut();
1272    let ptr = (ctx as *mut u8).sub(ALIGN_TO);
1273    let bytes = (ptr as *mut usize).read();
1274    let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
1275    alloc::dealloc(ptr, layout);
1276}
1277
1278/// **This function is an override for the C function, this is the an edited version of the original description:**
1279///
1280/// A callback function to be called when an illegal argument is passed to
1281/// an API call. It will only trigger for violations that are mentioned
1282/// explicitly in the header. **This will cause a panic**.
1283///
1284/// The philosophy is that these shouldn't be dealt with through a
1285/// specific return value, as calling code should not have branches to deal with
1286/// the case that this code itself is broken.
1287///
1288/// On the other hand, during debug stage, one would want to be informed about
1289/// such mistakes, and the default (crashing) may be inadvisable.
1290/// When this callback is triggered, the API function called is guaranteed not
1291/// to cause a crash, though its return value and output arguments are
1292/// undefined.
1293///
1294/// See also secp256k1_default_error_callback_fn.
1295///
1296///
1297/// # Safety
1298///
1299/// `message` string should be a null terminated C string and, up to the first null byte, must be valid UTF8.
1300///
1301/// For exact safety constraints see [`std::slice::from_raw_parts`] and [`std::str::from_utf8_unchecked`].
1302#[no_mangle]
1303#[cfg(not(rust_secp_no_symbol_renaming))]
1304pub unsafe extern "C" fn rustsecp256k1_v0_12_default_illegal_callback_fn(
1305    message: *const c_char,
1306    _data: *mut c_void,
1307) {
1308    use core::str;
1309    let msg_slice = slice::from_raw_parts(message as *const u8, strlen(message));
1310    let msg = str::from_utf8_unchecked(msg_slice);
1311    panic!("[libsecp256k1] illegal argument. {}", msg);
1312}
1313
1314/// **This function is an override for the C function, this is the an edited version of the original description:**
1315///
1316/// A callback function to be called when an internal consistency check
1317/// fails. **This will cause a panic**.
1318///
1319/// This can only trigger in case of a hardware failure, miscompilation,
1320/// memory corruption, serious bug in the library, or other error would can
1321/// otherwise result in undefined behaviour. It will not trigger due to mere
1322/// incorrect usage of the API (see secp256k1_default_illegal_callback_fn
1323/// for that). After this callback returns, anything may happen, including
1324/// crashing.
1325///
1326/// See also secp256k1_default_illegal_callback_fn.
1327///
1328/// # Safety
1329///
1330/// `message` string should be a null terminated C string and, up to the first null byte, must be valid UTF8.
1331///
1332/// For exact safety constraints see [`std::slice::from_raw_parts`] and [`std::str::from_utf8_unchecked`].
1333#[no_mangle]
1334#[cfg(not(rust_secp_no_symbol_renaming))]
1335pub unsafe extern "C" fn rustsecp256k1_v0_12_default_error_callback_fn(
1336    message: *const c_char,
1337    _data: *mut c_void,
1338) {
1339    use core::str;
1340    let msg_slice = slice::from_raw_parts(message as *const u8, strlen(message));
1341    let msg = str::from_utf8_unchecked(msg_slice);
1342    panic!("[libsecp256k1] internal consistency check failed {}", msg);
1343}
1344
1345/// Returns the length of the `str_ptr` string.
1346///
1347/// # Safety
1348///
1349/// `str_ptr` must be valid pointer and point to a valid null terminated C string.
1350#[cfg(not(rust_secp_no_symbol_renaming))]
1351unsafe fn strlen(mut str_ptr: *const c_char) -> usize {
1352    let mut ctr = 0;
1353    while *str_ptr != '\0' as c_char {
1354        ctr += 1;
1355        str_ptr = str_ptr.offset(1);
1356    }
1357    ctr
1358}
1359
1360/// A trait for producing pointers that will always be valid in C (assuming NULL pointer is a valid
1361/// no-op).
1362///
1363/// Rust does not guarantee pointers to Zero Sized Types
1364/// (<https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts>). In case the type
1365/// is empty this trait will return a NULL pointer, which should be handled in C.
1366pub trait CPtr {
1367    type Target;
1368    fn as_c_ptr(&self) -> *const Self::Target;
1369    fn as_mut_c_ptr(&mut self) -> *mut Self::Target;
1370}
1371
1372impl<T> CPtr for [T] {
1373    type Target = T;
1374    fn as_c_ptr(&self) -> *const Self::Target {
1375        if self.is_empty() {
1376            ptr::null()
1377        } else {
1378            self.as_ptr()
1379        }
1380    }
1381
1382    fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1383        if self.is_empty() {
1384            ptr::null_mut::<Self::Target>()
1385        } else {
1386            self.as_mut_ptr()
1387        }
1388    }
1389}
1390
1391impl CPtr for [u8; 32] {
1392    type Target = u8;
1393    fn as_c_ptr(&self) -> *const Self::Target { self.as_ptr() }
1394
1395    fn as_mut_c_ptr(&mut self) -> *mut Self::Target { self.as_mut_ptr() }
1396}
1397
1398impl<T: CPtr> CPtr for Option<T> {
1399    type Target = T::Target;
1400    fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1401        match self {
1402            Some(contents) => contents.as_mut_c_ptr(),
1403            None => ptr::null_mut(),
1404        }
1405    }
1406    fn as_c_ptr(&self) -> *const Self::Target {
1407        match self {
1408            Some(content) => content.as_c_ptr(),
1409            None => ptr::null(),
1410        }
1411    }
1412}
1413/// Total size (in bytes) of the key aggregation context.
1414/// This structure packs all metadata needed for aggregating individual public keys
1415/// into a single MuSig2 aggregated key (including coefficients and any extra metadata).
1416pub const MUSIG_KEYAGG_SIZE: usize = 197;
1417
1418/// Size (in bytes) of the secret nonce structure used in a MuSig2 session.
1419/// It holds the secret (ephemeral) nonces used internally for nonce derivation
1420/// before the corresponding public nonces are computed.
1421pub const MUSIG_SECNONCE_SIZE: usize = 132;
1422
1423/// Size (in bytes) of the public nonce structure.
1424/// This is derived from the secret nonce and shared among participants to build
1425/// nonce commitments in the MuSig2 protocol.
1426pub const MUSIG_PUBNONCE_SIZE: usize = 132;
1427
1428/// Size (in bytes) of the aggregated nonce structure.
1429/// Represents the combined nonce obtained by aggregating the individual public nonces
1430/// from all participants for the final signature computation.
1431pub const MUSIG_AGGNONCE_SIZE: usize = 132;
1432
1433/// Size (in bytes) of the session structure.
1434/// The session object holds all state needed for a MuSig2 signing session (e.g. aggregated nonce,
1435/// key aggregation info, and other state necessary for computing partial signatures).
1436pub const MUSIG_SESSION_SIZE: usize = 133;
1437
1438/// Size (in bytes) of the internal representation of a partial signature.
1439/// This structure include magic bytes ([0xeb, 0xfb, 0x1a, 0x32]) alongside the actual signature scalar.
1440pub const MUSIG_PART_SIG_SIZE: usize = 36;
1441
1442#[repr(C)]
1443#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1444pub struct MusigKeyAggCache([c_uchar; MUSIG_KEYAGG_SIZE]);
1445impl_array_newtype!(MusigKeyAggCache, c_uchar, MUSIG_KEYAGG_SIZE);
1446impl_raw_debug!(MusigKeyAggCache);
1447
1448#[repr(C)]
1449#[derive(Copy, Clone, PartialEq, Eq)]
1450pub struct MusigSecNonce([c_uchar; MUSIG_SECNONCE_SIZE]);
1451impl_array_newtype!(MusigSecNonce, c_uchar, MUSIG_SECNONCE_SIZE);
1452impl_raw_debug!(MusigSecNonce);
1453
1454impl MusigSecNonce {
1455    pub fn dangerous_from_bytes(bytes: [c_uchar; MUSIG_SECNONCE_SIZE]) -> Self {
1456        MusigSecNonce(bytes)
1457    }
1458
1459    pub fn dangerous_into_bytes(self) -> [c_uchar; MUSIG_SECNONCE_SIZE] { self.0 }
1460}
1461
1462#[repr(C)]
1463#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1464pub struct MusigPubNonce([c_uchar; MUSIG_PUBNONCE_SIZE]);
1465impl_array_newtype!(MusigPubNonce, c_uchar, MUSIG_PUBNONCE_SIZE);
1466impl_raw_debug!(MusigPubNonce);
1467
1468#[repr(C)]
1469#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1470pub struct MusigAggNonce([c_uchar; MUSIG_AGGNONCE_SIZE]);
1471impl_array_newtype!(MusigAggNonce, c_uchar, MUSIG_AGGNONCE_SIZE);
1472impl_raw_debug!(MusigAggNonce);
1473
1474#[repr(C)]
1475#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1476pub struct MusigSession([c_uchar; MUSIG_SESSION_SIZE]);
1477impl_array_newtype!(MusigSession, c_uchar, MUSIG_SESSION_SIZE);
1478impl_raw_debug!(MusigSession);
1479
1480#[repr(C)]
1481#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1482pub struct MusigPartialSignature([c_uchar; MUSIG_PART_SIG_SIZE]);
1483impl_array_newtype!(MusigPartialSignature, c_uchar, MUSIG_PART_SIG_SIZE);
1484impl_raw_debug!(MusigPartialSignature);
1485
1486#[cfg(secp256k1_fuzz)]
1487mod fuzz_dummy {
1488    use core::sync::atomic::{AtomicUsize, Ordering};
1489
1490    use super::*;
1491
1492    #[cfg(rust_secp_no_symbol_renaming)]
1493    compile_error!("We do not support fuzzing with rust_secp_no_symbol_renaming");
1494
1495    extern "C" {
1496        fn rustsecp256k1_v0_12_context_preallocated_size(flags: c_uint) -> size_t;
1497        fn rustsecp256k1_v0_12_context_preallocated_create(
1498            prealloc: NonNull<c_void>,
1499            flags: c_uint,
1500        ) -> NonNull<Context>;
1501        fn rustsecp256k1_v0_12_context_preallocated_clone(
1502            cx: *const Context,
1503            prealloc: NonNull<c_void>,
1504        ) -> NonNull<Context>;
1505    }
1506
1507    #[cfg(feature = "lowmemory")]
1508    const CTX_SIZE: usize = 1024 * 65;
1509    #[cfg(not(feature = "lowmemory"))]
1510    const CTX_SIZE: usize = 1024 * (1024 + 128);
1511    // Contexts
1512    pub unsafe fn secp256k1_context_preallocated_size(flags: c_uint) -> size_t {
1513        assert!(
1514            rustsecp256k1_v0_12_context_preallocated_size(flags) + std::mem::size_of::<c_uint>()
1515                <= CTX_SIZE
1516        );
1517        CTX_SIZE
1518    }
1519
1520    static HAVE_PREALLOCATED_CONTEXT: AtomicUsize = AtomicUsize::new(0);
1521    const HAVE_CONTEXT_NONE: usize = 0;
1522    const HAVE_CONTEXT_WORKING: usize = 1;
1523    const HAVE_CONTEXT_DONE: usize = 2;
1524    static mut PREALLOCATED_CONTEXT: [u8; CTX_SIZE] = [0; CTX_SIZE];
1525    pub unsafe fn secp256k1_context_preallocated_create(
1526        prealloc: NonNull<c_void>,
1527        flags: c_uint,
1528    ) -> NonNull<Context> {
1529        // While applications should generally avoid creating too many contexts, sometimes fuzzers
1530        // perform tasks repeatedly which real applications may only do rarely. Thus, we want to
1531        // avoid being overly slow here. We do so by having a static context and copying it into
1532        // new buffers instead of recalculating it. Because we shouldn't rely on std, we use a
1533        // simple hand-written OnceFlag built out of an atomic to gate the global static.
1534        let mut have_ctx = HAVE_PREALLOCATED_CONTEXT.load(Ordering::Relaxed);
1535        while have_ctx != HAVE_CONTEXT_DONE {
1536            if have_ctx == HAVE_CONTEXT_NONE {
1537                have_ctx = HAVE_PREALLOCATED_CONTEXT.swap(HAVE_CONTEXT_WORKING, Ordering::AcqRel);
1538                if have_ctx == HAVE_CONTEXT_NONE {
1539                    assert!(
1540                        rustsecp256k1_v0_12_context_preallocated_size(
1541                            SECP256K1_START_SIGN | SECP256K1_START_VERIFY
1542                        ) + std::mem::size_of::<c_uint>()
1543                            <= CTX_SIZE
1544                    );
1545                    assert_eq!(
1546                        rustsecp256k1_v0_12_context_preallocated_create(
1547                            NonNull::new_unchecked(
1548                                PREALLOCATED_CONTEXT[..].as_mut_ptr() as *mut c_void
1549                            ),
1550                            SECP256K1_START_SIGN | SECP256K1_START_VERIFY
1551                        ),
1552                        NonNull::new_unchecked(
1553                            PREALLOCATED_CONTEXT[..].as_mut_ptr() as *mut Context
1554                        )
1555                    );
1556                    assert_eq!(
1557                        HAVE_PREALLOCATED_CONTEXT.swap(HAVE_CONTEXT_DONE, Ordering::AcqRel),
1558                        HAVE_CONTEXT_WORKING
1559                    );
1560                } else if have_ctx == HAVE_CONTEXT_DONE {
1561                    // Another thread finished while we were swapping.
1562                    HAVE_PREALLOCATED_CONTEXT.store(HAVE_CONTEXT_DONE, Ordering::Release);
1563                }
1564            } else {
1565                // Another thread is building, just busy-loop until they're done.
1566                assert_eq!(have_ctx, HAVE_CONTEXT_WORKING);
1567                have_ctx = HAVE_PREALLOCATED_CONTEXT.load(Ordering::Acquire);
1568                #[cfg(feature = "std")]
1569                std::thread::yield_now();
1570            }
1571        }
1572        ptr::copy_nonoverlapping(
1573            PREALLOCATED_CONTEXT[..].as_ptr(),
1574            prealloc.as_ptr() as *mut u8,
1575            CTX_SIZE,
1576        );
1577        let ptr = (prealloc.as_ptr()).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1578        (ptr as *mut c_uint).write(flags);
1579        NonNull::new_unchecked(prealloc.as_ptr() as *mut Context)
1580    }
1581    pub unsafe fn secp256k1_context_preallocated_clone_size(_cx: *const Context) -> size_t {
1582        CTX_SIZE
1583    }
1584    pub unsafe fn secp256k1_context_preallocated_clone(
1585        cx: *const Context,
1586        prealloc: NonNull<c_void>,
1587    ) -> NonNull<Context> {
1588        let orig_ptr = (cx as *mut u8).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1589        let new_ptr =
1590            (prealloc.as_ptr() as *mut u8).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1591        let flags = (orig_ptr as *mut c_uint).read();
1592        (new_ptr as *mut c_uint).write(flags);
1593        rustsecp256k1_v0_12_context_preallocated_clone(cx, prealloc)
1594    }
1595
1596    pub unsafe fn secp256k1_context_randomize(
1597        cx: NonNull<Context>,
1598        _seed32: *const c_uchar,
1599    ) -> c_int {
1600        // This function is really slow, and unsuitable for fuzzing
1601        check_context_flags(cx.as_ptr(), 0);
1602        1
1603    }
1604
1605    unsafe fn check_context_flags(cx: *const Context, required_flags: c_uint) {
1606        assert!(!cx.is_null());
1607        let cx_flags = if cx == secp256k1_context_no_precomp {
1608            1
1609        } else {
1610            let ptr = (cx as *const u8).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1611            (ptr as *const c_uint).read()
1612        };
1613        assert_eq!(cx_flags & 1, 1); // SECP256K1_FLAGS_TYPE_CONTEXT
1614        assert_eq!(cx_flags & required_flags, required_flags);
1615    }
1616
1617    /// Checks that pk != 0xffff...ffff and pk[1..32] == pk[33..64]
1618    unsafe fn test_pk_validate(cx: *const Context, pk: *const PublicKey) -> c_int {
1619        check_context_flags(cx, 0);
1620        if (&*pk).0[1..32] != (&*pk).0[33..64]
1621            || ((*pk).0[32] != 0 && (&*pk).0[32] != 0xff)
1622            || secp256k1_ec_seckey_verify(cx, (&*pk).0[0..32].as_ptr()) == 0
1623        {
1624            0
1625        } else {
1626            1
1627        }
1628    }
1629    unsafe fn test_cleanup_pk(pk: *mut PublicKey) {
1630        (&mut *pk).0[32..].copy_from_slice(&(&*pk).0[..32]);
1631        if (&*pk).0[32] <= 0x7f {
1632            (&mut *pk).0[32] = 0;
1633        } else {
1634            (&mut *pk).0[32] = 0xff;
1635        }
1636    }
1637
1638    // Pubkeys
1639    pub unsafe fn secp256k1_ec_pubkey_parse(
1640        cx: *const Context,
1641        pk: *mut PublicKey,
1642        input: *const c_uchar,
1643        in_len: size_t,
1644    ) -> c_int {
1645        check_context_flags(cx, 0);
1646        match in_len {
1647            33 =>
1648                if *input != 2 && *input != 3 {
1649                    0
1650                } else {
1651                    ptr::copy(input.offset(1), (&mut *pk).0[0..32].as_mut_ptr(), 32);
1652                    ptr::copy(input.offset(2), (&mut *pk).0[33..64].as_mut_ptr(), 31);
1653                    if *input == 3 {
1654                        (*pk).0[32] = 0xff;
1655                    } else {
1656                        (*pk).0[32] = 0;
1657                    }
1658                    test_pk_validate(cx, pk)
1659                },
1660            65 =>
1661                if *input != 4 && *input != 6 && *input != 7 {
1662                    0
1663                } else {
1664                    ptr::copy(input.offset(1), (&mut *pk).0.as_mut_ptr(), 64);
1665                    test_cleanup_pk(pk);
1666                    test_pk_validate(cx, pk)
1667                },
1668            _ => 0,
1669        }
1670    }
1671
1672    /// Serialize PublicKey back to 33/65 byte pubkey
1673    pub unsafe fn secp256k1_ec_pubkey_serialize(
1674        cx: *const Context,
1675        output: *mut c_uchar,
1676        out_len: *mut size_t,
1677        pk: *const PublicKey,
1678        compressed: c_uint,
1679    ) -> c_int {
1680        check_context_flags(cx, 0);
1681        assert_eq!(test_pk_validate(cx, pk), 1);
1682        if compressed == SECP256K1_SER_COMPRESSED {
1683            assert_eq!(*out_len, 33);
1684            if (*pk).0[32] <= 0x7f {
1685                *output = 2;
1686            } else {
1687                *output = 3;
1688            }
1689            ptr::copy((*pk).0.as_ptr(), output.offset(1), 32);
1690        } else if compressed == SECP256K1_SER_UNCOMPRESSED {
1691            assert_eq!(*out_len, 65);
1692            *output = 4;
1693            ptr::copy((*pk).0.as_ptr(), output.offset(1), 64);
1694        } else {
1695            panic!("Bad flags");
1696        }
1697        1
1698    }
1699
1700    // EC
1701    /// Sets pk to sk||sk
1702    pub unsafe fn secp256k1_ec_pubkey_create(
1703        cx: *const Context,
1704        pk: *mut PublicKey,
1705        sk: *const c_uchar,
1706    ) -> c_int {
1707        check_context_flags(cx, SECP256K1_START_SIGN);
1708        if secp256k1_ec_seckey_verify(cx, sk) != 1 {
1709            return 0;
1710        }
1711        ptr::copy(sk, (&mut *pk).0[0..32].as_mut_ptr(), 32);
1712        test_cleanup_pk(pk);
1713        assert_eq!(test_pk_validate(cx, pk), 1);
1714        1
1715    }
1716
1717    pub unsafe fn secp256k1_ec_pubkey_negate(cx: *const Context, pk: *mut PublicKey) -> c_int {
1718        check_context_flags(cx, 0);
1719        assert_eq!(test_pk_validate(cx, pk), 1);
1720        if secp256k1_ec_seckey_negate(cx, (&mut *pk).0[..32].as_mut_ptr()) != 1 {
1721            return 0;
1722        }
1723        test_cleanup_pk(pk);
1724        assert_eq!(test_pk_validate(cx, pk), 1);
1725        1
1726    }
1727
1728    /// The PublicKey equivalent of secp256k1_ec_privkey_tweak_add
1729    pub unsafe fn secp256k1_ec_pubkey_tweak_add(
1730        cx: *const Context,
1731        pk: *mut PublicKey,
1732        tweak: *const c_uchar,
1733    ) -> c_int {
1734        check_context_flags(cx, SECP256K1_START_VERIFY);
1735        assert_eq!(test_pk_validate(cx, pk), 1);
1736        if secp256k1_ec_seckey_tweak_add(cx, (&mut *pk).0[..32].as_mut_ptr(), tweak) != 1 {
1737            return 0;
1738        }
1739        test_cleanup_pk(pk);
1740        assert_eq!(test_pk_validate(cx, pk), 1);
1741        1
1742    }
1743
1744    /// The PublicKey equivalent of secp256k1_ec_privkey_tweak_mul
1745    pub unsafe fn secp256k1_ec_pubkey_tweak_mul(
1746        cx: *const Context,
1747        pk: *mut PublicKey,
1748        tweak: *const c_uchar,
1749    ) -> c_int {
1750        check_context_flags(cx, 0);
1751        assert_eq!(test_pk_validate(cx, pk), 1);
1752        if secp256k1_ec_seckey_tweak_mul(cx, (&mut *pk).0[..32].as_mut_ptr(), tweak) != 1 {
1753            return 0;
1754        }
1755        test_cleanup_pk(pk);
1756        assert_eq!(test_pk_validate(cx, pk), 1);
1757        1
1758    }
1759
1760    pub unsafe fn secp256k1_ec_pubkey_combine(
1761        cx: *const Context,
1762        out: *mut PublicKey,
1763        ins: *const *const PublicKey,
1764        n: size_t,
1765    ) -> c_int {
1766        check_context_flags(cx, 0);
1767        assert!(n >= 1);
1768        (*out) = **ins;
1769        for i in 1..n {
1770            assert_eq!(test_pk_validate(cx, *ins.offset(i as isize)), 1);
1771            if secp256k1_ec_seckey_tweak_add(
1772                cx,
1773                (&mut *out).0[..32].as_mut_ptr(),
1774                (&**ins.offset(i as isize)).0[..32].as_ptr(),
1775            ) != 1
1776            {
1777                return 0;
1778            }
1779        }
1780        test_cleanup_pk(out);
1781        assert_eq!(test_pk_validate(cx, out), 1);
1782        1
1783    }
1784
1785    /// Sets out to point^scalar^1s
1786    pub unsafe fn secp256k1_ecdh(
1787        cx: *const Context,
1788        out: *mut c_uchar,
1789        point: *const PublicKey,
1790        scalar: *const c_uchar,
1791        hashfp: EcdhHashFn,
1792        data: *mut c_void,
1793    ) -> c_int {
1794        check_context_flags(cx, 0);
1795        assert_eq!(test_pk_validate(cx, point), 1);
1796        if secp256k1_ec_seckey_verify(cx, scalar) != 1 {
1797            return 0;
1798        }
1799
1800        let scalar_slice = slice::from_raw_parts(scalar, 32);
1801        let pk_slice = &(&*point).0[..32];
1802
1803        let mut res_arr = [0u8; 32];
1804        for i in 0..32 {
1805            res_arr[i] = scalar_slice[i] ^ pk_slice[i] ^ 1;
1806        }
1807
1808        if let Some(hashfn) = hashfp {
1809            (hashfn)(out, res_arr.as_ptr(), res_arr.as_ptr(), data);
1810        } else {
1811            res_arr[16] = 0x00; // result should always be a valid secret key
1812            let out_slice = slice::from_raw_parts_mut(out, 32);
1813            out_slice.copy_from_slice(&res_arr);
1814        }
1815        1
1816    }
1817
1818    // ECDSA
1819    /// Verifies that sig is msg32||pk[..32]
1820    pub unsafe fn secp256k1_ecdsa_verify(
1821        cx: *const Context,
1822        sig: *const Signature,
1823        msg32: *const c_uchar,
1824        pk: *const PublicKey,
1825    ) -> c_int {
1826        check_context_flags(cx, SECP256K1_START_VERIFY);
1827        // Actually verify
1828        let sig_sl = slice::from_raw_parts(sig as *const u8, 64);
1829        let msg_sl = slice::from_raw_parts(msg32 as *const u8, 32);
1830        if &sig_sl[..32] == msg_sl && sig_sl[32..] == (&*pk).0[0..32] {
1831            1
1832        } else {
1833            0
1834        }
1835    }
1836
1837    /// Sets sig to msg32||pk[..32]
1838    pub unsafe fn secp256k1_ecdsa_sign(
1839        cx: *const Context,
1840        sig: *mut Signature,
1841        msg32: *const c_uchar,
1842        sk: *const c_uchar,
1843        _noncefn: NonceFn,
1844        _noncedata: *const c_void,
1845    ) -> c_int {
1846        check_context_flags(cx, SECP256K1_START_SIGN);
1847        // Check context is built for signing (and compute pk)
1848        let mut new_pk = PublicKey::new();
1849        if secp256k1_ec_pubkey_create(cx, &mut new_pk, sk) != 1 {
1850            return 0;
1851        }
1852        // Sign
1853        let sig_sl = slice::from_raw_parts_mut(sig as *mut u8, 64);
1854        let msg_sl = slice::from_raw_parts(msg32 as *const u8, 32);
1855        sig_sl[..32].copy_from_slice(msg_sl);
1856        sig_sl[32..].copy_from_slice(&new_pk.0[..32]);
1857        1
1858    }
1859
1860    // Schnorr Signatures
1861    /// Verifies that sig is msg32||pk[32..]
1862    pub unsafe fn secp256k1_schnorrsig_verify(
1863        cx: *const Context,
1864        sig64: *const c_uchar,
1865        msg32: *const c_uchar,
1866        msglen: size_t,
1867        pubkey: *const XOnlyPublicKey,
1868    ) -> c_int {
1869        check_context_flags(cx, SECP256K1_START_VERIFY);
1870        // Check context is built for verification
1871        let mut new_pk = PublicKey::new();
1872        let _ = secp256k1_xonly_pubkey_tweak_add(cx, &mut new_pk, pubkey, msg32);
1873        // Actually verify
1874        let sig_sl = slice::from_raw_parts(sig64 as *const u8, 64);
1875        let msg_sl = slice::from_raw_parts(msg32 as *const u8, msglen);
1876        if &sig_sl[..32] == msg_sl && sig_sl[32..] == (&*pubkey).0[..32] {
1877            1
1878        } else {
1879            0
1880        }
1881    }
1882
1883    /// Sets sig to msg32||pk[..32]
1884    pub unsafe fn secp256k1_schnorrsig_sign(
1885        cx: *const Context,
1886        sig64: *mut c_uchar,
1887        msg32: *const c_uchar,
1888        keypair: *const Keypair,
1889        _aux_rand32: *const c_uchar,
1890    ) -> c_int {
1891        check_context_flags(cx, SECP256K1_START_SIGN);
1892        // Check context is built for signing
1893        let mut new_kp = Keypair::new();
1894        if secp256k1_keypair_create(cx, &mut new_kp, (*keypair).0.as_ptr()) != 1 {
1895            return 0;
1896        }
1897        assert_eq!(new_kp, *keypair);
1898        // Sign
1899        let sig_sl = slice::from_raw_parts_mut(sig64 as *mut u8, 64);
1900        let msg_sl = slice::from_raw_parts(msg32 as *const u8, 32);
1901        sig_sl[..32].copy_from_slice(msg_sl);
1902        sig_sl[32..].copy_from_slice(&new_kp.0[32..64]);
1903        1
1904    }
1905
1906    // Forwards to regular schnorrsig_sign function.
1907    pub unsafe fn secp256k1_schnorrsig_sign_custom(
1908        cx: *const Context,
1909        sig: *mut c_uchar,
1910        msg: *const c_uchar,
1911        _msg_len: size_t,
1912        keypair: *const Keypair,
1913        _extra_params: *const SchnorrSigExtraParams,
1914    ) -> c_int {
1915        secp256k1_schnorrsig_sign(cx, sig, msg, keypair, ptr::null())
1916    }
1917
1918    // Extra keys
1919    pub unsafe fn secp256k1_keypair_create(
1920        cx: *const Context,
1921        keypair: *mut Keypair,
1922        seckey: *const c_uchar,
1923    ) -> c_int {
1924        check_context_flags(cx, SECP256K1_START_SIGN);
1925        if secp256k1_ec_seckey_verify(cx, seckey) == 0 {
1926            return 0;
1927        }
1928
1929        let mut pk = PublicKey::new();
1930        if secp256k1_ec_pubkey_create(cx, &mut pk, seckey) == 0 {
1931            return 0;
1932        }
1933
1934        let seckey_slice = slice::from_raw_parts(seckey, 32);
1935        (&mut *keypair).0[..32].copy_from_slice(seckey_slice);
1936        (&mut *keypair).0[32..].copy_from_slice(&pk.0);
1937        1
1938    }
1939
1940    pub unsafe fn secp256k1_xonly_pubkey_parse(
1941        cx: *const Context,
1942        pubkey: *mut XOnlyPublicKey,
1943        input32: *const c_uchar,
1944    ) -> c_int {
1945        check_context_flags(cx, 0);
1946        let inslice = slice::from_raw_parts(input32, 32);
1947        (&mut *pubkey).0[..32].copy_from_slice(inslice);
1948        (&mut *pubkey).0[32..].copy_from_slice(inslice);
1949        test_cleanup_pk(pubkey as *mut PublicKey);
1950        test_pk_validate(cx, pubkey as *mut PublicKey)
1951    }
1952
1953    pub unsafe fn secp256k1_xonly_pubkey_serialize(
1954        cx: *const Context,
1955        output32: *mut c_uchar,
1956        pubkey: *const XOnlyPublicKey,
1957    ) -> c_int {
1958        check_context_flags(cx, 0);
1959        let outslice = slice::from_raw_parts_mut(output32, 32);
1960        outslice.copy_from_slice(&(&*pubkey).0[..32]);
1961        1
1962    }
1963
1964    pub unsafe fn secp256k1_xonly_pubkey_from_pubkey(
1965        cx: *const Context,
1966        xonly_pubkey: *mut XOnlyPublicKey,
1967        pk_parity: *mut c_int,
1968        pubkey: *const PublicKey,
1969    ) -> c_int {
1970        check_context_flags(cx, 0);
1971        if !pk_parity.is_null() {
1972            *pk_parity = ((*pubkey).0[32] == 0).into();
1973        }
1974        (*xonly_pubkey).0.copy_from_slice(&(&*pubkey).0);
1975        assert_eq!(test_pk_validate(cx, pubkey), 1);
1976        1
1977    }
1978
1979    pub unsafe fn secp256k1_xonly_pubkey_tweak_add(
1980        cx: *const Context,
1981        output_pubkey: *mut PublicKey,
1982        internal_pubkey: *const XOnlyPublicKey,
1983        tweak32: *const c_uchar,
1984    ) -> c_int {
1985        check_context_flags(cx, SECP256K1_START_VERIFY);
1986        (*output_pubkey).0.copy_from_slice(&(*internal_pubkey).0);
1987        secp256k1_ec_pubkey_tweak_add(cx, output_pubkey, tweak32)
1988    }
1989
1990    pub unsafe fn secp256k1_keypair_xonly_pub(
1991        cx: *const Context,
1992        pubkey: *mut XOnlyPublicKey,
1993        pk_parity: *mut c_int,
1994        keypair: *const Keypair,
1995    ) -> c_int {
1996        check_context_flags(cx, 0);
1997        if !pk_parity.is_null() {
1998            *pk_parity = ((&*keypair).0[64] == 0).into();
1999        }
2000        (&mut *pubkey).0.copy_from_slice(&(&*keypair).0[32..]);
2001        1
2002    }
2003
2004    pub unsafe fn secp256k1_keypair_xonly_tweak_add(
2005        cx: *const Context,
2006        keypair: *mut Keypair,
2007        tweak32: *const c_uchar,
2008    ) -> c_int {
2009        check_context_flags(cx, SECP256K1_START_VERIFY);
2010        let mut pk = PublicKey::new();
2011        pk.0.copy_from_slice(&(&*keypair).0[32..]);
2012        let mut sk = [0u8; 32];
2013        sk.copy_from_slice(&(&*keypair).0[..32]);
2014        assert_eq!(secp256k1_ec_pubkey_tweak_add(cx, &mut pk, tweak32), 1);
2015        assert_eq!(secp256k1_ec_seckey_tweak_add(cx, (&mut sk[..]).as_mut_ptr(), tweak32), 1);
2016        (&mut *keypair).0[..32].copy_from_slice(&sk);
2017        (&mut *keypair).0[32..].copy_from_slice(&pk.0);
2018        1
2019    }
2020
2021    pub unsafe fn secp256k1_xonly_pubkey_tweak_add_check(
2022        cx: *const Context,
2023        tweaked_pubkey32: *const c_uchar,
2024        tweaked_pubkey_parity: c_int,
2025        internal_pubkey: *const XOnlyPublicKey,
2026        tweak32: *const c_uchar,
2027    ) -> c_int {
2028        check_context_flags(cx, SECP256K1_START_VERIFY);
2029        let mut tweaked_pk = PublicKey::new();
2030        assert_eq!(
2031            secp256k1_xonly_pubkey_tweak_add(cx, &mut tweaked_pk, internal_pubkey, tweak32),
2032            1
2033        );
2034        let in_slice = slice::from_raw_parts(tweaked_pubkey32, 32);
2035        if &tweaked_pk.0[..32] == in_slice
2036            && tweaked_pubkey_parity == (tweaked_pk.0[32] == 0).into()
2037        {
2038            1
2039        } else {
2040            0
2041        }
2042    }
2043}
2044
2045#[cfg(secp256k1_fuzz)]
2046pub use self::fuzz_dummy::*;
2047
2048#[cfg(test)]
2049mod tests {
2050    #[cfg(not(rust_secp_no_symbol_renaming))]
2051    #[test]
2052    fn test_strlen() {
2053        use std::ffi::CString;
2054
2055        use super::strlen;
2056
2057        let orig = "test strlen \t \n";
2058        let test = CString::new(orig).unwrap();
2059
2060        assert_eq!(orig.len(), unsafe { strlen(test.as_ptr()) });
2061    }
2062}