diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28538c3f3c..09b7343161 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,4 +83,13 @@ jobs: - name: Cargo clippy run: cargo clippy + careful: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - uses: dtolnay/rust-toolchain@nightly + - run: cargo install cargo-careful + - run: cargo careful test --no-default-features --features non_portable,kems,sigs,std --manifest-path oqs/Cargo.toml # vim: set ft=yaml ts=2 sw=2 tw=0 et : diff --git a/CHANGELOG.md b/CHANGELOG.md index aaa4258a6e..7e93f9c06d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## oqs-sys v0.9.2 + +- Update to liboqs 0.11.0 +- Expose ML-KEM, ML-DSA, Cross, and Mayo +- Buffer Serialize/Deserialize uses serdect for hex when readable and binary when not +- Implement Debug for all structs + ## oqs-sys v0.9.1 * Fix pkg-config version detection (#246) diff --git a/oqs-sys/Cargo.toml b/oqs-sys/Cargo.toml index 6d24ac0dbf..0be753eacb 100644 --- a/oqs-sys/Cargo.toml +++ b/oqs-sys/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "oqs-sys" -version = "0.9.1+liboqs-0.9.0" -authors = ["Thom Wiggers "] +version = "0.9.2+liboqs-0.11.0" +authors = ["Thom Wiggers ", "Michael Lodder "] edition = "2021" links = "oqs" description = "Bindings to liboqs" @@ -20,7 +20,7 @@ libc = "0.2" [build-dependencies] pkg-config = "0.3" cmake = "0.1" -bindgen = "0.69" +bindgen = "0.70" build-deps = "0.1" [features] @@ -30,17 +30,21 @@ docs = [] non_portable = [] vendored = [] # algorithms: KEMs -kems = ["classic_mceliece", "frodokem", "hqc", "kyber", "ntruprime"] +kems = ["classic_mceliece", "frodokem", "hqc", "kyber", "ntruprime", "ml_kem"] bike = [] # BIKE is enabled by build.rs on non-windows targets classic_mceliece = [] frodokem = [] hqc = [] kyber = [] ntruprime = [] +ml_kem = [] # algorithms: Signature schemes -sigs = ["dilithium", "falcon", "sphincs"] +sigs = ["cross", "dilithium", "falcon", "mayo", "ml_dsa", "sphincs"] +cross = [] dilithium = [] falcon = [] +mayo = [] +ml_dsa = [] sphincs = [] [package.metadata.docs.rs] diff --git a/oqs-sys/build.rs b/oqs-sys/build.rs index 4e4560c9a9..e34c3fd928 100644 --- a/oqs-sys/build.rs +++ b/oqs-sys/build.rs @@ -22,8 +22,12 @@ fn generate_bindings(includedir: &Path, headerfile: &str, filter: &str) { // Whitelist OQS stuff .allowlist_recursively(false) .allowlist_type(filter) + .allowlist_type("secure_store_sk") + .allowlist_type("lock_key") + .allowlist_type("unlock_key") .allowlist_function(filter) .allowlist_var(filter) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) // Use core and libc .use_core() .ctypes_prefix("::libc") @@ -69,10 +73,14 @@ fn build_from_source() -> PathBuf { algorithm_feature!("KEM", "hqc"); algorithm_feature!("KEM", "kyber"); algorithm_feature!("KEM", "ntruprime"); + algorithm_feature!("KEM", "ml_kem"); // signature schemes algorithm_feature!("SIG", "dilithium"); algorithm_feature!("SIG", "falcon"); + algorithm_feature!("SIG", "mayo"); + algorithm_feature!("SIG", "cross"); + algorithm_feature!("SIG", "ml_dsa"); algorithm_feature!("SIG", "sphincs"); if cfg!(windows) { diff --git a/oqs-sys/liboqs b/oqs-sys/liboqs index 7c3a0e9aa7..6f30d7ef49 160000 --- a/oqs-sys/liboqs +++ b/oqs-sys/liboqs @@ -1 +1 @@ -Subproject commit 7c3a0e9aa7f9568e4dcafaf908ff8aa0008f0b71 +Subproject commit 6f30d7ef49ca590979d7a085cd662f00bb6855fe diff --git a/oqs/Cargo.toml b/oqs/Cargo.toml index 770e7b297b..6d8f884a16 100644 --- a/oqs/Cargo.toml +++ b/oqs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oqs" -version = "0.9.0" +version = "0.9.1" authors = ["Thom Wiggers "] edition = "2021" description = "A Rusty interface to Open-Quantum-Safe's liboqs" @@ -13,28 +13,34 @@ license = "MIT OR Apache-2.0" libc = "0.2" cstr_core = { version = "0.2", default-features = false, features = ["alloc"] } serde = { version = "1.0", optional = true, default-features = false, features = ["derive", "alloc"] } +serdect = { version = "0.3.0-rc.0", optional = true } [dependencies.oqs-sys] path = "../oqs-sys" -version = "0.9.0" +version = "0.9.2" default-features = false [features] default = ["oqs-sys/openssl", "kems", "sigs", "std"] +serde = ["dep:serde", "serdect"] std = [] non_portable = ["oqs-sys/non_portable"] vendored = ["oqs-sys/vendored"] # algorithms: KEMs -kems = ["oqs-sys/kems", "classic_mceliece", "frodokem", "hqc", "kyber", "ntruprime"] +kems = ["oqs-sys/kems", "classic_mceliece", "frodokem", "hqc", "kyber", "ntruprime", "ml_kem"] bike = ["oqs-sys/bike"] # not supported on Windows or 32-bit ARM classic_mceliece = ["oqs-sys/classic_mceliece"] frodokem = ["oqs-sys/frodokem"] hqc = ["oqs-sys/hqc"] kyber = ["oqs-sys/kyber"] ntruprime = ["oqs-sys/ntruprime"] +ml_kem = ["oqs-sys/ml_kem"] # algorithms: Signature schemes -sigs = ["oqs-sys/sigs", "dilithium", "falcon", "sphincs"] +sigs = ["oqs-sys/sigs", "cross", "dilithium", "falcon", "mayo", "ml_dsa", "sphincs"] +cross = ["oqs-sys/cross"] dilithium = ["oqs-sys/dilithium"] falcon = ["oqs-sys/falcon"] +mayo = ["oqs-sys/mayo"] +ml_dsa = ["oqs-sys/ml_dsa"] sphincs = ["oqs-sys/sphincs"] diff --git a/oqs/src/kem.rs b/oqs/src/kem.rs index 2f9d6e4efe..061cb82a49 100644 --- a/oqs/src/kem.rs +++ b/oqs/src/kem.rs @@ -5,6 +5,7 @@ use alloc::vec::Vec; use core::ptr::NonNull; +use core::str::FromStr; #[cfg(not(feature = "std"))] use cstr_core::CStr; @@ -24,7 +25,7 @@ newtype_buffer!(Ciphertext, CiphertextRef); newtype_buffer!(SharedSecret, SharedSecretRef); macro_rules! implement_kems { - { $(($feat: literal) $kem: ident: $oqs_id: ident),* $(,)? } => ( + { $(($feat: literal) $kem: ident: $oqs_id: ident: $str_name: literal),* $(,)? } => ( /// Supported algorithms by OQS /// @@ -49,6 +50,18 @@ macro_rules! implement_kems { id as *const _ as *const libc::c_char } + impl FromStr for Algorithm { + type Err = Error; + fn from_str(s: &str) -> Result { + match s { + $( + $str_name => Ok(Algorithm::$kem), + )* + _ => Err(Error::AlgorithmNotSupportedOrKnown), + } + } + } + $( #[cfg(test)] #[allow(non_snake_case)] @@ -108,40 +121,60 @@ macro_rules! implement_kems { assert!(!version.is_empty()); } } + + #[test] + fn test_from_str() { + let algo = Algorithm::$kem; + let name = algo.name(); + let res = name.parse::(); + if res.is_err() { + assert!(false, "Failed to parse: {:?}", name); + } + let algo2 = res.unwrap(); + assert_eq!(algo, algo2); + } } )* ) } +// List of supported KEM algorithms found in liboqs/src/kem/kem.h implement_kems! { - ("bike") BikeL1: OQS_KEM_alg_bike_l1, - ("bike") BikeL3: OQS_KEM_alg_bike_l3, - ("bike") BikeL5: OQS_KEM_alg_bike_l5, - ("classic_mceliece") ClassicMcEliece348864: OQS_KEM_alg_classic_mceliece_348864, - ("classic_mceliece") ClassicMcEliece348864f: OQS_KEM_alg_classic_mceliece_348864f, - ("classic_mceliece") ClassicMcEliece460896: OQS_KEM_alg_classic_mceliece_460896, - ("classic_mceliece") ClassicMcEliece460896f: OQS_KEM_alg_classic_mceliece_460896f, - ("classic_mceliece") ClassicMcEliece6688128: OQS_KEM_alg_classic_mceliece_6688128, - ("classic_mceliece") ClassicMcEliece6688128f: OQS_KEM_alg_classic_mceliece_6688128f, - ("classic_mceliece") ClassicMcEliece6960119: OQS_KEM_alg_classic_mceliece_6960119, - ("classic_mceliece") ClassicMcEliece6960119f: OQS_KEM_alg_classic_mceliece_6960119f, - ("classic_mceliece") ClassicMcEliece8192128: OQS_KEM_alg_classic_mceliece_8192128, - ("classic_mceliece") ClassicMcEliece8192128f: OQS_KEM_alg_classic_mceliece_8192128f, - ("hqc") Hqc128: OQS_KEM_alg_hqc_128, - ("hqc") Hqc192: OQS_KEM_alg_hqc_192, - ("hqc") Hqc256: OQS_KEM_alg_hqc_256, - ("kyber") Kyber512: OQS_KEM_alg_kyber_512, - ("kyber") Kyber768: OQS_KEM_alg_kyber_768, - ("kyber") Kyber1024: OQS_KEM_alg_kyber_1024, - ("ntruprime") NtruPrimeSntrup761: OQS_KEM_alg_ntruprime_sntrup761, - ("frodokem") FrodoKem640Aes: OQS_KEM_alg_frodokem_640_aes, - ("frodokem") FrodoKem640Shake: OQS_KEM_alg_frodokem_640_shake, - ("frodokem") FrodoKem976Aes: OQS_KEM_alg_frodokem_976_aes, - ("frodokem") FrodoKem976Shake: OQS_KEM_alg_frodokem_976_shake, - ("frodokem") FrodoKem1344Aes: OQS_KEM_alg_frodokem_1344_aes, - ("frodokem") FrodoKem1344Shake: OQS_KEM_alg_frodokem_1344_shake, + ("bike") BikeL1: OQS_KEM_alg_bike_l1: "BIKE-L1", + ("bike") BikeL3: OQS_KEM_alg_bike_l3: "BIKE-L3", + ("bike") BikeL5: OQS_KEM_alg_bike_l5: "BIKE-L5", + ("classic_mceliece") ClassicMcEliece348864: OQS_KEM_alg_classic_mceliece_348864: "Classic-McEliece-348864", + ("classic_mceliece") ClassicMcEliece348864f: OQS_KEM_alg_classic_mceliece_348864f: "Classic-McEliece-348864f", + ("classic_mceliece") ClassicMcEliece460896: OQS_KEM_alg_classic_mceliece_460896: "Classic-McEliece-460896", + ("classic_mceliece") ClassicMcEliece460896f: OQS_KEM_alg_classic_mceliece_460896f: "Classic-McEliece-460896f", + ("classic_mceliece") ClassicMcEliece6688128: OQS_KEM_alg_classic_mceliece_6688128: "Classic-McEliece-6688128", + ("classic_mceliece") ClassicMcEliece6688128f: OQS_KEM_alg_classic_mceliece_6688128f: "Classic-McEliece-6688128f", + ("classic_mceliece") ClassicMcEliece6960119: OQS_KEM_alg_classic_mceliece_6960119: "Classic-McEliece-6960119", + ("classic_mceliece") ClassicMcEliece6960119f: OQS_KEM_alg_classic_mceliece_6960119f: "Classic-McEliece-6960119f", + ("classic_mceliece") ClassicMcEliece8192128: OQS_KEM_alg_classic_mceliece_8192128: "Classic-McEliece-8192128", + ("classic_mceliece") ClassicMcEliece8192128f: OQS_KEM_alg_classic_mceliece_8192128f: "Classic-McEliece-8192128f", + ("hqc") Hqc128: OQS_KEM_alg_hqc_128: "HQC-128", + ("hqc") Hqc192: OQS_KEM_alg_hqc_192: "HQC-192", + ("hqc") Hqc256: OQS_KEM_alg_hqc_256: "HQC-256", + ("kyber") Kyber512: OQS_KEM_alg_kyber_512: "Kyber512", + ("kyber") Kyber768: OQS_KEM_alg_kyber_768: "Kyber768", + ("kyber") Kyber1024: OQS_KEM_alg_kyber_1024: "Kyber1024", + ("ntruprime") NtruPrimeSntrup761: OQS_KEM_alg_ntruprime_sntrup761: "sntrup761", + ("frodokem") FrodoKem640Aes: OQS_KEM_alg_frodokem_640_aes: "FrodoKEM-640-AES", + ("frodokem") FrodoKem640Shake: OQS_KEM_alg_frodokem_640_shake: "FrodoKEM-640-SHAKE", + ("frodokem") FrodoKem976Aes: OQS_KEM_alg_frodokem_976_aes: "FrodoKEM-976-AES", + ("frodokem") FrodoKem976Shake: OQS_KEM_alg_frodokem_976_shake: "FrodoKEM-976-SHAKE", + ("frodokem") FrodoKem1344Aes: OQS_KEM_alg_frodokem_1344_aes: "FrodoKEM-1344-AES", + ("frodokem") FrodoKem1344Shake: OQS_KEM_alg_frodokem_1344_shake: "FrodoKEM-1344-SHAKE", + ("ml_kem") MlKem512: OQS_KEM_alg_ml_kem_512: "ML-KEM-512", + ("ml_kem") MlKem768: OQS_KEM_alg_ml_kem_768: "ML-KEM-768", + ("ml_kem") MlKem1024: OQS_KEM_alg_ml_kem_1024: "ML-KEM-1024", } +// ("ml_kem") MlKem512Ipd: OQS_KEM_alg_ml_kem_512_ipd, +// ("ml_kem") MlKem768Ipd: OQS_KEM_alg_ml_kem_768_ipd, +// ("ml_kem") MlKem1024Ipd: OQS_KEM_alg_ml_kem_1024_ipd, + impl Algorithm { /// Returns true if this algorithm is enabled in the linked version /// of liboqs @@ -166,10 +199,9 @@ impl Algorithm { } } -#[cfg(feature = "std")] -impl std::fmt::Display for Algorithm { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.name().fmt(f) +impl Display for Algorithm { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + Display::fmt(self.name(), f) } } @@ -191,6 +223,47 @@ pub struct Kem { kem: NonNull, } +impl Debug for Kem { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("Kem") + .field("algorithm", &self.algorithm) + .field( + "method_name", + &unsafe { CStr::from_ptr(self.kem.as_ref().method_name) } + .to_str() + .expect("method name"), + ) + .field( + "alg_version", + &unsafe { CStr::from_ptr(self.kem.as_ref().alg_version) } + .to_str() + .expect("alg_version"), + ) + .field( + "claimed_nist_level", + &unsafe { self.kem.as_ref() }.claimed_nist_level, + ) + .field("ind_cca", &unsafe { self.kem.as_ref() }.ind_cca) + .field( + "length_public_key", + &unsafe { self.kem.as_ref() }.length_public_key, + ) + .field( + "length_secret_key", + &unsafe { self.kem.as_ref() }.length_secret_key, + ) + .field( + "length_ciphertext", + &unsafe { self.kem.as_ref() }.length_ciphertext, + ) + .field( + "length_shared_secret", + &unsafe { self.kem.as_ref() }.length_shared_secret, + ) + .finish() + } +} + unsafe impl Sync for Kem {} unsafe impl Send for Kem {} @@ -200,8 +273,8 @@ impl Drop for Kem { } } -impl core::convert::TryFrom for Kem { - type Error = crate::Error; +impl TryFrom for Kem { + type Error = Error; fn try_from(alg: Algorithm) -> Result { Kem::new(alg) } @@ -314,7 +387,7 @@ impl Kem { /// Generate a new keypair pub fn keypair(&self) -> Result<(PublicKey, SecretKey)> { let kem = unsafe { self.kem.as_ref() }; - let func = kem.keypair.unwrap(); + let func = kem.keypair.expect("keypair function not available"); let mut pk = PublicKey { bytes: Vec::with_capacity(kem.length_public_key), }; @@ -342,7 +415,7 @@ impl Kem { return Err(Error::InvalidLength); } let kem = unsafe { self.kem.as_ref() }; - let func = kem.encaps.unwrap(); + let func = kem.encaps.expect("encapsulate function not available"); let mut ct = Ciphertext { bytes: Vec::with_capacity(kem.length_ciphertext), }; @@ -383,7 +456,7 @@ impl Kem { let mut ss = SharedSecret { bytes: Vec::with_capacity(kem.length_shared_secret), }; - let func = kem.decaps.unwrap(); + let func = kem.decaps.expect("decapsulate function not available"); // Call decapsulate let status = unsafe { func(ss.bytes.as_mut_ptr(), ct.bytes.as_ptr(), sk.bytes.as_ptr()) }; status_to_result(status)?; diff --git a/oqs/src/lib.rs b/oqs/src/lib.rs index eabe09ffa1..0cbfdbe428 100644 --- a/oqs/src/lib.rs +++ b/oqs/src/lib.rs @@ -1,5 +1,12 @@ -#![warn(missing_docs)] +#![warn( + clippy::unwrap_used, + missing_debug_implementations, + missing_docs, + trivial_numeric_casts, + unused_qualifications +)] #![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] //! Friendly bindings to liboqs //! //! See the [`kem::Kem`](crate::kem::Kem) and [`sig::Sig`](crate::sig::Sig) structs for how to use this crate. @@ -49,6 +56,8 @@ use ffi::common::OQS_STATUS; /// Access the OQS ffi through this crate. pub use oqs_sys as ffi; +use core::fmt::{self, Debug, Display, Formatter}; + mod macros; /// Initialize liboqs @@ -82,6 +91,8 @@ pub fn init() { pub enum Error { /// Indicates an algorithm has been disabled AlgorithmDisabled, + /// Algorithm not supported or unknown + AlgorithmNotSupportedOrKnown, /// Generic error Error, /// Error occurred in OpenSSL functions external to liboqs @@ -96,10 +107,14 @@ impl std::error::Error for Error {} /// Result type for operations that may fail pub type Result = core::result::Result; -impl core::fmt::Display for Error { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { +impl Display for Error { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Error::AlgorithmDisabled => write!(f, "OQS Error: Algorithm has been disabled"), + Error::AlgorithmNotSupportedOrKnown => write!( + f, + "OQS Error: Algorithm not supported, has been disabled or is unknown" + ), Error::ErrorExternalOpenSSL => write!(f, "OQS error: OpenSSL call failed"), _ => write!(f, "OQS Error!"), } diff --git a/oqs/src/macros.rs b/oqs/src/macros.rs index 0ee2945973..9ebc28cf23 100644 --- a/oqs/src/macros.rs +++ b/oqs/src/macros.rs @@ -10,7 +10,6 @@ macro_rules! newtype_buffer { /// /// Optional support for `serde` if that feature is enabled. #[derive(Debug, Clone, PartialEq, Eq)] - #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct $name { bytes: Vec, } @@ -22,6 +21,26 @@ macro_rules! newtype_buffer { } } + #[cfg(feature = "serde")] + impl serde::Serialize for $name { + fn serialize(&self, s: S) -> core::result::Result + where + S: serde::Serializer, + { + serdect::slice::serialize_hex_lower_or_bin(&self.bytes, s) + } + } + + #[cfg(feature = "serde")] + impl<'de> serde::Deserialize<'de> for $name { + fn deserialize(d: D) -> core::result::Result + where + D: serde::Deserializer<'de>, + { + serdect::slice::deserialize_hex_or_bin_vec(d).map(|bytes| $name { bytes }) + } + } + /// Reference version of this type. /// /// Allows for copy-less usage @@ -72,10 +91,14 @@ macro_rules! newtype_buffer { impl $name { /// Length in bytes - #[allow(clippy::len_without_is_empty)] pub fn len(&self) -> usize { self.bytes.len() } + + /// True if the buffer is empty + pub fn is_empty(&self) -> bool { + self.bytes.is_empty() + } } }; } @@ -85,10 +108,6 @@ mod test { use alloc::vec; use alloc::vec::Vec; - // necessary for newtype_buffer call - #[cfg(feature = "serde")] - use serde::{Deserialize, Serialize}; - newtype_buffer!(TestBuf, TestBufRef); #[test] diff --git a/oqs/src/sig.rs b/oqs/src/sig.rs index c4a87519be..959f64ba6b 100644 --- a/oqs/src/sig.rs +++ b/oqs/src/sig.rs @@ -5,6 +5,7 @@ use alloc::vec::Vec; use core::ptr::NonNull; +use core::str::FromStr; #[cfg(not(feature = "std"))] use cstr_core::CStr; @@ -26,7 +27,7 @@ newtype_buffer!(Signature, SignatureRef); pub type Message = [u8]; macro_rules! implement_sigs { - { $(($feat: literal) $sig: ident: $oqs_id: ident),* $(,)? } => ( + { $(($feat: literal) $sig: ident: $oqs_id: ident: $str_name: literal),* $(,)? } => ( /// Supported algorithms by liboqs /// /// They may not all be enabled @@ -50,6 +51,18 @@ macro_rules! implement_sigs { id as *const _ as *const libc::c_char } + impl FromStr for Algorithm { + type Err = Error; + fn from_str(s: &str) -> Result { + match s { + $( + $str_name => Ok(Algorithm::$sig), + )* + _ => Err(Error::AlgorithmNotSupportedOrKnown), + } + } + } + $( #[cfg(test)] #[allow(non_snake_case)] @@ -108,29 +121,73 @@ macro_rules! implement_sigs { assert!(!version.is_empty()); } } + + + #[test] + fn test_from_str() { + let algo = Algorithm::$sig; + let name = algo.name(); + let res = name.parse::(); + if res.is_err() { + assert!(false, "Failed to parse: {:?}", name); + } + let algo2 = res.unwrap(); + assert_eq!(algo, algo2); + } } )* ) } +// List of supported Sig algorithms found in liboqs/src/sig/sig.h implement_sigs! { - ("dilithium") Dilithium2: OQS_SIG_alg_dilithium_2, - ("dilithium") Dilithium3: OQS_SIG_alg_dilithium_3, - ("dilithium") Dilithium5: OQS_SIG_alg_dilithium_5, - ("falcon") Falcon512: OQS_SIG_alg_falcon_512, - ("falcon") Falcon1024: OQS_SIG_alg_falcon_1024, - ("sphincs") SphincsSha2128fSimple: OQS_SIG_alg_sphincs_sha2_128f_simple, - ("sphincs") SphincsSha2128sSimple: OQS_SIG_alg_sphincs_sha2_128s_simple, - ("sphincs") SphincsSha2192fSimple: OQS_SIG_alg_sphincs_sha2_192f_simple, - ("sphincs") SphincsSha2192sSimple: OQS_SIG_alg_sphincs_sha2_192s_simple, - ("sphincs") SphincsSha2256fSimple: OQS_SIG_alg_sphincs_sha2_256f_simple, - ("sphincs") SphincsSha2256sSimple: OQS_SIG_alg_sphincs_sha2_256s_simple, - ("sphincs") SphincsShake128fSimple: OQS_SIG_alg_sphincs_shake_128f_simple, - ("sphincs") SphincsShake128sSimple: OQS_SIG_alg_sphincs_shake_128s_simple, - ("sphincs") SphincsShake192fSimple: OQS_SIG_alg_sphincs_shake_192f_simple, - ("sphincs") SphincsShake192sSimple: OQS_SIG_alg_sphincs_shake_192s_simple, - ("sphincs") SphincsShake256fSimple: OQS_SIG_alg_sphincs_shake_256f_simple, - ("sphincs") SphincsShake256sSimple: OQS_SIG_alg_sphincs_shake_256s_simple, + ("dilithium") Dilithium2: OQS_SIG_alg_dilithium_2: "Dilithium2", + ("dilithium") Dilithium3: OQS_SIG_alg_dilithium_3: "Dilithium3", + ("dilithium") Dilithium5: OQS_SIG_alg_dilithium_5: "Dilithium5", + ("falcon") Falcon512: OQS_SIG_alg_falcon_512: "Falcon-512", + ("falcon") Falcon1024: OQS_SIG_alg_falcon_1024: "Falcon-1024", + ("falcon") FalconPadded512: OQS_SIG_alg_falcon_padded_512: "Falcon-padded-512", + ("falcon") FalconPadded1024: OQS_SIG_alg_falcon_padded_1024: "Falcon-padded-1024", + ("sphincs") SphincsSha2128fSimple: OQS_SIG_alg_sphincs_sha2_128f_simple: "SPHINCS+-SHA2-128f-simple", + ("sphincs") SphincsSha2128sSimple: OQS_SIG_alg_sphincs_sha2_128s_simple: "SPHINCS+-SHA2-128s-simple", + ("sphincs") SphincsSha2192fSimple: OQS_SIG_alg_sphincs_sha2_192f_simple: "SPHINCS+-SHA2-192f-simple", + ("sphincs") SphincsSha2192sSimple: OQS_SIG_alg_sphincs_sha2_192s_simple: "SPHINCS+-SHA2-192s-simple", + ("sphincs") SphincsSha2256fSimple: OQS_SIG_alg_sphincs_sha2_256f_simple: "SPHINCS+-SHA2-256f-simple", + ("sphincs") SphincsSha2256sSimple: OQS_SIG_alg_sphincs_sha2_256s_simple: "SPHINCS+-SHA2-256s-simple", + ("sphincs") SphincsShake128fSimple: OQS_SIG_alg_sphincs_shake_128f_simple: "SPHINCS+-SHAKE-128f-simple", + ("sphincs") SphincsShake128sSimple: OQS_SIG_alg_sphincs_shake_128s_simple: "SPHINCS+-SHAKE-128s-simple", + ("sphincs") SphincsShake192fSimple: OQS_SIG_alg_sphincs_shake_192f_simple: "SPHINCS+-SHAKE-192f-simple", + ("sphincs") SphincsShake192sSimple: OQS_SIG_alg_sphincs_shake_192s_simple: "SPHINCS+-SHAKE-192s-simple", + ("sphincs") SphincsShake256fSimple: OQS_SIG_alg_sphincs_shake_256f_simple: "SPHINCS+-SHAKE-256f-simple", + ("sphincs") SphincsShake256sSimple: OQS_SIG_alg_sphincs_shake_256s_simple: "SPHINCS+-SHAKE-256s-simple", + ("ml_dsa") MlDsa44Ipd: OQS_SIG_alg_ml_dsa_44_ipd: "ML-DSA-44-ipd", + ("ml_dsa") MlDsa65Ipd: OQS_SIG_alg_ml_dsa_65_ipd: "ML-DSA-65-ipd", + ("ml_dsa") MlDsa87Ipd: OQS_SIG_alg_ml_dsa_87_ipd: "ML-DSA-87-ipd", + ("ml_dsa") MlDsa44: OQS_SIG_alg_ml_dsa_44: "ML-DSA-44", + ("ml_dsa") MlDsa65: OQS_SIG_alg_ml_dsa_65: "ML-DSA-65", + ("ml_dsa") MlDsa87: OQS_SIG_alg_ml_dsa_87: "ML-DSA-87", + ("mayo") Mayo1: OQS_SIG_alg_mayo_1: "MAYO-1", + ("mayo") Mayo2: OQS_SIG_alg_mayo_2: "MAYO-2", + ("mayo") Mayo3: OQS_SIG_alg_mayo_3: "MAYO-3", + ("mayo") Mayo5: OQS_SIG_alg_mayo_5: "MAYO-5", + ("cross") CrossRsdp128Balanced: OQS_SIG_alg_cross_rsdp_128_balanced: "cross-rsdp-128-balanced", + ("cross") CrossRspd128Fast: OQS_SIG_alg_cross_rsdp_128_fast: "cross-rsdp-128-fast", + ("cross") CrossRspd128Small: OQS_SIG_alg_cross_rsdp_128_small: "cross-rsdp-128-small", + ("cross") CrossRspd192Balanced: OQS_SIG_alg_cross_rsdp_192_balanced: "cross-rsdp-192-balanced", + ("cross") CrossRspd192Fast: OQS_SIG_alg_cross_rsdp_192_fast: "cross-rsdp-192-fast", + ("cross") CrossRspd192Small: OQS_SIG_alg_cross_rsdp_192_small: "cross-rsdp-192-small", + ("cross") CrossRspd256Balanced: OQS_SIG_alg_cross_rsdp_256_balanced: "cross-rsdp-256-balanced", + ("cross") CrossRspd256Fast: OQS_SIG_alg_cross_rsdp_256_fast: "cross-rsdp-256-fast", + ("cross") CrossRspd256Small: OQS_SIG_alg_cross_rsdp_256_small: "cross-rsdp-256-small", + ("cross") CrossRspdg128Balanced: OQS_SIG_alg_cross_rsdpg_128_balanced: "cross-rsdpg-128-balanced", + ("cross") CrossRspdg128Fast: OQS_SIG_alg_cross_rsdpg_128_fast: "cross-rsdpg-128-fast", + ("cross") CrossRspdg128Small: OQS_SIG_alg_cross_rsdpg_128_small: "cross-rsdpg-128-small", + ("cross") CrossRspdg192Balanced: OQS_SIG_alg_cross_rsdpg_192_balanced: "cross-rsdpg-192-balanced", + ("cross") CrossRspdg192Fast: OQS_SIG_alg_cross_rsdpg_192_fast: "cross-rsdpg-192-fast", + ("cross") CrossRspdg192Small: OQS_SIG_alg_cross_rsdpg_192_small: "cross-rsdpg-192-small", + ("cross") CrossRspdg256Balanced: OQS_SIG_alg_cross_rsdpg_256_balanced: "cross-rsdpg-256-balanced", + ("cross") CrossRspdg256Fast: OQS_SIG_alg_cross_rsdpg_256_fast: "cross-rsdpg-256-fast", + ("cross") CrossRspdg256Small: OQS_SIG_alg_cross_rsdpg_256_small: "cross-rsdpg-256-small", } impl Algorithm { @@ -175,6 +232,43 @@ pub struct Sig { sig: NonNull, } +impl Debug for Sig { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("Sig") + .field("algorithm", &self.algorithm) + .field( + "method_name", + &unsafe { CStr::from_ptr(self.sig.as_ref().method_name) } + .to_str() + .expect("method name"), + ) + .field( + "alg_version", + &unsafe { CStr::from_ptr(self.sig.as_ref().alg_version) } + .to_str() + .expect("alg_version"), + ) + .field( + "claimed_nist_level", + &unsafe { self.sig.as_ref() }.claimed_nist_level, + ) + .field("euf_cma", &unsafe { self.sig.as_ref() }.euf_cma) + .field( + "length_public_key", + &unsafe { self.sig.as_ref() }.length_public_key, + ) + .field( + "length_secret_key", + &unsafe { self.sig.as_ref() }.length_secret_key, + ) + .field( + "length_signature", + &unsafe { self.sig.as_ref() }.length_signature, + ) + .finish() + } +} + unsafe impl Sync for Sig {} unsafe impl Send for Sig {} @@ -184,15 +278,14 @@ impl Drop for Sig { } } -#[cfg(feature = "std")] -impl std::fmt::Display for Algorithm { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.name().fmt(f) +impl Display for Algorithm { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + Display::fmt(self.name(), f) } } -impl core::convert::TryFrom for Sig { - type Error = crate::Error; +impl TryFrom for Sig { + type Error = Error; fn try_from(alg: Algorithm) -> Result { Sig::new(alg) } @@ -284,7 +377,7 @@ impl Sig { /// Generate a new keypair pub fn keypair(&self) -> Result<(PublicKey, SecretKey)> { let sig = unsafe { self.sig.as_ref() }; - let func = sig.keypair.unwrap(); + let func = sig.keypair.expect("keypair function not available"); let mut pk = PublicKey { bytes: Vec::with_capacity(sig.length_public_key), }; @@ -309,7 +402,7 @@ impl Sig { ) -> Result { let sk = sk.into(); let sig = unsafe { self.sig.as_ref() }; - let func = sig.sign.unwrap(); + let func = sig.sign.expect("sign function not available"); let mut sig = Signature { bytes: Vec::with_capacity(sig.length_signature), }; @@ -346,7 +439,7 @@ impl Sig { return Err(Error::InvalidLength); } let sig = unsafe { self.sig.as_ref() }; - let func = sig.verify.unwrap(); + let func = sig.verify.expect("verify function not available"); let status = unsafe { func( message.as_ptr(),