Skip to content

[WIP] kdf crate #1879

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

[WIP] kdf crate #1879

wants to merge 1 commit into from

Conversation

tarcieri
Copy link
Member

Traits which provide an API for interacting with Key Derivation Functions.

We have several of these located at https://github.com/rustcrypto/kdfs and password-based KDFs at https://github.com/RustCrypto/password-hashes but the APIs for using these are typically just free functions, whereas traits could provide a common API.

Traits which provide an API for interacting with Key Derivation
Functions.

We have several of these located at https://github.com/rustcrypto/kdfs
and password-based KDFs at https://github.com/RustCrypto/password-hashes
but the APIs for using these are typically just free functions, whereas
traits could provide a common API.
@tarcieri
Copy link
Member Author

I opened this up for discussion primarily, and also reserved the kdf crate name with the minimal proposed API.

I think we probably need a lot more traits than this, particularly ones for representing the "expand" and "extract" steps in proper KDFs like HKDF.

#![warn(missing_docs, unused_qualifications, missing_debug_implementations)]

/// Use the KDF to derive the given amount of output.
pub trait Derive {
Copy link
Member Author

@tarcieri tarcieri May 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should be Expand?

Suggested change
pub trait Derive {
pub trait Expand {

Copy link
Member Author

@tarcieri tarcieri May 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess one question is: does the "expand" name make sense for one-shot KDFs which don't provide separate "extract" and "expand" steps?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's better to call it KeyDeriveFn and name the method derive_key? Though the Fn part is a bit problematic since it may be confused with the Fn closure traits.

pub trait Derive {
/// Consumes the KDF instance and derives as much data as will fit in `out`,
/// overwriting its contents.
fn derive(self, out: &mut [u8]);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this consume self, but it could potentially borrow self mutably, which would allow for calling it multiple times:

Suggested change
fn derive(self, out: &mut [u8]);
fn derive(&mut self, out: &mut [u8]);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also may be worth to provide derivation parameters. For example, in the hkdf case it would be okm. And the method should probably return Result. It would b needed for both concat-kdf and bake-kdf.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this trait assumes a separate init step which could have its own params, but also notably expand has an "info" parameter, at least in HKDF

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also note a separate init is mostly useful for extract-and-expand constructions, whereas most KDFs are one-shot, so it would be nice to have something specific to the latter

@tarcieri
Copy link
Member Author

tarcieri commented May 31, 2025

Another important question: output size limits and fallibility. Should we have a try_derive/try_expand and an Error type?

How about a trait with an associated constant or typenum type that defines the maximum output size?

@daxpedda
Copy link
Contributor

daxpedda commented Jun 2, 2025

I am assuming that "key stretching functions", e.g. Argon2, Scrypt and such, don't fall under this trait?

@tarcieri
Copy link
Member Author

tarcieri commented Jun 2, 2025

@daxpedda I think it would be good to eventually support password-based KDFs. I think they wind up having a very similar API to other KDFs, to the point it might just be a marker trait and some usage guidelines.

That said, it would probably be good to focus on traits for what's in https://github.com/rustcrypto/kdfs for now

@daxpedda
Copy link
Contributor

daxpedda commented Jun 2, 2025

FWIW: I don't have much feedback for this kind of interface, but for OPAQUE we would like to have a trait for key stretching functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants