Skip to content

digest: add OpenSSL::Digest#squeeze#1083

Open
rhenium wants to merge 2 commits into
ruby:masterfrom
rhenium:ky/digest-xof
Open

digest: add OpenSSL::Digest#squeeze#1083
rhenium wants to merge 2 commits into
ruby:masterfrom
rhenium:ky/digest-xof

Conversation

@rhenium

@rhenium rhenium commented Jul 8, 2026

Copy link
Copy Markdown
Member

Closes #1082

Comment thread ext/openssl/ossl_digest.c Outdated
GetDigest(self, ctx);
str = rb_str_new(NULL, EVP_MD_CTX_size(ctx));
int size = EVP_MD_CTX_size(ctx);
if (size < 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In OpenSSL 1.1.1, EVP_MD_CTX_size actually return positive values and SHAKE128 and SHAKE256 actually "work". OpenSSL 3.0 broke this intentionally because it was kind of wrong to return anything, and what OpenSSL 1.1.1 returned was actually even more wrong.

Perhaps this is the behavior you want and SHAKE128 working in OpenSSL 1.1.1 is fine using just #digest.

With OpenSSL 1.1.1

EVP_shake128() -> 16
EVP_shake256() -> 32

The reason why this is "bad" is because SHAKE256 should actually return a 512-bit value for 256-bits of security, and SHAKE128 should return 256.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It seems this was changed in OpenSSL 3.4. The old defaults don't seem right, but it's probably not ruby/openssl's job to fix it.

Comment thread ext/openssl/ossl_digest.c
Comment thread ext/openssl/ossl_digest.c Outdated
@rhenium rhenium force-pushed the ky/digest-xof branch 2 times, most recently from ad1fdd4 to 6b5de36 Compare July 10, 2026 10:51
rhenium added 2 commits July 10, 2026 19:55
Add support for extendable-output functions (XOFs). An XOF is a hash
function that can produce arbitrary length of output. The interface of
the existing Digest::Class#digest and its variants is unsuitable for
this purpose.

Add a new method to "squeeze" the specified amount of output from the
XOF. This method can be called repeatedly. OpenSSL 3.3 or later and
AWS-LC support this.
In OpenSSL 3.4 or later, SHAKE digests do not have a default output
length and EVP_MD_CTX_size() returns -1. Raise
OpenSSL::Digest::DigestError if the function returns a negative number.

Fortunately, this is currently caught by a sanity check in
rb_str_new() and leads to ArgumentError with the message "negative
string size (or size too big)". Still, the caller should check it.

Also, override #inspect to rescue an exception raised in #hexdigest.
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.

Expose XOFs like SHAKE128 and SHAKE256

2 participants