Skip to content

Improve Hmac API#4205

Closed
tcharding wants to merge 2 commits intorust-bitcoin:masterfrom
tcharding:03-06-hmac
Closed

Improve Hmac API#4205
tcharding wants to merge 2 commits intorust-bitcoin:masterfrom
tcharding:03-06-hmac

Conversation

@tcharding
Copy link
Copy Markdown
Member

@tcharding tcharding commented Mar 6, 2025

Done as part of #4196. These are the easy ones, all the other missing things require knowing the length of the inner array I believe. Patch 2 is already tricky enough to warrant a PR.

As we do for other hash types put an inherent function on the `Hmac`
type. Allows removal of a few `GeneralHash` trait imports.
As we do for other hash types (by way of the `GeneralHash` trait) add
two helper functions to the `Hmac` type. Note we need a key and it has
the same type as the data being hashed - possibly confusing.
@github-actions github-actions bot added C-bitcoin PRs modifying the bitcoin crate C-hashes PRs modifying the hashes crate test labels Mar 6, 2025
Copy link
Copy Markdown
Collaborator

@Kixunil Kixunil left a comment

Choose a reason for hiding this comment

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

ACK 2ae186d

However, to reduce churn, I'd prefer to hold off merging this until we reach decision regarding hash_byte_chunks and possibly remove the method.

}

/// Hashes some bytes.
pub fn hash(key: &[u8], data: &[u8]) -> Self
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Damn, this sucks, but I don't see any sensible way of fixing it. These are the times when I wish for Swift-like named arguments.

}

/// Hashes all the byte slices retrieved from the iterator together.
pub fn hash_byte_chunks<B, I>(key: &[u8], byte_slices: I) -> Self
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

In #3130 (comment) @apoelstra noted that this may be dangerous if people are using it incorrectly. Which makes me think if we even should have it. But if we do, I think these should have a big warning about it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should just drop it (well, deprecate it). It's a pretty obscure API (I always forget it exists except when it comes up in PRs like this).

The "manual" implementation isn't much longer -- let eng = HashEngine::new(key); byte_slices.map(|sl| eng.input(s)).count(); eng.finalize() and composes more naturally with other iterator adaptors.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I agree. I was also thinking of having something like this:

#[derive(Default, Clone)]
pub struct HashBuilder<T: HashEngine>(T);

impl<T: HashEngine> HashBuilder<T> {
    fn new() -> Self where T: Default() { /* ... */ }
    fn input_fixed<const N: usize>(self, data: &[u8; N]) -> Self { self.0.input(data); self }
    fn input_len_prefixed<const INTEGER_SIZE: usize>(self, data: &[u8]) -> Result<Self, InputTooLongErrror> { /* tries to serialize data.len() as a INTEGER_SIZE bytes long integer and write it */ }
    fn input_assume_non_semantic_chunk(self, data: &[u8]) -> Self { self.0.input(data), self }
}

This would both make hash building a bit more convenient (builder API with Iterator::fold compatibility) and also help enforce good practices.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a neat API! But I'd prefer not to prioritize it because there are lots of open questions around it. For example, how do we do the length prefixes? If we use bitcoin-style varints is this any better than just being able to consensus-encoded a byteslice into a hash engine?

Also if users want to be putting structured data into hashes in general they probably want to be using something like merlin anyway.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

not to prioritize

Yes, obviously. :) This can be done after 1.0. I'd certainly not waste time on this right now.

I was thinking just some basics that several applications might already do. Similar to LenPrefixed encoder in tokio (at the time it was introduced I was coincidentally just working on a protocol that had that exact thing).

@tcharding tcharding marked this pull request as draft March 6, 2025 21:35
@apoelstra
Copy link
Copy Markdown
Member

In #4085 we add some new copies of the chunks function in commit 2b6ef31. If we deprecate the existing ones here we also need to revert that commit.

@apoelstra
Copy link
Copy Markdown
Member

Needs rebase because of #4085 in any case.

@tcharding tcharding closed this Mar 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-bitcoin PRs modifying the bitcoin crate C-hashes PRs modifying the hashes crate test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants