From 3d0fd474fb82572aff89a42101483d6bce293bab Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 31 Jan 2026 17:56:58 -0700 Subject: [PATCH] frodo-kem: preliminary `no_std` support The existing uses of `std` can probably be worked around, but for now this allows the crate to compile in `no_std` contexts --- frodo-kem/Cargo.toml | 4 +++- frodo-kem/src/hazmat/models.rs | 1 + frodo-kem/src/hazmat/traits.rs | 4 ++++ frodo-kem/src/lib.rs | 19 +++++++++++++++---- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/frodo-kem/Cargo.toml b/frodo-kem/Cargo.toml index 1ea8aa0..5384fca 100644 --- a/frodo-kem/Cargo.toml +++ b/frodo-kem/Cargo.toml @@ -19,6 +19,7 @@ default = [ "frodo", "efrodo", "serde", + "std" ] hazmat = [] efrodo = [ @@ -52,7 +53,8 @@ frodo1344shake = [] openssl = ["openssl-aes", "openssl-shake"] openssl-aes = ["dep:openssl-sys"] openssl-shake = ["dep:openssl-sys"] -serde = ["dep:hex", "dep:serde"] +serde = ["std", "dep:hex", "dep:serde"] +std = [] [dependencies] aes = { version = "0.9.0-rc.2", optional = true } diff --git a/frodo-kem/src/hazmat/models.rs b/frodo-kem/src/hazmat/models.rs index 0208a44..1e6e86c 100644 --- a/frodo-kem/src/hazmat/models.rs +++ b/frodo-kem/src/hazmat/models.rs @@ -2,6 +2,7 @@ use super::{Expanded, Kem, Params, Sample}; use crate::{Error, FrodoResult}; +use alloc::{boxed::Box, vec::Vec}; use core::marker::PhantomData; use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/frodo-kem/src/hazmat/traits.rs b/frodo-kem/src/hazmat/traits.rs index 342d905..cc271b1 100644 --- a/frodo-kem/src/hazmat/traits.rs +++ b/frodo-kem/src/hazmat/traits.rs @@ -4,6 +4,7 @@ use crate::hazmat::{ Ciphertext, CiphertextRef, DecryptionKey, DecryptionKeyRef, EncryptionKey, EncryptionKeyRef, SharedSecret, }; +use alloc::{string::String, vec::Vec}; use rand_core::CryptoRng; use sha3::digest::{ExtendableOutput, ExtendableOutputReset, Update}; use subtle::{Choice, ConditionallySelectable}; @@ -27,6 +28,7 @@ pub trait Sample: Default { /// Expand the seed to produce the matrix A pub trait Expanded: Default { /// The method used to expand the seed + #[cfg_attr(not(feature = "std"), allow(dead_code))] const METHOD: &'static str; /// Expand the seed to produce the matrix A /// Generate matrix A (N x N) column-wise @@ -106,6 +108,7 @@ pub trait Params: Sized + Default { /// The base FrodoKEM methods pub trait Kem: Params + Expanded + Sample { /// The name of the frodoKEM algorithm + #[cfg_attr(not(feature = "std"), allow(dead_code))] const NAME: &'static str; /// Generate a keypair @@ -426,6 +429,7 @@ pub trait Kem: Params + Expanded + Sample { } /// Get the algorithm name + #[cfg_attr(not(feature = "std"), allow(dead_code))] fn algorithm(&self) -> String { format!("{}-{}-{}", Self::NAME, Self::N, Self::METHOD) } diff --git a/frodo-kem/src/lib.rs b/frodo-kem/src/lib.rs index 292bca4..6e100c3 100644 --- a/frodo-kem/src/lib.rs +++ b/frodo-kem/src/lib.rs @@ -1,4 +1,4 @@ -// #![no_std] TODO +#![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc = include_str!("../README.md")] #![doc( @@ -96,21 +96,29 @@ )))] compile_error!("no algorithm feature enabled"); -mod error; -pub use error::*; +#[macro_use] +extern crate alloc; +#[cfg(feature = "std")] +extern crate std; #[cfg(feature = "hazmat")] pub mod hazmat; #[cfg(not(feature = "hazmat"))] mod hazmat; -use hazmat::*; +mod error; +pub use error::*; +use alloc::vec::Vec; use core::marker::PhantomData; +use hazmat::*; use rand_core::CryptoRng; use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, ZeroizeOnDrop}; +#[cfg(feature = "serde")] +use alloc::string::{String, ToString}; + macro_rules! serde_impl { ($name:ident, $from_method:ident) => { #[cfg(feature = "serde")] @@ -508,6 +516,7 @@ impl ConstantTimeEq for Algorithm { (Self::FrodoKem976Shake, Self::FrodoKem976Shake) => Choice::from(1), #[cfg(feature = "frodo1344shake")] (Self::FrodoKem1344Shake, Self::FrodoKem1344Shake) => Choice::from(1), + #[allow(unreachable_patterns)] _ => Choice::from(0), } } @@ -519,6 +528,7 @@ impl Default for Algorithm { } } +#[cfg(feature = "std")] impl core::fmt::Display for Algorithm { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { static ALGORITHMS: std::sync::LazyLock> = @@ -592,6 +602,7 @@ impl core::fmt::Display for Algorithm { } } +#[cfg(feature = "std")] impl core::str::FromStr for Algorithm { type Err = Error;