Skip to content
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

Digest and DynDigest not usable with non-fixed length digests #1094

Open
wookietreiber opened this issue Sep 2, 2022 · 1 comment
Open
Labels
digest Hash function crate

Comments

@wookietreiber
Copy link

Digest requires FixedOutput and DynDigest requires FixedOutputReset. k12::KangarooTwelve implements neither, so I can't fully generically/universally allow users to pick it when providing a function that takes e.g. DynDigest:

use std::path::Path;

use anyhow::Result;
use digest::DynDigest;

fn hash_path(path: impl AsRef<Path>, hasher: &mut dyn DynDigest) -> Result<()> {
    let path = path.as_ref();
    let content = std::fs::read_to_string(path)?;
    let bytes = content.as_bytes();
    hasher.update(bytes);
    let hash = hasher.finalize_reset();
    let hash: String = hash.iter().map(|byte| format!("{:02x}", byte)).collect();
    println!("{}  {}", hash, path.display());
    Ok(())
}

fn main() {
    hash_path("Cargo.toml", &mut md5::Md5::default()).unwrap();
    hash_path("Cargo.toml", &mut k12::KangarooTwelve::default()).unwrap();
}
error[E0277]: the trait bound `KangarooTwelve: FixedOutputReset` is not satisfied
  --> src/main.rs:19:29
   |
19 |     hash_path("Cargo.toml", &mut k12::KangarooTwelve::default()).unwrap();
   |     ---------               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FixedOutputReset` is not implemented for `KangarooTwelve`
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `FixedOutputReset` is implemented for `CoreWrapper<T>`
   = note: required because of the requirements on the impl of `DynDigest` for `KangarooTwelve`
   = note: required for the cast to the object type `dyn DynDigest`

Are there alternatives to Digest and DynDigest that don't require a fixed output? As author of a function like fn hash_path I don't really care about the length of the output, so could Digest and DynDigest alternatively be changed to not require fixed output?


I noticed this while implementing clap-digest. I basically had to drop all implementations that have variable lengths, and was wondering if there is or could be another abstraction that would allow variable length digests as well.

@newpavlov
Copy link
Member

newpavlov commented Sep 2, 2022

No, you would need to develop your own trait which abstracts over fixed output hashes and XOFs. We may potentially adapt it into digest later.

Note that, k12 is a XOF, i.e. it can produce hash of an arbitrary length. So finalization methods of the hypothetical trait have to accept desired length of output hash. But what it will do for fixed output functions in cases of length mismatch? Should the methods panic, or maybe truncate if requested length is smaller?

An alternative approach could be to introduce a wrapper which transforms XOF into a type which implements the FixedOutput trait, something like:

// This type implements `FixedOutput` with `OutputSize = U32`
type KangarooTwelve_256 = XofFixedWrapper<k12::KangarooTwelve, U32>;

@newpavlov newpavlov added the digest Hash function crate label Sep 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
digest Hash function crate
Projects
None yet
Development

No branches or pull requests

3 participants
@newpavlov @wookietreiber and others