Skip to content

digest: add blanket-impls feature to gate blanket Digest impl#2311

Closed
remix7531 wants to merge 1 commit intoRustCrypto:masterfrom
remix7531:digest/blanket-impls-pr
Closed

digest: add blanket-impls feature to gate blanket Digest impl#2311
remix7531 wants to merge 1 commit intoRustCrypto:masterfrom
remix7531:digest/blanket-impls-pr

Conversation

@remix7531
Copy link

Summary

This PR adds a blanket-impls feature flag (enabled by default) to the digest crate that gates the blanket implementation:

impl<D: FixedOutput + Default + Update + HashMarker> Digest for D { ... }

Motivation

I am working on a formally verified hash function and want to implement the Digest trait for it. For formal verification, it is desirable to express the hasher as a single pure function rather than splitting it across the Update + FixedOutput trait hierarchy, as the incremental update model does not map cleanly to the verification model.

Currently this is impossible due to coherence: the always-present blanket impl conflicts with any manual Digest implementation at compile time, with no way to opt out.

Gating the blanket impl behind a feature flag unblocks this use case. Crates that need a manual implementation can opt out with default-features = false, while all existing users are unaffected.

Compatibility

Non-breaking. The feature is on by default, so existing users and downstream crates are unaffected.

Add a new `blanket-impls` feature flag (enabled by default) that gates
the blanket `impl<D: FixedOutput + Default + Update + HashMarker> Digest
for D` implementation. This allows downstream crates that provide their
own manual `Digest` implementations to disable the blanket impl and
avoid coherence conflicts.
@remix7531
Copy link
Author

Maybe it is better to make this an opt in feature. Open for feedback.

@newpavlov
Copy link
Member

newpavlov commented Feb 18, 2026

I am working on a formally verified hash function and want to implement the Digest trait for it. For formal verification, it is desirable to express the hasher as a single pure function rather than splitting it across the Update + FixedOutput trait hierarchy, as the incremental update model does not map cleanly to the verification model.

The Digest trait requires incremental API support, so I don't see how this would help you.

If you absolutely want to work with a one-shot function AND implement digest traits, you always can accumulate message into Vec<u8> in Update and then hash the result in FixedOutput.

@newpavlov newpavlov closed this Feb 18, 2026
@remix7531
Copy link
Author

The reason this is useful is because of how the proof works.

  1. Proof the functional digest is equivalent to the high level specification
  2. Proof the incremental API is functionally correct i.e. splitting the message up into chunks and using the incremental API should have same behavior as the functional digest.

My functional digest and the incremental API are separate. Additionally, working with traits is not so easy with HAX and F*

Please re-open

@newpavlov
Copy link
Member

You haven't answered how exactly removal of the blanket implementation helps. Do you plan to implement only Digest::digest and panic on Digest::update and other methods?

The Digest trait was designed as a simple convenience wrapper around the more granular traits. I don't think we want to change it to satisfy a pretty niche use case.

Additionally, the proposed feature is not additive. For example, a crate may simultaneously implement Digest and Update for a type and it would work as long as the feature is not enabled, but as soon as it gets enabled (e.g. in a separate dependency like sha2) it would break the build.

No one forces you to implement digest traits, your crate can provide just free-standing pure functions, while digest compatibility layer can be implemented behind a feature or in a separate crate.

@remix7531
Copy link
Author

I will push the code soon. I am implementing all methods of the digest trait. I want high level compatibility with RustCrypto.

@newpavlov
Copy link
Member

newpavlov commented Feb 19, 2026

If you are able to implement Digest::{new, update, finalize} methods, then you should be able to implement Default, Update and FixedOutput as well.

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.

2 participants

Comments