1#![deny(unsafe_op_in_unsafe_fn)]
45
46mod error;
47
48use core::ffi::{c_char, c_int, c_void};
49use std::ffi::{CStr, CString};
50use std::marker::PhantomData;
51use std::ptr::NonNull;
52
53pub use error::{Error, Result};
54
55fn status_to_result(status: bicycl_rs_sys::bicycl_status_t) -> Result<()> {
56 if status == bicycl_rs_sys::bicycl_status_t::BICYCL_OK {
57 Ok(())
58 } else {
59 Err(Error::from_status(status))
60 }
61}
62
63fn ffi_string_from_len<F>(mut f: F) -> Result<String>
64where
65 F: FnMut(*mut c_char, *mut usize) -> bicycl_rs_sys::bicycl_status_t,
66{
67 let buf = ffi_bytes_from_len(|buf, len| f(buf.cast::<c_char>(), len))?;
68 let cstr = CStr::from_bytes_with_nul(&buf).map_err(|_| Error::Internal)?;
69 Ok(cstr.to_str()?.to_owned())
70}
71
72fn ffi_bytes_from_len<F>(mut f: F) -> Result<Vec<u8>>
73where
74 F: FnMut(*mut u8, *mut usize) -> bicycl_rs_sys::bicycl_status_t,
75{
76 let mut len: usize = 0;
77 let first = f(std::ptr::null_mut(), &mut len as *mut usize);
78 if first != bicycl_rs_sys::bicycl_status_t::BICYCL_ERR_BUFFER_TOO_SMALL
79 && first != bicycl_rs_sys::bicycl_status_t::BICYCL_OK
80 {
81 return Err(Error::from_status(first));
82 }
83
84 let mut buf = vec![0_u8; len];
85 if len == 0 {
86 return Ok(buf);
87 }
88
89 let second = f(buf.as_mut_ptr(), &mut len as *mut usize);
90 status_to_result(second)?;
91 buf.truncate(len);
92 Ok(buf)
93}
94
95pub fn abi_version() -> u32 {
100 unsafe { bicycl_rs_sys::bicycl_get_abi_version() }
101}
102
103pub fn version() -> &'static str {
107 unsafe {
108 let p = bicycl_rs_sys::bicycl_get_version();
109 if p.is_null() {
110 return "";
111 }
112 CStr::from_ptr(p).to_str().unwrap_or("")
113 }
114}
115
116pub fn zeroize(buf: &mut [u8]) {
121 unsafe {
122 bicycl_rs_sys::bicycl_zeroize(buf.as_mut_ptr().cast::<c_void>(), buf.len());
123 }
124}
125
126#[derive(Debug)]
139pub struct Context {
140 raw: NonNull<bicycl_rs_sys::bicycl_context_t>,
141 _marker: PhantomData<*mut ()>,
142}
143
144impl Context {
145 pub fn new() -> Result<Self> {
151 let mut raw = std::ptr::null_mut();
152 let status = unsafe { bicycl_rs_sys::bicycl_context_new(&mut raw as *mut _) };
153 status_to_result(status)?;
154 let raw = NonNull::new(raw).expect("bicycl_context_new returned null");
155 Ok(Self {
156 raw,
157 _marker: PhantomData,
158 })
159 }
160
161 pub fn last_error(&self) -> &str {
163 unsafe {
164 let p = bicycl_rs_sys::bicycl_context_last_error(self.raw.as_ptr());
165 if p.is_null() {
166 return "";
167 }
168 CStr::from_ptr(p).to_str().unwrap_or("")
169 }
170 }
171
172 pub fn clear_error(&mut self) {
174 unsafe { bicycl_rs_sys::bicycl_context_clear_error(self.raw.as_ptr()) }
175 }
176
177 pub fn randgen_from_seed_decimal(&self, seed_decimal: &str) -> Result<RandGen> {
183 let seed_c = CString::new(seed_decimal)?;
184 let mut raw = std::ptr::null_mut();
185 let status = unsafe {
186 bicycl_rs_sys::bicycl_randgen_new_from_seed_decimal(
187 self.raw.as_ptr(),
188 seed_c.as_ptr(),
189 &mut raw as *mut _,
190 )
191 };
192 status_to_result(status)?;
193 let raw = NonNull::new(raw).expect("bicycl_randgen_new_from_seed_decimal returned null");
194 Ok(RandGen {
195 raw,
196 _marker: PhantomData,
197 })
198 }
199
200 pub fn classgroup_from_discriminant_decimal(
204 &self,
205 discriminant_decimal: &str,
206 ) -> Result<ClassGroup> {
207 let disc_c = CString::new(discriminant_decimal)?;
208 let mut raw = std::ptr::null_mut();
209 let status = unsafe {
210 bicycl_rs_sys::bicycl_classgroup_new_from_discriminant_decimal(
211 self.raw.as_ptr(),
212 disc_c.as_ptr(),
213 &mut raw as *mut _,
214 )
215 };
216 status_to_result(status)?;
217 let raw = NonNull::new(raw)
218 .expect("bicycl_classgroup_new_from_discriminant_decimal returned null");
219 Ok(ClassGroup {
220 raw,
221 _marker: PhantomData,
222 })
223 }
224
225 pub fn paillier(&self, modulus_bits: u32) -> Result<Paillier> {
229 let mut raw = std::ptr::null_mut();
230 let status = unsafe {
231 bicycl_rs_sys::bicycl_paillier_new(self.raw.as_ptr(), modulus_bits, &mut raw as *mut _)
232 };
233 status_to_result(status)?;
234 let raw = NonNull::new(raw).expect("bicycl_paillier_new returned null");
235 Ok(Paillier {
236 raw,
237 _marker: PhantomData,
238 })
239 }
240
241 pub fn joye_libert(&self, modulus_bits: u32, k: u32) -> Result<JoyeLibert> {
246 let mut raw = std::ptr::null_mut();
247 let status = unsafe {
248 bicycl_rs_sys::bicycl_joye_libert_new(
249 self.raw.as_ptr(),
250 modulus_bits,
251 k,
252 &mut raw as *mut _,
253 )
254 };
255 status_to_result(status)?;
256 let raw = NonNull::new(raw).expect("bicycl_joye_libert_new returned null");
257 Ok(JoyeLibert {
258 raw,
259 _marker: PhantomData,
260 })
261 }
262
263 pub fn cl_hsmqk(&self, q_decimal: &str, k: u32, p_decimal: &str) -> Result<ClHsmqk> {
269 let q_c = CString::new(q_decimal)?;
270 let p_c = CString::new(p_decimal)?;
271 let mut raw = std::ptr::null_mut();
272 let status = unsafe {
273 bicycl_rs_sys::bicycl_cl_hsmqk_new(
274 self.raw.as_ptr(),
275 q_c.as_ptr(),
276 k,
277 p_c.as_ptr(),
278 &mut raw as *mut _,
279 )
280 };
281 status_to_result(status)?;
282 let raw = NonNull::new(raw).expect("bicycl_cl_hsmqk_new returned null");
283 Ok(ClHsmqk {
284 raw,
285 _marker: PhantomData,
286 })
287 }
288
289 pub fn cl_hsm2k(&self, n_decimal: &str, k: u32) -> Result<ClHsm2k> {
294 let n_c = CString::new(n_decimal)?;
295 let mut raw = std::ptr::null_mut();
296 let status = unsafe {
297 bicycl_rs_sys::bicycl_cl_hsm2k_new(
298 self.raw.as_ptr(),
299 n_c.as_ptr(),
300 k,
301 &mut raw as *mut _,
302 )
303 };
304 status_to_result(status)?;
305 let raw = NonNull::new(raw).expect("bicycl_cl_hsm2k_new returned null");
306 Ok(ClHsm2k {
307 raw,
308 _marker: PhantomData,
309 })
310 }
311
312 pub fn ecdsa(&self, seclevel_bits: u32) -> Result<Ecdsa> {
316 let mut raw = std::ptr::null_mut();
317 let status = unsafe {
318 bicycl_rs_sys::bicycl_ecdsa_new(self.raw.as_ptr(), seclevel_bits, &mut raw as *mut _)
319 };
320 status_to_result(status)?;
321 let raw = NonNull::new(raw).expect("bicycl_ecdsa_new returned null");
322 Ok(Ecdsa {
323 raw,
324 _marker: PhantomData,
325 })
326 }
327
328 pub fn two_party_ecdsa_session(
333 &self,
334 rng: &mut RandGen,
335 seclevel_bits: u32,
336 ) -> Result<TwoPartyEcdsaSession> {
337 let mut raw = std::ptr::null_mut();
338 let status = unsafe {
339 bicycl_rs_sys::bicycl_two_party_ecdsa_session_new(
340 self.raw.as_ptr(),
341 rng.raw.as_ptr(),
342 seclevel_bits,
343 &mut raw as *mut _,
344 )
345 };
346 status_to_result(status)?;
347 let raw = NonNull::new(raw).expect("bicycl_two_party_ecdsa_session_new returned null");
348 Ok(TwoPartyEcdsaSession {
349 raw,
350 _state: PhantomData,
351 _marker: PhantomData,
352 })
353 }
354
355 pub fn cl_dlog_session(&self, rng: &mut RandGen, seclevel_bits: u32) -> Result<ClDlogSession> {
361 let mut raw = std::ptr::null_mut();
362 let status = unsafe {
363 bicycl_rs_sys::bicycl_cl_dlog_session_new(
364 self.raw.as_ptr(),
365 rng.raw.as_ptr(),
366 seclevel_bits,
367 &mut raw as *mut _,
368 )
369 };
370 status_to_result(status)?;
371 let raw = NonNull::new(raw).expect("bicycl_cl_dlog_session_new returned null");
372 Ok(ClDlogSession {
373 raw,
374 _state: PhantomData,
375 _marker: PhantomData,
376 })
377 }
378
379 pub fn threshold_ecdsa_session(
385 &self,
386 rng: &mut RandGen,
387 seclevel_bits: u32,
388 n_players: u32,
389 threshold_t: u32,
390 ) -> Result<ThresholdEcdsaSession> {
391 let mut raw = std::ptr::null_mut();
392 let status = unsafe {
393 bicycl_rs_sys::bicycl_threshold_ecdsa_session_new(
394 self.raw.as_ptr(),
395 rng.raw.as_ptr(),
396 seclevel_bits,
397 n_players,
398 threshold_t,
399 &mut raw as *mut _,
400 )
401 };
402 status_to_result(status)?;
403 let raw = NonNull::new(raw).expect("bicycl_threshold_ecdsa_session_new returned null");
404 Ok(ThresholdEcdsaSession {
405 raw,
406 _state: PhantomData,
407 _marker: PhantomData,
408 })
409 }
410}
411
412impl Drop for Context {
413 fn drop(&mut self) {
414 unsafe { bicycl_rs_sys::bicycl_context_free(self.raw.as_ptr()) }
415 }
416}
417
418#[derive(Debug)]
422pub struct RandGen {
423 raw: NonNull<bicycl_rs_sys::bicycl_randgen_t>,
424 _marker: PhantomData<*mut ()>,
425}
426
427impl Drop for RandGen {
428 fn drop(&mut self) {
429 unsafe { bicycl_rs_sys::bicycl_randgen_free(self.raw.as_ptr()) }
430 }
431}
432
433#[derive(Debug)]
437pub struct ClassGroup {
438 raw: NonNull<bicycl_rs_sys::bicycl_classgroup_t>,
439 _marker: PhantomData<*mut ()>,
440}
441
442impl ClassGroup {
443 pub fn one(&self, ctx: &Context) -> Result<Qfi> {
445 let mut raw = std::ptr::null_mut();
446 let status = unsafe {
447 bicycl_rs_sys::bicycl_classgroup_one(
448 ctx.raw.as_ptr(),
449 self.raw.as_ptr(),
450 &mut raw as *mut _,
451 )
452 };
453 status_to_result(status)?;
454 let raw = NonNull::new(raw).expect("bicycl_classgroup_one returned null");
455 Ok(Qfi {
456 raw,
457 _marker: PhantomData,
458 })
459 }
460
461 pub fn nudupl(&self, ctx: &Context, input: &Qfi) -> Result<Qfi> {
463 let mut raw = std::ptr::null_mut();
464 let status = unsafe {
465 bicycl_rs_sys::bicycl_classgroup_nudupl(
466 ctx.raw.as_ptr(),
467 self.raw.as_ptr(),
468 input.raw.as_ptr(),
469 &mut raw as *mut _,
470 )
471 };
472 status_to_result(status)?;
473 let raw = NonNull::new(raw).expect("bicycl_classgroup_nudupl returned null");
474 Ok(Qfi {
475 raw,
476 _marker: PhantomData,
477 })
478 }
479}
480
481impl Drop for ClassGroup {
482 fn drop(&mut self) {
483 unsafe { bicycl_rs_sys::bicycl_classgroup_free(self.raw.as_ptr()) }
484 }
485}
486
487#[derive(Debug)]
491pub struct Qfi {
492 raw: NonNull<bicycl_rs_sys::bicycl_qfi_t>,
493 _marker: PhantomData<*mut ()>,
494}
495
496impl Qfi {
497 pub fn is_one(&self, ctx: &Context) -> Result<bool> {
499 let mut out: c_int = 0;
500 let status = unsafe {
501 bicycl_rs_sys::bicycl_qfi_is_one(
502 ctx.raw.as_ptr(),
503 self.raw.as_ptr(),
504 &mut out as *mut _,
505 )
506 };
507 status_to_result(status)?;
508 Ok(out != 0)
509 }
510
511 pub fn discriminant_decimal(&self, ctx: &Context) -> Result<String> {
513 ffi_string_from_len(|buf, len| unsafe {
514 bicycl_rs_sys::bicycl_qfi_discriminant_decimal(
515 ctx.raw.as_ptr(),
516 self.raw.as_ptr(),
517 buf,
518 len,
519 )
520 })
521 }
522}
523
524impl Drop for Qfi {
525 fn drop(&mut self) {
526 unsafe { bicycl_rs_sys::bicycl_qfi_free(self.raw.as_ptr()) }
527 }
528}
529
530#[derive(Debug)]
534pub struct Paillier {
535 raw: NonNull<bicycl_rs_sys::bicycl_paillier_t>,
536 _marker: PhantomData<*mut ()>,
537}
538
539#[derive(Debug)]
541pub struct PaillierSecretKey {
542 raw: NonNull<bicycl_rs_sys::bicycl_paillier_sk_t>,
543 _marker: PhantomData<*mut ()>,
544}
545
546#[derive(Debug)]
548pub struct PaillierPublicKey {
549 raw: NonNull<bicycl_rs_sys::bicycl_paillier_pk_t>,
550 _marker: PhantomData<*mut ()>,
551}
552
553#[derive(Debug)]
555pub struct PaillierCiphertext {
556 raw: NonNull<bicycl_rs_sys::bicycl_paillier_ct_t>,
557 _marker: PhantomData<*mut ()>,
558}
559
560impl Paillier {
561 pub fn keygen(
565 &self,
566 ctx: &Context,
567 rng: &mut RandGen,
568 ) -> Result<(PaillierSecretKey, PaillierPublicKey)> {
569 let mut sk_raw = std::ptr::null_mut();
570 let mut pk_raw = std::ptr::null_mut();
571 let status = unsafe {
572 bicycl_rs_sys::bicycl_paillier_keygen(
573 ctx.raw.as_ptr(),
574 self.raw.as_ptr(),
575 rng.raw.as_ptr(),
576 &mut sk_raw as *mut _,
577 &mut pk_raw as *mut _,
578 )
579 };
580 status_to_result(status)?;
581
582 let sk = PaillierSecretKey {
583 raw: NonNull::new(sk_raw).expect("bicycl_paillier_keygen/sk returned null"),
584 _marker: PhantomData,
585 };
586 let pk = PaillierPublicKey {
587 raw: NonNull::new(pk_raw).expect("bicycl_paillier_keygen/pk returned null"),
588 _marker: PhantomData,
589 };
590 Ok((sk, pk))
591 }
592
593 pub fn encrypt_decimal(
597 &self,
598 ctx: &Context,
599 pk: &PaillierPublicKey,
600 rng: &mut RandGen,
601 message_decimal: &str,
602 ) -> Result<PaillierCiphertext> {
603 let message_c = CString::new(message_decimal)?;
604 let mut ct_raw = std::ptr::null_mut();
605 let status = unsafe {
606 bicycl_rs_sys::bicycl_paillier_encrypt_decimal(
607 ctx.raw.as_ptr(),
608 self.raw.as_ptr(),
609 pk.raw.as_ptr(),
610 rng.raw.as_ptr(),
611 message_c.as_ptr(),
612 &mut ct_raw as *mut _,
613 )
614 };
615 status_to_result(status)?;
616 let raw = NonNull::new(ct_raw).expect("bicycl_paillier_encrypt_decimal returned null");
617 Ok(PaillierCiphertext {
618 raw,
619 _marker: PhantomData,
620 })
621 }
622
623 pub fn decrypt_decimal(
629 &self,
630 ctx: &Context,
631 pk: &PaillierPublicKey,
632 sk: &PaillierSecretKey,
633 ct: &PaillierCiphertext,
634 ) -> Result<String> {
635 ffi_string_from_len(|buf, len| unsafe {
636 bicycl_rs_sys::bicycl_paillier_decrypt_decimal(
637 ctx.raw.as_ptr(),
638 self.raw.as_ptr(),
639 pk.raw.as_ptr(),
640 sk.raw.as_ptr(),
641 ct.raw.as_ptr(),
642 buf,
643 len,
644 )
645 })
646 }
647}
648
649impl Drop for Paillier {
650 fn drop(&mut self) {
651 unsafe { bicycl_rs_sys::bicycl_paillier_free(self.raw.as_ptr()) }
652 }
653}
654
655impl Drop for PaillierSecretKey {
656 fn drop(&mut self) {
657 unsafe { bicycl_rs_sys::bicycl_paillier_sk_free(self.raw.as_ptr()) }
658 }
659}
660
661impl Drop for PaillierPublicKey {
662 fn drop(&mut self) {
663 unsafe { bicycl_rs_sys::bicycl_paillier_pk_free(self.raw.as_ptr()) }
664 }
665}
666
667impl Drop for PaillierCiphertext {
668 fn drop(&mut self) {
669 unsafe { bicycl_rs_sys::bicycl_paillier_ct_free(self.raw.as_ptr()) }
670 }
671}
672
673#[derive(Debug)]
677pub struct JoyeLibert {
678 raw: NonNull<bicycl_rs_sys::bicycl_joye_libert_t>,
679 _marker: PhantomData<*mut ()>,
680}
681
682#[derive(Debug)]
684pub struct JoyeLibertSecretKey {
685 raw: NonNull<bicycl_rs_sys::bicycl_joye_libert_sk_t>,
686 _marker: PhantomData<*mut ()>,
687}
688
689#[derive(Debug)]
691pub struct JoyeLibertPublicKey {
692 raw: NonNull<bicycl_rs_sys::bicycl_joye_libert_pk_t>,
693 _marker: PhantomData<*mut ()>,
694}
695
696#[derive(Debug)]
698pub struct JoyeLibertCiphertext {
699 raw: NonNull<bicycl_rs_sys::bicycl_joye_libert_ct_t>,
700 _marker: PhantomData<*mut ()>,
701}
702
703impl JoyeLibert {
704 pub fn keygen(
706 &self,
707 ctx: &Context,
708 rng: &mut RandGen,
709 ) -> Result<(JoyeLibertSecretKey, JoyeLibertPublicKey)> {
710 let mut sk_raw = std::ptr::null_mut();
711 let mut pk_raw = std::ptr::null_mut();
712 let status = unsafe {
713 bicycl_rs_sys::bicycl_joye_libert_keygen(
714 ctx.raw.as_ptr(),
715 self.raw.as_ptr(),
716 rng.raw.as_ptr(),
717 &mut sk_raw as *mut _,
718 &mut pk_raw as *mut _,
719 )
720 };
721 status_to_result(status)?;
722
723 let sk = JoyeLibertSecretKey {
724 raw: NonNull::new(sk_raw).expect("bicycl_joye_libert_keygen/sk returned null"),
725 _marker: PhantomData,
726 };
727 let pk = JoyeLibertPublicKey {
728 raw: NonNull::new(pk_raw).expect("bicycl_joye_libert_keygen/pk returned null"),
729 _marker: PhantomData,
730 };
731 Ok((sk, pk))
732 }
733
734 pub fn encrypt_decimal(
738 &self,
739 ctx: &Context,
740 pk: &JoyeLibertPublicKey,
741 rng: &mut RandGen,
742 message_decimal: &str,
743 ) -> Result<JoyeLibertCiphertext> {
744 let message_c = CString::new(message_decimal)?;
745 let mut ct_raw = std::ptr::null_mut();
746 let status = unsafe {
747 bicycl_rs_sys::bicycl_joye_libert_encrypt_decimal(
748 ctx.raw.as_ptr(),
749 self.raw.as_ptr(),
750 pk.raw.as_ptr(),
751 rng.raw.as_ptr(),
752 message_c.as_ptr(),
753 &mut ct_raw as *mut _,
754 )
755 };
756 status_to_result(status)?;
757 let raw = NonNull::new(ct_raw).expect("bicycl_joye_libert_encrypt_decimal returned null");
758 Ok(JoyeLibertCiphertext {
759 raw,
760 _marker: PhantomData,
761 })
762 }
763
764 pub fn decrypt_decimal(
766 &self,
767 ctx: &Context,
768 sk: &JoyeLibertSecretKey,
769 ct: &JoyeLibertCiphertext,
770 ) -> Result<String> {
771 ffi_string_from_len(|buf, len| unsafe {
772 bicycl_rs_sys::bicycl_joye_libert_decrypt_decimal(
773 ctx.raw.as_ptr(),
774 self.raw.as_ptr(),
775 sk.raw.as_ptr(),
776 ct.raw.as_ptr(),
777 buf,
778 len,
779 )
780 })
781 }
782}
783
784impl Drop for JoyeLibert {
785 fn drop(&mut self) {
786 unsafe { bicycl_rs_sys::bicycl_joye_libert_free(self.raw.as_ptr()) }
787 }
788}
789
790impl Drop for JoyeLibertSecretKey {
791 fn drop(&mut self) {
792 unsafe { bicycl_rs_sys::bicycl_joye_libert_sk_free(self.raw.as_ptr()) }
793 }
794}
795
796impl Drop for JoyeLibertPublicKey {
797 fn drop(&mut self) {
798 unsafe { bicycl_rs_sys::bicycl_joye_libert_pk_free(self.raw.as_ptr()) }
799 }
800}
801
802impl Drop for JoyeLibertCiphertext {
803 fn drop(&mut self) {
804 unsafe { bicycl_rs_sys::bicycl_joye_libert_ct_free(self.raw.as_ptr()) }
805 }
806}
807
808#[derive(Debug)]
812pub struct ClHsmqk {
813 raw: NonNull<bicycl_rs_sys::bicycl_cl_hsmqk_t>,
814 _marker: PhantomData<*mut ()>,
815}
816
817#[derive(Debug)]
819pub struct ClHsmqkSecretKey {
820 raw: NonNull<bicycl_rs_sys::bicycl_cl_hsmqk_sk_t>,
821 _marker: PhantomData<*mut ()>,
822}
823
824#[derive(Debug)]
826pub struct ClHsmqkPublicKey {
827 raw: NonNull<bicycl_rs_sys::bicycl_cl_hsmqk_pk_t>,
828 _marker: PhantomData<*mut ()>,
829}
830
831#[derive(Debug)]
833pub struct ClHsmqkCiphertext {
834 raw: NonNull<bicycl_rs_sys::bicycl_cl_hsmqk_ct_t>,
835 _marker: PhantomData<*mut ()>,
836}
837
838impl ClHsmqk {
839 pub fn keygen(
841 &self,
842 ctx: &Context,
843 rng: &mut RandGen,
844 ) -> Result<(ClHsmqkSecretKey, ClHsmqkPublicKey)> {
845 let mut sk_raw = std::ptr::null_mut();
846 let mut pk_raw = std::ptr::null_mut();
847 let status = unsafe {
848 bicycl_rs_sys::bicycl_cl_hsmqk_keygen(
849 ctx.raw.as_ptr(),
850 self.raw.as_ptr(),
851 rng.raw.as_ptr(),
852 &mut sk_raw as *mut _,
853 &mut pk_raw as *mut _,
854 )
855 };
856 status_to_result(status)?;
857
858 let sk = ClHsmqkSecretKey {
859 raw: NonNull::new(sk_raw).expect("bicycl_cl_hsmqk_keygen/sk returned null"),
860 _marker: PhantomData,
861 };
862 let pk = ClHsmqkPublicKey {
863 raw: NonNull::new(pk_raw).expect("bicycl_cl_hsmqk_keygen/pk returned null"),
864 _marker: PhantomData,
865 };
866 Ok((sk, pk))
867 }
868
869 pub fn encrypt_decimal(
871 &self,
872 ctx: &Context,
873 pk: &ClHsmqkPublicKey,
874 rng: &mut RandGen,
875 message_decimal: &str,
876 ) -> Result<ClHsmqkCiphertext> {
877 let message_c = CString::new(message_decimal)?;
878 let mut ct_raw = std::ptr::null_mut();
879 let status = unsafe {
880 bicycl_rs_sys::bicycl_cl_hsmqk_encrypt_decimal(
881 ctx.raw.as_ptr(),
882 self.raw.as_ptr(),
883 pk.raw.as_ptr(),
884 rng.raw.as_ptr(),
885 message_c.as_ptr(),
886 &mut ct_raw as *mut _,
887 )
888 };
889 status_to_result(status)?;
890 let raw = NonNull::new(ct_raw).expect("bicycl_cl_hsmqk_encrypt_decimal returned null");
891 Ok(ClHsmqkCiphertext {
892 raw,
893 _marker: PhantomData,
894 })
895 }
896
897 pub fn decrypt_decimal(
899 &self,
900 ctx: &Context,
901 sk: &ClHsmqkSecretKey,
902 ct: &ClHsmqkCiphertext,
903 ) -> Result<String> {
904 ffi_string_from_len(|buf, len| unsafe {
905 bicycl_rs_sys::bicycl_cl_hsmqk_decrypt_decimal(
906 ctx.raw.as_ptr(),
907 self.raw.as_ptr(),
908 sk.raw.as_ptr(),
909 ct.raw.as_ptr(),
910 buf,
911 len,
912 )
913 })
914 }
915
916 pub fn add_ciphertexts(
918 &self,
919 ctx: &Context,
920 pk: &ClHsmqkPublicKey,
921 rng: &mut RandGen,
922 ca: &ClHsmqkCiphertext,
923 cb: &ClHsmqkCiphertext,
924 ) -> Result<ClHsmqkCiphertext> {
925 let mut ct_raw = std::ptr::null_mut();
926 let status = unsafe {
927 bicycl_rs_sys::bicycl_cl_hsmqk_add_ciphertexts(
928 ctx.raw.as_ptr(),
929 self.raw.as_ptr(),
930 pk.raw.as_ptr(),
931 rng.raw.as_ptr(),
932 ca.raw.as_ptr(),
933 cb.raw.as_ptr(),
934 &mut ct_raw as *mut _,
935 )
936 };
937 status_to_result(status)?;
938 let raw = NonNull::new(ct_raw).expect("bicycl_cl_hsmqk_add_ciphertexts returned null");
939 Ok(ClHsmqkCiphertext {
940 raw,
941 _marker: PhantomData,
942 })
943 }
944
945 pub fn scal_ciphertext_decimal(
949 &self,
950 ctx: &Context,
951 pk: &ClHsmqkPublicKey,
952 rng: &mut RandGen,
953 ct: &ClHsmqkCiphertext,
954 scalar_decimal: &str,
955 ) -> Result<ClHsmqkCiphertext> {
956 let scalar_c = CString::new(scalar_decimal)?;
957 let mut out_raw = std::ptr::null_mut();
958 let status = unsafe {
959 bicycl_rs_sys::bicycl_cl_hsmqk_scal_ciphertext_decimal(
960 ctx.raw.as_ptr(),
961 self.raw.as_ptr(),
962 pk.raw.as_ptr(),
963 rng.raw.as_ptr(),
964 ct.raw.as_ptr(),
965 scalar_c.as_ptr(),
966 &mut out_raw as *mut _,
967 )
968 };
969 status_to_result(status)?;
970 let raw =
971 NonNull::new(out_raw).expect("bicycl_cl_hsmqk_scal_ciphertext_decimal returned null");
972 Ok(ClHsmqkCiphertext {
973 raw,
974 _marker: PhantomData,
975 })
976 }
977
978 pub fn addscal_ciphertexts_decimal(
984 &self,
985 ctx: &Context,
986 pk: &ClHsmqkPublicKey,
987 rng: &mut RandGen,
988 ca: &ClHsmqkCiphertext,
989 cb: &ClHsmqkCiphertext,
990 scalar_decimal: &str,
991 ) -> Result<ClHsmqkCiphertext> {
992 let scalar_c = CString::new(scalar_decimal)?;
993 let mut out_raw = std::ptr::null_mut();
994 let status = unsafe {
995 bicycl_rs_sys::bicycl_cl_hsmqk_addscal_ciphertexts_decimal(
996 ctx.raw.as_ptr(),
997 self.raw.as_ptr(),
998 pk.raw.as_ptr(),
999 rng.raw.as_ptr(),
1000 ca.raw.as_ptr(),
1001 cb.raw.as_ptr(),
1002 scalar_c.as_ptr(),
1003 &mut out_raw as *mut _,
1004 )
1005 };
1006 status_to_result(status)?;
1007 let raw = NonNull::new(out_raw)
1008 .expect("bicycl_cl_hsmqk_addscal_ciphertexts_decimal returned null");
1009 Ok(ClHsmqkCiphertext {
1010 raw,
1011 _marker: PhantomData,
1012 })
1013 }
1014}
1015
1016impl Drop for ClHsmqk {
1017 fn drop(&mut self) {
1018 unsafe { bicycl_rs_sys::bicycl_cl_hsmqk_free(self.raw.as_ptr()) }
1019 }
1020}
1021
1022impl Drop for ClHsmqkSecretKey {
1023 fn drop(&mut self) {
1024 unsafe { bicycl_rs_sys::bicycl_cl_hsmqk_sk_free(self.raw.as_ptr()) }
1025 }
1026}
1027
1028impl Drop for ClHsmqkPublicKey {
1029 fn drop(&mut self) {
1030 unsafe { bicycl_rs_sys::bicycl_cl_hsmqk_pk_free(self.raw.as_ptr()) }
1031 }
1032}
1033
1034impl Drop for ClHsmqkCiphertext {
1035 fn drop(&mut self) {
1036 unsafe { bicycl_rs_sys::bicycl_cl_hsmqk_ct_free(self.raw.as_ptr()) }
1037 }
1038}
1039
1040#[derive(Debug)]
1044pub struct ClHsm2k {
1045 raw: NonNull<bicycl_rs_sys::bicycl_cl_hsm2k_t>,
1046 _marker: PhantomData<*mut ()>,
1047}
1048
1049#[derive(Debug)]
1051pub struct ClHsm2kSecretKey {
1052 raw: NonNull<bicycl_rs_sys::bicycl_cl_hsm2k_sk_t>,
1053 _marker: PhantomData<*mut ()>,
1054}
1055
1056#[derive(Debug)]
1058pub struct ClHsm2kPublicKey {
1059 raw: NonNull<bicycl_rs_sys::bicycl_cl_hsm2k_pk_t>,
1060 _marker: PhantomData<*mut ()>,
1061}
1062
1063#[derive(Debug)]
1065pub struct ClHsm2kCiphertext {
1066 raw: NonNull<bicycl_rs_sys::bicycl_cl_hsm2k_ct_t>,
1067 _marker: PhantomData<*mut ()>,
1068}
1069
1070impl ClHsm2k {
1071 pub fn keygen(
1073 &self,
1074 ctx: &Context,
1075 rng: &mut RandGen,
1076 ) -> Result<(ClHsm2kSecretKey, ClHsm2kPublicKey)> {
1077 let mut sk_raw = std::ptr::null_mut();
1078 let mut pk_raw = std::ptr::null_mut();
1079 let status = unsafe {
1080 bicycl_rs_sys::bicycl_cl_hsm2k_keygen(
1081 ctx.raw.as_ptr(),
1082 self.raw.as_ptr(),
1083 rng.raw.as_ptr(),
1084 &mut sk_raw as *mut _,
1085 &mut pk_raw as *mut _,
1086 )
1087 };
1088 status_to_result(status)?;
1089
1090 let sk = ClHsm2kSecretKey {
1091 raw: NonNull::new(sk_raw).expect("bicycl_cl_hsm2k_keygen/sk returned null"),
1092 _marker: PhantomData,
1093 };
1094 let pk = ClHsm2kPublicKey {
1095 raw: NonNull::new(pk_raw).expect("bicycl_cl_hsm2k_keygen/pk returned null"),
1096 _marker: PhantomData,
1097 };
1098 Ok((sk, pk))
1099 }
1100
1101 pub fn encrypt_decimal(
1103 &self,
1104 ctx: &Context,
1105 pk: &ClHsm2kPublicKey,
1106 rng: &mut RandGen,
1107 message_decimal: &str,
1108 ) -> Result<ClHsm2kCiphertext> {
1109 let message_c = CString::new(message_decimal)?;
1110 let mut ct_raw = std::ptr::null_mut();
1111 let status = unsafe {
1112 bicycl_rs_sys::bicycl_cl_hsm2k_encrypt_decimal(
1113 ctx.raw.as_ptr(),
1114 self.raw.as_ptr(),
1115 pk.raw.as_ptr(),
1116 rng.raw.as_ptr(),
1117 message_c.as_ptr(),
1118 &mut ct_raw as *mut _,
1119 )
1120 };
1121 status_to_result(status)?;
1122 let raw = NonNull::new(ct_raw).expect("bicycl_cl_hsm2k_encrypt_decimal returned null");
1123 Ok(ClHsm2kCiphertext {
1124 raw,
1125 _marker: PhantomData,
1126 })
1127 }
1128
1129 pub fn decrypt_decimal(
1131 &self,
1132 ctx: &Context,
1133 sk: &ClHsm2kSecretKey,
1134 ct: &ClHsm2kCiphertext,
1135 ) -> Result<String> {
1136 ffi_string_from_len(|buf, len| unsafe {
1137 bicycl_rs_sys::bicycl_cl_hsm2k_decrypt_decimal(
1138 ctx.raw.as_ptr(),
1139 self.raw.as_ptr(),
1140 sk.raw.as_ptr(),
1141 ct.raw.as_ptr(),
1142 buf,
1143 len,
1144 )
1145 })
1146 }
1147
1148 pub fn add_ciphertexts(
1150 &self,
1151 ctx: &Context,
1152 pk: &ClHsm2kPublicKey,
1153 rng: &mut RandGen,
1154 ca: &ClHsm2kCiphertext,
1155 cb: &ClHsm2kCiphertext,
1156 ) -> Result<ClHsm2kCiphertext> {
1157 let mut ct_raw = std::ptr::null_mut();
1158 let status = unsafe {
1159 bicycl_rs_sys::bicycl_cl_hsm2k_add_ciphertexts(
1160 ctx.raw.as_ptr(),
1161 self.raw.as_ptr(),
1162 pk.raw.as_ptr(),
1163 rng.raw.as_ptr(),
1164 ca.raw.as_ptr(),
1165 cb.raw.as_ptr(),
1166 &mut ct_raw as *mut _,
1167 )
1168 };
1169 status_to_result(status)?;
1170 let raw = NonNull::new(ct_raw).expect("bicycl_cl_hsm2k_add_ciphertexts returned null");
1171 Ok(ClHsm2kCiphertext {
1172 raw,
1173 _marker: PhantomData,
1174 })
1175 }
1176
1177 pub fn scal_ciphertext_decimal(
1179 &self,
1180 ctx: &Context,
1181 pk: &ClHsm2kPublicKey,
1182 rng: &mut RandGen,
1183 ct: &ClHsm2kCiphertext,
1184 scalar_decimal: &str,
1185 ) -> Result<ClHsm2kCiphertext> {
1186 let scalar_c = CString::new(scalar_decimal)?;
1187 let mut out_raw = std::ptr::null_mut();
1188 let status = unsafe {
1189 bicycl_rs_sys::bicycl_cl_hsm2k_scal_ciphertext_decimal(
1190 ctx.raw.as_ptr(),
1191 self.raw.as_ptr(),
1192 pk.raw.as_ptr(),
1193 rng.raw.as_ptr(),
1194 ct.raw.as_ptr(),
1195 scalar_c.as_ptr(),
1196 &mut out_raw as *mut _,
1197 )
1198 };
1199 status_to_result(status)?;
1200 let raw =
1201 NonNull::new(out_raw).expect("bicycl_cl_hsm2k_scal_ciphertext_decimal returned null");
1202 Ok(ClHsm2kCiphertext {
1203 raw,
1204 _marker: PhantomData,
1205 })
1206 }
1207
1208 pub fn addscal_ciphertexts_decimal(
1214 &self,
1215 ctx: &Context,
1216 pk: &ClHsm2kPublicKey,
1217 rng: &mut RandGen,
1218 ca: &ClHsm2kCiphertext,
1219 cb: &ClHsm2kCiphertext,
1220 scalar_decimal: &str,
1221 ) -> Result<ClHsm2kCiphertext> {
1222 let scalar_c = CString::new(scalar_decimal)?;
1223 let mut out_raw = std::ptr::null_mut();
1224 let status = unsafe {
1225 bicycl_rs_sys::bicycl_cl_hsm2k_addscal_ciphertexts_decimal(
1226 ctx.raw.as_ptr(),
1227 self.raw.as_ptr(),
1228 pk.raw.as_ptr(),
1229 rng.raw.as_ptr(),
1230 ca.raw.as_ptr(),
1231 cb.raw.as_ptr(),
1232 scalar_c.as_ptr(),
1233 &mut out_raw as *mut _,
1234 )
1235 };
1236 status_to_result(status)?;
1237 let raw = NonNull::new(out_raw)
1238 .expect("bicycl_cl_hsm2k_addscal_ciphertexts_decimal returned null");
1239 Ok(ClHsm2kCiphertext {
1240 raw,
1241 _marker: PhantomData,
1242 })
1243 }
1244}
1245
1246impl Drop for ClHsm2k {
1247 fn drop(&mut self) {
1248 unsafe { bicycl_rs_sys::bicycl_cl_hsm2k_free(self.raw.as_ptr()) }
1249 }
1250}
1251
1252impl Drop for ClHsm2kSecretKey {
1253 fn drop(&mut self) {
1254 unsafe { bicycl_rs_sys::bicycl_cl_hsm2k_sk_free(self.raw.as_ptr()) }
1255 }
1256}
1257
1258impl Drop for ClHsm2kPublicKey {
1259 fn drop(&mut self) {
1260 unsafe { bicycl_rs_sys::bicycl_cl_hsm2k_pk_free(self.raw.as_ptr()) }
1261 }
1262}
1263
1264impl Drop for ClHsm2kCiphertext {
1265 fn drop(&mut self) {
1266 unsafe { bicycl_rs_sys::bicycl_cl_hsm2k_ct_free(self.raw.as_ptr()) }
1267 }
1268}
1269
1270#[derive(Debug)]
1274pub struct Ecdsa {
1275 raw: NonNull<bicycl_rs_sys::bicycl_ecdsa_t>,
1276 _marker: PhantomData<*mut ()>,
1277}
1278
1279#[derive(Debug)]
1281pub struct EcdsaSecretKey {
1282 raw: NonNull<bicycl_rs_sys::bicycl_ecdsa_sk_t>,
1283 _marker: PhantomData<*mut ()>,
1284}
1285
1286#[derive(Debug)]
1288pub struct EcdsaPublicKey {
1289 raw: NonNull<bicycl_rs_sys::bicycl_ecdsa_pk_t>,
1290 _marker: PhantomData<*mut ()>,
1291}
1292
1293#[derive(Debug)]
1295pub struct EcdsaSignature {
1296 raw: NonNull<bicycl_rs_sys::bicycl_ecdsa_sig_t>,
1297 _marker: PhantomData<*mut ()>,
1298}
1299
1300impl Ecdsa {
1301 pub fn keygen(
1303 &self,
1304 ctx: &Context,
1305 rng: &mut RandGen,
1306 ) -> Result<(EcdsaSecretKey, EcdsaPublicKey)> {
1307 let mut sk_raw = std::ptr::null_mut();
1308 let mut pk_raw = std::ptr::null_mut();
1309 let status = unsafe {
1310 bicycl_rs_sys::bicycl_ecdsa_keygen(
1311 ctx.raw.as_ptr(),
1312 self.raw.as_ptr(),
1313 rng.raw.as_ptr(),
1314 &mut sk_raw as *mut _,
1315 &mut pk_raw as *mut _,
1316 )
1317 };
1318 status_to_result(status)?;
1319 let sk = EcdsaSecretKey {
1320 raw: NonNull::new(sk_raw).expect("bicycl_ecdsa_keygen/sk returned null"),
1321 _marker: PhantomData,
1322 };
1323 let pk = EcdsaPublicKey {
1324 raw: NonNull::new(pk_raw).expect("bicycl_ecdsa_keygen/pk returned null"),
1325 _marker: PhantomData,
1326 };
1327 Ok((sk, pk))
1328 }
1329
1330 pub fn sign_message(
1334 &self,
1335 ctx: &Context,
1336 rng: &mut RandGen,
1337 sk: &EcdsaSecretKey,
1338 msg: &[u8],
1339 ) -> Result<EcdsaSignature> {
1340 let mut sig_raw = std::ptr::null_mut();
1341 let status = unsafe {
1342 bicycl_rs_sys::bicycl_ecdsa_sign_message(
1343 ctx.raw.as_ptr(),
1344 self.raw.as_ptr(),
1345 rng.raw.as_ptr(),
1346 sk.raw.as_ptr(),
1347 msg.as_ptr(),
1348 msg.len(),
1349 &mut sig_raw as *mut _,
1350 )
1351 };
1352 status_to_result(status)?;
1353 let raw = NonNull::new(sig_raw).expect("bicycl_ecdsa_sign_message returned null");
1354 Ok(EcdsaSignature {
1355 raw,
1356 _marker: PhantomData,
1357 })
1358 }
1359
1360 pub fn verify_message(
1366 &self,
1367 ctx: &Context,
1368 pk: &EcdsaPublicKey,
1369 msg: &[u8],
1370 sig: &EcdsaSignature,
1371 ) -> Result<bool> {
1372 let mut out_valid: c_int = 0;
1373 let status = unsafe {
1374 bicycl_rs_sys::bicycl_ecdsa_verify_message(
1375 ctx.raw.as_ptr(),
1376 self.raw.as_ptr(),
1377 pk.raw.as_ptr(),
1378 msg.as_ptr(),
1379 msg.len(),
1380 sig.raw.as_ptr(),
1381 &mut out_valid as *mut _,
1382 )
1383 };
1384 status_to_result(status)?;
1385 Ok(out_valid != 0)
1386 }
1387}
1388
1389impl EcdsaSignature {
1390 pub fn r_decimal(&self, ctx: &Context) -> Result<String> {
1392 ffi_string_from_len(|buf, len| unsafe {
1393 bicycl_rs_sys::bicycl_ecdsa_sig_r_decimal(ctx.raw.as_ptr(), self.raw.as_ptr(), buf, len)
1394 })
1395 }
1396
1397 pub fn s_decimal(&self, ctx: &Context) -> Result<String> {
1399 ffi_string_from_len(|buf, len| unsafe {
1400 bicycl_rs_sys::bicycl_ecdsa_sig_s_decimal(ctx.raw.as_ptr(), self.raw.as_ptr(), buf, len)
1401 })
1402 }
1403}
1404
1405pub mod two_party {
1409 pub struct New;
1410 pub struct Keygen1;
1411 pub struct Keygen2;
1412 pub struct Keygen3;
1413 pub struct KeygenDone;
1414 pub struct Sign1;
1415 pub struct Sign2;
1416 pub struct Sign3;
1417 pub struct Sign4;
1418 pub struct SignDone;
1419}
1420
1421pub struct TwoPartyEcdsaSession<S = two_party::New> {
1447 raw: NonNull<bicycl_rs_sys::bicycl_two_party_ecdsa_session_t>,
1448 _state: PhantomData<S>,
1449 _marker: PhantomData<*mut ()>,
1450}
1451
1452impl<S> std::fmt::Debug for TwoPartyEcdsaSession<S> {
1453 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1454 f.debug_struct("TwoPartyEcdsaSession")
1455 .field("raw", &self.raw)
1456 .finish()
1457 }
1458}
1459
1460impl<S> TwoPartyEcdsaSession<S> {
1461 fn transition<T>(self) -> TwoPartyEcdsaSession<T> {
1462 let raw = self.raw;
1463 std::mem::forget(self);
1464 TwoPartyEcdsaSession {
1465 raw,
1466 _state: PhantomData,
1467 _marker: PhantomData,
1468 }
1469 }
1470}
1471
1472impl<S> Drop for TwoPartyEcdsaSession<S> {
1473 fn drop(&mut self) {
1474 unsafe { bicycl_rs_sys::bicycl_two_party_ecdsa_session_free(self.raw.as_ptr()) }
1475 }
1476}
1477
1478impl TwoPartyEcdsaSession<two_party::New> {
1479 pub fn keygen_round1(
1480 self,
1481 ctx: &Context,
1482 rng: &mut RandGen,
1483 ) -> Result<TwoPartyEcdsaSession<two_party::Keygen1>> {
1484 let status = unsafe {
1485 bicycl_rs_sys::bicycl_two_party_ecdsa_keygen_round1(
1486 ctx.raw.as_ptr(),
1487 self.raw.as_ptr(),
1488 rng.raw.as_ptr(),
1489 )
1490 };
1491 status_to_result(status)?;
1492 Ok(self.transition())
1493 }
1494}
1495
1496impl TwoPartyEcdsaSession<two_party::Keygen1> {
1497 pub fn keygen_round2(
1498 self,
1499 ctx: &Context,
1500 rng: &mut RandGen,
1501 ) -> Result<TwoPartyEcdsaSession<two_party::Keygen2>> {
1502 let status = unsafe {
1503 bicycl_rs_sys::bicycl_two_party_ecdsa_keygen_round2(
1504 ctx.raw.as_ptr(),
1505 self.raw.as_ptr(),
1506 rng.raw.as_ptr(),
1507 )
1508 };
1509 status_to_result(status)?;
1510 Ok(self.transition())
1511 }
1512}
1513
1514impl TwoPartyEcdsaSession<two_party::Keygen2> {
1515 pub fn keygen_round3(
1516 self,
1517 ctx: &Context,
1518 rng: &mut RandGen,
1519 ) -> Result<TwoPartyEcdsaSession<two_party::Keygen3>> {
1520 let status = unsafe {
1521 bicycl_rs_sys::bicycl_two_party_ecdsa_keygen_round3(
1522 ctx.raw.as_ptr(),
1523 self.raw.as_ptr(),
1524 rng.raw.as_ptr(),
1525 )
1526 };
1527 status_to_result(status)?;
1528 Ok(self.transition())
1529 }
1530}
1531
1532impl TwoPartyEcdsaSession<two_party::Keygen3> {
1533 pub fn keygen_round4(
1534 self,
1535 ctx: &Context,
1536 ) -> Result<TwoPartyEcdsaSession<two_party::KeygenDone>> {
1537 let status = unsafe {
1538 bicycl_rs_sys::bicycl_two_party_ecdsa_keygen_round4(ctx.raw.as_ptr(), self.raw.as_ptr())
1539 };
1540 status_to_result(status)?;
1541 Ok(self.transition())
1542 }
1543}
1544
1545impl TwoPartyEcdsaSession<two_party::KeygenDone> {
1546 pub fn sign_round1(
1547 self,
1548 ctx: &Context,
1549 rng: &mut RandGen,
1550 msg: &[u8],
1551 ) -> Result<TwoPartyEcdsaSession<two_party::Sign1>> {
1552 let status = unsafe {
1553 bicycl_rs_sys::bicycl_two_party_ecdsa_sign_round1(
1554 ctx.raw.as_ptr(),
1555 self.raw.as_ptr(),
1556 rng.raw.as_ptr(),
1557 msg.as_ptr(),
1558 msg.len(),
1559 )
1560 };
1561 status_to_result(status)?;
1562 Ok(self.transition())
1563 }
1564}
1565
1566impl TwoPartyEcdsaSession<two_party::Sign1> {
1567 pub fn sign_round2(
1568 self,
1569 ctx: &Context,
1570 rng: &mut RandGen,
1571 ) -> Result<TwoPartyEcdsaSession<two_party::Sign2>> {
1572 let status = unsafe {
1573 bicycl_rs_sys::bicycl_two_party_ecdsa_sign_round2(
1574 ctx.raw.as_ptr(),
1575 self.raw.as_ptr(),
1576 rng.raw.as_ptr(),
1577 )
1578 };
1579 status_to_result(status)?;
1580 Ok(self.transition())
1581 }
1582}
1583
1584impl TwoPartyEcdsaSession<two_party::Sign2> {
1585 pub fn sign_round3(self, ctx: &Context) -> Result<TwoPartyEcdsaSession<two_party::Sign3>> {
1586 let status = unsafe {
1587 bicycl_rs_sys::bicycl_two_party_ecdsa_sign_round3(ctx.raw.as_ptr(), self.raw.as_ptr())
1588 };
1589 status_to_result(status)?;
1590 Ok(self.transition())
1591 }
1592}
1593
1594impl TwoPartyEcdsaSession<two_party::Sign3> {
1595 pub fn sign_round4(
1596 self,
1597 ctx: &Context,
1598 rng: &mut RandGen,
1599 ) -> Result<TwoPartyEcdsaSession<two_party::Sign4>> {
1600 let status = unsafe {
1601 bicycl_rs_sys::bicycl_two_party_ecdsa_sign_round4(
1602 ctx.raw.as_ptr(),
1603 self.raw.as_ptr(),
1604 rng.raw.as_ptr(),
1605 )
1606 };
1607 status_to_result(status)?;
1608 Ok(self.transition())
1609 }
1610}
1611
1612impl TwoPartyEcdsaSession<two_party::Sign4> {
1613 pub fn sign_finalize(
1615 self,
1616 ctx: &Context,
1617 ) -> Result<(TwoPartyEcdsaSession<two_party::SignDone>, bool)> {
1618 let mut out_valid: c_int = 0;
1619 let status = unsafe {
1620 bicycl_rs_sys::bicycl_two_party_ecdsa_sign_finalize(
1621 ctx.raw.as_ptr(),
1622 self.raw.as_ptr(),
1623 &mut out_valid as *mut _,
1624 )
1625 };
1626 status_to_result(status)?;
1627 Ok((self.transition(), out_valid != 0))
1628 }
1629}
1630
1631pub mod cl_dlog {
1635 pub struct New;
1636 pub struct Prepared;
1637 pub struct Proved;
1638 pub struct StatementImported;
1639 pub struct Ready;
1640}
1641
1642pub struct ClDlogSession<S = cl_dlog::New> {
1670 raw: NonNull<bicycl_rs_sys::bicycl_cl_dlog_session_t>,
1671 _state: PhantomData<S>,
1672 _marker: PhantomData<*mut ()>,
1673}
1674
1675impl<S> std::fmt::Debug for ClDlogSession<S> {
1676 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1677 f.debug_struct("ClDlogSession")
1678 .field("raw", &self.raw)
1679 .finish()
1680 }
1681}
1682
1683impl<S> ClDlogSession<S> {
1684 fn transition<T>(self) -> ClDlogSession<T> {
1685 let raw = self.raw;
1686 std::mem::forget(self);
1687 ClDlogSession {
1688 raw,
1689 _state: PhantomData,
1690 _marker: PhantomData,
1691 }
1692 }
1693}
1694
1695impl<S> Drop for ClDlogSession<S> {
1696 fn drop(&mut self) {
1697 unsafe { bicycl_rs_sys::bicycl_cl_dlog_session_free(self.raw.as_ptr()) }
1698 }
1699}
1700
1701#[derive(Debug)]
1707pub struct ClDlogMessage {
1708 raw: NonNull<bicycl_rs_sys::bicycl_cl_dlog_message_t>,
1709 _marker: PhantomData<*mut ()>,
1710}
1711
1712impl ClDlogSession<cl_dlog::New> {
1713 pub fn prepare_statement(
1715 self,
1716 ctx: &Context,
1717 rng: &mut RandGen,
1718 ) -> Result<ClDlogSession<cl_dlog::Prepared>> {
1719 let status = unsafe {
1720 bicycl_rs_sys::bicycl_cl_dlog_session_prepare_statement(
1721 ctx.raw.as_ptr(),
1722 self.raw.as_ptr(),
1723 rng.raw.as_ptr(),
1724 )
1725 };
1726 status_to_result(status)?;
1727 Ok(self.transition())
1728 }
1729
1730 pub fn import_statement(
1732 self,
1733 ctx: &Context,
1734 msg: &ClDlogMessage,
1735 ) -> Result<ClDlogSession<cl_dlog::StatementImported>> {
1736 let status = unsafe {
1737 bicycl_rs_sys::bicycl_cl_dlog_session_import_statement(
1738 ctx.raw.as_ptr(),
1739 self.raw.as_ptr(),
1740 msg.raw.as_ptr(),
1741 )
1742 };
1743 status_to_result(status)?;
1744 Ok(self.transition())
1745 }
1746}
1747
1748impl ClDlogSession<cl_dlog::Prepared> {
1749 pub fn prove_round(
1751 self,
1752 ctx: &Context,
1753 rng: &mut RandGen,
1754 ) -> Result<ClDlogSession<cl_dlog::Proved>> {
1755 let status = unsafe {
1756 bicycl_rs_sys::bicycl_cl_dlog_session_prove_round(
1757 ctx.raw.as_ptr(),
1758 self.raw.as_ptr(),
1759 rng.raw.as_ptr(),
1760 )
1761 };
1762 status_to_result(status)?;
1763 Ok(self.transition())
1764 }
1765}
1766
1767impl ClDlogSession<cl_dlog::Proved> {
1768 pub fn export_statement(&self, ctx: &Context, out_msg: &mut ClDlogMessage) -> Result<()> {
1770 let status = unsafe {
1771 bicycl_rs_sys::bicycl_cl_dlog_session_export_statement(
1772 ctx.raw.as_ptr(),
1773 self.raw.as_ptr(),
1774 out_msg.raw.as_ptr(),
1775 )
1776 };
1777 status_to_result(status)
1778 }
1779
1780 pub fn export_proof(&self, ctx: &Context, out_msg: &mut ClDlogMessage) -> Result<()> {
1782 let status = unsafe {
1783 bicycl_rs_sys::bicycl_cl_dlog_session_export_proof(
1784 ctx.raw.as_ptr(),
1785 self.raw.as_ptr(),
1786 out_msg.raw.as_ptr(),
1787 )
1788 };
1789 status_to_result(status)
1790 }
1791
1792 pub fn verify_round(&self, ctx: &Context) -> Result<bool> {
1794 let mut out_valid: c_int = 0;
1795 let status = unsafe {
1796 bicycl_rs_sys::bicycl_cl_dlog_session_verify_round(
1797 ctx.raw.as_ptr(),
1798 self.raw.as_ptr(),
1799 &mut out_valid as *mut _,
1800 )
1801 };
1802 status_to_result(status)?;
1803 Ok(out_valid != 0)
1804 }
1805}
1806
1807impl ClDlogSession<cl_dlog::StatementImported> {
1808 pub fn import_proof(
1810 self,
1811 ctx: &Context,
1812 msg: &ClDlogMessage,
1813 ) -> Result<ClDlogSession<cl_dlog::Ready>> {
1814 let status = unsafe {
1815 bicycl_rs_sys::bicycl_cl_dlog_session_import_proof(
1816 ctx.raw.as_ptr(),
1817 self.raw.as_ptr(),
1818 msg.raw.as_ptr(),
1819 )
1820 };
1821 status_to_result(status)?;
1822 Ok(self.transition())
1823 }
1824}
1825
1826impl ClDlogSession<cl_dlog::Ready> {
1827 pub fn verify_round(&self, ctx: &Context) -> Result<bool> {
1829 let mut out_valid: c_int = 0;
1830 let status = unsafe {
1831 bicycl_rs_sys::bicycl_cl_dlog_session_verify_round(
1832 ctx.raw.as_ptr(),
1833 self.raw.as_ptr(),
1834 &mut out_valid as *mut _,
1835 )
1836 };
1837 status_to_result(status)?;
1838 Ok(out_valid != 0)
1839 }
1840}
1841
1842impl ClDlogMessage {
1843 pub fn new() -> Result<Self> {
1845 let mut raw = std::ptr::null_mut();
1846 let status = unsafe { bicycl_rs_sys::bicycl_cl_dlog_message_new(&mut raw as *mut _) };
1847 status_to_result(status)?;
1848 let raw = NonNull::new(raw).expect("bicycl_cl_dlog_message_new returned null");
1849 Ok(Self {
1850 raw,
1851 _marker: PhantomData,
1852 })
1853 }
1854
1855 pub fn to_bytes(&self, ctx: &Context) -> Result<Vec<u8>> {
1857 ffi_bytes_from_len(|buf, len| unsafe {
1858 bicycl_rs_sys::bicycl_cl_dlog_message_export_bytes(
1859 ctx.raw.as_ptr(),
1860 self.raw.as_ptr(),
1861 buf,
1862 len,
1863 )
1864 })
1865 }
1866
1867 pub fn load_bytes(&mut self, ctx: &Context, bytes: &[u8]) -> Result<()> {
1869 let status = unsafe {
1870 bicycl_rs_sys::bicycl_cl_dlog_message_import_bytes(
1871 ctx.raw.as_ptr(),
1872 self.raw.as_ptr(),
1873 bytes.as_ptr(),
1874 bytes.len(),
1875 )
1876 };
1877 status_to_result(status)
1878 }
1879}
1880
1881impl Drop for ClDlogMessage {
1882 fn drop(&mut self) {
1883 unsafe { bicycl_rs_sys::bicycl_cl_dlog_message_free(self.raw.as_ptr()) }
1884 }
1885}
1886
1887pub mod threshold {
1891 pub struct New;
1892 pub struct Keygen1;
1893 pub struct Keygen2;
1894 pub struct KeygenDone;
1895 pub struct Sign1;
1896 pub struct Sign2;
1897 pub struct Sign3;
1898 pub struct Sign4;
1899 pub struct Sign5;
1900 pub struct Sign6;
1901 pub struct Sign7;
1902 pub struct Sign8;
1903 pub struct SignDone;
1904}
1905
1906pub struct ThresholdEcdsaSession<S = threshold::New> {
1929 raw: NonNull<bicycl_rs_sys::bicycl_threshold_ecdsa_session_t>,
1930 _state: PhantomData<S>,
1931 _marker: PhantomData<*mut ()>,
1932}
1933
1934impl<S> std::fmt::Debug for ThresholdEcdsaSession<S> {
1935 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1936 f.debug_struct("ThresholdEcdsaSession")
1937 .field("raw", &self.raw)
1938 .finish()
1939 }
1940}
1941
1942impl<S> ThresholdEcdsaSession<S> {
1943 fn transition<T>(self) -> ThresholdEcdsaSession<T> {
1944 let raw = self.raw;
1945 std::mem::forget(self);
1946 ThresholdEcdsaSession {
1947 raw,
1948 _state: PhantomData,
1949 _marker: PhantomData,
1950 }
1951 }
1952}
1953
1954impl<S> Drop for ThresholdEcdsaSession<S> {
1955 fn drop(&mut self) {
1956 unsafe { bicycl_rs_sys::bicycl_threshold_ecdsa_session_free(self.raw.as_ptr()) }
1957 }
1958}
1959
1960impl ThresholdEcdsaSession<threshold::New> {
1961 pub fn keygen_round1(
1962 self,
1963 ctx: &Context,
1964 rng: &mut RandGen,
1965 ) -> Result<ThresholdEcdsaSession<threshold::Keygen1>> {
1966 let status = unsafe {
1967 bicycl_rs_sys::bicycl_threshold_ecdsa_keygen_round1(
1968 ctx.raw.as_ptr(),
1969 self.raw.as_ptr(),
1970 rng.raw.as_ptr(),
1971 )
1972 };
1973 status_to_result(status)?;
1974 Ok(self.transition())
1975 }
1976}
1977
1978impl ThresholdEcdsaSession<threshold::Keygen1> {
1979 pub fn keygen_round2(
1980 self,
1981 ctx: &Context,
1982 rng: &mut RandGen,
1983 ) -> Result<ThresholdEcdsaSession<threshold::Keygen2>> {
1984 let status = unsafe {
1985 bicycl_rs_sys::bicycl_threshold_ecdsa_keygen_round2(
1986 ctx.raw.as_ptr(),
1987 self.raw.as_ptr(),
1988 rng.raw.as_ptr(),
1989 )
1990 };
1991 status_to_result(status)?;
1992 Ok(self.transition())
1993 }
1994}
1995
1996impl ThresholdEcdsaSession<threshold::Keygen2> {
1997 pub fn keygen_finalize(
1998 self,
1999 ctx: &Context,
2000 ) -> Result<ThresholdEcdsaSession<threshold::KeygenDone>> {
2001 let status = unsafe {
2002 bicycl_rs_sys::bicycl_threshold_ecdsa_keygen_finalize(
2003 ctx.raw.as_ptr(),
2004 self.raw.as_ptr(),
2005 )
2006 };
2007 status_to_result(status)?;
2008 Ok(self.transition())
2009 }
2010}
2011
2012impl ThresholdEcdsaSession<threshold::KeygenDone> {
2013 pub fn sign_round1(
2014 self,
2015 ctx: &Context,
2016 rng: &mut RandGen,
2017 msg: &[u8],
2018 ) -> Result<ThresholdEcdsaSession<threshold::Sign1>> {
2019 let status = unsafe {
2020 bicycl_rs_sys::bicycl_threshold_ecdsa_sign_round1(
2021 ctx.raw.as_ptr(),
2022 self.raw.as_ptr(),
2023 rng.raw.as_ptr(),
2024 msg.as_ptr(),
2025 msg.len(),
2026 )
2027 };
2028 status_to_result(status)?;
2029 Ok(self.transition())
2030 }
2031}
2032
2033impl ThresholdEcdsaSession<threshold::Sign1> {
2034 pub fn sign_round2(
2035 self,
2036 ctx: &Context,
2037 rng: &mut RandGen,
2038 ) -> Result<ThresholdEcdsaSession<threshold::Sign2>> {
2039 let status = unsafe {
2040 bicycl_rs_sys::bicycl_threshold_ecdsa_sign_round2(
2041 ctx.raw.as_ptr(),
2042 self.raw.as_ptr(),
2043 rng.raw.as_ptr(),
2044 )
2045 };
2046 status_to_result(status)?;
2047 Ok(self.transition())
2048 }
2049}
2050
2051impl ThresholdEcdsaSession<threshold::Sign2> {
2052 pub fn sign_round3(self, ctx: &Context) -> Result<ThresholdEcdsaSession<threshold::Sign3>> {
2053 let status = unsafe {
2054 bicycl_rs_sys::bicycl_threshold_ecdsa_sign_round3(ctx.raw.as_ptr(), self.raw.as_ptr())
2055 };
2056 status_to_result(status)?;
2057 Ok(self.transition())
2058 }
2059}
2060
2061impl ThresholdEcdsaSession<threshold::Sign3> {
2062 pub fn sign_round4(self, ctx: &Context) -> Result<ThresholdEcdsaSession<threshold::Sign4>> {
2063 let status = unsafe {
2064 bicycl_rs_sys::bicycl_threshold_ecdsa_sign_round4(ctx.raw.as_ptr(), self.raw.as_ptr())
2065 };
2066 status_to_result(status)?;
2067 Ok(self.transition())
2068 }
2069}
2070
2071impl ThresholdEcdsaSession<threshold::Sign4> {
2072 pub fn sign_round5(
2073 self,
2074 ctx: &Context,
2075 rng: &mut RandGen,
2076 ) -> Result<ThresholdEcdsaSession<threshold::Sign5>> {
2077 let status = unsafe {
2078 bicycl_rs_sys::bicycl_threshold_ecdsa_sign_round5(
2079 ctx.raw.as_ptr(),
2080 self.raw.as_ptr(),
2081 rng.raw.as_ptr(),
2082 )
2083 };
2084 status_to_result(status)?;
2085 Ok(self.transition())
2086 }
2087}
2088
2089impl ThresholdEcdsaSession<threshold::Sign5> {
2090 pub fn sign_round6(
2091 self,
2092 ctx: &Context,
2093 rng: &mut RandGen,
2094 ) -> Result<ThresholdEcdsaSession<threshold::Sign6>> {
2095 let status = unsafe {
2096 bicycl_rs_sys::bicycl_threshold_ecdsa_sign_round6(
2097 ctx.raw.as_ptr(),
2098 self.raw.as_ptr(),
2099 rng.raw.as_ptr(),
2100 )
2101 };
2102 status_to_result(status)?;
2103 Ok(self.transition())
2104 }
2105}
2106
2107impl ThresholdEcdsaSession<threshold::Sign6> {
2108 pub fn sign_round7(
2109 self,
2110 ctx: &Context,
2111 rng: &mut RandGen,
2112 ) -> Result<ThresholdEcdsaSession<threshold::Sign7>> {
2113 let status = unsafe {
2114 bicycl_rs_sys::bicycl_threshold_ecdsa_sign_round7(
2115 ctx.raw.as_ptr(),
2116 self.raw.as_ptr(),
2117 rng.raw.as_ptr(),
2118 )
2119 };
2120 status_to_result(status)?;
2121 Ok(self.transition())
2122 }
2123}
2124
2125impl ThresholdEcdsaSession<threshold::Sign7> {
2126 pub fn sign_round8(self, ctx: &Context) -> Result<ThresholdEcdsaSession<threshold::Sign8>> {
2127 let status = unsafe {
2128 bicycl_rs_sys::bicycl_threshold_ecdsa_sign_round8(ctx.raw.as_ptr(), self.raw.as_ptr())
2129 };
2130 status_to_result(status)?;
2131 Ok(self.transition())
2132 }
2133}
2134
2135impl ThresholdEcdsaSession<threshold::Sign8> {
2136 pub fn sign_finalize(
2137 self,
2138 ctx: &Context,
2139 ) -> Result<ThresholdEcdsaSession<threshold::SignDone>> {
2140 let status = unsafe {
2141 bicycl_rs_sys::bicycl_threshold_ecdsa_sign_finalize(ctx.raw.as_ptr(), self.raw.as_ptr())
2142 };
2143 status_to_result(status)?;
2144 Ok(self.transition())
2145 }
2146}
2147
2148impl ThresholdEcdsaSession<threshold::SignDone> {
2149 pub fn signature_valid(&self, ctx: &Context) -> Result<bool> {
2151 let mut out_valid: c_int = 0;
2152 let status = unsafe {
2153 bicycl_rs_sys::bicycl_threshold_ecdsa_signature_valid(
2154 ctx.raw.as_ptr(),
2155 self.raw.as_ptr(),
2156 &mut out_valid as *mut _,
2157 )
2158 };
2159 status_to_result(status)?;
2160 Ok(out_valid != 0)
2161 }
2162}
2163
2164impl Drop for Ecdsa {
2165 fn drop(&mut self) {
2166 unsafe { bicycl_rs_sys::bicycl_ecdsa_free(self.raw.as_ptr()) }
2167 }
2168}
2169
2170impl Drop for EcdsaSecretKey {
2171 fn drop(&mut self) {
2172 unsafe { bicycl_rs_sys::bicycl_ecdsa_sk_free(self.raw.as_ptr()) }
2173 }
2174}
2175
2176impl Drop for EcdsaPublicKey {
2177 fn drop(&mut self) {
2178 unsafe { bicycl_rs_sys::bicycl_ecdsa_pk_free(self.raw.as_ptr()) }
2179 }
2180}
2181
2182impl Drop for EcdsaSignature {
2183 fn drop(&mut self) {
2184 unsafe { bicycl_rs_sys::bicycl_ecdsa_sig_free(self.raw.as_ptr()) }
2185 }
2186}