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#![cfg_attr(docsrs, feature(doc_auto_cfg))]
11
12#[cfg(any(test, feature = "std"))]
13extern crate core;
14
15#[cfg(feature = "alloc")]
16extern crate alloc;
17
18#[cfg(secp256k1_fuzz)]
19const THIS_UNUSED_CONSTANT_IS_YOUR_WARNING_THAT_ALL_THE_CRYPTO_IN_THIS_LIB_IS_DISABLED_FOR_FUZZING: usize = 0;
20
21mod macros;
22pub mod types;
23
24#[cfg(feature = "recovery")]
25pub mod recovery;
26
27use core::ptr::NonNull;
28use core::{ptr, slice};
29
30use types::*;
31
32pub const SECP256K1_START_NONE: c_uint = 1;
34pub const SECP256K1_START_VERIFY: c_uint = 1 | (1 << 8);
36pub const SECP256K1_START_SIGN: c_uint = 1 | (1 << 9);
38#[allow(unused_parens)]
40pub const SECP256K1_SER_UNCOMPRESSED: c_uint = (1 << 1);
41pub const SECP256K1_SER_COMPRESSED: c_uint = (1 << 1) | (1 << 8);
43
44pub type NonceFn = Option<
53 unsafe extern "C" fn(
54 nonce32: *mut c_uchar,
55 msg32: *const c_uchar,
56 key32: *const c_uchar,
57 algo16: *const c_uchar,
58 data: *mut c_void,
59 attempt: c_uint,
60 ) -> c_int,
61>;
62
63pub type EcdhHashFn = Option<
66 unsafe extern "C" fn(
67 output: *mut c_uchar,
68 x: *const c_uchar,
69 y: *const c_uchar,
70 data: *mut c_void,
71 ) -> c_int,
72>;
73
74pub type SchnorrNonceFn = Option<
84 unsafe extern "C" fn(
85 nonce32: *mut c_uchar,
86 msg32: *const c_uchar,
87 msg_len: size_t,
88 key32: *const c_uchar,
89 xonly_pk32: *const c_uchar,
90 algo16: *const c_uchar,
91 algo_len: size_t,
92 data: *mut c_void,
93 ) -> c_int,
94>;
95
96pub type EllswiftEcdhHashFn = Option<
98 unsafe extern "C" fn(
99 output: *mut c_uchar,
100 x32: *const c_uchar,
101 ell_a64: *const c_uchar,
102 ell_b64: *const c_uchar,
103 data: *mut c_void,
104 ) -> c_int,
105>;
106
107#[repr(C)]
109pub struct SchnorrSigExtraParams {
110 magic: [c_uchar; 4],
111 nonce_fp: SchnorrNonceFn,
112 ndata: *const c_void,
113}
114
115impl SchnorrSigExtraParams {
116 pub fn new(nonce_fp: SchnorrNonceFn, ndata: *const c_void) -> Self {
127 SchnorrSigExtraParams { magic: [0xda, 0x6f, 0xb3, 0x8c], nonce_fp, ndata }
128 }
129}
130
131#[derive(Clone, Debug)]
145#[repr(C)]
146pub struct Context(c_int);
147
148#[repr(C)]
150#[derive(Copy, Clone)]
151#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
152pub struct PublicKey([c_uchar; 64]);
153impl_array_newtype!(PublicKey, c_uchar, 64);
154impl_raw_debug!(PublicKey);
155
156impl PublicKey {
157 pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 64]) }
165
166 pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self { PublicKey(data) }
176
177 pub fn underlying_bytes(self) -> [c_uchar; 64] { self.0 }
182
183 fn serialize(&self) -> [u8; 33] {
185 let mut buf = [0u8; 33];
186 let mut len = 33;
187 unsafe {
188 let ret = secp256k1_ec_pubkey_serialize(
189 secp256k1_context_no_precomp,
190 buf.as_mut_c_ptr(),
191 &mut len,
192 self,
193 SECP256K1_SER_COMPRESSED,
194 );
195 debug_assert_eq!(ret, 1);
196 debug_assert_eq!(len, 33);
197 };
198 buf
199 }
200}
201
202#[cfg(not(secp256k1_fuzz))]
203impl PartialOrd for PublicKey {
204 fn partial_cmp(&self, other: &PublicKey) -> Option<core::cmp::Ordering> {
205 Some(self.cmp(other))
206 }
207}
208
209#[cfg(not(secp256k1_fuzz))]
210impl Ord for PublicKey {
211 fn cmp(&self, other: &PublicKey) -> core::cmp::Ordering {
212 let ret = unsafe { secp256k1_ec_pubkey_cmp(secp256k1_context_no_precomp, self, other) };
213 ret.cmp(&0i32)
214 }
215}
216
217#[cfg(not(secp256k1_fuzz))]
218impl PartialEq for PublicKey {
219 fn eq(&self, other: &Self) -> bool { self.cmp(other) == core::cmp::Ordering::Equal }
220}
221
222#[cfg(not(secp256k1_fuzz))]
223impl Eq for PublicKey {}
224
225#[cfg(not(secp256k1_fuzz))]
226impl core::hash::Hash for PublicKey {
227 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
228 let ser = self.serialize();
229 ser.hash(state);
230 }
231}
232
233#[repr(C)]
235#[derive(Copy, Clone)]
236#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
237pub struct Signature([c_uchar; 64]);
238impl_array_newtype!(Signature, c_uchar, 64);
239impl_raw_debug!(Signature);
240
241impl Signature {
242 pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 64]) }
250
251 pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self { Signature(data) }
261
262 pub fn underlying_bytes(self) -> [c_uchar; 64] { self.0 }
267
268 fn serialize(&self) -> [u8; 64] {
270 let mut buf = [0u8; 64];
271 unsafe {
272 let ret = secp256k1_ecdsa_signature_serialize_compact(
273 secp256k1_context_no_precomp,
274 buf.as_mut_c_ptr(),
275 self,
276 );
277 debug_assert!(ret == 1);
278 }
279 buf
280 }
281}
282
283#[cfg(not(secp256k1_fuzz))]
284impl PartialOrd for Signature {
285 fn partial_cmp(&self, other: &Signature) -> Option<core::cmp::Ordering> {
286 Some(self.cmp(other))
287 }
288}
289
290#[cfg(not(secp256k1_fuzz))]
291impl Ord for Signature {
292 fn cmp(&self, other: &Signature) -> core::cmp::Ordering {
293 let this = self.serialize();
294 let that = other.serialize();
295 this.cmp(&that)
296 }
297}
298
299#[cfg(not(secp256k1_fuzz))]
300impl PartialEq for Signature {
301 fn eq(&self, other: &Self) -> bool { self.cmp(other) == core::cmp::Ordering::Equal }
302}
303
304#[cfg(not(secp256k1_fuzz))]
305impl Eq for Signature {}
306
307#[cfg(not(secp256k1_fuzz))]
308impl core::hash::Hash for Signature {
309 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
310 let ser = self.serialize();
311 ser.hash(state);
312 }
313}
314
315#[repr(C)]
316#[derive(Copy, Clone)]
317#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
318pub struct XOnlyPublicKey([c_uchar; 64]);
319impl_array_newtype!(XOnlyPublicKey, c_uchar, 64);
320impl_raw_debug!(XOnlyPublicKey);
321
322impl XOnlyPublicKey {
323 pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 64]) }
331
332 pub unsafe fn from_array_unchecked(data: [c_uchar; 64]) -> Self { XOnlyPublicKey(data) }
342
343 pub fn underlying_bytes(self) -> [c_uchar; 64] { self.0 }
348
349 fn serialize(&self) -> [u8; 32] {
351 let mut buf = [0u8; 32];
352 unsafe {
353 let ret = secp256k1_xonly_pubkey_serialize(
354 secp256k1_context_no_precomp,
355 buf.as_mut_c_ptr(),
356 self,
357 );
358 assert_eq!(ret, 1);
359 };
360 buf
361 }
362}
363
364#[cfg(not(secp256k1_fuzz))]
365impl PartialOrd for XOnlyPublicKey {
366 fn partial_cmp(&self, other: &XOnlyPublicKey) -> Option<core::cmp::Ordering> {
367 Some(self.cmp(other))
368 }
369}
370
371#[cfg(not(secp256k1_fuzz))]
372impl Ord for XOnlyPublicKey {
373 fn cmp(&self, other: &XOnlyPublicKey) -> core::cmp::Ordering {
374 let ret = unsafe { secp256k1_xonly_pubkey_cmp(secp256k1_context_no_precomp, self, other) };
375 ret.cmp(&0i32)
376 }
377}
378
379#[cfg(not(secp256k1_fuzz))]
380impl PartialEq for XOnlyPublicKey {
381 fn eq(&self, other: &Self) -> bool { self.cmp(other) == core::cmp::Ordering::Equal }
382}
383
384#[cfg(not(secp256k1_fuzz))]
385impl Eq for XOnlyPublicKey {}
386
387#[cfg(not(secp256k1_fuzz))]
388impl core::hash::Hash for XOnlyPublicKey {
389 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
390 let ser = self.serialize();
391 ser.hash(state);
392 }
393}
394
395#[repr(C)]
396#[derive(Copy, Clone)]
397#[cfg_attr(secp256k1_fuzz, derive(PartialEq, Eq, PartialOrd, Ord, Hash))]
398pub struct Keypair([c_uchar; 96]);
399impl_array_newtype!(Keypair, c_uchar, 96);
400impl_raw_debug!(Keypair);
401
402impl Keypair {
403 pub unsafe fn new() -> Self { Self::from_array_unchecked([0; 96]) }
411
412 pub unsafe fn from_array_unchecked(data: [c_uchar; 96]) -> Self { Keypair(data) }
422
423 pub fn underlying_bytes(self) -> [c_uchar; 96] { self.0 }
428
429 fn public_key(&self) -> PublicKey {
431 unsafe {
432 let mut pk = PublicKey::new();
433 let ret = secp256k1_keypair_pub(secp256k1_context_no_precomp, &mut pk, self);
434 debug_assert_eq!(ret, 1);
435 pk
436 }
437 }
438
439 #[inline]
446 pub fn non_secure_erase(&mut self) { non_secure_erase_impl(&mut self.0, DUMMY_KEYPAIR); }
447}
448
449#[cfg(target_endian = "little")]
451const DUMMY_KEYPAIR: [c_uchar; 96] = [
452 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
453 143, 7, 221, 213, 233, 245, 23, 156, 255, 25, 72, 96, 52, 24, 30, 215, 101, 5, 186, 170, 213,
454 62, 93, 153, 64, 100, 18, 123, 86, 197, 132, 27, 209, 232, 168, 105, 122, 212, 34, 81, 222, 57,
455 246, 167, 32, 129, 223, 223, 66, 171, 197, 66, 166, 214, 254, 7, 21, 84, 139, 88, 143, 175,
456 190, 112,
457];
458#[cfg(all(target_endian = "big", target_pointer_width = "32"))]
459const DUMMY_KEYPAIR: [c_uchar; 96] = [
460 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
461 213, 221, 7, 143, 156, 23, 245, 233, 96, 72, 25, 255, 215, 30, 24, 52, 170, 186, 5, 101, 153,
462 93, 62, 213, 123, 18, 100, 64, 27, 132, 197, 86, 105, 168, 232, 209, 81, 34, 212, 122, 167,
463 246, 57, 222, 223, 223, 129, 32, 66, 197, 171, 66, 7, 254, 214, 166, 88, 139, 84, 21, 112, 190,
464 175, 143,
465];
466#[cfg(all(target_endian = "big", target_pointer_width = "64"))]
467const DUMMY_KEYPAIR: [c_uchar; 96] = [
468 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
469 156, 23, 245, 233, 213, 221, 7, 143, 215, 30, 24, 52, 96, 72, 25, 255, 153, 93, 62, 213, 170,
470 186, 5, 101, 27, 132, 197, 86, 123, 18, 100, 64, 81, 34, 212, 122, 105, 168, 232, 209, 223,
471 223, 129, 32, 167, 246, 57, 222, 7, 254, 214, 166, 66, 197, 171, 66, 112, 190, 175, 143, 88,
472 139, 84, 21,
473];
474
475#[inline(always)]
479pub fn non_secure_erase_impl<T>(dst: &mut T, src: T) {
480 use core::sync::atomic;
481 unsafe {
483 ptr::write_volatile(dst, src);
484 }
485
486 atomic::compiler_fence(atomic::Ordering::SeqCst);
488}
489
490#[cfg(not(secp256k1_fuzz))]
491impl PartialOrd for Keypair {
492 fn partial_cmp(&self, other: &Keypair) -> Option<core::cmp::Ordering> { Some(self.cmp(other)) }
493}
494
495#[cfg(not(secp256k1_fuzz))]
496impl Ord for Keypair {
497 fn cmp(&self, other: &Keypair) -> core::cmp::Ordering {
498 let this = self.public_key();
499 let that = other.public_key();
500 this.cmp(&that)
501 }
502}
503
504#[cfg(not(secp256k1_fuzz))]
505impl PartialEq for Keypair {
506 fn eq(&self, other: &Self) -> bool { self.cmp(other) == core::cmp::Ordering::Equal }
507}
508
509#[cfg(not(secp256k1_fuzz))]
510impl Eq for Keypair {}
511
512#[cfg(not(secp256k1_fuzz))]
513impl core::hash::Hash for Keypair {
514 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
515 let pk = self.public_key();
519 let ser = pk.serialize();
520 ser.hash(state);
521 }
522}
523
524#[repr(C)]
526#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
527pub struct ElligatorSwift([u8; 64]);
528
529impl ElligatorSwift {
530 pub fn from_array(arr: [u8; 64]) -> Self { ElligatorSwift(arr) }
531 pub fn to_array(self) -> [u8; 64] { self.0 }
532}
533
534impl_array_newtype!(ElligatorSwift, u8, 64);
535impl_raw_debug!(ElligatorSwift);
536
537extern "C" {
538 #[cfg_attr(
540 not(rust_secp_no_symbol_renaming),
541 link_name = "rustsecp256k1_v0_12_ecdh_hash_function_default"
542 )]
543 pub static secp256k1_ecdh_hash_function_default: EcdhHashFn;
544
545 #[cfg_attr(
547 not(rust_secp_no_symbol_renaming),
548 link_name = "rustsecp256k1_v0_12_ellswift_xdh_hash_function_bip324"
549 )]
550 pub static secp256k1_ellswift_xdh_hash_function_bip324: EllswiftEcdhHashFn;
551
552 #[cfg_attr(
553 not(rust_secp_no_symbol_renaming),
554 link_name = "rustsecp256k1_v0_12_nonce_function_rfc6979"
555 )]
556 pub static secp256k1_nonce_function_rfc6979: NonceFn;
557
558 #[cfg_attr(
559 not(rust_secp_no_symbol_renaming),
560 link_name = "rustsecp256k1_v0_12_nonce_function_default"
561 )]
562 pub static secp256k1_nonce_function_default: NonceFn;
563
564 #[cfg_attr(
565 not(rust_secp_no_symbol_renaming),
566 link_name = "rustsecp256k1_v0_12_nonce_function_bip340"
567 )]
568 pub static secp256k1_nonce_function_bip340: SchnorrNonceFn;
569
570 #[cfg_attr(
571 not(rust_secp_no_symbol_renaming),
572 link_name = "rustsecp256k1_v0_12_context_no_precomp"
573 )]
574 pub static secp256k1_context_no_precomp: *const Context;
575
576 #[cfg_attr(
578 not(rust_secp_no_symbol_renaming),
579 link_name = "rustsecp256k1_v0_12_context_preallocated_destroy"
580 )]
581 pub fn secp256k1_context_preallocated_destroy(cx: NonNull<Context>);
582
583 #[cfg_attr(
585 not(rust_secp_no_symbol_renaming),
586 link_name = "rustsecp256k1_v0_12_ecdsa_signature_parse_der"
587 )]
588 pub fn secp256k1_ecdsa_signature_parse_der(
589 cx: *const Context,
590 sig: *mut Signature,
591 input: *const c_uchar,
592 in_len: size_t,
593 ) -> c_int;
594
595 #[cfg_attr(
596 not(rust_secp_no_symbol_renaming),
597 link_name = "rustsecp256k1_v0_12_ecdsa_signature_parse_compact"
598 )]
599 pub fn secp256k1_ecdsa_signature_parse_compact(
600 cx: *const Context,
601 sig: *mut Signature,
602 input64: *const c_uchar,
603 ) -> c_int;
604
605 #[cfg_attr(
606 not(rust_secp_no_symbol_renaming),
607 link_name = "rustsecp256k1_v0_12_ecdsa_signature_parse_der_lax"
608 )]
609 pub fn ecdsa_signature_parse_der_lax(
610 cx: *const Context,
611 sig: *mut Signature,
612 input: *const c_uchar,
613 in_len: size_t,
614 ) -> c_int;
615
616 #[cfg_attr(
617 not(rust_secp_no_symbol_renaming),
618 link_name = "rustsecp256k1_v0_12_ecdsa_signature_serialize_der"
619 )]
620 pub fn secp256k1_ecdsa_signature_serialize_der(
621 cx: *const Context,
622 output: *mut c_uchar,
623 out_len: *mut size_t,
624 sig: *const Signature,
625 ) -> c_int;
626
627 #[cfg_attr(
628 not(rust_secp_no_symbol_renaming),
629 link_name = "rustsecp256k1_v0_12_ecdsa_signature_serialize_compact"
630 )]
631 pub fn secp256k1_ecdsa_signature_serialize_compact(
632 cx: *const Context,
633 output64: *mut c_uchar,
634 sig: *const Signature,
635 ) -> c_int;
636
637 #[cfg_attr(
638 not(rust_secp_no_symbol_renaming),
639 link_name = "rustsecp256k1_v0_12_ecdsa_signature_normalize"
640 )]
641 pub fn secp256k1_ecdsa_signature_normalize(
642 cx: *const Context,
643 out_sig: *mut Signature,
644 in_sig: *const Signature,
645 ) -> c_int;
646
647 #[cfg_attr(
649 not(rust_secp_no_symbol_renaming),
650 link_name = "rustsecp256k1_v0_12_ec_seckey_verify"
651 )]
652 pub fn secp256k1_ec_seckey_verify(cx: *const Context, sk: *const c_uchar) -> c_int;
653
654 #[cfg_attr(
655 not(rust_secp_no_symbol_renaming),
656 link_name = "rustsecp256k1_v0_12_ec_seckey_negate"
657 )]
658 pub fn secp256k1_ec_seckey_negate(cx: *const Context, sk: *mut c_uchar) -> c_int;
659
660 #[cfg_attr(
661 not(rust_secp_no_symbol_renaming),
662 link_name = "rustsecp256k1_v0_12_ec_seckey_tweak_add"
663 )]
664 pub fn secp256k1_ec_seckey_tweak_add(
665 cx: *const Context,
666 sk: *mut c_uchar,
667 tweak: *const c_uchar,
668 ) -> c_int;
669 #[cfg_attr(
670 not(rust_secp_no_symbol_renaming),
671 link_name = "rustsecp256k1_v0_12_ec_seckey_tweak_mul"
672 )]
673 pub fn secp256k1_ec_seckey_tweak_mul(
674 cx: *const Context,
675 sk: *mut c_uchar,
676 tweak: *const c_uchar,
677 ) -> c_int;
678
679 #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_keypair_sec")]
680 pub fn secp256k1_keypair_sec(
681 cx: *const Context,
682 output_seckey: *mut c_uchar,
683 keypair: *const Keypair,
684 ) -> c_int;
685
686 #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_keypair_pub")]
687 pub fn secp256k1_keypair_pub(
688 cx: *const Context,
689 output_pubkey: *mut PublicKey,
690 keypair: *const Keypair,
691 ) -> c_int;
692 #[cfg_attr(
694 not(rust_secp_no_symbol_renaming),
695 link_name = "rustsecp256k1_v0_12_ellswift_encode"
696 )]
697 pub fn secp256k1_ellswift_encode(
698 ctx: *const Context,
699 ell64: *mut c_uchar,
700 pubkey: *const PublicKey,
701 rnd32: *const c_uchar,
702 ) -> c_int;
703 #[cfg_attr(
704 not(rust_secp_no_symbol_renaming),
705 link_name = "rustsecp256k1_v0_12_ellswift_decode"
706 )]
707 pub fn secp256k1_ellswift_decode(
708 ctx: *const Context,
709 pubkey: *mut u8,
710 ell64: *const c_uchar,
711 ) -> c_int;
712 #[cfg_attr(
713 not(rust_secp_no_symbol_renaming),
714 link_name = "rustsecp256k1_v0_12_ellswift_create"
715 )]
716 pub fn secp256k1_ellswift_create(
717 ctx: *const Context,
718 ell64: *mut c_uchar,
719 seckey32: *const c_uchar,
720 aux_rand32: *const c_uchar,
721 ) -> c_int;
722 #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ellswift_xdh")]
723 pub fn secp256k1_ellswift_xdh(
724 ctx: *const Context,
725 output: *mut c_uchar,
726 ell_a64: *const c_uchar,
727 ell_b64: *const c_uchar,
728 seckey32: *const c_uchar,
729 party: c_int,
730 hashfp: EllswiftEcdhHashFn,
731 data: *mut c_void,
732 ) -> c_int;
733
734 #[cfg_attr(
735 not(rust_secp_no_symbol_renaming),
736 link_name = "rustsecp256k1_v0_12_musig_pubnonce_parse"
737 )]
738 pub fn secp256k1_musig_pubnonce_parse(
739 cx: *const Context,
740 nonce: *mut MusigPubNonce,
741 in66: *const c_uchar,
742 ) -> c_int;
743
744 #[cfg_attr(
745 not(rust_secp_no_symbol_renaming),
746 link_name = "rustsecp256k1_v0_12_musig_pubnonce_serialize"
747 )]
748 pub fn secp256k1_musig_pubnonce_serialize(
749 cx: *const Context,
750 out66: *mut c_uchar,
751 nonce: *const MusigPubNonce,
752 ) -> c_int;
753
754 #[cfg_attr(
755 not(rust_secp_no_symbol_renaming),
756 link_name = "rustsecp256k1_v0_12_musig_aggnonce_parse"
757 )]
758 pub fn secp256k1_musig_aggnonce_parse(
759 cx: *const Context,
760 nonce: *mut MusigAggNonce,
761 in66: *const c_uchar,
762 ) -> c_int;
763
764 #[cfg_attr(
765 not(rust_secp_no_symbol_renaming),
766 link_name = "rustsecp256k1_v0_12_musig_aggnonce_serialize"
767 )]
768 pub fn secp256k1_musig_aggnonce_serialize(
769 cx: *const Context,
770 out66: *mut c_uchar,
771 nonce: *const MusigAggNonce,
772 ) -> c_int;
773
774 #[cfg_attr(
775 not(rust_secp_no_symbol_renaming),
776 link_name = "rustsecp256k1_v0_12_musig_partial_sig_parse"
777 )]
778 pub fn secp256k1_musig_partial_sig_parse(
779 cx: *const Context,
780 sig: *mut MusigPartialSignature,
781 in32: *const c_uchar,
782 ) -> c_int;
783
784 #[cfg_attr(
785 not(rust_secp_no_symbol_renaming),
786 link_name = "rustsecp256k1_v0_12_musig_partial_sig_serialize"
787 )]
788 pub fn secp256k1_musig_partial_sig_serialize(
789 cx: *const Context,
790 out32: *mut c_uchar,
791 sig: *const MusigPartialSignature,
792 ) -> c_int;
793
794 #[cfg_attr(
795 not(rust_secp_no_symbol_renaming),
796 link_name = "rustsecp256k1_v0_12_musig_pubkey_agg"
797 )]
798 pub fn secp256k1_musig_pubkey_agg(
799 cx: *const Context,
800 agg_pk: *mut XOnlyPublicKey,
801 keyagg_cache: *mut MusigKeyAggCache,
802 pubkeys: *const *const PublicKey,
803 n_pubkeys: size_t,
804 ) -> c_int;
805
806 #[cfg_attr(
807 not(rust_secp_no_symbol_renaming),
808 link_name = "rustsecp256k1_v0_12_musig_pubkey_get"
809 )]
810 pub fn secp256k1_musig_pubkey_get(
811 cx: *const Context,
812 agg_pk: *mut PublicKey,
813 keyagg_cache: *const MusigKeyAggCache,
814 ) -> c_int;
815
816 #[cfg_attr(
817 not(rust_secp_no_symbol_renaming),
818 link_name = "rustsecp256k1_v0_12_musig_pubkey_ec_tweak_add"
819 )]
820 pub fn secp256k1_musig_pubkey_ec_tweak_add(
821 cx: *const Context,
822 output_pubkey: *mut PublicKey,
823 keyagg_cache: *mut MusigKeyAggCache,
824 tweak32: *const c_uchar,
825 ) -> c_int;
826
827 #[cfg_attr(
828 not(rust_secp_no_symbol_renaming),
829 link_name = "rustsecp256k1_v0_12_musig_pubkey_xonly_tweak_add"
830 )]
831 pub fn secp256k1_musig_pubkey_xonly_tweak_add(
832 cx: *const Context,
833 output_pubkey: *mut PublicKey,
834 keyagg_cache: *mut MusigKeyAggCache,
835 tweak32: *const c_uchar,
836 ) -> c_int;
837
838 #[cfg_attr(
839 not(rust_secp_no_symbol_renaming),
840 link_name = "rustsecp256k1_v0_12_musig_nonce_gen"
841 )]
842 pub fn secp256k1_musig_nonce_gen(
843 cx: *const Context,
844 secnonce: *mut MusigSecNonce,
845 pubnonce: *mut MusigPubNonce,
846 session_secrand32: *mut c_uchar,
847 seckey: *const c_uchar,
848 pubkey: *const PublicKey,
849 msg32: *const c_uchar,
850 keyagg_cache: *const MusigKeyAggCache,
851 extra_input32: *const c_uchar,
852 ) -> c_int;
853
854 #[cfg_attr(
855 not(rust_secp_no_symbol_renaming),
856 link_name = "rustsecp256k1_v0_12_musig_nonce_agg"
857 )]
858 pub fn secp256k1_musig_nonce_agg(
859 cx: *const Context,
860 aggnonce: *mut MusigAggNonce,
861 pubnonces: *const *const MusigPubNonce,
862 n_pubnonces: size_t,
863 ) -> c_int;
864
865 #[cfg_attr(
866 not(rust_secp_no_symbol_renaming),
867 link_name = "rustsecp256k1_v0_12_musig_nonce_process"
868 )]
869 pub fn secp256k1_musig_nonce_process(
870 cx: *const Context,
871 session: *mut MusigSession,
872 aggnonce: *const MusigAggNonce,
873 msg32: *const c_uchar,
874 keyagg_cache: *const MusigKeyAggCache,
875 ) -> c_int;
876
877 #[cfg_attr(
878 not(rust_secp_no_symbol_renaming),
879 link_name = "rustsecp256k1_v0_12_musig_partial_sign"
880 )]
881 pub fn secp256k1_musig_partial_sign(
882 cx: *const Context,
883 partial_sig: *mut MusigPartialSignature,
884 secnonce: *mut MusigSecNonce,
885 keypair: *const Keypair,
886 keyagg_cache: *const MusigKeyAggCache,
887 session: *const MusigSession,
888 ) -> c_int;
889
890 #[cfg_attr(
891 not(rust_secp_no_symbol_renaming),
892 link_name = "rustsecp256k1_v0_12_musig_partial_sig_verify"
893 )]
894 pub fn secp256k1_musig_partial_sig_verify(
895 cx: *const Context,
896 partial_sig: *const MusigPartialSignature,
897 pubnonce: *const MusigPubNonce,
898 pubkey: *const PublicKey,
899 keyagg_cache: *const MusigKeyAggCache,
900 session: *const MusigSession,
901 ) -> c_int;
902
903 #[cfg_attr(
904 not(rust_secp_no_symbol_renaming),
905 link_name = "rustsecp256k1_v0_12_musig_partial_sig_agg"
906 )]
907 pub fn secp256k1_musig_partial_sig_agg(
908 cx: *const Context,
909 sig64: *mut c_uchar,
910 session: *const MusigSession,
911 partial_sigs: *const *const MusigPartialSignature,
912 n_sigs: size_t,
913 ) -> c_int;
914
915 #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ec_pubkey_sort")]
916 pub fn secp256k1_ec_pubkey_sort(
917 ctx: *const Context,
918 pubkeys: *mut *const PublicKey,
919 n_pubkeys: size_t,
920 ) -> c_int;
921}
922
923#[cfg(not(secp256k1_fuzz))]
924extern "C" {
925 #[cfg_attr(
927 not(rust_secp_no_symbol_renaming),
928 link_name = "rustsecp256k1_v0_12_context_preallocated_size"
929 )]
930 pub fn secp256k1_context_preallocated_size(flags: c_uint) -> size_t;
931
932 #[cfg_attr(
933 not(rust_secp_no_symbol_renaming),
934 link_name = "rustsecp256k1_v0_12_context_preallocated_create"
935 )]
936 pub fn secp256k1_context_preallocated_create(
937 prealloc: NonNull<c_void>,
938 flags: c_uint,
939 ) -> NonNull<Context>;
940
941 #[cfg_attr(
942 not(rust_secp_no_symbol_renaming),
943 link_name = "rustsecp256k1_v0_12_context_preallocated_clone_size"
944 )]
945 pub fn secp256k1_context_preallocated_clone_size(cx: *const Context) -> size_t;
946
947 #[cfg_attr(
948 not(rust_secp_no_symbol_renaming),
949 link_name = "rustsecp256k1_v0_12_context_preallocated_clone"
950 )]
951 pub fn secp256k1_context_preallocated_clone(
952 cx: *const Context,
953 prealloc: NonNull<c_void>,
954 ) -> NonNull<Context>;
955
956 #[cfg_attr(
957 not(rust_secp_no_symbol_renaming),
958 link_name = "rustsecp256k1_v0_12_context_randomize"
959 )]
960 pub fn secp256k1_context_randomize(cx: NonNull<Context>, seed32: *const c_uchar) -> c_int;
961 #[cfg_attr(
963 not(rust_secp_no_symbol_renaming),
964 link_name = "rustsecp256k1_v0_12_ec_pubkey_parse"
965 )]
966 pub fn secp256k1_ec_pubkey_parse(
967 cx: *const Context,
968 pk: *mut PublicKey,
969 input: *const c_uchar,
970 in_len: size_t,
971 ) -> c_int;
972
973 #[cfg_attr(
974 not(rust_secp_no_symbol_renaming),
975 link_name = "rustsecp256k1_v0_12_ec_pubkey_serialize"
976 )]
977 pub fn secp256k1_ec_pubkey_serialize(
978 cx: *const Context,
979 output: *mut c_uchar,
980 out_len: *mut size_t,
981 pk: *const PublicKey,
982 compressed: c_uint,
983 ) -> c_int;
984
985 #[cfg_attr(
987 not(rust_secp_no_symbol_renaming),
988 link_name = "rustsecp256k1_v0_12_ec_pubkey_create"
989 )]
990 pub fn secp256k1_ec_pubkey_create(
991 cx: *const Context,
992 pk: *mut PublicKey,
993 sk: *const c_uchar,
994 ) -> c_int;
995
996 #[cfg_attr(
997 not(rust_secp_no_symbol_renaming),
998 link_name = "rustsecp256k1_v0_12_ec_pubkey_negate"
999 )]
1000 pub fn secp256k1_ec_pubkey_negate(cx: *const Context, pk: *mut PublicKey) -> c_int;
1001
1002 #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ec_pubkey_cmp")]
1003 pub fn secp256k1_ec_pubkey_cmp(
1004 cx: *const Context,
1005 pubkey1: *const PublicKey,
1006 pubkey2: *const PublicKey,
1007 ) -> c_int;
1008
1009 #[cfg_attr(
1010 not(rust_secp_no_symbol_renaming),
1011 link_name = "rustsecp256k1_v0_12_ec_pubkey_tweak_add"
1012 )]
1013 pub fn secp256k1_ec_pubkey_tweak_add(
1014 cx: *const Context,
1015 pk: *mut PublicKey,
1016 tweak: *const c_uchar,
1017 ) -> c_int;
1018
1019 #[cfg_attr(
1020 not(rust_secp_no_symbol_renaming),
1021 link_name = "rustsecp256k1_v0_12_ec_pubkey_tweak_mul"
1022 )]
1023 pub fn secp256k1_ec_pubkey_tweak_mul(
1024 cx: *const Context,
1025 pk: *mut PublicKey,
1026 tweak: *const c_uchar,
1027 ) -> c_int;
1028
1029 #[cfg_attr(
1030 not(rust_secp_no_symbol_renaming),
1031 link_name = "rustsecp256k1_v0_12_ec_pubkey_combine"
1032 )]
1033 pub fn secp256k1_ec_pubkey_combine(
1034 cx: *const Context,
1035 out: *mut PublicKey,
1036 ins: *const *const PublicKey,
1037 n: size_t,
1038 ) -> c_int;
1039
1040 #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ecdh")]
1041 pub fn secp256k1_ecdh(
1042 cx: *const Context,
1043 output: *mut c_uchar,
1044 pubkey: *const PublicKey,
1045 seckey: *const c_uchar,
1046 hashfp: EcdhHashFn,
1047 data: *mut c_void,
1048 ) -> c_int;
1049
1050 #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ecdsa_verify")]
1052 pub fn secp256k1_ecdsa_verify(
1053 cx: *const Context,
1054 sig: *const Signature,
1055 msg32: *const c_uchar,
1056 pk: *const PublicKey,
1057 ) -> c_int;
1058
1059 #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_ecdsa_sign")]
1060 pub fn secp256k1_ecdsa_sign(
1061 cx: *const Context,
1062 sig: *mut Signature,
1063 msg32: *const c_uchar,
1064 sk: *const c_uchar,
1065 noncefn: NonceFn,
1066 noncedata: *const c_void,
1067 ) -> c_int;
1068
1069 #[cfg_attr(
1071 not(rust_secp_no_symbol_renaming),
1072 link_name = "rustsecp256k1_v0_12_schnorrsig_sign"
1073 )]
1074 pub fn secp256k1_schnorrsig_sign(
1075 cx: *const Context,
1076 sig: *mut c_uchar,
1077 msg32: *const c_uchar,
1078 keypair: *const Keypair,
1079 aux_rand32: *const c_uchar,
1080 ) -> c_int;
1081
1082 #[cfg_attr(
1084 not(rust_secp_no_symbol_renaming),
1085 link_name = "rustsecp256k1_v0_12_schnorrsig_sign_custom"
1086 )]
1087 pub fn secp256k1_schnorrsig_sign_custom(
1088 cx: *const Context,
1089 sig: *mut c_uchar,
1090 msg: *const c_uchar,
1091 msg_len: size_t,
1092 keypair: *const Keypair,
1093 extra_params: *const SchnorrSigExtraParams,
1094 ) -> c_int;
1095
1096 #[cfg_attr(
1097 not(rust_secp_no_symbol_renaming),
1098 link_name = "rustsecp256k1_v0_12_schnorrsig_verify"
1099 )]
1100 pub fn secp256k1_schnorrsig_verify(
1101 cx: *const Context,
1102 sig64: *const c_uchar,
1103 msg32: *const c_uchar,
1104 msglen: size_t,
1105 pubkey: *const XOnlyPublicKey,
1106 ) -> c_int;
1107
1108 #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_12_keypair_create")]
1110 pub fn secp256k1_keypair_create(
1111 cx: *const Context,
1112 keypair: *mut Keypair,
1113 seckey: *const c_uchar,
1114 ) -> c_int;
1115
1116 #[cfg_attr(
1117 not(rust_secp_no_symbol_renaming),
1118 link_name = "rustsecp256k1_v0_12_xonly_pubkey_parse"
1119 )]
1120 pub fn secp256k1_xonly_pubkey_parse(
1121 cx: *const Context,
1122 pubkey: *mut XOnlyPublicKey,
1123 input32: *const c_uchar,
1124 ) -> c_int;
1125
1126 #[cfg_attr(
1127 not(rust_secp_no_symbol_renaming),
1128 link_name = "rustsecp256k1_v0_12_xonly_pubkey_serialize"
1129 )]
1130 pub fn secp256k1_xonly_pubkey_serialize(
1131 cx: *const Context,
1132 output32: *mut c_uchar,
1133 pubkey: *const XOnlyPublicKey,
1134 ) -> c_int;
1135
1136 #[cfg_attr(
1137 not(rust_secp_no_symbol_renaming),
1138 link_name = "rustsecp256k1_v0_12_xonly_pubkey_from_pubkey"
1139 )]
1140 pub fn secp256k1_xonly_pubkey_from_pubkey(
1141 cx: *const Context,
1142 xonly_pubkey: *mut XOnlyPublicKey,
1143 pk_parity: *mut c_int,
1144 pubkey: *const PublicKey,
1145 ) -> c_int;
1146
1147 #[cfg_attr(
1148 not(rust_secp_no_symbol_renaming),
1149 link_name = "rustsecp256k1_v0_12_xonly_pubkey_cmp"
1150 )]
1151 pub fn secp256k1_xonly_pubkey_cmp(
1152 cx: *const Context,
1153 pubkey1: *const XOnlyPublicKey,
1154 pubkey2: *const XOnlyPublicKey,
1155 ) -> c_int;
1156
1157 #[cfg_attr(
1158 not(rust_secp_no_symbol_renaming),
1159 link_name = "rustsecp256k1_v0_12_xonly_pubkey_tweak_add"
1160 )]
1161 pub fn secp256k1_xonly_pubkey_tweak_add(
1162 cx: *const Context,
1163 output_pubkey: *mut PublicKey,
1164 internal_pubkey: *const XOnlyPublicKey,
1165 tweak32: *const c_uchar,
1166 ) -> c_int;
1167
1168 #[cfg_attr(
1169 not(rust_secp_no_symbol_renaming),
1170 link_name = "rustsecp256k1_v0_12_keypair_xonly_pub"
1171 )]
1172 pub fn secp256k1_keypair_xonly_pub(
1173 cx: *const Context,
1174 pubkey: *mut XOnlyPublicKey,
1175 pk_parity: *mut c_int,
1176 keypair: *const Keypair,
1177 ) -> c_int;
1178
1179 #[cfg_attr(
1180 not(rust_secp_no_symbol_renaming),
1181 link_name = "rustsecp256k1_v0_12_keypair_xonly_tweak_add"
1182 )]
1183 pub fn secp256k1_keypair_xonly_tweak_add(
1184 cx: *const Context,
1185 keypair: *mut Keypair,
1186 tweak32: *const c_uchar,
1187 ) -> c_int;
1188
1189 #[cfg_attr(
1190 not(rust_secp_no_symbol_renaming),
1191 link_name = "rustsecp256k1_v0_12_xonly_pubkey_tweak_add_check"
1192 )]
1193 pub fn secp256k1_xonly_pubkey_tweak_add_check(
1194 cx: *const Context,
1195 tweaked_pubkey32: *const c_uchar,
1196 tweaked_pubkey_parity: c_int,
1197 internal_pubkey: *const XOnlyPublicKey,
1198 tweak32: *const c_uchar,
1199 ) -> c_int;
1200}
1201
1202#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
1218pub unsafe fn secp256k1_context_create(flags: c_uint) -> NonNull<Context> {
1219 rustsecp256k1_v0_12_context_create(flags)
1220}
1221
1222#[no_mangle]
1226#[allow(clippy::missing_safety_doc)] #[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
1228pub unsafe extern "C" fn rustsecp256k1_v0_12_context_create(flags: c_uint) -> NonNull<Context> {
1229 use core::mem;
1230
1231 use crate::alloc::alloc;
1232 assert!(ALIGN_TO >= mem::align_of::<usize>());
1233 assert!(ALIGN_TO >= mem::align_of::<&usize>());
1234 assert!(ALIGN_TO >= mem::size_of::<usize>());
1235
1236 let bytes = secp256k1_context_preallocated_size(flags) + ALIGN_TO;
1238 let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
1239 let ptr = alloc::alloc(layout);
1240 if ptr.is_null() {
1241 alloc::handle_alloc_error(layout);
1242 }
1243 (ptr as *mut usize).write(bytes);
1244 let ptr = ptr.add(ALIGN_TO);
1247 let ptr = NonNull::new_unchecked(ptr as *mut c_void); secp256k1_context_preallocated_create(ptr, flags)
1249}
1250
1251#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
1261pub unsafe fn secp256k1_context_destroy(ctx: NonNull<Context>) {
1262 rustsecp256k1_v0_12_context_destroy(ctx)
1263}
1264
1265#[no_mangle]
1266#[allow(clippy::missing_safety_doc)] #[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
1268pub unsafe extern "C" fn rustsecp256k1_v0_12_context_destroy(mut ctx: NonNull<Context>) {
1269 use crate::alloc::alloc;
1270 secp256k1_context_preallocated_destroy(ctx);
1271 let ctx: *mut Context = ctx.as_mut();
1272 let ptr = (ctx as *mut u8).sub(ALIGN_TO);
1273 let bytes = (ptr as *mut usize).read();
1274 let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
1275 alloc::dealloc(ptr, layout);
1276}
1277
1278#[no_mangle]
1303#[cfg(not(rust_secp_no_symbol_renaming))]
1304pub unsafe extern "C" fn rustsecp256k1_v0_12_default_illegal_callback_fn(
1305 message: *const c_char,
1306 _data: *mut c_void,
1307) {
1308 use core::str;
1309 let msg_slice = slice::from_raw_parts(message as *const u8, strlen(message));
1310 let msg = str::from_utf8_unchecked(msg_slice);
1311 panic!("[libsecp256k1] illegal argument. {}", msg);
1312}
1313
1314#[no_mangle]
1334#[cfg(not(rust_secp_no_symbol_renaming))]
1335pub unsafe extern "C" fn rustsecp256k1_v0_12_default_error_callback_fn(
1336 message: *const c_char,
1337 _data: *mut c_void,
1338) {
1339 use core::str;
1340 let msg_slice = slice::from_raw_parts(message as *const u8, strlen(message));
1341 let msg = str::from_utf8_unchecked(msg_slice);
1342 panic!("[libsecp256k1] internal consistency check failed {}", msg);
1343}
1344
1345#[cfg(not(rust_secp_no_symbol_renaming))]
1351unsafe fn strlen(mut str_ptr: *const c_char) -> usize {
1352 let mut ctr = 0;
1353 while *str_ptr != '\0' as c_char {
1354 ctr += 1;
1355 str_ptr = str_ptr.offset(1);
1356 }
1357 ctr
1358}
1359
1360pub trait CPtr {
1367 type Target;
1368 fn as_c_ptr(&self) -> *const Self::Target;
1369 fn as_mut_c_ptr(&mut self) -> *mut Self::Target;
1370}
1371
1372impl<T> CPtr for [T] {
1373 type Target = T;
1374 fn as_c_ptr(&self) -> *const Self::Target {
1375 if self.is_empty() {
1376 ptr::null()
1377 } else {
1378 self.as_ptr()
1379 }
1380 }
1381
1382 fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1383 if self.is_empty() {
1384 ptr::null_mut::<Self::Target>()
1385 } else {
1386 self.as_mut_ptr()
1387 }
1388 }
1389}
1390
1391impl CPtr for [u8; 32] {
1392 type Target = u8;
1393 fn as_c_ptr(&self) -> *const Self::Target { self.as_ptr() }
1394
1395 fn as_mut_c_ptr(&mut self) -> *mut Self::Target { self.as_mut_ptr() }
1396}
1397
1398impl<T: CPtr> CPtr for Option<T> {
1399 type Target = T::Target;
1400 fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
1401 match self {
1402 Some(contents) => contents.as_mut_c_ptr(),
1403 None => ptr::null_mut(),
1404 }
1405 }
1406 fn as_c_ptr(&self) -> *const Self::Target {
1407 match self {
1408 Some(content) => content.as_c_ptr(),
1409 None => ptr::null(),
1410 }
1411 }
1412}
1413pub const MUSIG_KEYAGG_SIZE: usize = 197;
1417
1418pub const MUSIG_SECNONCE_SIZE: usize = 132;
1422
1423pub const MUSIG_PUBNONCE_SIZE: usize = 132;
1427
1428pub const MUSIG_AGGNONCE_SIZE: usize = 132;
1432
1433pub const MUSIG_SESSION_SIZE: usize = 133;
1437
1438pub const MUSIG_PART_SIG_SIZE: usize = 36;
1441
1442#[repr(C)]
1443#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1444pub struct MusigKeyAggCache([c_uchar; MUSIG_KEYAGG_SIZE]);
1445impl_array_newtype!(MusigKeyAggCache, c_uchar, MUSIG_KEYAGG_SIZE);
1446impl_raw_debug!(MusigKeyAggCache);
1447
1448#[repr(C)]
1449#[derive(Copy, Clone, PartialEq, Eq)]
1450pub struct MusigSecNonce([c_uchar; MUSIG_SECNONCE_SIZE]);
1451impl_array_newtype!(MusigSecNonce, c_uchar, MUSIG_SECNONCE_SIZE);
1452impl_raw_debug!(MusigSecNonce);
1453
1454impl MusigSecNonce {
1455 pub fn dangerous_from_bytes(bytes: [c_uchar; MUSIG_SECNONCE_SIZE]) -> Self {
1456 MusigSecNonce(bytes)
1457 }
1458
1459 pub fn dangerous_into_bytes(self) -> [c_uchar; MUSIG_SECNONCE_SIZE] { self.0 }
1460}
1461
1462#[repr(C)]
1463#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1464pub struct MusigPubNonce([c_uchar; MUSIG_PUBNONCE_SIZE]);
1465impl_array_newtype!(MusigPubNonce, c_uchar, MUSIG_PUBNONCE_SIZE);
1466impl_raw_debug!(MusigPubNonce);
1467
1468#[repr(C)]
1469#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1470pub struct MusigAggNonce([c_uchar; MUSIG_AGGNONCE_SIZE]);
1471impl_array_newtype!(MusigAggNonce, c_uchar, MUSIG_AGGNONCE_SIZE);
1472impl_raw_debug!(MusigAggNonce);
1473
1474#[repr(C)]
1475#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1476pub struct MusigSession([c_uchar; MUSIG_SESSION_SIZE]);
1477impl_array_newtype!(MusigSession, c_uchar, MUSIG_SESSION_SIZE);
1478impl_raw_debug!(MusigSession);
1479
1480#[repr(C)]
1481#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1482pub struct MusigPartialSignature([c_uchar; MUSIG_PART_SIG_SIZE]);
1483impl_array_newtype!(MusigPartialSignature, c_uchar, MUSIG_PART_SIG_SIZE);
1484impl_raw_debug!(MusigPartialSignature);
1485
1486#[cfg(secp256k1_fuzz)]
1487mod fuzz_dummy {
1488 use core::sync::atomic::{AtomicUsize, Ordering};
1489
1490 use super::*;
1491
1492 #[cfg(rust_secp_no_symbol_renaming)]
1493 compile_error!("We do not support fuzzing with rust_secp_no_symbol_renaming");
1494
1495 extern "C" {
1496 fn rustsecp256k1_v0_12_context_preallocated_size(flags: c_uint) -> size_t;
1497 fn rustsecp256k1_v0_12_context_preallocated_create(
1498 prealloc: NonNull<c_void>,
1499 flags: c_uint,
1500 ) -> NonNull<Context>;
1501 fn rustsecp256k1_v0_12_context_preallocated_clone(
1502 cx: *const Context,
1503 prealloc: NonNull<c_void>,
1504 ) -> NonNull<Context>;
1505 }
1506
1507 #[cfg(feature = "lowmemory")]
1508 const CTX_SIZE: usize = 1024 * 65;
1509 #[cfg(not(feature = "lowmemory"))]
1510 const CTX_SIZE: usize = 1024 * (1024 + 128);
1511 pub unsafe fn secp256k1_context_preallocated_size(flags: c_uint) -> size_t {
1513 assert!(
1514 rustsecp256k1_v0_12_context_preallocated_size(flags) + std::mem::size_of::<c_uint>()
1515 <= CTX_SIZE
1516 );
1517 CTX_SIZE
1518 }
1519
1520 static HAVE_PREALLOCATED_CONTEXT: AtomicUsize = AtomicUsize::new(0);
1521 const HAVE_CONTEXT_NONE: usize = 0;
1522 const HAVE_CONTEXT_WORKING: usize = 1;
1523 const HAVE_CONTEXT_DONE: usize = 2;
1524 static mut PREALLOCATED_CONTEXT: [u8; CTX_SIZE] = [0; CTX_SIZE];
1525 pub unsafe fn secp256k1_context_preallocated_create(
1526 prealloc: NonNull<c_void>,
1527 flags: c_uint,
1528 ) -> NonNull<Context> {
1529 let mut have_ctx = HAVE_PREALLOCATED_CONTEXT.load(Ordering::Relaxed);
1535 while have_ctx != HAVE_CONTEXT_DONE {
1536 if have_ctx == HAVE_CONTEXT_NONE {
1537 have_ctx = HAVE_PREALLOCATED_CONTEXT.swap(HAVE_CONTEXT_WORKING, Ordering::AcqRel);
1538 if have_ctx == HAVE_CONTEXT_NONE {
1539 assert!(
1540 rustsecp256k1_v0_12_context_preallocated_size(
1541 SECP256K1_START_SIGN | SECP256K1_START_VERIFY
1542 ) + std::mem::size_of::<c_uint>()
1543 <= CTX_SIZE
1544 );
1545 assert_eq!(
1546 rustsecp256k1_v0_12_context_preallocated_create(
1547 NonNull::new_unchecked(
1548 PREALLOCATED_CONTEXT[..].as_mut_ptr() as *mut c_void
1549 ),
1550 SECP256K1_START_SIGN | SECP256K1_START_VERIFY
1551 ),
1552 NonNull::new_unchecked(
1553 PREALLOCATED_CONTEXT[..].as_mut_ptr() as *mut Context
1554 )
1555 );
1556 assert_eq!(
1557 HAVE_PREALLOCATED_CONTEXT.swap(HAVE_CONTEXT_DONE, Ordering::AcqRel),
1558 HAVE_CONTEXT_WORKING
1559 );
1560 } else if have_ctx == HAVE_CONTEXT_DONE {
1561 HAVE_PREALLOCATED_CONTEXT.store(HAVE_CONTEXT_DONE, Ordering::Release);
1563 }
1564 } else {
1565 assert_eq!(have_ctx, HAVE_CONTEXT_WORKING);
1567 have_ctx = HAVE_PREALLOCATED_CONTEXT.load(Ordering::Acquire);
1568 #[cfg(feature = "std")]
1569 std::thread::yield_now();
1570 }
1571 }
1572 ptr::copy_nonoverlapping(
1573 PREALLOCATED_CONTEXT[..].as_ptr(),
1574 prealloc.as_ptr() as *mut u8,
1575 CTX_SIZE,
1576 );
1577 let ptr = (prealloc.as_ptr()).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1578 (ptr as *mut c_uint).write(flags);
1579 NonNull::new_unchecked(prealloc.as_ptr() as *mut Context)
1580 }
1581 pub unsafe fn secp256k1_context_preallocated_clone_size(_cx: *const Context) -> size_t {
1582 CTX_SIZE
1583 }
1584 pub unsafe fn secp256k1_context_preallocated_clone(
1585 cx: *const Context,
1586 prealloc: NonNull<c_void>,
1587 ) -> NonNull<Context> {
1588 let orig_ptr = (cx as *mut u8).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1589 let new_ptr =
1590 (prealloc.as_ptr() as *mut u8).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1591 let flags = (orig_ptr as *mut c_uint).read();
1592 (new_ptr as *mut c_uint).write(flags);
1593 rustsecp256k1_v0_12_context_preallocated_clone(cx, prealloc)
1594 }
1595
1596 pub unsafe fn secp256k1_context_randomize(
1597 cx: NonNull<Context>,
1598 _seed32: *const c_uchar,
1599 ) -> c_int {
1600 check_context_flags(cx.as_ptr(), 0);
1602 1
1603 }
1604
1605 unsafe fn check_context_flags(cx: *const Context, required_flags: c_uint) {
1606 assert!(!cx.is_null());
1607 let cx_flags = if cx == secp256k1_context_no_precomp {
1608 1
1609 } else {
1610 let ptr = (cx as *const u8).add(CTX_SIZE).sub(std::mem::size_of::<c_uint>());
1611 (ptr as *const c_uint).read()
1612 };
1613 assert_eq!(cx_flags & 1, 1); assert_eq!(cx_flags & required_flags, required_flags);
1615 }
1616
1617 unsafe fn test_pk_validate(cx: *const Context, pk: *const PublicKey) -> c_int {
1619 check_context_flags(cx, 0);
1620 if (&*pk).0[1..32] != (&*pk).0[33..64]
1621 || ((*pk).0[32] != 0 && (&*pk).0[32] != 0xff)
1622 || secp256k1_ec_seckey_verify(cx, (&*pk).0[0..32].as_ptr()) == 0
1623 {
1624 0
1625 } else {
1626 1
1627 }
1628 }
1629 unsafe fn test_cleanup_pk(pk: *mut PublicKey) {
1630 (&mut *pk).0[32..].copy_from_slice(&(&*pk).0[..32]);
1631 if (&*pk).0[32] <= 0x7f {
1632 (&mut *pk).0[32] = 0;
1633 } else {
1634 (&mut *pk).0[32] = 0xff;
1635 }
1636 }
1637
1638 pub unsafe fn secp256k1_ec_pubkey_parse(
1640 cx: *const Context,
1641 pk: *mut PublicKey,
1642 input: *const c_uchar,
1643 in_len: size_t,
1644 ) -> c_int {
1645 check_context_flags(cx, 0);
1646 match in_len {
1647 33 =>
1648 if *input != 2 && *input != 3 {
1649 0
1650 } else {
1651 ptr::copy(input.offset(1), (&mut *pk).0[0..32].as_mut_ptr(), 32);
1652 ptr::copy(input.offset(2), (&mut *pk).0[33..64].as_mut_ptr(), 31);
1653 if *input == 3 {
1654 (*pk).0[32] = 0xff;
1655 } else {
1656 (*pk).0[32] = 0;
1657 }
1658 test_pk_validate(cx, pk)
1659 },
1660 65 =>
1661 if *input != 4 && *input != 6 && *input != 7 {
1662 0
1663 } else {
1664 ptr::copy(input.offset(1), (&mut *pk).0.as_mut_ptr(), 64);
1665 test_cleanup_pk(pk);
1666 test_pk_validate(cx, pk)
1667 },
1668 _ => 0,
1669 }
1670 }
1671
1672 pub unsafe fn secp256k1_ec_pubkey_serialize(
1674 cx: *const Context,
1675 output: *mut c_uchar,
1676 out_len: *mut size_t,
1677 pk: *const PublicKey,
1678 compressed: c_uint,
1679 ) -> c_int {
1680 check_context_flags(cx, 0);
1681 assert_eq!(test_pk_validate(cx, pk), 1);
1682 if compressed == SECP256K1_SER_COMPRESSED {
1683 assert_eq!(*out_len, 33);
1684 if (*pk).0[32] <= 0x7f {
1685 *output = 2;
1686 } else {
1687 *output = 3;
1688 }
1689 ptr::copy((*pk).0.as_ptr(), output.offset(1), 32);
1690 } else if compressed == SECP256K1_SER_UNCOMPRESSED {
1691 assert_eq!(*out_len, 65);
1692 *output = 4;
1693 ptr::copy((*pk).0.as_ptr(), output.offset(1), 64);
1694 } else {
1695 panic!("Bad flags");
1696 }
1697 1
1698 }
1699
1700 pub unsafe fn secp256k1_ec_pubkey_create(
1703 cx: *const Context,
1704 pk: *mut PublicKey,
1705 sk: *const c_uchar,
1706 ) -> c_int {
1707 check_context_flags(cx, SECP256K1_START_SIGN);
1708 if secp256k1_ec_seckey_verify(cx, sk) != 1 {
1709 return 0;
1710 }
1711 ptr::copy(sk, (&mut *pk).0[0..32].as_mut_ptr(), 32);
1712 test_cleanup_pk(pk);
1713 assert_eq!(test_pk_validate(cx, pk), 1);
1714 1
1715 }
1716
1717 pub unsafe fn secp256k1_ec_pubkey_negate(cx: *const Context, pk: *mut PublicKey) -> c_int {
1718 check_context_flags(cx, 0);
1719 assert_eq!(test_pk_validate(cx, pk), 1);
1720 if secp256k1_ec_seckey_negate(cx, (&mut *pk).0[..32].as_mut_ptr()) != 1 {
1721 return 0;
1722 }
1723 test_cleanup_pk(pk);
1724 assert_eq!(test_pk_validate(cx, pk), 1);
1725 1
1726 }
1727
1728 pub unsafe fn secp256k1_ec_pubkey_tweak_add(
1730 cx: *const Context,
1731 pk: *mut PublicKey,
1732 tweak: *const c_uchar,
1733 ) -> c_int {
1734 check_context_flags(cx, SECP256K1_START_VERIFY);
1735 assert_eq!(test_pk_validate(cx, pk), 1);
1736 if secp256k1_ec_seckey_tweak_add(cx, (&mut *pk).0[..32].as_mut_ptr(), tweak) != 1 {
1737 return 0;
1738 }
1739 test_cleanup_pk(pk);
1740 assert_eq!(test_pk_validate(cx, pk), 1);
1741 1
1742 }
1743
1744 pub unsafe fn secp256k1_ec_pubkey_tweak_mul(
1746 cx: *const Context,
1747 pk: *mut PublicKey,
1748 tweak: *const c_uchar,
1749 ) -> c_int {
1750 check_context_flags(cx, 0);
1751 assert_eq!(test_pk_validate(cx, pk), 1);
1752 if secp256k1_ec_seckey_tweak_mul(cx, (&mut *pk).0[..32].as_mut_ptr(), tweak) != 1 {
1753 return 0;
1754 }
1755 test_cleanup_pk(pk);
1756 assert_eq!(test_pk_validate(cx, pk), 1);
1757 1
1758 }
1759
1760 pub unsafe fn secp256k1_ec_pubkey_combine(
1761 cx: *const Context,
1762 out: *mut PublicKey,
1763 ins: *const *const PublicKey,
1764 n: size_t,
1765 ) -> c_int {
1766 check_context_flags(cx, 0);
1767 assert!(n >= 1);
1768 (*out) = **ins;
1769 for i in 1..n {
1770 assert_eq!(test_pk_validate(cx, *ins.offset(i as isize)), 1);
1771 if secp256k1_ec_seckey_tweak_add(
1772 cx,
1773 (&mut *out).0[..32].as_mut_ptr(),
1774 (&**ins.offset(i as isize)).0[..32].as_ptr(),
1775 ) != 1
1776 {
1777 return 0;
1778 }
1779 }
1780 test_cleanup_pk(out);
1781 assert_eq!(test_pk_validate(cx, out), 1);
1782 1
1783 }
1784
1785 pub unsafe fn secp256k1_ecdh(
1787 cx: *const Context,
1788 out: *mut c_uchar,
1789 point: *const PublicKey,
1790 scalar: *const c_uchar,
1791 hashfp: EcdhHashFn,
1792 data: *mut c_void,
1793 ) -> c_int {
1794 check_context_flags(cx, 0);
1795 assert_eq!(test_pk_validate(cx, point), 1);
1796 if secp256k1_ec_seckey_verify(cx, scalar) != 1 {
1797 return 0;
1798 }
1799
1800 let scalar_slice = slice::from_raw_parts(scalar, 32);
1801 let pk_slice = &(&*point).0[..32];
1802
1803 let mut res_arr = [0u8; 32];
1804 for i in 0..32 {
1805 res_arr[i] = scalar_slice[i] ^ pk_slice[i] ^ 1;
1806 }
1807
1808 if let Some(hashfn) = hashfp {
1809 (hashfn)(out, res_arr.as_ptr(), res_arr.as_ptr(), data);
1810 } else {
1811 res_arr[16] = 0x00; let out_slice = slice::from_raw_parts_mut(out, 32);
1813 out_slice.copy_from_slice(&res_arr);
1814 }
1815 1
1816 }
1817
1818 pub unsafe fn secp256k1_ecdsa_verify(
1821 cx: *const Context,
1822 sig: *const Signature,
1823 msg32: *const c_uchar,
1824 pk: *const PublicKey,
1825 ) -> c_int {
1826 check_context_flags(cx, SECP256K1_START_VERIFY);
1827 let sig_sl = slice::from_raw_parts(sig as *const u8, 64);
1829 let msg_sl = slice::from_raw_parts(msg32 as *const u8, 32);
1830 if &sig_sl[..32] == msg_sl && sig_sl[32..] == (&*pk).0[0..32] {
1831 1
1832 } else {
1833 0
1834 }
1835 }
1836
1837 pub unsafe fn secp256k1_ecdsa_sign(
1839 cx: *const Context,
1840 sig: *mut Signature,
1841 msg32: *const c_uchar,
1842 sk: *const c_uchar,
1843 _noncefn: NonceFn,
1844 _noncedata: *const c_void,
1845 ) -> c_int {
1846 check_context_flags(cx, SECP256K1_START_SIGN);
1847 let mut new_pk = PublicKey::new();
1849 if secp256k1_ec_pubkey_create(cx, &mut new_pk, sk) != 1 {
1850 return 0;
1851 }
1852 let sig_sl = slice::from_raw_parts_mut(sig as *mut u8, 64);
1854 let msg_sl = slice::from_raw_parts(msg32 as *const u8, 32);
1855 sig_sl[..32].copy_from_slice(msg_sl);
1856 sig_sl[32..].copy_from_slice(&new_pk.0[..32]);
1857 1
1858 }
1859
1860 pub unsafe fn secp256k1_schnorrsig_verify(
1863 cx: *const Context,
1864 sig64: *const c_uchar,
1865 msg32: *const c_uchar,
1866 msglen: size_t,
1867 pubkey: *const XOnlyPublicKey,
1868 ) -> c_int {
1869 check_context_flags(cx, SECP256K1_START_VERIFY);
1870 let mut new_pk = PublicKey::new();
1872 let _ = secp256k1_xonly_pubkey_tweak_add(cx, &mut new_pk, pubkey, msg32);
1873 let sig_sl = slice::from_raw_parts(sig64 as *const u8, 64);
1875 let msg_sl = slice::from_raw_parts(msg32 as *const u8, msglen);
1876 if &sig_sl[..32] == msg_sl && sig_sl[32..] == (&*pubkey).0[..32] {
1877 1
1878 } else {
1879 0
1880 }
1881 }
1882
1883 pub unsafe fn secp256k1_schnorrsig_sign(
1885 cx: *const Context,
1886 sig64: *mut c_uchar,
1887 msg32: *const c_uchar,
1888 keypair: *const Keypair,
1889 _aux_rand32: *const c_uchar,
1890 ) -> c_int {
1891 check_context_flags(cx, SECP256K1_START_SIGN);
1892 let mut new_kp = Keypair::new();
1894 if secp256k1_keypair_create(cx, &mut new_kp, (*keypair).0.as_ptr()) != 1 {
1895 return 0;
1896 }
1897 assert_eq!(new_kp, *keypair);
1898 let sig_sl = slice::from_raw_parts_mut(sig64 as *mut u8, 64);
1900 let msg_sl = slice::from_raw_parts(msg32 as *const u8, 32);
1901 sig_sl[..32].copy_from_slice(msg_sl);
1902 sig_sl[32..].copy_from_slice(&new_kp.0[32..64]);
1903 1
1904 }
1905
1906 pub unsafe fn secp256k1_schnorrsig_sign_custom(
1908 cx: *const Context,
1909 sig: *mut c_uchar,
1910 msg: *const c_uchar,
1911 _msg_len: size_t,
1912 keypair: *const Keypair,
1913 _extra_params: *const SchnorrSigExtraParams,
1914 ) -> c_int {
1915 secp256k1_schnorrsig_sign(cx, sig, msg, keypair, ptr::null())
1916 }
1917
1918 pub unsafe fn secp256k1_keypair_create(
1920 cx: *const Context,
1921 keypair: *mut Keypair,
1922 seckey: *const c_uchar,
1923 ) -> c_int {
1924 check_context_flags(cx, SECP256K1_START_SIGN);
1925 if secp256k1_ec_seckey_verify(cx, seckey) == 0 {
1926 return 0;
1927 }
1928
1929 let mut pk = PublicKey::new();
1930 if secp256k1_ec_pubkey_create(cx, &mut pk, seckey) == 0 {
1931 return 0;
1932 }
1933
1934 let seckey_slice = slice::from_raw_parts(seckey, 32);
1935 (&mut *keypair).0[..32].copy_from_slice(seckey_slice);
1936 (&mut *keypair).0[32..].copy_from_slice(&pk.0);
1937 1
1938 }
1939
1940 pub unsafe fn secp256k1_xonly_pubkey_parse(
1941 cx: *const Context,
1942 pubkey: *mut XOnlyPublicKey,
1943 input32: *const c_uchar,
1944 ) -> c_int {
1945 check_context_flags(cx, 0);
1946 let inslice = slice::from_raw_parts(input32, 32);
1947 (&mut *pubkey).0[..32].copy_from_slice(inslice);
1948 (&mut *pubkey).0[32..].copy_from_slice(inslice);
1949 test_cleanup_pk(pubkey as *mut PublicKey);
1950 test_pk_validate(cx, pubkey as *mut PublicKey)
1951 }
1952
1953 pub unsafe fn secp256k1_xonly_pubkey_serialize(
1954 cx: *const Context,
1955 output32: *mut c_uchar,
1956 pubkey: *const XOnlyPublicKey,
1957 ) -> c_int {
1958 check_context_flags(cx, 0);
1959 let outslice = slice::from_raw_parts_mut(output32, 32);
1960 outslice.copy_from_slice(&(&*pubkey).0[..32]);
1961 1
1962 }
1963
1964 pub unsafe fn secp256k1_xonly_pubkey_from_pubkey(
1965 cx: *const Context,
1966 xonly_pubkey: *mut XOnlyPublicKey,
1967 pk_parity: *mut c_int,
1968 pubkey: *const PublicKey,
1969 ) -> c_int {
1970 check_context_flags(cx, 0);
1971 if !pk_parity.is_null() {
1972 *pk_parity = ((*pubkey).0[32] == 0).into();
1973 }
1974 (*xonly_pubkey).0.copy_from_slice(&(&*pubkey).0);
1975 assert_eq!(test_pk_validate(cx, pubkey), 1);
1976 1
1977 }
1978
1979 pub unsafe fn secp256k1_xonly_pubkey_tweak_add(
1980 cx: *const Context,
1981 output_pubkey: *mut PublicKey,
1982 internal_pubkey: *const XOnlyPublicKey,
1983 tweak32: *const c_uchar,
1984 ) -> c_int {
1985 check_context_flags(cx, SECP256K1_START_VERIFY);
1986 (*output_pubkey).0.copy_from_slice(&(*internal_pubkey).0);
1987 secp256k1_ec_pubkey_tweak_add(cx, output_pubkey, tweak32)
1988 }
1989
1990 pub unsafe fn secp256k1_keypair_xonly_pub(
1991 cx: *const Context,
1992 pubkey: *mut XOnlyPublicKey,
1993 pk_parity: *mut c_int,
1994 keypair: *const Keypair,
1995 ) -> c_int {
1996 check_context_flags(cx, 0);
1997 if !pk_parity.is_null() {
1998 *pk_parity = ((&*keypair).0[64] == 0).into();
1999 }
2000 (&mut *pubkey).0.copy_from_slice(&(&*keypair).0[32..]);
2001 1
2002 }
2003
2004 pub unsafe fn secp256k1_keypair_xonly_tweak_add(
2005 cx: *const Context,
2006 keypair: *mut Keypair,
2007 tweak32: *const c_uchar,
2008 ) -> c_int {
2009 check_context_flags(cx, SECP256K1_START_VERIFY);
2010 let mut pk = PublicKey::new();
2011 pk.0.copy_from_slice(&(&*keypair).0[32..]);
2012 let mut sk = [0u8; 32];
2013 sk.copy_from_slice(&(&*keypair).0[..32]);
2014 assert_eq!(secp256k1_ec_pubkey_tweak_add(cx, &mut pk, tweak32), 1);
2015 assert_eq!(secp256k1_ec_seckey_tweak_add(cx, (&mut sk[..]).as_mut_ptr(), tweak32), 1);
2016 (&mut *keypair).0[..32].copy_from_slice(&sk);
2017 (&mut *keypair).0[32..].copy_from_slice(&pk.0);
2018 1
2019 }
2020
2021 pub unsafe fn secp256k1_xonly_pubkey_tweak_add_check(
2022 cx: *const Context,
2023 tweaked_pubkey32: *const c_uchar,
2024 tweaked_pubkey_parity: c_int,
2025 internal_pubkey: *const XOnlyPublicKey,
2026 tweak32: *const c_uchar,
2027 ) -> c_int {
2028 check_context_flags(cx, SECP256K1_START_VERIFY);
2029 let mut tweaked_pk = PublicKey::new();
2030 assert_eq!(
2031 secp256k1_xonly_pubkey_tweak_add(cx, &mut tweaked_pk, internal_pubkey, tweak32),
2032 1
2033 );
2034 let in_slice = slice::from_raw_parts(tweaked_pubkey32, 32);
2035 if &tweaked_pk.0[..32] == in_slice
2036 && tweaked_pubkey_parity == (tweaked_pk.0[32] == 0).into()
2037 {
2038 1
2039 } else {
2040 0
2041 }
2042 }
2043}
2044
2045#[cfg(secp256k1_fuzz)]
2046pub use self::fuzz_dummy::*;
2047
2048#[cfg(test)]
2049mod tests {
2050 #[cfg(not(rust_secp_no_symbol_renaming))]
2051 #[test]
2052 fn test_strlen() {
2053 use std::ffi::CString;
2054
2055 use super::strlen;
2056
2057 let orig = "test strlen \t \n";
2058 let test = CString::new(orig).unwrap();
2059
2060 assert_eq!(orig.len(), unsafe { strlen(test.as_ptr()) });
2061 }
2062}