Skip to main content

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