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
10#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
11#![cfg_attr(docsrs, feature(doc_auto_cfg))]
12
13#[cfg(any(test, feature = "std"))]
14extern crate core;
15
16#[cfg(feature = "alloc")]
17extern crate alloc;
18
19#[cfg(secp256k1_fuzz)]
20const THIS_UNUSED_CONSTANT_IS_YOUR_WARNING_THAT_ALL_THE_CRYPTO_IN_THIS_LIB_IS_DISABLED_FOR_FUZZING: usize = 0;
21
22mod macros;
23pub mod types;
24
25#[cfg(feature = "recovery")]
26pub mod recovery;
27
28use core::{slice, ptr};
29use core::ptr::NonNull;
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. Ordinary users of the library
45/// never need to see this type; only if you need to control
46/// nonce generation do you need to use it. I have deliberately
47/// made this hard to do: you have to write your own wrapper
48/// around the FFI functions to use it. And it's an unsafe type.
49/// Nonces are generated deterministically by RFC6979 by
50/// default; there should be no need to ever change this.
51pub type NonceFn = Option<unsafe extern "C" fn(
52    nonce32: *mut c_uchar,
53    msg32: *const c_uchar,
54    key32: *const c_uchar,
55    algo16: *const c_uchar,
56    data: *mut c_void,
57    attempt: c_uint,
58) -> c_int>;
59
60/// Hash function to use to post-process an ECDH point to get
61/// a shared secret.
62pub type EcdhHashFn = Option<unsafe extern "C" fn(
63    output: *mut c_uchar,
64    x: *const c_uchar,
65    y: *const c_uchar,
66    data: *mut c_void,
67) -> c_int>;
68
69///  Same as secp256k1_nonce function with the exception of accepting an
70///  additional pubkey argument and not requiring an attempt argument. The pubkey
71///  argument can protect signature schemes with key-prefixed challenge hash
72///  inputs against reusing the nonce when signing with the wrong precomputed
73///  pubkey.
74pub type SchnorrNonceFn = Option<unsafe extern "C" fn(
75    nonce32: *mut c_uchar,
76    msg32: *const c_uchar,
77    msg_len: size_t,
78    key32: *const c_uchar,
79    xonly_pk32: *const c_uchar,
80    algo16: *const c_uchar,
81    algo_len: size_t,
82    data: *mut c_void,
83) -> c_int>;
84
85/// A hash function used by `ellswift_ecdh` to hash the final ECDH shared secret.
86pub type EllswiftEcdhHashFn = Option<unsafe extern "C" fn(
87    output: *mut c_uchar,
88    x32: *const c_uchar,
89    ell_a64: *const c_uchar,
90    ell_b64: *const c_uchar,
91    data: *mut c_void,
92) -> c_int>;
93
94/// Data structure that contains additional arguments for schnorrsig_sign_custom.
95#[repr(C)]
96pub struct SchnorrSigExtraParams {
97    magic: [c_uchar; 4],
98    nonce_fp: SchnorrNonceFn,
99    ndata: *const c_void,
100}
101
102impl SchnorrSigExtraParams {
103    /// Create a new SchnorrSigExtraParams properly initialized.
104    ///
105    /// `nonce_fp`: pointer to a nonce generation function. If NULL
106    /// rustsecp256k1_v0_5_0_nonce_function_bip340 is used
107    ///
108    /// `ndata`: pointer to arbitrary data used by the nonce generation function
109    /// (can be NULL). If it is non-NULL and
110    /// rustsecp256k1_v0_5_0_nonce_function_bip340 is used,
111    /// then ndata must be a pointer to 32-byte auxiliary randomness as per
112    /// BIP-340.
113    pub fn new(nonce_fp: SchnorrNonceFn, ndata: *const c_void) -> Self {
114        SchnorrSigExtraParams {
115            magic: [0xda, 0x6f, 0xb3, 0x8c],
116            nonce_fp,
117            ndata,
118        }
119    }
120}
121
122/// A Secp256k1 context, containing various precomputed values and such
123/// needed to do elliptic curve computations. If you create one of these
124/// with `secp256k1_context_create` you MUST destroy it with
125/// `secp256k1_context_destroy`, or else you will have a memory leak.
126#[derive(Clone, Debug)]
127#[repr(C)] pub struct Context(c_int);
128
129/// Library-internal representation of a Secp256k1 public key
130#[repr(C)]
131#[derive(Copy, Clone)]
132#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
133pub struct PublicKey([c_uchar; 64]);
134impl_array_newtype!(PublicKey, c_uchar, 64);
135impl_raw_debug!(PublicKey);
136
137impl PublicKey {
138    /// Creates an "uninitialized" FFI public key which is zeroed out
139    ///
140    /// # Safety
141    ///
142    /// If you pass this to any FFI functions, except as an out-pointer,
143    /// the result is likely to be an assertation failure and process
144    /// termination.
145    pub unsafe fn new() -> Self {
146        Self::from_array_unchecked([0; 64])
147    }
148
149    /// Create a new public key usable for the FFI interface from raw bytes
150    ///
151    /// # Safety
152    ///
153    /// Does not check the validity of the underlying representation. If it is
154    /// invalid the result may be assertation failures (and process aborts) from
155    /// the underlying library. You should not use this method except with data
156    /// that you obtained from the FFI interface of the same version of this
157    /// library.
158    pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self {
159        PublicKey(data)
160    }
161
162    /// Returns the underlying FFI opaque representation of the public key
163    ///
164    /// You should not use this unless you really know what you are doing. It is
165    /// essentially only useful for extending the FFI interface itself.
166    pub fn underlying_bytes(self) -> [c_uchar; 64] {
167        self.0
168    }
169
170    /// Serializes this public key as a byte-encoded pair of values, in compressed form.
171    fn serialize(&self) -> [u8; 33] {
172        let mut buf = [0u8; 33];
173        let mut len = 33;
174        unsafe {
175            let ret = secp256k1_ec_pubkey_serialize(
176                secp256k1_context_no_precomp,
177                buf.as_mut_c_ptr(),
178                &mut len,
179                self,
180                SECP256K1_SER_COMPRESSED,
181            );
182            debug_assert_eq!(ret, 1);
183            debug_assert_eq!(len, 33);
184        };
185        buf
186    }
187}
188
189#[cfg(not(secp256k1_fuzz))]
190impl PartialOrd for PublicKey {
191    fn partial_cmp(&self, other: &PublicKey) -> Option<core::cmp::Ordering> {
192        Some(self.cmp(other))
193    }
194}
195
196#[cfg(not(secp256k1_fuzz))]
197impl Ord for PublicKey {
198    fn cmp(&self, other: &PublicKey) -> core::cmp::Ordering {
199        let ret = unsafe {
200            secp256k1_ec_pubkey_cmp(secp256k1_context_no_precomp, self, other)
201        };
202        ret.cmp(&0i32)
203    }
204}
205
206#[cfg(not(secp256k1_fuzz))]
207impl PartialEq for PublicKey {
208    fn eq(&self, other: &Self) -> bool {
209        self.cmp(other) == core::cmp::Ordering::Equal
210    }
211}
212
213#[cfg(not(secp256k1_fuzz))]
214impl Eq for PublicKey {}
215
216#[cfg(not(secp256k1_fuzz))]
217impl core::hash::Hash for PublicKey {
218    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
219        let ser = self.serialize();
220        ser.hash(state);
221    }
222}
223
224/// Library-internal representation of a Secp256k1 signature
225#[repr(C)]
226#[derive(Copy, Clone)]
227#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
228pub struct Signature([c_uchar; 64]);
229impl_array_newtype!(Signature, c_uchar, 64);
230impl_raw_debug!(Signature);
231
232impl Signature {
233    /// Creates an "uninitialized" FFI signature which is zeroed out
234    ///
235    /// # Safety
236    ///
237    /// If you pass this to any FFI functions, except as an out-pointer,
238    /// the result is likely to be an assertation failure and process
239    /// termination.
240    pub unsafe fn new() -> Self {
241        Self::from_array_unchecked([0; 64])
242    }
243
244    /// Create a new signature usable for the FFI interface from raw bytes
245    ///
246    /// # Safety
247    ///
248    /// Does not check the validity of the underlying representation. If it is
249    /// invalid the result may be assertation failures (and process aborts) from
250    /// the underlying library. You should not use this method except with data
251    /// that you obtained from the FFI interface of the same version of this
252    /// library.
253    pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self {
254        Signature(data)
255    }
256
257    /// Returns the underlying FFI opaque representation of the signature
258    ///
259    /// You should not use this unless you really know what you are doing. It is
260    /// essentially only useful for extending the FFI interface itself.
261    pub fn underlying_bytes(self) -> [c_uchar; 64] {
262        self.0
263    }
264
265    /// Serializes the signature in compact format.
266    fn serialize(&self) -> [u8; 64] {
267        let mut buf = [0u8; 64];
268        unsafe {
269            let ret = secp256k1_ecdsa_signature_serialize_compact(
270                secp256k1_context_no_precomp,
271                buf.as_mut_c_ptr(),
272                self,
273            );
274            debug_assert!(ret == 1);
275        }
276        buf
277    }
278}
279
280#[cfg(not(secp256k1_fuzz))]
281impl PartialOrd for Signature {
282    fn partial_cmp(&self, other: &Signature) -> Option<core::cmp::Ordering> {
283        Some(self.cmp(other))
284    }
285}
286
287#[cfg(not(secp256k1_fuzz))]
288impl Ord for Signature {
289    fn cmp(&self, other: &Signature) -> core::cmp::Ordering {
290        let this = self.serialize();
291        let that = other.serialize();
292        this.cmp(&that)
293    }
294}
295
296#[cfg(not(secp256k1_fuzz))]
297impl PartialEq for Signature {
298    fn eq(&self, other: &Self) -> bool {
299        self.cmp(other) == core::cmp::Ordering::Equal
300    }
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 {
330        Self::from_array_unchecked([0; 64])
331    }
332
333    /// Create a new x-only public key usable for the FFI interface from raw bytes
334    ///
335    /// # Safety
336    ///
337    /// Does not check the validity of the underlying representation. If it is
338    /// invalid the result may be assertation failures (and process aborts) from
339    /// the underlying library. You should not use this method except with data
340    /// that you obtained from the FFI interface of the same version of this
341    /// library.
342    pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self {
343        XOnlyPublicKey(data)
344    }
345
346    /// Returns the underlying FFI opaque representation of the x-only public key
347    ///
348    /// You should not use this unless you really know what you are doing. It is
349    /// essentially only useful for extending the FFI interface itself.
350    pub fn underlying_bytes(self) -> [c_uchar; 64] {
351        self.0
352    }
353
354    /// Serializes this key as a byte-encoded x coordinate value (32 bytes).
355    fn serialize(&self) -> [u8; 32] {
356        let mut buf = [0u8; 32];
357        unsafe {
358            let ret = secp256k1_xonly_pubkey_serialize(
359                secp256k1_context_no_precomp,
360                buf.as_mut_c_ptr(),
361                self,
362            );
363            assert_eq!(ret, 1);
364        };
365        buf
366    }
367}
368
369#[cfg(not(secp256k1_fuzz))]
370impl PartialOrd for XOnlyPublicKey {
371    fn partial_cmp(&self, other: &XOnlyPublicKey) -> Option<core::cmp::Ordering> {
372        Some(self.cmp(other))
373    }
374}
375
376#[cfg(not(secp256k1_fuzz))]
377impl Ord for XOnlyPublicKey {
378    fn cmp(&self, other: &XOnlyPublicKey) -> core::cmp::Ordering {
379        let ret = unsafe {
380            secp256k1_xonly_pubkey_cmp(secp256k1_context_no_precomp, self, other)
381        };
382        ret.cmp(&0i32)
383    }
384}
385
386#[cfg(not(secp256k1_fuzz))]
387impl PartialEq for XOnlyPublicKey {
388    fn eq(&self, other: &Self) -> bool {
389        self.cmp(other) == core::cmp::Ordering::Equal
390    }
391}
392
393#[cfg(not(secp256k1_fuzz))]
394impl Eq for XOnlyPublicKey {}
395
396#[cfg(not(secp256k1_fuzz))]
397impl core::hash::Hash for XOnlyPublicKey {
398    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
399        let ser = self.serialize();
400        ser.hash(state);
401    }
402}
403
404#[repr(C)]
405#[derive(Copy, Clone)]
406#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
407pub struct Keypair([c_uchar; 96]);
408impl_array_newtype!(Keypair, c_uchar, 96);
409impl_raw_debug!(Keypair);
410
411impl Keypair {
412    /// Creates an "uninitialized" FFI keypair which is zeroed out
413    ///
414    /// # Safety
415    ///
416    /// If you pass this to any FFI functions, except as an out-pointer,
417    /// the result is likely to be an assertation failure and process
418    /// termination.
419    pub unsafe fn new() -> Self {
420        Self::from_array_unchecked([0; 96])
421    }
422
423    /// Create a new keypair usable for the FFI interface from raw bytes
424    ///
425    /// # Safety
426    ///
427    /// Does not check the validity of the underlying representation. If it is
428    /// invalid the result may be assertation failures (and process aborts) from
429    /// the underlying library. You should not use this method except with data
430    /// that you obtained from the FFI interface of the same version of this
431    /// library.
432    pub unsafe fn from_array_unchecked(data: [c_uchar; 96]) -> Self {
433        Keypair(data)
434    }
435
436    /// Returns the underlying FFI opaque representation of the x-only public key
437    ///
438    /// You should not use this unless you really know what you are doing. It is
439    /// essentially only useful for extending the FFI interface itself.
440    pub fn underlying_bytes(self) -> [c_uchar; 96] {
441        self.0
442    }
443
444    /// Creates a new compressed public key from this key pair.
445    fn public_key(&self) -> PublicKey {
446        unsafe {
447            let mut pk = PublicKey::new();
448            let ret = secp256k1_keypair_pub(
449                secp256k1_context_no_precomp,
450                &mut pk,
451                self,
452            );
453            debug_assert_eq!(ret, 1);
454            pk
455        }
456    }
457
458    /// Attempts to erase the contents of the underlying array.
459    ///
460    /// Note, however, that the compiler is allowed to freely copy or move the
461    /// contents of this array to other places in memory. Preventing this behavior
462    /// is very subtle. For more discussion on this, please see the documentation
463    /// of the [`zeroize`](https://docs.rs/zeroize) crate.
464    #[inline]
465    pub fn non_secure_erase(&mut self) {
466        non_secure_erase_impl(&mut self.0, DUMMY_KEYPAIR);
467    }
468}
469
470// DUMMY_KEYPAIR is the internal repr of a valid key pair with secret key `[1u8; 32]`
471#[cfg(target_endian = "little")]
472const DUMMY_KEYPAIR: [c_uchar; 96] = [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, 143, 7, 221, 213, 233, 245, 23, 156, 255, 25, 72, 96, 52, 24, 30, 215, 101, 5, 186, 170, 213, 62, 93, 153, 64, 100, 18, 123, 86, 197, 132, 27, 209, 232, 168, 105, 122, 212, 34, 81, 222, 57, 246, 167, 32, 129, 223, 223, 66, 171, 197, 66, 166, 214, 254, 7, 21, 84, 139, 88, 143, 175, 190, 112];
473#[cfg(all(target_endian = "big", target_pointer_width = "32"))]
474const DUMMY_KEYPAIR: [c_uchar; 96] = [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, 213, 221, 7, 143, 156, 23, 245, 233, 96, 72, 25, 255, 215, 30, 24, 52, 170, 186, 5, 101, 153, 93, 62, 213, 123, 18, 100, 64, 27, 132, 197, 86, 105, 168, 232, 209, 81, 34, 212, 122, 167, 246, 57, 222, 223, 223, 129, 32, 66, 197, 171, 66, 7, 254, 214, 166, 88, 139, 84, 21, 112, 190, 175, 143];
475#[cfg(all(target_endian = "big", target_pointer_width = "64"))]
476const DUMMY_KEYPAIR: [c_uchar; 96] = [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, 156, 23, 245, 233, 213, 221, 7, 143, 215, 30, 24, 52, 96, 72, 25, 255, 153, 93, 62, 213, 170, 186, 5, 101, 27, 132, 197, 86, 123, 18, 100, 64, 81, 34, 212, 122, 105, 168, 232, 209, 223, 223, 129, 32, 167, 246, 57, 222, 7, 254, 214, 166, 66, 197, 171, 66, 112, 190, 175, 143, 88, 139, 84, 21];
477
478/// Does a best attempt at secure erasure using Rust intrinsics.
479///
480/// The implementation is based on the approach used by the [`zeroize`](https://docs.rs/zeroize) crate.
481#[inline(always)]
482pub fn non_secure_erase_impl<T>(dst: &mut T, src: T) {
483    use core::sync::atomic;
484    // overwrite using volatile value
485    unsafe { ptr::write_volatile(dst, src); }
486
487    // prevent future accesses from being reordered to before erasure
488    atomic::compiler_fence(atomic::Ordering::SeqCst);
489}
490
491#[cfg(not(secp256k1_fuzz))]
492impl PartialOrd for Keypair {
493    fn partial_cmp(&self, other: &Keypair) -> Option<core::cmp::Ordering> {
494        Some(self.cmp(other))
495    }
496}
497
498#[cfg(not(secp256k1_fuzz))]
499impl Ord for Keypair {
500    fn cmp(&self, other: &Keypair) -> core::cmp::Ordering {
501        let this = self.public_key();
502        let that = other.public_key();
503        this.cmp(&that)
504    }
505}
506
507#[cfg(not(secp256k1_fuzz))]
508impl PartialEq for Keypair {
509    fn eq(&self, other: &Self) -> bool {
510        self.cmp(other) == core::cmp::Ordering::Equal
511    }
512}
513
514#[cfg(not(secp256k1_fuzz))]
515impl Eq for Keypair {}
516
517#[cfg(not(secp256k1_fuzz))]
518impl core::hash::Hash for Keypair {
519    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
520        // To hash the key pair we just hash the serialized public key. Since any change to the
521        // secret key would also be a change to the public key this is a valid one way function from
522        // the key pair to the digest.
523        let pk = self.public_key();
524        let ser = pk.serialize();
525        ser.hash(state);
526    }
527}
528
529/// Library-internal representation of a ElligatorSwift encoded group element.
530#[repr(C)]
531#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
532pub struct ElligatorSwift([u8; 64]);
533
534impl ElligatorSwift {
535    pub fn from_array(arr: [u8; 64]) -> Self {
536        ElligatorSwift(arr)
537    }
538    pub fn to_array(self) -> [u8; 64] {
539        self.0
540    }
541}
542
543impl_array_newtype!(ElligatorSwift, u8, 64);
544impl_raw_debug!(ElligatorSwift);
545
546extern "C" {
547    /// Default ECDH hash function
548    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdh_hash_function_default")]
549    pub static secp256k1_ecdh_hash_function_default: EcdhHashFn;
550
551    /// Default ECDH hash function for BIP324 key establishment
552    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ellswift_xdh_hash_function_bip324")]
553    pub static secp256k1_ellswift_xdh_hash_function_bip324: EllswiftEcdhHashFn;
554
555    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_nonce_function_rfc6979")]
556    pub static secp256k1_nonce_function_rfc6979: NonceFn;
557
558    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_nonce_function_default")]
559    pub static secp256k1_nonce_function_default: NonceFn;
560
561    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_nonce_function_bip340")]
562    pub static secp256k1_nonce_function_bip340: SchnorrNonceFn;
563
564    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_context_no_precomp")]
565    pub static secp256k1_context_no_precomp: *const Context;
566
567    // Contexts
568    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_context_preallocated_destroy")]
569    pub fn secp256k1_context_preallocated_destroy(cx: NonNull<Context>);
570
571    // Signatures
572    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdsa_signature_parse_der")]
573    pub fn secp256k1_ecdsa_signature_parse_der(cx: *const Context, sig: *mut Signature,
574                                               input: *const c_uchar, in_len: size_t)
575                                               -> c_int;
576
577    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdsa_signature_parse_compact")]
578    pub fn secp256k1_ecdsa_signature_parse_compact(cx: *const Context, sig: *mut Signature,
579                                                   input64: *const c_uchar)
580                                                   -> c_int;
581
582    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdsa_signature_parse_der_lax")]
583    pub fn ecdsa_signature_parse_der_lax(cx: *const Context, sig: *mut Signature,
584                                         input: *const c_uchar, in_len: size_t)
585                                         -> c_int;
586
587    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdsa_signature_serialize_der")]
588    pub fn secp256k1_ecdsa_signature_serialize_der(cx: *const Context, output: *mut c_uchar,
589                                                   out_len: *mut size_t, sig: *const Signature)
590                                                   -> c_int;
591
592    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdsa_signature_serialize_compact")]
593    pub fn secp256k1_ecdsa_signature_serialize_compact(cx: *const Context, output64: *mut c_uchar,
594                                                       sig: *const Signature)
595                                                       -> c_int;
596
597    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdsa_signature_normalize")]
598    pub fn secp256k1_ecdsa_signature_normalize(cx: *const Context, out_sig: *mut Signature,
599                                               in_sig: *const Signature)
600                                               -> c_int;
601
602    // Secret Keys
603    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_seckey_verify")]
604    pub fn secp256k1_ec_seckey_verify(cx: *const Context,
605                                      sk: *const c_uchar) -> c_int;
606
607    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_seckey_negate")]
608    pub fn secp256k1_ec_seckey_negate(cx: *const Context,
609                                      sk: *mut c_uchar) -> c_int;
610
611    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_seckey_tweak_add")]
612    pub fn secp256k1_ec_seckey_tweak_add(cx: *const Context,
613                                        sk: *mut c_uchar,
614                                        tweak: *const c_uchar)
615                                        -> c_int;
616    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_seckey_tweak_mul")]
617    pub fn secp256k1_ec_seckey_tweak_mul(cx: *const Context,
618                                        sk: *mut c_uchar,
619                                        tweak: *const c_uchar)
620                                        -> c_int;
621
622    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_keypair_sec")]
623    pub fn secp256k1_keypair_sec(cx: *const Context,
624                                 output_seckey: *mut c_uchar,
625                                 keypair: *const Keypair)
626                                 -> c_int;
627
628    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_keypair_pub")]
629    pub fn secp256k1_keypair_pub(cx: *const Context,
630                                 output_pubkey: *mut PublicKey,
631                                 keypair: *const Keypair)
632                                 -> c_int;
633    // Elligator Swift
634    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ellswift_encode")]
635    pub fn secp256k1_ellswift_encode(ctx: *const Context,
636                                     ell64: *mut c_uchar,
637                                     pubkey: *const PublicKey,
638                                     rnd32: *const c_uchar)
639                                     -> c_int;
640    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ellswift_decode")]
641    pub fn secp256k1_ellswift_decode(ctx: *const Context,
642                                     pubkey: *mut u8,
643                                     ell64: *const c_uchar)
644                                     -> c_int;
645    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ellswift_create")]
646    pub fn secp256k1_ellswift_create(ctx: *const Context,
647                                     ell64: *mut c_uchar,
648                                     seckey32: *const c_uchar,
649                                     aux_rand32: *const c_uchar)
650                                     -> c_int;
651    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ellswift_xdh")]
652    pub fn secp256k1_ellswift_xdh(ctx: *const Context,
653                                  output: *mut c_uchar,
654                                  ell_a64: *const c_uchar,
655                                  ell_b64: *const c_uchar,
656                                  seckey32: *const c_uchar,
657                                  party: c_int,
658                                  hashfp: EllswiftEcdhHashFn,
659                                  data: *mut c_void)
660                                  -> c_int;
661}
662
663#[cfg(not(secp256k1_fuzz))]
664extern "C" {
665    // Contexts
666    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_context_preallocated_size")]
667    pub fn secp256k1_context_preallocated_size(flags: c_uint) -> size_t;
668
669    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_context_preallocated_create")]
670    pub fn secp256k1_context_preallocated_create(prealloc: NonNull<c_void>, flags: c_uint) -> NonNull<Context>;
671
672    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_context_preallocated_clone_size")]
673    pub fn secp256k1_context_preallocated_clone_size(cx: *const Context) -> size_t;
674
675    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_context_preallocated_clone")]
676    pub fn secp256k1_context_preallocated_clone(cx: *const Context, prealloc: NonNull<c_void>) -> NonNull<Context>;
677
678    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_context_randomize")]
679    pub fn secp256k1_context_randomize(cx: NonNull<Context>,
680                                       seed32: *const c_uchar)
681                                       -> c_int;
682    // Pubkeys
683    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_pubkey_parse")]
684    pub fn secp256k1_ec_pubkey_parse(cx: *const Context, pk: *mut PublicKey,
685                                     input: *const c_uchar, in_len: size_t)
686                                     -> c_int;
687
688    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_pubkey_serialize")]
689    pub fn secp256k1_ec_pubkey_serialize(cx: *const Context, output: *mut c_uchar,
690                                         out_len: *mut size_t, pk: *const PublicKey,
691                                         compressed: c_uint)
692                                         -> c_int;
693
694    // EC
695    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_pubkey_create")]
696    pub fn secp256k1_ec_pubkey_create(cx: *const Context, pk: *mut PublicKey,
697                                      sk: *const c_uchar) -> c_int;
698
699
700    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_pubkey_negate")]
701    pub fn secp256k1_ec_pubkey_negate(cx: *const Context,
702                                      pk: *mut PublicKey) -> c_int;
703
704
705    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_pubkey_cmp")]
706    pub fn secp256k1_ec_pubkey_cmp(cx: *const Context,
707                                   pubkey1: *const PublicKey,
708                                   pubkey2: *const PublicKey)
709                                   -> c_int;
710
711    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_pubkey_tweak_add")]
712    pub fn secp256k1_ec_pubkey_tweak_add(cx: *const Context,
713                                         pk: *mut PublicKey,
714                                         tweak: *const c_uchar)
715                                         -> c_int;
716
717    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_pubkey_tweak_mul")]
718    pub fn secp256k1_ec_pubkey_tweak_mul(cx: *const Context,
719                                         pk: *mut PublicKey,
720                                         tweak: *const c_uchar)
721                                         -> c_int;
722
723    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ec_pubkey_combine")]
724    pub fn secp256k1_ec_pubkey_combine(cx: *const Context,
725                                       out: *mut PublicKey,
726                                       ins: *const *const PublicKey,
727                                       n: size_t)
728                                       -> c_int;
729
730    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdh")]
731    pub fn secp256k1_ecdh(
732        cx: *const Context,
733        output: *mut c_uchar,
734        pubkey: *const PublicKey,
735        seckey: *const c_uchar,
736        hashfp: EcdhHashFn,
737        data: *mut c_void,
738    ) -> c_int;
739
740    // ECDSA
741    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdsa_verify")]
742    pub fn secp256k1_ecdsa_verify(cx: *const Context,
743                                  sig: *const Signature,
744                                  msg32: *const c_uchar,
745                                  pk: *const PublicKey)
746                                  -> c_int;
747
748    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_ecdsa_sign")]
749    pub fn secp256k1_ecdsa_sign(cx: *const Context,
750                                sig: *mut Signature,
751                                msg32: *const c_uchar,
752                                sk: *const c_uchar,
753                                noncefn: NonceFn,
754                                noncedata: *const c_void)
755                                -> c_int;
756
757    // Schnorr Signatures
758    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_schnorrsig_sign")]
759    pub fn secp256k1_schnorrsig_sign(
760        cx: *const Context,
761        sig: *mut c_uchar,
762        msg32: *const c_uchar,
763        keypair: *const Keypair,
764        aux_rand32: *const c_uchar
765    ) -> c_int;
766
767    // Schnorr Signatures with extra parameters (see [`SchnorrSigExtraParams`])
768    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_schnorrsig_sign_custom")]
769    pub fn secp256k1_schnorrsig_sign_custom(
770        cx: *const Context,
771        sig: *mut c_uchar,
772        msg: *const c_uchar,
773        msg_len: size_t,
774        keypair: *const Keypair,
775        extra_params: *const SchnorrSigExtraParams,
776    ) -> c_int;
777
778    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_schnorrsig_verify")]
779    pub fn secp256k1_schnorrsig_verify(
780        cx: *const Context,
781        sig64: *const c_uchar,
782        msg32: *const c_uchar,
783        msglen: size_t,
784        pubkey: *const XOnlyPublicKey,
785    ) -> c_int;
786
787    // Extra keys
788    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_keypair_create")]
789    pub fn secp256k1_keypair_create(
790        cx: *const Context,
791        keypair: *mut Keypair,
792        seckey: *const c_uchar,
793    ) -> c_int;
794
795    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_xonly_pubkey_parse")]
796    pub fn secp256k1_xonly_pubkey_parse(
797        cx: *const Context,
798        pubkey: *mut XOnlyPublicKey,
799        input32: *const c_uchar,
800    ) -> c_int;
801
802    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_xonly_pubkey_serialize")]
803    pub fn secp256k1_xonly_pubkey_serialize(
804        cx: *const Context,
805        output32: *mut c_uchar,
806        pubkey: *const XOnlyPublicKey,
807    ) -> c_int;
808
809    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_xonly_pubkey_from_pubkey")]
810    pub fn secp256k1_xonly_pubkey_from_pubkey(
811        cx: *const Context,
812        xonly_pubkey: *mut XOnlyPublicKey,
813        pk_parity: *mut c_int,
814        pubkey: *const PublicKey,
815    ) -> c_int;
816
817    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_xonly_pubkey_cmp")]
818    pub fn secp256k1_xonly_pubkey_cmp(
819        cx: *const Context,
820        pubkey1: *const XOnlyPublicKey,
821        pubkey2: *const XOnlyPublicKey
822    ) -> c_int;
823
824    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_xonly_pubkey_tweak_add")]
825    pub fn secp256k1_xonly_pubkey_tweak_add(
826        cx: *const Context,
827        output_pubkey: *mut PublicKey,
828        internal_pubkey: *const XOnlyPublicKey,
829        tweak32: *const c_uchar,
830    ) -> c_int;
831
832    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_keypair_xonly_pub")]
833    pub fn secp256k1_keypair_xonly_pub(
834        cx: *const Context,
835        pubkey: *mut XOnlyPublicKey,
836        pk_parity: *mut c_int,
837        keypair: *const Keypair
838    ) -> c_int;
839
840    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_keypair_xonly_tweak_add")]
841    pub fn secp256k1_keypair_xonly_tweak_add(
842        cx: *const Context,
843        keypair: *mut Keypair,
844        tweak32: *const c_uchar,
845    ) -> c_int;
846
847    #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_10_0_xonly_pubkey_tweak_add_check")]
848    pub fn secp256k1_xonly_pubkey_tweak_add_check(
849        cx: *const Context,
850        tweaked_pubkey32: *const c_uchar,
851        tweaked_pubkey_parity: c_int,
852        internal_pubkey: *const XOnlyPublicKey,
853        tweak32: *const c_uchar,
854    ) -> c_int;
855}
856
857/// A reimplementation of the C function `secp256k1_context_create` in rust.
858///
859/// This function allocates memory, the pointer should be deallocated using
860/// `secp256k1_context_destroy`. Failure to do so will result in a memory leak.
861///
862/// Input `flags` control which parts of the context to initialize.
863///
864/// # Safety
865///
866/// This function is unsafe because it calls unsafe functions however (assuming no bugs) no
867/// undefined behavior is possible.
868///
869/// # Returns
870///
871/// The newly created secp256k1 raw context.
872#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
873pub unsafe fn secp256k1_context_create(flags: c_uint) -> NonNull<Context> {
874    rustsecp256k1_v0_10_0_context_create(flags)
875}
876
877/// A reimplementation of the C function `secp256k1_context_create` in rust.
878///
879/// See [`secp256k1_context_create`] for documentation and safety constraints.
880#[no_mangle]
881#[allow(clippy::missing_safety_doc)] // Documented above.
882#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
883pub unsafe extern "C" fn rustsecp256k1_v0_10_0_context_create(flags: c_uint) -> NonNull<Context> {
884    use core::mem;
885    use crate::alloc::alloc;
886    assert!(ALIGN_TO >= mem::align_of::<usize>());
887    assert!(ALIGN_TO >= mem::align_of::<&usize>());
888    assert!(ALIGN_TO >= mem::size_of::<usize>());
889
890    // We need to allocate `ALIGN_TO` more bytes in order to write the amount of bytes back.
891    let bytes = secp256k1_context_preallocated_size(flags) + ALIGN_TO;
892    let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
893    let ptr = alloc::alloc(layout);
894    if ptr.is_null() {
895        alloc::handle_alloc_error(layout);
896    }
897    (ptr as *mut usize).write(bytes);
898    // We must offset a whole ALIGN_TO in order to preserve the same alignment
899    // this means we "lose" ALIGN_TO-size_of(usize) for padding.
900    let ptr = ptr.add(ALIGN_TO);
901    let ptr = NonNull::new_unchecked(ptr as *mut c_void); // Checked above.
902    secp256k1_context_preallocated_create(ptr, flags)
903}
904
905/// A reimplementation of the C function `secp256k1_context_destroy` in rust.
906///
907/// This function destroys and deallcates the context created by `secp256k1_context_create`.
908///
909/// The pointer shouldn't be used after passing to this function, consider it as passing it to `free()`.
910///
911/// # Safety
912///
913///  `ctx` must be a valid pointer to a block of memory created using [`secp256k1_context_create`].
914#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
915pub unsafe fn secp256k1_context_destroy(ctx: NonNull<Context>) {
916    rustsecp256k1_v0_10_0_context_destroy(ctx)
917}
918
919#[no_mangle]
920#[allow(clippy::missing_safety_doc)] // Documented above.
921#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
922pub unsafe extern "C" fn rustsecp256k1_v0_10_0_context_destroy(mut ctx: NonNull<Context>) {
923    use crate::alloc::alloc;
924    secp256k1_context_preallocated_destroy(ctx);
925    let ctx: *mut Context = ctx.as_mut();
926    let ptr = (ctx as *mut u8).sub(ALIGN_TO);
927    let bytes = (ptr as *mut usize).read();
928    let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
929    alloc::dealloc(ptr, layout);
930}
931
932/// **This function is an override for the C function, this is the an edited version of the original description:**
933///
934/// A callback function to be called when an illegal argument is passed to
935/// an API call. It will only trigger for violations that are mentioned
936/// explicitly in the header. **This will cause a panic**.
937///
938/// The philosophy is that these shouldn't be dealt with through a
939/// specific return value, as calling code should not have branches to deal with
940/// the case that this code itself is broken.
941///
942/// On the other hand, during debug stage, one would want to be informed about
943/// such mistakes, and the default (crashing) may be inadvisable.
944/// When this callback is triggered, the API function called is guaranteed not
945/// to cause a crash, though its return value and output arguments are
946/// undefined.
947///
948/// See also secp256k1_default_error_callback_fn.
949///
950///
951/// # Safety
952///
953/// `message` string should be a null terminated C string and, up to the first null byte, must be valid UTF8.
954///
955/// For exact safety constraints see [`std::slice::from_raw_parts`] and [`std::str::from_utf8_unchecked`].
956#[no_mangle]
957#[cfg(not(rust_secp_no_symbol_renaming))]
958pub unsafe extern "C" fn rustsecp256k1_v0_10_0_default_illegal_callback_fn(message: *const c_char, _data: *mut c_void) {
959    use core::str;
960    let msg_slice = slice::from_raw_parts(message as *const u8, strlen(message));
961    let msg = str::from_utf8_unchecked(msg_slice);
962    panic!("[libsecp256k1] illegal argument. {}", msg);
963}
964
965/// **This function is an override for the C function, this is the an edited version of the original description:**
966///
967/// A callback function to be called when an internal consistency check
968/// fails. **This will cause a panic**.
969///
970/// This can only trigger in case of a hardware failure, miscompilation,
971/// memory corruption, serious bug in the library, or other error would can
972/// otherwise result in undefined behaviour. It will not trigger due to mere
973/// incorrect usage of the API (see secp256k1_default_illegal_callback_fn
974/// for that). After this callback returns, anything may happen, including
975/// crashing.
976///
977/// See also secp256k1_default_illegal_callback_fn.
978///
979/// # Safety
980///
981/// `message` string should be a null terminated C string and, up to the first null byte, must be valid UTF8.
982///
983/// For exact safety constraints see [`std::slice::from_raw_parts`] and [`std::str::from_utf8_unchecked`].
984#[no_mangle]
985#[cfg(not(rust_secp_no_symbol_renaming))]
986pub unsafe extern "C" fn rustsecp256k1_v0_10_0_default_error_callback_fn(message: *const c_char, _data: *mut c_void) {
987    use core::str;
988    let msg_slice = slice::from_raw_parts(message as *const u8, strlen(message));
989    let msg = str::from_utf8_unchecked(msg_slice);
990    panic!("[libsecp256k1] internal consistency check failed {}", msg);
991}
992
993/// Returns the length of the `str_ptr` string.
994///
995/// # Safety
996///
997/// `str_ptr` must be valid pointer and point to a valid null terminated C string.
998#[cfg(not(rust_secp_no_symbol_renaming))]
999unsafe fn strlen(mut str_ptr: *const c_char) -> usize {
1000    let mut ctr = 0;
1001    while *str_ptr != '\0' as c_char {
1002        ctr += 1;
1003        str_ptr = str_ptr.offset(1);
1004    }
1005    ctr
1006}
1007
1008
1009/// A trait for producing pointers that will always be valid in C (assuming NULL pointer is a valid
1010/// no-op).
1011///
1012/// Rust does not guarantee pointers to Zero Sized Types
1013/// (<https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts>). In case the type
1014/// is empty this trait will return a NULL pointer, which should be handled in C.
1015pub trait CPtr {
1016    type Target;
1017    fn as_c_ptr(&self) -> *const Self::Target;
1018    fn as_mut_c_ptr(&mut self) -> *mut Self::Target;
1019}
1020
1021impl<T> CPtr for [T] {
1022    type Target = T;
1023    fn as_c_ptr(&self) -> *const Self::Target {
1024        if self.is_empty() {
1025            ptr::null()
1026        } else {
1027            self.as_ptr()
1028        }
1029    }
1030
1031    fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1032        if self.is_empty() {
1033            ptr::null_mut::<Self::Target>()
1034        } else {
1035            self.as_mut_ptr()
1036        }
1037    }
1038}
1039
1040impl<T> CPtr for &[T] {
1041    type Target = T;
1042    fn as_c_ptr(&self) -> *const Self::Target {
1043        if self.is_empty() {
1044            ptr::null()
1045        } else {
1046            self.as_ptr()
1047        }
1048    }
1049
1050    fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1051        if self.is_empty() {
1052            ptr::null_mut()
1053        } else {
1054            self.as_ptr() as *mut Self::Target
1055        }
1056    }
1057    
1058}
1059
1060impl CPtr for [u8; 32] {
1061    type Target = u8;
1062    fn as_c_ptr(&self) -> *const Self::Target {
1063        self.as_ptr()
1064    }
1065
1066    fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1067        self.as_mut_ptr()
1068    }
1069}
1070
1071impl <T: CPtr> CPtr for Option<T> {
1072    type Target = T::Target;
1073    fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1074        match self {
1075            Some(contents) => contents.as_mut_c_ptr(),
1076            None => ptr::null_mut(),
1077        }
1078    }
1079    fn as_c_ptr(&self) -> *const Self::Target {
1080        match self {
1081            Some(content) => content.as_c_ptr(),
1082            None => ptr::null(),
1083        }
1084    }
1085}
1086
1087#[cfg(secp256k1_fuzz)]
1088mod fuzz_dummy {
1089    use super::*;
1090    use core::sync::atomic::{AtomicUsize, Ordering};
1091
1092    #[cfg(rust_secp_no_symbol_renaming)] compile_error!("We do not support fuzzing with rust_secp_no_symbol_renaming");
1093
1094    extern "C" {
1095        fn rustsecp256k1_v0_10_0_context_preallocated_size(flags: c_uint) -> size_t;
1096        fn rustsecp256k1_v0_10_0_context_preallocated_create(prealloc: NonNull<c_void>, flags: c_uint) -> NonNull<Context>;
1097        fn rustsecp256k1_v0_10_0_context_preallocated_clone(cx: *const Context, prealloc: NonNull<c_void>) -> NonNull<Context>;
1098    }
1099
1100    #[cfg(feature = "lowmemory")]
1101    const CTX_SIZE: usize = 1024 * 65;
1102    #[cfg(not(feature = "lowmemory"))]
1103    const CTX_SIZE: usize = 1024 * (1024 + 128);
1104    // Contexts
1105    pub unsafe fn secp256k1_context_preallocated_size(flags: c_uint) -> size_t {
1106        assert!(rustsecp256k1_v0_10_0_context_preallocated_size(flags) + std::mem::size_of::<c_uint>() <= CTX_SIZE);
1107        CTX_SIZE
1108    }
1109
1110    static HAVE_PREALLOCATED_CONTEXT: AtomicUsize = AtomicUsize::new(0);
1111    const HAVE_CONTEXT_NONE: usize = 0;
1112    const HAVE_CONTEXT_WORKING: usize = 1;
1113    const HAVE_CONTEXT_DONE: usize = 2;
1114    static mut PREALLOCATED_CONTEXT: [u8; CTX_SIZE] = [0; CTX_SIZE];
1115    pub unsafe fn secp256k1_context_preallocated_create(prealloc: NonNull<c_void>, flags: c_uint) -> NonNull<Context> {
1116        // While applications should generally avoid creating too many contexts, sometimes fuzzers
1117        // perform tasks repeatedly which real applications may only do rarely. Thus, we want to
1118        // avoid being overly slow here. We do so by having a static context and copying it into
1119        // new buffers instead of recalculating it. Because we shouldn't rely on std, we use a
1120        // simple hand-written OnceFlag built out of an atomic to gate the global static.
1121        let mut have_ctx = HAVE_PREALLOCATED_CONTEXT.load(Ordering::Relaxed);
1122        while have_ctx != HAVE_CONTEXT_DONE {
1123            if have_ctx == HAVE_CONTEXT_NONE {
1124                have_ctx = HAVE_PREALLOCATED_CONTEXT.swap(HAVE_CONTEXT_WORKING, Ordering::AcqRel);
1125                if have_ctx == HAVE_CONTEXT_NONE {
1126                    assert!(rustsecp256k1_v0_10_0_context_preallocated_size(SECP256K1_START_SIGN | SECP256K1_START_VERIFY) + std::mem::size_of::<c_uint>() <= CTX_SIZE);
1127                    assert_eq!(rustsecp256k1_v0_10_0_context_preallocated_create(
1128                            NonNull::new_unchecked(PREALLOCATED_CONTEXT[..].as_mut_ptr() as *mut c_void),
1129                            SECP256K1_START_SIGN | SECP256K1_START_VERIFY),
1130                        NonNull::new_unchecked(PREALLOCATED_CONTEXT[..].as_mut_ptr() as *mut Context));
1131                    assert_eq!(HAVE_PREALLOCATED_CONTEXT.swap(HAVE_CONTEXT_DONE, Ordering::AcqRel),
1132                        HAVE_CONTEXT_WORKING);
1133                } else if have_ctx == HAVE_CONTEXT_DONE {
1134                    // Another thread finished while we were swapping.
1135                    HAVE_PREALLOCATED_CONTEXT.store(HAVE_CONTEXT_DONE, Ordering::Release);
1136                }
1137            } else {
1138                // Another thread is building, just busy-loop until they're done.
1139                assert_eq!(have_ctx, HAVE_CONTEXT_WORKING);
1140                have_ctx = HAVE_PREALLOCATED_CONTEXT.load(Ordering::Acquire);
1141                #[cfg(feature = "std")]
1142                std::thread::yield_now();
1143            }
1144        }
1145        ptr::copy_nonoverlapping(PREALLOCATED_CONTEXT[..].as_ptr(), prealloc.as_ptr() as *mut u8, CTX_SIZE);
1146        let ptr = (prealloc.as_ptr()).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1147        (ptr as *mut c_uint).write(flags);
1148        NonNull::new_unchecked(prealloc.as_ptr() as *mut Context)
1149    }
1150    pub unsafe fn secp256k1_context_preallocated_clone_size(_cx: *const Context) -> size_t { CTX_SIZE }
1151    pub unsafe fn secp256k1_context_preallocated_clone(cx: *const Context, prealloc: NonNull<c_void>) -> NonNull<Context> {
1152        let orig_ptr = (cx as *mut u8).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1153        let new_ptr = (prealloc.as_ptr() as *mut u8).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1154        let flags = (orig_ptr as *mut c_uint).read();
1155        (new_ptr as *mut c_uint).write(flags);
1156        rustsecp256k1_v0_10_0_context_preallocated_clone(cx, prealloc)
1157    }
1158
1159    pub unsafe fn secp256k1_context_randomize(cx: NonNull<Context>,
1160                                              _seed32: *const c_uchar)
1161                                              -> c_int {
1162        // This function is really slow, and unsuitable for fuzzing
1163        check_context_flags(cx.as_ptr(), 0);
1164        1
1165    }
1166
1167    unsafe fn check_context_flags(cx: *const Context, required_flags: c_uint) {
1168        assert!(!cx.is_null());
1169        let cx_flags = if cx == secp256k1_context_no_precomp {
1170            1
1171        } else {
1172            let ptr = (cx as *const u8).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1173            (ptr as *const c_uint).read()
1174        };
1175        assert_eq!(cx_flags & 1, 1); // SECP256K1_FLAGS_TYPE_CONTEXT
1176        assert_eq!(cx_flags & required_flags, required_flags);
1177    }
1178
1179    /// Checks that pk != 0xffff...ffff and pk[1..32] == pk[33..64]
1180    unsafe fn test_pk_validate(cx: *const Context,
1181                               pk: *const PublicKey) -> c_int {
1182        check_context_flags(cx, 0);
1183        if (*pk).0[1..32] != (*pk).0[33..64] ||
1184           ((*pk).0[32] != 0 && (*pk).0[32] != 0xff) ||
1185           secp256k1_ec_seckey_verify(cx, (*pk).0[0..32].as_ptr()) == 0 {
1186            0
1187        } else {
1188            1
1189        }
1190    }
1191    unsafe fn test_cleanup_pk(pk: *mut PublicKey) {
1192        (*pk).0[32..].copy_from_slice(&(*pk).0[..32]);
1193        if (*pk).0[32] <= 0x7f {
1194            (*pk).0[32] = 0;
1195        } else {
1196            (*pk).0[32] = 0xff;
1197        }
1198    }
1199
1200    // Pubkeys
1201    pub unsafe fn secp256k1_ec_pubkey_parse(cx: *const Context, pk: *mut PublicKey,
1202                                            input: *const c_uchar, in_len: size_t)
1203                                            -> c_int {
1204        check_context_flags(cx, 0);
1205        match in_len {
1206            33 => {
1207                if *input != 2 && *input != 3 {
1208                    0
1209                } else {
1210                    ptr::copy(input.offset(1), (*pk).0[0..32].as_mut_ptr(), 32);
1211                    ptr::copy(input.offset(2), (*pk).0[33..64].as_mut_ptr(), 31);
1212                    if *input == 3 {
1213                        (*pk).0[32] = 0xff;
1214                    } else {
1215                        (*pk).0[32] = 0;
1216                    }
1217                    test_pk_validate(cx, pk)
1218                }
1219            },
1220            65 => {
1221                if *input != 4 && *input != 6 && *input != 7 {
1222                    0
1223                } else {
1224                    ptr::copy(input.offset(1), (*pk).0.as_mut_ptr(), 64);
1225                    test_cleanup_pk(pk);
1226                    test_pk_validate(cx, pk)
1227                }
1228            },
1229            _ => 0
1230        }
1231    }
1232
1233    /// Serialize PublicKey back to 33/65 byte pubkey
1234    pub unsafe fn secp256k1_ec_pubkey_serialize(cx: *const Context, output: *mut c_uchar,
1235                                                out_len: *mut size_t, pk: *const PublicKey,
1236                                                compressed: c_uint)
1237                                                -> c_int {
1238        check_context_flags(cx, 0);
1239        assert_eq!(test_pk_validate(cx, pk), 1);
1240        if compressed == SECP256K1_SER_COMPRESSED {
1241            assert_eq!(*out_len, 33);
1242            if (*pk).0[32] <= 0x7f {
1243                *output = 2;
1244            } else {
1245                *output = 3;
1246            }
1247            ptr::copy((*pk).0.as_ptr(), output.offset(1), 32);
1248        } else if compressed == SECP256K1_SER_UNCOMPRESSED {
1249            assert_eq!(*out_len, 65);
1250            *output = 4;
1251            ptr::copy((*pk).0.as_ptr(), output.offset(1), 64);
1252        } else {
1253            panic!("Bad flags");
1254        }
1255        1
1256     }
1257
1258    // EC
1259    /// Sets pk to sk||sk
1260    pub unsafe fn secp256k1_ec_pubkey_create(cx: *const Context, pk: *mut PublicKey,
1261                                             sk: *const c_uchar) -> c_int {
1262        check_context_flags(cx, SECP256K1_START_SIGN);
1263        if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
1264        ptr::copy(sk, (*pk).0[0..32].as_mut_ptr(), 32);
1265        test_cleanup_pk(pk);
1266        assert_eq!(test_pk_validate(cx, pk), 1);
1267        1
1268    }
1269
1270    pub unsafe fn secp256k1_ec_pubkey_negate(cx: *const Context,
1271                                             pk: *mut PublicKey) -> c_int {
1272        check_context_flags(cx, 0);
1273        assert_eq!(test_pk_validate(cx, pk), 1);
1274        if secp256k1_ec_seckey_negate(cx, (*pk).0[..32].as_mut_ptr()) != 1 { return 0; }
1275        test_cleanup_pk(pk);
1276        assert_eq!(test_pk_validate(cx, pk), 1);
1277        1
1278    }
1279
1280    /// The PublicKey equivalent of secp256k1_ec_privkey_tweak_add
1281    pub unsafe fn secp256k1_ec_pubkey_tweak_add(cx: *const Context,
1282                                                pk: *mut PublicKey,
1283                                                tweak: *const c_uchar)
1284                                                -> c_int {
1285        check_context_flags(cx, SECP256K1_START_VERIFY);
1286        assert_eq!(test_pk_validate(cx, pk), 1);
1287        if secp256k1_ec_seckey_tweak_add(cx, (*pk).0[..32].as_mut_ptr(), tweak) != 1 { return 0; }
1288        test_cleanup_pk(pk);
1289        assert_eq!(test_pk_validate(cx, pk), 1);
1290        1
1291    }
1292
1293    /// The PublicKey equivalent of secp256k1_ec_privkey_tweak_mul
1294    pub unsafe fn secp256k1_ec_pubkey_tweak_mul(cx: *const Context,
1295                                                pk: *mut PublicKey,
1296                                                tweak: *const c_uchar)
1297                                                -> c_int {
1298        check_context_flags(cx, 0);
1299        assert_eq!(test_pk_validate(cx, pk), 1);
1300        if secp256k1_ec_seckey_tweak_mul(cx, (*pk).0[..32].as_mut_ptr(), tweak) != 1 { return 0; }
1301        test_cleanup_pk(pk);
1302        assert_eq!(test_pk_validate(cx, pk), 1);
1303        1
1304    }
1305
1306    pub unsafe fn secp256k1_ec_pubkey_combine(cx: *const Context,
1307                                              out: *mut PublicKey,
1308                                              ins: *const *const PublicKey,
1309                                              n: size_t)
1310                                              -> c_int {
1311        check_context_flags(cx, 0);
1312        assert!(n >= 1);
1313        (*out) = **ins;
1314        for i in 1..n {
1315            assert_eq!(test_pk_validate(cx, *ins.offset(i as isize)), 1);
1316            if secp256k1_ec_seckey_tweak_add(cx, (*out).0[..32].as_mut_ptr(), (**ins.offset(i as isize)).0[..32].as_ptr()) != 1 {
1317                return 0;
1318            }
1319        }
1320        test_cleanup_pk(out);
1321        assert_eq!(test_pk_validate(cx, out), 1);
1322        1
1323    }
1324
1325    /// Sets out to point^scalar^1s
1326    pub unsafe fn secp256k1_ecdh(
1327        cx: *const Context,
1328        out: *mut c_uchar,
1329        point: *const PublicKey,
1330        scalar: *const c_uchar,
1331        hashfp: EcdhHashFn,
1332        data: *mut c_void,
1333    ) -> c_int {
1334        check_context_flags(cx, 0);
1335        assert_eq!(test_pk_validate(cx, point), 1);
1336        if secp256k1_ec_seckey_verify(cx, scalar) != 1 { return 0; }
1337
1338        let scalar_slice = slice::from_raw_parts(scalar, 32);
1339        let pk_slice = &(*point).0[..32];
1340
1341        let mut res_arr = [0u8; 32];
1342        for i in 0..32 {
1343            res_arr[i] = scalar_slice[i] ^ pk_slice[i] ^ 1;
1344        }
1345
1346        if let Some(hashfn) = hashfp {
1347            (hashfn)(out, res_arr.as_ptr(), res_arr.as_ptr(), data);
1348        } else {
1349            res_arr[16] = 0x00; // result should always be a valid secret key
1350            let out_slice = slice::from_raw_parts_mut(out, 32);
1351            out_slice.copy_from_slice(&res_arr);
1352        }
1353        1
1354    }
1355
1356    // ECDSA
1357    /// Verifies that sig is msg32||pk[..32]
1358    pub unsafe fn secp256k1_ecdsa_verify(cx: *const Context,
1359                                         sig: *const Signature,
1360                                         msg32: *const c_uchar,
1361                                         pk: *const PublicKey)
1362                                         -> c_int {
1363        check_context_flags(cx, SECP256K1_START_VERIFY);
1364        // Actually verify
1365        let sig_sl = slice::from_raw_parts(sig as *const u8, 64);
1366        let msg_sl = slice::from_raw_parts(msg32 as *const u8, 32);
1367        if &sig_sl[..32] == msg_sl && sig_sl[32..] == (*pk).0[0..32] {
1368            1
1369        } else {
1370            0
1371        }
1372    }
1373
1374    /// Sets sig to msg32||pk[..32]
1375    pub unsafe fn secp256k1_ecdsa_sign(cx: *const Context,
1376                                       sig: *mut Signature,
1377                                       msg32: *const c_uchar,
1378                                       sk: *const c_uchar,
1379                                       _noncefn: NonceFn,
1380                                       _noncedata: *const c_void)
1381                                       -> c_int {
1382        check_context_flags(cx, SECP256K1_START_SIGN);
1383        // Check context is built for signing (and compute pk)
1384        let mut new_pk = PublicKey::new();
1385        if secp256k1_ec_pubkey_create(cx, &mut new_pk, sk) != 1 {
1386            return 0;
1387        }
1388        // Sign
1389        let sig_sl = slice::from_raw_parts_mut(sig as *mut u8, 64);
1390        let msg_sl = slice::from_raw_parts(msg32 as *const u8, 32);
1391        sig_sl[..32].copy_from_slice(msg_sl);
1392        sig_sl[32..].copy_from_slice(&new_pk.0[..32]);
1393        1
1394    }
1395
1396    // Schnorr Signatures
1397    /// Verifies that sig is msg32||pk[32..]
1398    pub unsafe fn secp256k1_schnorrsig_verify(
1399        cx: *const Context,
1400        sig64: *const c_uchar,
1401        msg32: *const c_uchar,
1402        msglen: size_t,
1403        pubkey: *const XOnlyPublicKey,
1404    ) -> c_int {
1405        check_context_flags(cx, SECP256K1_START_VERIFY);
1406        // Check context is built for verification
1407        let mut new_pk = PublicKey::new();
1408        let _ = secp256k1_xonly_pubkey_tweak_add(cx, &mut new_pk, pubkey, msg32);
1409        // Actually verify
1410        let sig_sl = slice::from_raw_parts(sig64 as *const u8, 64);
1411        let msg_sl = slice::from_raw_parts(msg32 as *const u8, msglen);
1412        if &sig_sl[..32] == msg_sl && sig_sl[32..] == (*pubkey).0[..32] {
1413            1
1414        } else {
1415            0
1416        }
1417    }
1418
1419    /// Sets sig to msg32||pk[..32]
1420    pub unsafe fn secp256k1_schnorrsig_sign(
1421        cx: *const Context,
1422        sig64: *mut c_uchar,
1423        msg32: *const c_uchar,
1424        keypair: *const Keypair,
1425        _aux_rand32: *const c_uchar
1426    ) -> c_int {
1427        check_context_flags(cx, SECP256K1_START_SIGN);
1428        // Check context is built for signing
1429        let mut new_kp = Keypair::new();
1430        if secp256k1_keypair_create(cx, &mut new_kp, (*keypair).0.as_ptr()) != 1 {
1431            return 0;
1432        }
1433        assert_eq!(new_kp, *keypair);
1434        // Sign
1435        let sig_sl = slice::from_raw_parts_mut(sig64 as *mut u8, 64);
1436        let msg_sl = slice::from_raw_parts(msg32 as *const u8, 32);
1437        sig_sl[..32].copy_from_slice(msg_sl);
1438        sig_sl[32..].copy_from_slice(&new_kp.0[32..64]);
1439        1
1440    }
1441
1442
1443    // Forwards to regular schnorrsig_sign function.
1444    pub unsafe fn secp256k1_schnorrsig_sign_custom(
1445        cx: *const Context,
1446        sig: *mut c_uchar,
1447        msg: *const c_uchar,
1448        _msg_len: size_t,
1449        keypair: *const Keypair,
1450        _extra_params: *const SchnorrSigExtraParams,
1451    ) -> c_int {
1452        secp256k1_schnorrsig_sign(cx, sig, msg, keypair, ptr::null())
1453    }
1454
1455    // Extra keys
1456    pub unsafe fn secp256k1_keypair_create(
1457        cx: *const Context,
1458        keypair: *mut Keypair,
1459        seckey: *const c_uchar,
1460    ) -> c_int {
1461        check_context_flags(cx, SECP256K1_START_SIGN);
1462        if secp256k1_ec_seckey_verify(cx, seckey) == 0 { return 0; }
1463
1464        let mut pk = PublicKey::new();
1465        if secp256k1_ec_pubkey_create(cx, &mut pk, seckey) == 0 { return 0; }
1466
1467        let seckey_slice = slice::from_raw_parts(seckey, 32);
1468        (*keypair).0[..32].copy_from_slice(seckey_slice);
1469        (*keypair).0[32..].copy_from_slice(&pk.0);
1470        1
1471    }
1472
1473    pub unsafe fn secp256k1_xonly_pubkey_parse(
1474        cx: *const Context,
1475        pubkey: *mut XOnlyPublicKey,
1476        input32: *const c_uchar,
1477    ) -> c_int {
1478        check_context_flags(cx, 0);
1479        let inslice = slice::from_raw_parts(input32, 32);
1480        (*pubkey).0[..32].copy_from_slice(inslice);
1481        (*pubkey).0[32..].copy_from_slice(inslice);
1482        test_cleanup_pk(pubkey as *mut PublicKey);
1483        test_pk_validate(cx, pubkey as *mut PublicKey)
1484    }
1485
1486    pub unsafe fn secp256k1_xonly_pubkey_serialize(
1487        cx: *const Context,
1488        output32: *mut c_uchar,
1489        pubkey: *const XOnlyPublicKey,
1490    ) -> c_int {
1491        check_context_flags(cx, 0);
1492        let outslice = slice::from_raw_parts_mut(output32, 32);
1493        outslice.copy_from_slice(&(*pubkey).0[..32]);
1494        1
1495    }
1496
1497    pub unsafe fn secp256k1_xonly_pubkey_from_pubkey(
1498        cx: *const Context,
1499        xonly_pubkey: *mut XOnlyPublicKey,
1500        pk_parity: *mut c_int,
1501        pubkey: *const PublicKey,
1502    ) -> c_int {
1503        check_context_flags(cx, 0);
1504        if !pk_parity.is_null() {
1505            *pk_parity = ((*pubkey).0[32] == 0).into();
1506        }
1507        (*xonly_pubkey).0.copy_from_slice(&(*pubkey).0);
1508        assert_eq!(test_pk_validate(cx, pubkey), 1);
1509        1
1510    }
1511
1512    pub unsafe fn secp256k1_xonly_pubkey_tweak_add(
1513        cx: *const Context,
1514        output_pubkey: *mut PublicKey,
1515        internal_pubkey: *const XOnlyPublicKey,
1516        tweak32: *const c_uchar,
1517    ) -> c_int {
1518        check_context_flags(cx, SECP256K1_START_VERIFY);
1519        (*output_pubkey).0.copy_from_slice(&(*internal_pubkey).0);
1520        secp256k1_ec_pubkey_tweak_add(cx, output_pubkey, tweak32)
1521    }
1522
1523    pub unsafe fn secp256k1_keypair_xonly_pub(
1524        cx: *const Context,
1525        pubkey: *mut XOnlyPublicKey,
1526        pk_parity: *mut c_int,
1527        keypair: *const Keypair
1528    ) -> c_int {
1529        check_context_flags(cx, 0);
1530        if !pk_parity.is_null() {
1531            *pk_parity = ((*keypair).0[64] == 0).into();
1532        }
1533        (*pubkey).0.copy_from_slice(&(*keypair).0[32..]);
1534        1
1535    }
1536
1537    pub unsafe fn secp256k1_keypair_xonly_tweak_add(
1538        cx: *const Context,
1539        keypair: *mut Keypair,
1540        tweak32: *const c_uchar,
1541    ) -> c_int {
1542        check_context_flags(cx, SECP256K1_START_VERIFY);
1543        let mut pk = PublicKey::new();
1544        pk.0.copy_from_slice(&(*keypair).0[32..]);
1545        let mut sk = [0u8; 32];
1546        sk.copy_from_slice(&(*keypair).0[..32]);
1547        assert_eq!(secp256k1_ec_pubkey_tweak_add(cx, &mut pk, tweak32), 1);
1548        assert_eq!(secp256k1_ec_seckey_tweak_add(cx, (&mut sk[..]).as_mut_ptr(), tweak32), 1);
1549        (*keypair).0[..32].copy_from_slice(&sk);
1550        (*keypair).0[32..].copy_from_slice(&pk.0);
1551        1
1552    }
1553
1554    pub unsafe fn secp256k1_xonly_pubkey_tweak_add_check(
1555        cx: *const Context,
1556        tweaked_pubkey32: *const c_uchar,
1557        tweaked_pubkey_parity: c_int,
1558        internal_pubkey: *const XOnlyPublicKey,
1559        tweak32: *const c_uchar,
1560    ) -> c_int {
1561        check_context_flags(cx, SECP256K1_START_VERIFY);
1562        let mut tweaked_pk = PublicKey::new();
1563        assert_eq!(secp256k1_xonly_pubkey_tweak_add(cx, &mut tweaked_pk, internal_pubkey, tweak32), 1);
1564        let in_slice = slice::from_raw_parts(tweaked_pubkey32, 32);
1565        if &tweaked_pk.0[..32] == in_slice && tweaked_pubkey_parity == (tweaked_pk.0[32] == 0).into() {
1566            1
1567        } else {
1568            0
1569        }
1570    }
1571}
1572
1573#[cfg(secp256k1_fuzz)]
1574pub use self::fuzz_dummy::*;
1575
1576#[cfg(test)]
1577mod tests {
1578    #[cfg(not(rust_secp_no_symbol_renaming))]
1579    #[test]
1580    fn test_strlen() {
1581        use std::ffi::CString;
1582        use super::strlen;
1583
1584        let orig = "test strlen \t \n";
1585        let test = CString::new(orig).unwrap();
1586
1587        assert_eq!(orig.len(), unsafe {strlen(test.as_ptr())});
1588    }
1589}
1590