1#![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
31pub const SECP256K1_START_NONE: c_uint = 1;
33pub const SECP256K1_START_VERIFY: c_uint = 1 | (1 << 8);
35pub const SECP256K1_START_SIGN: c_uint = 1 | (1 << 9);
37#[allow(unused_parens)]
39pub const SECP256K1_SER_UNCOMPRESSED: c_uint = (1 << 1);
40pub const SECP256K1_SER_COMPRESSED: c_uint = (1 << 1) | (1 << 8);
42
43pub 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
62pub 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
73pub 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
95pub 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#[repr(C)]
108pub struct SchnorrSigExtraParams {
109 magic: [c_uchar; 4],
110 nonce_fp: SchnorrNonceFn,
111 ndata: *const c_void,
112}
113
114impl SchnorrSigExtraParams {
115 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#[derive(Clone, Debug)]
144#[repr(C)]
145pub struct Context(c_int);
146
147#[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 pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 64]) }
164
165 pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self { PublicKey(data) }
175
176 pub fn underlying_bytes(self) -> [c_uchar; 64] { self.0 }
181
182 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#[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 pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 64]) }
249
250 pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self { Signature(data) }
260
261 pub fn underlying_bytes(self) -> [c_uchar; 64] { self.0 }
266
267 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 pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 64]) }
330
331 pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self { XOnlyPublicKey(data) }
341
342 pub fn underlying_bytes(self) -> [c_uchar; 64] { self.0 }
347
348 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 pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 96]) }
410
411 pub unsafe fn from_array_unchecked(data: [c_uchar; 96]) -> Self { Keypair(data) }
421
422 pub fn underlying_bytes(self) -> [c_uchar; 96] { self.0 }
427
428 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 #[inline]
445 pub fn non_secure_erase(&mut self) { non_secure_erase_impl(&mut self.0, DUMMY_KEYPAIR); }
446}
447
448#[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#[inline(always)]
478pub fn non_secure_erase_impl<T>(dst: &mut T, src: T) {
479 use core::sync::atomic;
480 unsafe {
482 ptr::write_volatile(dst, src);
483 }
484
485 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 let pk = self.public_key();
518 let ser = pk.serialize();
519 ser.hash(state);
520 }
521}
522
523#[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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#[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#[no_mangle]
1225#[allow(clippy::missing_safety_doc)] #[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 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 let ptr = ptr.add(ALIGN_TO);
1246 let ptr = NonNull::new_unchecked(ptr as *mut c_void); secp256k1_context_preallocated_create(ptr, flags)
1248}
1249
1250#[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)] #[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#[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#[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#[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
1359pub 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}
1412pub const MUSIG_KEYAGG_SIZE: usize = 197;
1416
1417pub const MUSIG_SECNONCE_SIZE: usize = 132;
1421
1422pub const MUSIG_PUBNONCE_SIZE: usize = 132;
1426
1427pub const MUSIG_AGGNONCE_SIZE: usize = 132;
1431
1432pub const MUSIG_SESSION_SIZE: usize = 133;
1436
1437pub 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 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 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 HAVE_PREALLOCATED_CONTEXT.store(HAVE_CONTEXT_DONE, Ordering::Release);
1562 }
1563 } else {
1564 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 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); assert_eq!(cx_flags & required_flags, required_flags);
1614 }
1615
1616 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 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 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 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 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 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 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; let out_slice = slice::from_raw_parts_mut(out, 32);
1812 out_slice.copy_from_slice(&res_arr);
1813 }
1814 1
1815 }
1816
1817 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 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 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 let mut new_pk = PublicKey::new();
1848 if secp256k1_ec_pubkey_create(cx, &mut new_pk, sk) != 1 {
1849 return 0;
1850 }
1851 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 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 let mut new_pk = PublicKey::new();
1871 let _ = secp256k1_xonly_pubkey_tweak_add(cx, &mut new_pk, pubkey, msg32);
1872 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 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 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 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 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 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}