Skip to content

pwhash: Simplify strHash/strVerify APIs #24112

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

BrainBlasted
Copy link

@BrainBlasted BrainBlasted commented Jun 7, 2025

These APIs were "generic" in a way that obfuscated their intended use (e.g. using runtime errors for invalid parameters), and made use of a combination of output parameters and a return value that's lead to confusion in multiple projects.

This PR aims to simplify the APIs such that each one accurately communicates intent and is harder to misuse.

See #23994 for context and rationale

There's no real reason for these to be generic functions - the only
reason they're written as such is for the benchmarking code. Otherwise,
being generic harms their usability and contorts these functions in
a way that violates Zig Zen.

This commit rewrites the three pwhash functions and their associated
structs to be non-generic, allowing for each API to properly communicate
their intended inputs in their function arguments and type fields.
Greatly simplifies the API for most use cases.
@BrainBlasted BrainBlasted force-pushed the cdavis/pwhash-api-tweaks branch from 838d754 to 3c9404a Compare June 7, 2025 15:40
params: Params,
mode: Mode = .argon2id,
encoding: pwhash.Encoding = .phc,
strhash_max_bytes: usize = 128,
Copy link
Author

Choose a reason for hiding this comment

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

Comment on lines +776 to +779
const buf_len = comptime if (options.strhash_max_bytes) |len| len else switch (options.encoding) {
.crypt => hash_length,
.phc => hash_length * 2,
};
Copy link
Author

Choose a reason for hiding this comment

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

These default values were based on the comments for the hash_length constant and the tests. Please let me know if something else should be chosen.

params: Params,
encoding: pwhash.Encoding,
strhash_max_bytes: usize = 128,
Copy link
Author

Choose a reason for hiding this comment

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

This one is also based on the tests.

@BrainBlasted
Copy link
Author

CC: @jedisct1

@jedisct1
Copy link
Contributor

jedisct1 commented Jun 7, 2025

/cc @x13a

I don't like the fact that an allocator becomes mandatory, while functions like bcrypt don't need any dynamic allocation, though.

@BrainBlasted
Copy link
Author

Dynamic allocation isn't necessary for bcrypt, but it is for argon2 and scrypt.

What are your thoughts on having both strHash() and allocStrHash() for these APIs?

@BrainBlasted
Copy link
Author

BrainBlasted commented Jun 7, 2025

Or: bufStrHash() & allocStrHash()?

@jedisct1
Copy link
Contributor

jedisct1 commented Jun 7, 2025

Or: bufStrHash() & allocStrHash()?

This is even more confusing.

The nullable allocator in HashOptions is indeed weird, especially since the HashOptions structure is different for each algorithm. We can probably avoid it.

@jedisct1
Copy link
Contributor

jedisct1 commented Jun 7, 2025

Since hash strings are guaranteed to be short, if we want to avoid returning a slice, a BoundedArray could be a good fit.

@GrayHatter
Copy link
Contributor

any reason you decided an allocator was better instead of a std.BoundedArray? I agree with @jedisct1 that making an allocator here mandatory feels unnecessary.

.crypt => hash_length,
.phc => hash_length * 2,
};
var buf: [buf_len]u8 = undefined;

Choose a reason for hiding this comment

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

maybe provide strHash and strHashAlloc for bcrypt? We still use the stack based approach in std, but don't give the developer any choice if they know what they're doing

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.

4 participants