1use pyo3::exceptions::PyValueError;
2use pyo3::prelude::*;
3use pyo3::types::PyBytes;
4
5macro_rules! impl_codec_class {
7 ($py_name:ident, $rust_type:ty, $doc:expr) => {
8 #[doc = $doc]
9 #[pyclass]
10 #[allow(non_camel_case_types)]
11 struct $py_name {
12 inner: $rust_type,
13 }
14
15 #[pymethods]
16 impl $py_name {
17 #[new]
29 #[pyo3(signature = (key=None, keyless=false))]
30 fn new(key: Option<String>, keyless: bool) -> PyResult<Self> {
31 let inner = match (key, keyless) {
32 (Some(key), false) => <$rust_type>::new(&key).map_err(|e| {
33 PyValueError::new_err(format!("Failed to create codec: {}", e))
34 })?,
35 (None, true) => <$rust_type>::new_keyless().map_err(|e| {
36 PyValueError::new_err(format!(
37 "Failed to create codec with hardcoded key: {}",
38 e
39 ))
40 })?,
41 (Some(_), true) => {
42 return Err(PyValueError::new_err(
43 "Cannot specify both key and keyless=True",
44 ));
45 }
46 (None, false) => {
47 return Err(PyValueError::new_err(
48 "Must provide either key or set keyless=True",
49 ));
50 }
51 };
52
53 Ok(Self { inner })
54 }
55
56 fn enc(&self, plaintext: &str) -> PyResult<String> {
67 let result = self.inner.enc(plaintext);
68 result.map_err(|e| PyValueError::new_err(format!("Enc operation failed: {}", e)))
69 }
70
71 #[pyo3(signature = (obtext))]
82 fn dec(&self, obtext: &str) -> PyResult<String> {
83 let result = self.inner.dec(obtext);
84 result.map_err(|e| PyValueError::new_err(format!("Dec operation failed: {}", e)))
85 }
86
87 #[getter]
92 fn format(&self) -> String {
93 format!("{}", self.inner.format())
94 }
95
96 #[getter]
98 fn scheme(&self) -> String {
99 self.inner.scheme().to_string()
100 }
101
102 #[getter]
104 fn encoding(&self) -> String {
105 self.inner.encoding().to_string()
106 }
107
108 #[getter]
110 fn key(&self) -> String {
111 self.inner.key()
112 }
113
114 #[getter]
116 fn key_hex(&self) -> String {
117 self.inner.key_hex()
118 }
119
120 #[getter]
122 fn key_bytes(&self, py: Python) -> PyResult<Py<PyBytes>> {
123 Ok(PyBytes::new_bound(py, self.inner.key_bytes()).into())
124 }
125 }
126 };
127}
128
129macro_rules! impl_zcodec_class {
130 ($py_name:ident, $rust_type:ty, $doc:expr) => {
131 #[doc = $doc]
132 #[pyclass]
133 #[allow(non_camel_case_types)]
134 struct $py_name {
135 inner: $rust_type,
136 }
137
138 #[pymethods]
139 impl $py_name {
140 #[new]
152 #[pyo3(signature = (secret=None, keyless=false))]
153 fn new(secret: Option<String>, keyless: bool) -> PyResult<Self> {
154 let inner = match (secret, keyless) {
155 (Some(secret), false) => <$rust_type>::new(&secret).map_err(|e| {
156 PyValueError::new_err(format!("Failed to create codec: {}", e))
157 })?,
158 (None, true) => <$rust_type>::new_keyless().map_err(|e| {
159 PyValueError::new_err(format!(
160 "Failed to create codec with hardcoded secret: {}",
161 e
162 ))
163 })?,
164 (Some(_), true) => {
165 return Err(PyValueError::new_err(
166 "Cannot specify both secret and keyless=True",
167 ));
168 }
169 (None, false) => {
170 return Err(PyValueError::new_err(
171 "Must provide either secret or set keyless=True",
172 ));
173 }
174 };
175
176 Ok(Self { inner })
177 }
178
179 fn enc(&self, plaintext: &str) -> PyResult<String> {
190 let result = self.inner.enc(plaintext);
191 result.map_err(|e| PyValueError::new_err(format!("Enc operation failed: {}", e)))
192 }
193
194 #[pyo3(signature = (obtext))]
205 fn dec(&self, obtext: &str) -> PyResult<String> {
206 let result = self.inner.dec(obtext);
207 result.map_err(|e| PyValueError::new_err(format!("Dec operation failed: {}", e)))
208 }
209
210 #[getter]
215 fn format(&self) -> String {
216 format!("{}", self.inner.format())
217 }
218
219 #[getter]
221 fn scheme(&self) -> String {
222 self.inner.scheme().to_string()
223 }
224
225 #[getter]
227 fn encoding(&self) -> String {
228 self.inner.encoding().to_string()
229 }
230
231 #[getter]
233 fn secret(&self) -> String {
234 self.inner.secret()
235 }
236
237 #[getter]
239 fn secret_hex(&self) -> String {
240 self.inner.secret_hex()
241 }
242
243 #[getter]
245 fn secret_bytes(&self, py: Python) -> PyResult<Py<PyBytes>> {
246 Ok(PyBytes::new_bound(py, self.inner.secret_bytes()).into())
247 }
248 }
249 };
250}
251
252#[cfg(feature = "aags")]
255impl_codec_class!(
256 AagsB32,
257 ::oboron::AagsB32,
258 "Aags codec (deterministic AES-GCM-SIV) with B32 encoding "
259);
260#[cfg(feature = "aags")]
261impl_codec_class!(
262 AagsB64,
263 ::oboron::AagsB64,
264 "Aags codec (deterministic AES-GCM-SIV) with B64 encoding"
265);
266#[cfg(feature = "aags")]
267impl_codec_class!(
268 AagsC32,
269 ::oboron::AagsC32,
270 "Aags codec (deterministic AES-GCM-SIV) with C32 encoding"
271);
272#[cfg(feature = "aags")]
273impl_codec_class!(
274 AagsHex,
275 ::oboron::AagsHex,
276 "Aags codec (deterministic AES-GCM-SIV) with Hex encoding"
277);
278
279#[cfg(feature = "aasv")]
282impl_codec_class!(
283 AasvB32,
284 ::oboron::AasvB32,
285 "Aasv codec (deterministic AES-SIV, nonce-misuse resistant) with B32 encoding"
286);
287#[cfg(feature = "aasv")]
288impl_codec_class!(
289 AasvB64,
290 ::oboron::AasvB64,
291 "Aasv codec (deterministic AES-SIV, nonce-misuse resistant) with B64 encoding"
292);
293#[cfg(feature = "aasv")]
294impl_codec_class!(
295 AasvC32,
296 ::oboron::AasvC32,
297 "Aasv codec (deterministic AES-SIV, nonce-misuse resistant) with C32 encoding"
298);
299#[cfg(feature = "aasv")]
300impl_codec_class!(
301 AasvHex,
302 ::oboron::AasvHex,
303 "Aasv codec (deterministic AES-SIV, nonce-misuse resistant) with Hex encoding"
304);
305
306#[cfg(feature = "apgs")]
309impl_codec_class!(
310 ApgsB32,
311 ::oboron::ApgsB32,
312 "Apgs codec (probabilistic AES-GCM-SIV) with B32 encoding"
313);
314#[cfg(feature = "apgs")]
315impl_codec_class!(
316 ApgsB64,
317 ::oboron::ApgsB64,
318 "Apgs codec (probabilistic AES-GCM-SIV) with B64 encoding"
319);
320#[cfg(feature = "apgs")]
321impl_codec_class!(
322 ApgsC32,
323 ::oboron::ApgsC32,
324 "Apgs codec (probabilistic AES-GCM-SIV) with C32 encoding"
325);
326#[cfg(feature = "apgs")]
327impl_codec_class!(
328 ApgsHex,
329 ::oboron::ApgsHex,
330 "Apgs codec (probabilistic AES-GCM-SIV) with Hex encoding"
331);
332
333#[cfg(feature = "apsv")]
336impl_codec_class!(
337 ApsvB32,
338 ::oboron::ApsvB32,
339 "Apsv codec (probabilistic AES-SIV) with B32 encoding"
340);
341#[cfg(feature = "apsv")]
342impl_codec_class!(
343 ApsvB64,
344 ::oboron::ApsvB64,
345 "Apsv codec (probabilistic AES-SIV) with B64 encoding"
346);
347#[cfg(feature = "apsv")]
348impl_codec_class!(
349 ApsvC32,
350 ::oboron::ApsvC32,
351 "Apsv codec (probabilistic AES-SIV) with C32 encoding"
352);
353#[cfg(feature = "apsv")]
354impl_codec_class!(
355 ApsvHex,
356 ::oboron::ApsvHex,
357 "Apsv codec (probabilistic AES-SIV) with Hex encoding"
358);
359
360#[cfg(feature = "upbc")]
363impl_codec_class!(
364 UpbcB32,
365 ::oboron::UpbcB32,
366 "Upbc codec (probabilistic AES-CBC) with B32 encoding"
367);
368#[cfg(feature = "upbc")]
369impl_codec_class!(
370 UpbcB64,
371 ::oboron::UpbcB64,
372 "Upbc codec (probabilistic AES-CBC) with B64 encoding"
373);
374#[cfg(feature = "upbc")]
375impl_codec_class!(
376 UpbcC32,
377 ::oboron::UpbcC32,
378 "Upbc codec (probabilistic AES-CBC) with C32 encoding"
379);
380#[cfg(feature = "upbc")]
381impl_codec_class!(
382 UpbcHex,
383 ::oboron::UpbcHex,
384 "Upbc codec (probabilistic AES-CBC) with Hex encoding"
385);
386
387#[cfg(feature = "zrbcx")]
390impl_zcodec_class!(
391 ZrbcxB32,
392 ::oboron::ztier::ZrbcxB32,
393 "Zrbcx codec (deterministic AES-CBC, constant IV) with B32 encoding "
394);
395#[cfg(feature = "zrbcx")]
396impl_zcodec_class!(
397 ZrbcxB64,
398 ::oboron::ztier::ZrbcxB64,
399 "Zrbcx codec (deterministic AES-CBC, constant IV) with B64 encoding"
400);
401#[cfg(feature = "zrbcx")]
402impl_zcodec_class!(
403 ZrbcxC32,
404 ::oboron::ztier::ZrbcxC32,
405 "Zrbcx codec (deterministic AES-CBC, constant IV) with C32 encoding"
406);
407#[cfg(feature = "zrbcx")]
408impl_zcodec_class!(
409 ZrbcxHex,
410 ::oboron::ztier::ZrbcxHex,
411 "Zrbcx codec (deterministic AES-CBC, constant IV) with Hex encoding"
412);
413
414impl_codec_class!(
419 Mock1B32,
420 ::oboron::Mock1B32,
421 "Mock1 codec (identity scheme, for testing) with B32 encoding"
422);
423impl_codec_class!(
424 Mock1B64,
425 ::oboron::Mock1B64,
426 "Mock1 codec (identity scheme, for testing) with B64 encoding"
427);
428impl_codec_class!(
429 Mock1C32,
430 ::oboron::Mock1C32,
431 "Mock1 codec (identity scheme, for testing) with C32 encoding"
432);
433impl_codec_class!(
434 Mock1Hex,
435 ::oboron::Mock1Hex,
436 "Mock1 codec (identity scheme, for testing) with Hex encoding"
437);
438
439impl_codec_class!(
442 Mock2B32,
443 ::oboron::Mock2B32,
444 "Mock2 codec (reverse plaintext scheme, for testing) with B32 encoding"
445);
446impl_codec_class!(
447 Mock2B64,
448 ::oboron::Mock2B64,
449 "Mock2 codec (reverse plaintext scheme, for testing) with B64 encoding"
450);
451impl_codec_class!(
452 Mock2C32,
453 ::oboron::Mock2C32,
454 "Mock2 codec (reverse plaintext scheme, for testing) with C32 encoding"
455);
456impl_codec_class!(
457 Mock2Hex,
458 ::oboron::Mock2Hex,
459 "Mock2 codec (reverse plaintext scheme, for testing) with Hex encoding"
460);
461
462impl_zcodec_class!(
465 Zmock1B32,
466 ::oboron::ztier::Zmock1B32,
467 "Zmock1 codec (identity scheme, for testing) with B32 encoding"
468);
469impl_zcodec_class!(
470 Zmock1B64,
471 ::oboron::ztier::Zmock1B64,
472 "Zmock1 codec (identity scheme, for testing) with B64 encoding"
473);
474impl_zcodec_class!(
475 Zmock1C32,
476 ::oboron::ztier::Zmock1C32,
477 "Zmock1 codec (identity scheme, for testing) with C32 encoding"
478);
479impl_zcodec_class!(
480 Zmock1Hex,
481 ::oboron::ztier::Zmock1Hex,
482 "Zmock1 codec (identity scheme, for testing) with Hex encoding"
483);
484
485#[cfg(feature = "legacy")]
488impl_zcodec_class!(
489 LegacyB32,
490 ::oboron::ztier::LegacyB32,
491 "Legacy codec (deterministic AES-CBC, constant IV, custom padding) with B32 encoding\n\n\
492 **LEGACY**: This scheme is maintained for backward compatibility only.\n\
493 For new projects, use Zrbcx or more secure schemes like Aags/Aasv."
494);
495#[cfg(feature = "legacy")]
496impl_zcodec_class!(
497 LegacyB64,
498 ::oboron::ztier::LegacyB64,
499 "Legacy codec (deterministic AES-CBC, constant IV, custom padding) with B64 encoding\n\n\
500 **LEGACY**: This scheme is maintained for backward compatibility only.\n\
501 For new projects, use Zrbcx or more secure schemes like Aags/Aasv."
502);
503#[cfg(feature = "legacy")]
504impl_zcodec_class!(
505 LegacyC32,
506 ::oboron::ztier::LegacyC32,
507 "Legacy codec (deterministic AES-CBC, constant IV, custom padding) with C32 encoding\n\n\
508 **LEGACY**: This scheme is maintained for backward compatibility only.\n\
509 For new projects, use Zrbcx or more secure schemes like Aags/Aasv."
510);
511#[cfg(feature = "legacy")]
512impl_zcodec_class!(
513 LegacyHex,
514 ::oboron::ztier::LegacyHex,
515 "Legacy codec (deterministic AES-CBC, constant IV, custom padding) with Hex encoding\n\n\
516 **LEGACY**: This scheme is maintained for backward compatibility only.\n\
517 For new projects, use Zrbcx or more secure schemes like Aags/Aasv."
518);
519
520#[pyclass]
525struct Ob {
526 inner: ::oboron::Ob,
527}
528
529#[pymethods]
530impl Ob {
531 #[new]
544 #[pyo3(signature = (format, key=None, keyless=false))]
545 fn new(format: &str, key: Option<String>, keyless: bool) -> PyResult<Self> {
546 let inner = match (key, keyless) {
547 (Some(key), false) => ::oboron::Ob::new(format, &key)
548 .map_err(|e| PyValueError::new_err(format!("Failed to create Ob: {}", e)))?,
549 (None, true) => ::oboron::Ob::new_keyless(format).map_err(|e| {
550 PyValueError::new_err(format!("Failed to create Ob with hardcoded key: {}", e))
551 })?,
552 (Some(_), true) => {
553 return Err(PyValueError::new_err(
554 "Cannot specify both key and keyless=True",
555 ));
556 }
557 (None, false) => {
558 return Err(PyValueError::new_err(
559 "Must provide either key or set keyless=True",
560 ));
561 }
562 };
563
564 Ok(Self { inner })
565 }
566
567 fn enc(&self, plaintext: &str) -> PyResult<String> {
578 let result = self.inner.enc(plaintext);
579 result.map_err(|e| PyValueError::new_err(format!("Enc operation failed: {}", e)))
580 }
581
582 #[pyo3(signature = (obtext))]
593 fn dec(&self, obtext: &str) -> PyResult<String> {
594 let result = self.inner.dec(obtext);
595 result.map_err(|e| PyValueError::new_err(format!("Dec operation failed: {}", e)))
596 }
597
598 fn autodec(&self, obtext: &str) -> PyResult<String> {
612 let result = self.inner.autodec(obtext);
613 result.map_err(|e| PyValueError::new_err(format!("Autodec operation failed: {}", e)))
614 }
615
616 #[getter]
621 fn format(&self) -> String {
622 format!("{}", self.inner.format())
623 }
624
625 #[getter]
627 fn scheme(&self) -> String {
628 self.inner.scheme().to_string()
629 }
630
631 #[getter]
633 fn encoding(&self) -> String {
634 self.inner.encoding().to_string()
635 }
636
637 #[getter]
639 fn key(&self) -> String {
640 self.inner.key()
641 }
642
643 #[getter]
645 fn key_hex(&self) -> String {
646 self.inner.key_hex()
647 }
648
649 #[getter]
651 fn key_bytes(&self, py: Python) -> PyResult<Py<PyBytes>> {
652 Ok(PyBytes::new_bound(py, self.inner.key_bytes()).into())
653 }
654
655 fn set_format(&mut self, format: &str) -> PyResult<()> {
663 self.inner
664 .set_format(format)
665 .map_err(|e| PyValueError::new_err(format!("Failed to set format: {}", e)))
666 }
667
668 fn set_scheme(&mut self, scheme: &str) -> PyResult<()> {
676 let scheme_enum = ::oboron::Scheme::from_str(scheme)
677 .map_err(|e| PyValueError::new_err(format!("Invalid scheme: {}", e)))?;
678 self.inner
679 .set_scheme(scheme_enum)
680 .map_err(|e| PyValueError::new_err(format!("Failed to set scheme: {}", e)))
681 }
682
683 fn set_encoding(&mut self, encoding: &str) -> PyResult<()> {
692 let encoding_enum = ::oboron::Encoding::from_str(encoding)
693 .map_err(|e| PyValueError::new_err(format!("Invalid encoding: {}", e)))?;
694 self.inner
695 .set_encoding(encoding_enum)
696 .map_err(|e| PyValueError::new_err(format!("Failed to set encoding: {}", e)))
697 }
698}
699
700#[pyclass]
706struct Omnib {
707 inner: ::oboron::Omnib,
708}
709
710#[pymethods]
711impl Omnib {
712 #[new]
724 #[pyo3(signature = (key=None, keyless=false))]
725 fn new(key: Option<String>, keyless: bool) -> PyResult<Self> {
726 let inner = match (key, keyless) {
727 (Some(key), false) => ::oboron::Omnib::new(&key)
728 .map_err(|e| PyValueError::new_err(format!("Failed to create Omnib: {}", e)))?,
729 (None, true) => ::oboron::Omnib::new_keyless().map_err(|e| {
730 PyValueError::new_err(format!("Failed to create Omnib with hardcoded key: {}", e))
731 })?,
732 (Some(_), true) => {
733 return Err(PyValueError::new_err(
734 "Cannot specify both key and keyless=True",
735 ));
736 }
737 (None, false) => {
738 return Err(PyValueError::new_err(
739 "Must provide either key or set keyless=True",
740 ));
741 }
742 };
743
744 Ok(Self { inner })
745 }
746
747 fn enc(&self, plaintext: &str, format: &str) -> PyResult<String> {
759 let result = self.inner.enc(plaintext, format);
760 result.map_err(|e| PyValueError::new_err(format!("Enc operation failed: {}", e)))
761 }
762
763 fn dec(&self, obtext: &str, format: &str) -> PyResult<String> {
775 let result = self.inner.dec(obtext, format);
776 result.map_err(|e| PyValueError::new_err(format!("Dec operation failed: {}", e)))
777 }
778
779 fn autodec(&self, obtext: &str) -> PyResult<String> {
793 let result = self.inner.autodec(obtext);
794 result.map_err(|e| PyValueError::new_err(format!("Autodec operation failed: {}", e)))
795 }
796
797 #[getter]
799 fn key(&self) -> String {
800 self.inner.key()
801 }
802
803 #[getter]
805 fn key_hex(&self) -> String {
806 self.inner.key_hex()
807 }
808
809 #[getter]
811 fn key_bytes(&self, py: Python) -> PyResult<Py<PyBytes>> {
812 Ok(PyBytes::new_bound(py, self.inner.key_bytes()).into())
813 }
814}
815
816#[pyclass]
818struct Obz {
819 inner: ::oboron::ztier::Obz,
820}
821
822#[pymethods]
823impl Obz {
824 #[new]
837 #[pyo3(signature = (format, key=None, keyless=false))]
838 fn new(format: &str, key: Option<String>, keyless: bool) -> PyResult<Self> {
839 let inner = match (key, keyless) {
840 (Some(key), false) => ::oboron::ztier::Obz::new(format, &key)
841 .map_err(|e| PyValueError::new_err(format!("Failed to create Obz: {}", e)))?,
842 (None, true) => ::oboron::ztier::Obz::new_keyless(format).map_err(|e| {
843 PyValueError::new_err(format!("Failed to create Obz with hardcoded key: {}", e))
844 })?,
845 (Some(_), true) => {
846 return Err(PyValueError::new_err(
847 "Cannot specify both key and keyless=True",
848 ));
849 }
850 (None, false) => {
851 return Err(PyValueError::new_err(
852 "Must provide either key or set keyless=True",
853 ));
854 }
855 };
856
857 Ok(Self { inner })
858 }
859
860 fn enc(&self, plaintext: &str) -> PyResult<String> {
871 let result = self.inner.enc(plaintext);
872 result.map_err(|e| PyValueError::new_err(format!("Enc operation failed: {}", e)))
873 }
874
875 #[pyo3(signature = (obtext))]
886 fn dec(&self, obtext: &str) -> PyResult<String> {
887 let result = self.inner.dec(obtext);
888 result.map_err(|e| PyValueError::new_err(format!("Dec operation failed: {}", e)))
889 }
890
891 fn autodec(&self, obtext: &str) -> PyResult<String> {
905 let result = self.inner.autodec(obtext);
906 result.map_err(|e| PyValueError::new_err(format!("Autodec operation failed: {}", e)))
907 }
908
909 #[getter]
914 fn format(&self) -> String {
915 format!("{}", self.inner.format())
916 }
917
918 #[getter]
920 fn scheme(&self) -> String {
921 self.inner.scheme().to_string()
922 }
923
924 #[getter]
926 fn encoding(&self) -> String {
927 self.inner.encoding().to_string()
928 }
929
930 #[getter]
932 fn secret(&self) -> String {
933 self.inner.secret()
934 }
935
936 #[getter]
938 fn secret_hex(&self) -> String {
939 self.inner.secret_hex()
940 }
941
942 #[getter]
944 fn secret_bytes(&self, py: Python) -> PyResult<Py<PyBytes>> {
945 Ok(PyBytes::new_bound(py, self.inner.secret_bytes()).into())
946 }
947
948 fn set_format(&mut self, format: &str) -> PyResult<()> {
956 self.inner
957 .set_format(format)
958 .map_err(|e| PyValueError::new_err(format!("Failed to set format: {}", e)))
959 }
960
961 fn set_scheme(&mut self, scheme: &str) -> PyResult<()> {
969 let scheme_enum = ::oboron::Scheme::from_str(scheme)
970 .map_err(|e| PyValueError::new_err(format!("Invalid scheme: {}", e)))?;
971 self.inner
972 .set_scheme(scheme_enum)
973 .map_err(|e| PyValueError::new_err(format!("Failed to set scheme: {}", e)))
974 }
975
976 fn set_encoding(&mut self, encoding: &str) -> PyResult<()> {
985 let encoding_enum = ::oboron::Encoding::from_str(encoding)
986 .map_err(|e| PyValueError::new_err(format!("Invalid encoding: {}", e)))?;
987 self.inner
988 .set_encoding(encoding_enum)
989 .map_err(|e| PyValueError::new_err(format!("Failed to set encoding: {}", e)))
990 }
991}
992
993#[pyclass]
995struct Omnibz {
996 inner: ::oboron::ztier::Omnibz,
997}
998
999#[pymethods]
1000impl Omnibz {
1001 #[new]
1013 #[pyo3(signature = (secret=None, keyless=false))]
1014 fn new(secret: Option<String>, keyless: bool) -> PyResult<Self> {
1015 let inner = match (secret, keyless) {
1016 (Some(secret), false) => ::oboron::ztier::Omnibz::new(&secret)
1017 .map_err(|e| PyValueError::new_err(format!("Failed to create Omnibz: {}", e)))?,
1018 (None, true) => ::oboron::ztier::Omnibz::new_keyless().map_err(|e| {
1019 PyValueError::new_err(format!(
1020 "Failed to create Omnibz with hardcoded secret: {}",
1021 e
1022 ))
1023 })?,
1024 (Some(_), true) => {
1025 return Err(PyValueError::new_err(
1026 "Cannot specify both secret and keyless=True",
1027 ));
1028 }
1029 (None, false) => {
1030 return Err(PyValueError::new_err(
1031 "Must provide either secret or set keyless=True",
1032 ));
1033 }
1034 };
1035
1036 Ok(Self { inner })
1037 }
1038
1039 fn enc(&self, plaintext: &str, format: &str) -> PyResult<String> {
1051 let result = self.inner.enc(plaintext, format);
1052 result.map_err(|e| PyValueError::new_err(format!("Enc operation failed: {}", e)))
1053 }
1054
1055 fn dec(&self, obtext: &str, format: &str) -> PyResult<String> {
1067 let result = self.inner.dec(obtext, format);
1068 result.map_err(|e| PyValueError::new_err(format!("Dec operation failed: {}", e)))
1069 }
1070
1071 fn autodec(&self, obtext: &str) -> PyResult<String> {
1085 let result = self.inner.autodec(obtext);
1086 result.map_err(|e| PyValueError::new_err(format!("Autodec operation failed: {}", e)))
1087 }
1088
1089 fn secret(&self) -> String {
1091 self.inner.secret()
1092 }
1093
1094 fn secret_hex(&self) -> String {
1096 self.inner.secret_hex()
1097 }
1098
1099 fn secret_bytes(&self, py: Python) -> PyResult<Py<PyBytes>> {
1101 Ok(PyBytes::new_bound(py, self.inner.secret_bytes()).into())
1102 }
1103}
1104
1105#[pyfunction]
1110fn generate_key() -> PyResult<String> {
1111 Ok(::oboron::generate_key())
1112}
1113
1114#[pyfunction]
1119fn generate_key_hex() -> PyResult<String> {
1120 Ok(::oboron::generate_key_hex())
1121}
1122
1123#[pyfunction]
1128fn generate_key_bytes(py: Python) -> PyResult<Py<PyBytes>> {
1129 let key = ::oboron::generate_key_bytes();
1130 Ok(PyBytes::new_bound(py, &key).into())
1131}
1132
1133#[pyfunction]
1138fn generate_secret() -> PyResult<String> {
1139 Ok(::oboron::generate_secret())
1140}
1141
1142#[pyfunction]
1147fn generate_secret_hex() -> PyResult<String> {
1148 Ok(::oboron::generate_secret_hex())
1149}
1150
1151#[pyfunction]
1156fn generate_secret_bytes(py: Python) -> PyResult<Py<PyBytes>> {
1157 let secret = ::oboron::generate_secret_bytes();
1158 Ok(PyBytes::new_bound(py, &secret).into())
1159}
1160
1161#[pyfunction]
1178fn enc(plaintext: &str, format: &str, key: &str) -> PyResult<String> {
1179 ::oboron::enc(plaintext, format, key)
1180 .map_err(|e| PyValueError::new_err(format!("Enc operation failed: {}", e)))
1181}
1182
1183#[pyfunction]
1195#[cfg(feature = "keyless")]
1196fn enc_keyless(plaintext: &str, format: &str) -> PyResult<String> {
1197 ::oboron::enc_keyless(plaintext, format)
1198 .map_err(|e| PyValueError::new_err(format!("Enc operation failed: {}", e)))
1199}
1200
1201#[pyfunction]
1214fn dec(obtext: &str, format: &str, key: &str) -> PyResult<String> {
1215 ::oboron::dec(obtext, format, key)
1216 .map_err(|e| PyValueError::new_err(format!("Dec operation failed: {}", e)))
1217}
1218
1219#[pyfunction]
1231#[cfg(feature = "keyless")]
1232fn dec_keyless(obtext: &str, format: &str) -> PyResult<String> {
1233 ::oboron::dec_keyless(obtext, format)
1234 .map_err(|e| PyValueError::new_err(format!("Dec operation failed: {}", e)))
1235}
1236
1237#[pyfunction]
1249fn autodec(obtext: &str, key: &str) -> PyResult<String> {
1250 ::oboron::autodec(obtext, key)
1251 .map_err(|e| PyValueError::new_err(format!("Autodec operation failed: {}", e)))
1252}
1253
1254#[pyfunction]
1265#[cfg(feature = "keyless")]
1266fn autodec_keyless(obtext: &str) -> PyResult<String> {
1267 ::oboron::autodec_keyless(obtext)
1268 .map_err(|e| PyValueError::new_err(format!("Autodec operation failed: {}", e)))
1269}
1270
1271#[pymodule]
1273fn _oboron(m: &Bound<'_, PyModule>) -> PyResult<()> {
1274 m.add("__version__", env!("CARGO_PKG_VERSION"))?;
1276
1277 m.add_class::<Ob>()?;
1279
1280 m.add_class::<Omnib>()?;
1282
1283 #[cfg(feature = "aags")]
1285 {
1286 m.add_class::<AagsC32>()?;
1287 m.add_class::<AagsB32>()?;
1288 m.add_class::<AagsB64>()?;
1289 m.add_class::<AagsHex>()?;
1290 }
1291
1292 #[cfg(feature = "apgs")]
1294 {
1295 m.add_class::<ApgsC32>()?;
1296 m.add_class::<ApgsB32>()?;
1297 m.add_class::<ApgsB64>()?;
1298 m.add_class::<ApgsHex>()?;
1299 }
1300
1301 #[cfg(feature = "aasv")]
1303 {
1304 m.add_class::<AasvC32>()?;
1305 m.add_class::<AasvB32>()?;
1306 m.add_class::<AasvB64>()?;
1307 m.add_class::<AasvHex>()?;
1308 }
1309
1310 #[cfg(feature = "apsv")]
1312 {
1313 m.add_class::<ApsvC32>()?;
1314 m.add_class::<ApsvB32>()?;
1315 m.add_class::<ApsvB64>()?;
1316 m.add_class::<ApsvHex>()?;
1317 }
1318
1319 #[cfg(feature = "upbc")]
1321 {
1322 m.add_class::<UpbcC32>()?;
1323 m.add_class::<UpbcB32>()?;
1324 m.add_class::<UpbcB64>()?;
1325 m.add_class::<UpbcHex>()?;
1326 }
1327
1328 #[cfg(feature = "mock")]
1332 {
1333 m.add_class::<Mock1C32>()?;
1335 m.add_class::<Mock1B32>()?;
1336 m.add_class::<Mock1B64>()?;
1337 m.add_class::<Mock1Hex>()?;
1338 m.add_class::<Mock2C32>()?;
1340 m.add_class::<Mock2B32>()?;
1341 m.add_class::<Mock2B64>()?;
1342 m.add_class::<Mock2Hex>()?;
1343 }
1344
1345 m.add_class::<Obz>()?;
1349
1350 m.add_class::<Omnibz>()?;
1352
1353 #[cfg(feature = "zrbcx")]
1355 {
1356 m.add_class::<ZrbcxC32>()?;
1357 m.add_class::<ZrbcxB32>()?;
1358 m.add_class::<ZrbcxB64>()?;
1359 m.add_class::<ZrbcxHex>()?;
1360 }
1361
1362 #[cfg(feature = "zmock")]
1364 {
1365 m.add_class::<Zmock1C32>()?;
1367 m.add_class::<Zmock1B32>()?;
1368 m.add_class::<Zmock1B64>()?;
1369 m.add_class::<Zmock1Hex>()?;
1370 }
1371
1372 #[cfg(feature = "legacy")]
1374 {
1375 m.add_class::<LegacyC32>()?;
1376 m.add_class::<LegacyB32>()?;
1377 m.add_class::<LegacyB64>()?;
1378 m.add_class::<LegacyHex>()?;
1379 }
1380
1381 m.add_function(wrap_pyfunction!(generate_key, m)?)?;
1385 m.add_function(wrap_pyfunction!(generate_key_hex, m)?)?;
1386 m.add_function(wrap_pyfunction!(generate_key_bytes, m)?)?;
1387 m.add_function(wrap_pyfunction!(generate_secret, m)?)?;
1388 m.add_function(wrap_pyfunction!(generate_secret_hex, m)?)?;
1389 m.add_function(wrap_pyfunction!(generate_secret_bytes, m)?)?;
1390
1391 m.add_function(wrap_pyfunction!(enc, m)?)?;
1393 #[cfg(feature = "keyless")]
1394 m.add_function(wrap_pyfunction!(enc_keyless, m)?)?;
1395 m.add_function(wrap_pyfunction!(dec, m)?)?;
1396 #[cfg(feature = "keyless")]
1397 m.add_function(wrap_pyfunction!(dec_keyless, m)?)?;
1398 m.add_function(wrap_pyfunction!(autodec, m)?)?;
1399 #[cfg(feature = "keyless")]
1400 m.add_function(wrap_pyfunction!(autodec_keyless, m)?)?;
1401
1402 Ok(())
1403}