Commit Graph

65 Commits

Author SHA1 Message Date
Andrew Poelstra a5d96ceb39
hashes: remove private `internal_new` method
This method is used to implement `from_byte_array`. But there is no need
for the method to exist. We can just inline it in `from_byte_array` and
reduce the amount of indirection in our macros.

Also make the same change in sha256t.
2025-05-05 17:00:13 +00:00
Andrew Poelstra aadd7df266
hashes: move `from_engine` fn impl out of macro body
This macro is pretty weird -- it requires that a freestanding
`from_engine` method exists, which it uses to implement a `from_engine`
method within an impl block, by just calling through to the freestanding
method.

To reduce indirection, at a very small cost in increased repeated code
(we now need to add a `impl Hash {` and `}` and doccomment around each
freestanding function, we just remove this from the macro entirely.

This will allow us to implement `from_engine` for `sha256t::Hash` in a
different way than for the non-generic hash types.

To minimize the diff, we do not re-indent the freestanding
`from_engine`. We will do that in the next commit. However, the diff is
still a bit noisy because I had to replace `fn from_engine` with `pub fn
from_engine` in every case. I took the opportunity to also change the
return type from `Hash` to `Self` to make it clearer that these are
constructors.
2025-05-05 17:00:07 +00:00
Jamil Lambert f22e997587
Use parameters instead of arguments in rustdocs
The rustdocs use both `# Parameters` and `# Arguments` to mean the same
thing.

Change all of them to `# Parameters` to be consistent.
2025-04-22 10:43:13 +01:00
Jamil Lambert e2c7be6d2f
Fix typo 2025-04-22 10:39:43 +01:00
Martin Habovstiak e8a42d5851 Unify/reduce usage of `unsafe`
Since the introduction of `Script` `unsafe` started slowly creeping in
as more types with similar semantics were added. The `unsafe` in these
cases is just for trivial conversions between various pointer-like
types. As such, it's possible to move these into a single macro that
takes care of the conversions at one place and avoid repeating the same
`unsafe` code in the codebase. This decreases the cost of audits which
now only need to happen in `internals`, focuses any changes to happen in
that single macro and decreases the chance that we will mess up
similarly to the recent `try_into().expect()` issue (but this time with
UB rather than panic).

The new macro accepts syntax very similar to the already-existing struct
declarations with these differences:

* The struct MUST NOT have `#[repr(transparent)]` - it's added by the
  macro
* If the struct uses `PhantomData` it must be the first field and the
  real data must be the second field (to allow unsized types).
* The struct must be immediately followed by an impl block containing at
  least on conversion function.
* If the struct has generics the impl block has to use the same names of
  generics.
* The conversion functions don't have bodies (similarly to required
  trait methods) and have a fixed set of allowed signatures.
* Underscore (`_`) must be used in place of the inner type in the
  conversion function parameters.

The existing code can simply call the macro with simple changes and get
the same behavior without any direct use of `unsafe`. This change
already calls the macro for all relevant existing types. There are still
some usages left unrelated to the macro, except one additional
conversion in reverse direction on `Script`. It could be moved as well
but since it's on a single place so far it's not really required.
2025-03-27 20:15:37 +01:00
Tobin C. Harding 95ad91cdb6
hashes: Remove the GeneralHash trait
Now that we are able to unambiguously go from a hash engine to its
associated hash type there is no longer any need for the `GeneralHash`
trait.

Please note that IMO this concept of a general hash type as opposed to
one where one can hash arbitrary data still exists in the codebase - it
is implicitly in the `hash_newtype` macro.

Remove the `GeneralHash` trait.
2025-03-06 11:47:29 +11:00
Tobin C. Harding 2b6ef31469
hashes: Add hash_byte_chunks function to modules
Add a standalone `hash_byte_chunks` function that is a drop in
 replacement for `GeneralHash::hash_byte_chunks`. Do not add it to
 `hmac` - this is in parity with the current code because `Hmac` does
 not implement `GeneralHash::hash_byte_chunks`.
2025-03-06 11:47:29 +11:00
Tobin C. Harding d3846895d7
hashes: Add hash function to modules
Add a standalone `hash` function that is a drop in replacement for
`GeneralHash::hash`. Do not add it to `hmac` - this is in parity with
the current code because `Hmac` does not implement `GeneralHash::hash`.

Use the new function in `bitcoin` removing all occurrences of
`GeneralHash` from `bitcoin`.

In `hashes` replace usage of `GeneralHash::hash` with the new `hash`
function.
2025-03-06 11:47:29 +11:00
Tobin C. Harding f61e93ccf1
Properly deprecate Hash::from_slice
The `hashes::error::FromSliceError` error is only returned from
`from_slice`. We attempted to deprecate this function but it seems we
only did half a job at it.

- deprecate _all_ instances of the method/function
- deprecate the error type
2025-02-18 19:27:30 +11:00
Tobin C. Harding fd4586eaae
Invert dependency between io and hashes
Currently in order to release `hashes v1.0` we need to 1.0 `io` as well.
For multiple reasons, many out of our control, the `io` crate may not
stabalise any time soon.

Instead we can invert the dependency between the two crates.

This is an ingenious idea, props to Kixunil for coming up with it.

Notes

- `io` does not currently re-export the `hashes` crate.
- This work highlights that we cannot call `hash_reader` on a siphash.
- The `Hmac::hash_reader` uses the default key which may not be obvious.

Signed-off-by: Tobin C. Harding <me@tobin.cc>
2025-02-11 09:17:21 +11:00
Tobin C. Harding 6002ccdc56
Add a tagged sha256t hash engine
We would like it if two different pre-tagged engines were considered
different types so it is not possible to mix them up.

Add a new `sha256t::HashEngine<T>` where `T` is a tag the same as on
`sha256t::Hash<T>`.
2025-02-08 13:27:30 +11:00
Tobin C. Harding 3e8e2e46bf
Use Self::Engine in GeneralHash impl
Match the trait method signature. Internal change only.
2025-02-08 13:27:30 +11:00
Jamil Lambert, PhD 30132c56bb
Fix rustdoc indentation
New nightly lint picked up an incorrect indentation.

Remove extra space.
2025-02-04 16:47:43 +00:00
Tobin C. Harding ec06028f63
hashes: Make hex dependency optional
The only reason we need `hex-conservative` is to parse strings and
format them as hex. For users that do not require this functionality we
can make the `hex-conservative` crate an optional dependency.

The `serde` feature requires `Display` so we enable `hex` from the
`serde` feature.

If `hex` feature is not enabled we still need to be able to debug so
provide `fmt::Debug` functionality by way of macros.

Close: #2654
2024-11-14 09:36:55 +11:00
Tobin C. Harding 9dce0b4b8c
Remove hex string trait bounds from GeneralHash
For the `hashes` crate we would like to make `hex` an optional
dependency. In preparation for doing so do the following:

- Remove the trait bounds from `GeneralHash`
- Split the hex/string stuff out of `impl_bytelike_traits` into a
  separate macro.
2024-11-13 14:01:13 +11:00
Tobin C. Harding 766f498b33
Pull serde stuff out of impl_bytelike_traits macro
The `impl_bytelike_traits` macro is public and it is used in the
`hash_newtype` macro, also public.

Currently if a user calls the `hash_newtype` macro in a crate that
depends on `hashes` without the `serde` feature enabled and with no
`serde` dependency everything works. However if the user then adds a
dependency that happens to enable the `serde` feature in `hashes` their
build will blow up because `serde` code will start getting called from
the original crate's call to `hash_newtype`.

Pull the serde stuff out of `hash_newtype` and provide a macro to
implement it `impl_serde_for_newtype`.
2024-11-13 12:28:47 +11:00
merge-script 4797a75586
Merge rust-bitcoin/rust-bitcoin#3584: Standardize constructor type function docs
1649b68589 Standardize wording to `constructs a new` (Jamil Lambert, PhD)
27f94d5540 Replace `creates` with `constructs` (Jamil Lambert, PhD)

Pull request description:

  As discussed in issue #3575 there are various ways of saying a new object is created.

  These have all be standardized to the agreed version.

  Close #3575

ACKs for top commit:
  apoelstra:
    ACK 1649b68589834dfe9d5b63812da3e9f0e5930107; successfully ran local tests
  tcharding:
    ACK 1649b68589

Tree-SHA512: 0ed9b56819c95f1fc14da1e0fdbbe03c4af2d97a95ea6b56125f72913e8d832db5d2882d713ae139d00614e651f3834a4d72528bdf776231cceb6772bf2f9963
2024-11-06 16:05:24 +00:00
Jamil Lambert, PhD 1649b68589
Standardize wording to `constructs a new`
There is a range of different wordings used in the docs of constructor
type functions.

Change all to start with `Constructs a new` or `Constructs an empty`.
2024-11-05 13:02:26 +00:00
Tobin C. Harding 7652d0ddfc
hashes: Hide innards of FromSliceError
In preparation for releasing 1.0 we want to hide all error internals. Do
so for the single error type in the `hashes` crate.
2024-11-05 11:17:29 +11:00
Tobin C. Harding 90b2ac03e3
hashes: Introduce impl_bytelike_traits macro
We have a couple of problems:

1. There are two macros currently for fmt stuff that do similar things,
`arr_newtype_fmt_impl` and `hex_fmt_impl` - the difference is not
immediately obvious, its the way that the byte array is iterated.

2. Our hash types are missing `AsRef<[u8; len]>` and `Borrow<[u8; len]>`.

Introduce a new macro and remove a bunch of other macros. Include
extensive docs but hide the macro from public docs because its not
really for consumers of the library.

The macro requires `$crate::hex` to point to `hex-conservative`.

Note the macro is pretty generic (as in general purpose), `hashes` might
not be the right home for it. Potentially a better place would be in
`hex` itself?
2024-11-02 08:10:43 +11:00
Tobin C. Harding 2868985a91
Replace TBD with next hashes release version
We are about to release `bitcoin_hashes 0.15.0`, replace the TBD string
with the version number.

Requires changing `allow(deprecated_in_future)` attribute to
`allow(deprecated)` (in functions that are them self deprecated).
2024-10-30 07:10:36 +11:00
Tobin C. Harding baab5e580d
hashes: Move private macro
We have two files one for public macros and one for private macros. Move
the `engine_input_impl` macro to the private macros file.

Requires change to call sites because we do not have `use_macros`
attribute on the `internal_macros` file.
2024-10-29 14:06:12 +11:00
Tobin C. Harding 5a736edaaa
hashes: Move serde_macros code into macros
Roll the `serde_macros` module into `macros`, requires making `macros`
public but since it explicitly holds public macros this is reasonable.

Keep the original module and deprecate it.
2024-10-27 07:07:01 +11:00
Tobin C. Harding 12f261c009
hashes: Re-order from_byte_array
The `hashes` crate has a bunch of similar types defined by a bunch of
similar macros and impl blocks, all of which makes it difficult to tell
exactly what is implemented where. In an effort to make the code easier
to read order the `from_byte_array` constructor in the same place across
the crate. Note also we typically put constructors up the top, also
`from_byte_array` is the likely most used constructor so put it first.

FWIW I discovered this while polishing the HTML docs.

Internal change only.
2024-10-16 12:22:42 +11:00
Tobin C. Harding c11587d60d
hashes: Rename hash_type macro
Conceptually (and using traits) we split the hashes into "general"
hash types and more restricted hash types (`Hash`). Also we observe that
the `hash_type` macro defines all the inherent functions name
identically to the `GeneralHash` trait methods.

Rename the trait to describe better what it does.

Internal change only.
2024-10-16 12:22:42 +11:00
Tobin C. Harding 62617cf9ac
hashes: Move from_engine function to other macro
The `from_engine` function is associated with a general hash type but we
are defining it in the `hash_type` macro which holds nothing but
functions associated with the `Hash` trait. By "associated" I mean
methods on the type as opposed to trait methods.

In preparation for re-naming the `hash_type` macro move the
`from_engine` function there. Requires duplicating the code in the
`siphash` impl block, this is as expected because the `siphash` requires
a custom implementation of the general hashing functionality.

Internal change only.
2024-10-16 12:22:22 +11:00
Tobin C. Harding 2cc944578d
Fully deprecate Hash::from_slice
We had an initial go at this but we didn't do the `Hash` trait method.
In order to do so we need to hack the serde code a fair bit, note the
public visitor types.
2024-10-15 07:56:05 +11:00
Tobin C. Harding 3b7ba4f977
Remove the SliceIndex implementation from hash types
If folk really want to index into a hash they can us `as_byte_array`
then index that.

Includes a bump to the version number of `hashes` to `v0.15.0` - this
is because otherwise `secp` won't build since we are breaking an API
that is used in the current release of secp.

Fix: #3115
2024-10-02 10:18:45 +10:00
Tobin C. Harding 58704c2eff
Remove schemars all together
We introduced schemars as a personal favor to a user, and it broke our
CI repeatedly but eventually it seemed like it was stable (mainly, our
MSRV caught up with its MSRV) so we just let it slide. In the end having
schemars on hashes but nowhere else in the rust-bitcoin ecosystem did
not prove that useful.

Remove schemars all together.

Fix: #3393
2024-09-23 06:57:00 +10:00
Liam Aharon 25d906d936
Use UFCS in macros 2024-09-14 09:46:57 +02:00
Tobin C. Harding ae93e226e3
Remove hashes io feature
Currently we only get `std::io::Write` impls when the `bitcoin-io`
dependency is used. This is overly restrictive, it would be nice to have
`std::io::Write` imlps even without the `bitcoin-io` dependency.

Copy the logic out of the `bitcoin_io::impl_write` macro into `hashes`
but feature gate it differently.

Call the new macro inside `hash_type` (and in `hmac`), remove the
`impls` module, and move the tests to the integration test directory.

Remove the `io` feature from `hashes`, now if users enable `std` they
get `std::io::Write` impls and if they enable `bitcoin-io` they get
`bitcoin_io::Write` impls as well.
2024-09-09 06:37:49 +10:00
Tobin C. Harding d72f730211
hashes: Use $crate in internal macros
These are only called from within the crate but it is still more correct
to use `$crate` and saves this from biting us later if we copy the code
someplace else.

Internal change only.
2024-09-06 09:20:10 +10:00
merge-script 9233eb2fa3
Merge rust-bitcoin/rust-bitcoin#3275: Enforce that `Hash::Bytes` is an array
be13397570 Make hmac & hkdf more robust against buggy `Hash` (Martin Habovstiak)
94c0614bda Enforce that `Hash::Bytes` is an array (Martin Habovstiak)

Pull request description:

  This makes sure `Hash::Bytes` is an array. We've discussed this somewhere but I don't remember where.

  I'm not sure if the second commit is actually valuable but hopefully shouldn't make things worse.

ACKs for top commit:
  apoelstra:
    ACK be13397570 successfully ran local tests; yep, this looks like an improvement. Agreed that the second commit has questionable value but doe not make things worse
  tcharding:
    ACK be13397570

Tree-SHA512: 0fed982084f0f98927c2b4a275cec81cb4bbc0efbf01551a0a4a8b6b39a4504830243ee8d55a5c0418d81b5d4babc7b22332dbacc0609ced8fada84d2961ae71
2024-09-02 00:42:39 +00:00
Martin Habovstiak 94c0614bda Enforce that `Hash::Bytes` is an array
In the future we would like to guarantee the correctness of `LEN` which
is currently not entirely possible, so this at least adds a sealed trait
enforcing the `Bytes` type to be an array. Consumers concerned about the
validity of the length can access the `LEN` constant on `Bytes` instead
to get the correct length of the array.
2024-08-30 06:16:44 +02:00
Antoni Spaanderman a14cdaf859
don't enable std by default when testing
- make tests no_std compatible by adding imports to alloc or std
- feature gate tests behind the 'alloc' feature if they use anything
  from 'alloc' (like the `format!` macro)
- schemars feature enables alloc
2024-08-26 21:08:23 +02:00
Fmt Bot fbf7f41875 2024-08-25 automated rustfmt nightly 2024-08-25 01:14:09 +00:00
Martin Habovstiak 1a91492204 Clean up the siphash mess
Previously we had removed `Default` impl on `siphash24::HashEngine` by
reimplementing the type manually. This was a really bad idea as it
inevitably led to API differences that broke the build which we didn't
notice because of unrelated bug. It should've just split the macro from
the start as was suggested but it was claimed to be difficult, I don't
think was the case as can be seen by this PR.

This commit does what the previous one should've done: it renames the
macro to have `_no_default` suffix, creates another one of the original
name that calls into `_no_default` one and moves anything related to
`Default`. This cleanly ensures all previous hashes stay the same while
siphash gets `Default` removed. This also removes all now-conflicting
impls from `siphash24` module which makes the module almost identical to
what it looked like before the change. The only differences are removed
`Default`/`new`, fixes in tests and recent rename of `as_u64` to
`to_u64`.
2024-08-23 05:54:41 +02:00
Tobin C. Harding 191897f9ea
Manually format
Run `rustfmt` and manually fix the places where comments are moved to
the wrong place.
2024-08-08 09:38:45 +10:00
merge-script 075ab9d3e0
Merge rust-bitcoin/rust-bitcoin#3127: hashes: Call through to trait methods
975f22f399 hashes: Call through to trait methods (Tobin C. Harding)

Pull request description:

  Currently we have duplicate code in inherent functions that also occurs in the default implementation of the `GeneralHash` trait methods, this is unnecessary because we can call through to the trait methods.

ACKs for top commit:
  Kixunil:
    ACK 975f22f399
  apoelstra:
    ACK 975f22f399 successfully ran local tests

Tree-SHA512: 74d8905a20d75536abf477dd2226e3cb12d8bd7330b1769e520840df1538362c6cbec6a976dfeb771797732b1f9259ee4f1970cadb69eca67b8b9bbe956ceeca
2024-08-06 16:58:59 +00:00
Tobin C. Harding 0a045d87ea
hashes: Add a new hash_reader function
Add a function `hash_reader` that uses the `BufRead` trait to read
bytes directly into the hash engine.

Add the functionality to:

- as a trait method in the `GeneralHash` trait with default implementation
- as inherent functions to all the hash types

Close: #3050
2024-08-06 10:38:57 +10:00
Tobin C. Harding 975f22f399
hashes: Call through to trait methods
Currently we have duplicate code in inherent functions that also occurs
in the default implementation of the `GeneralHash` trait methods, this
is unnecessary because we can call through to the trait methods.
2024-08-06 10:28:03 +10:00
Tobin C. Harding 360d1fb1bb
hashes: Use $crate in macro
Depending on types being in scope when calling macros is bad practice
but we have mistakenly done so in `internal_macros` when using the
`FromSliceError`.

Use `$crate::FromSliceError` in the macro and remove import statements.
2024-07-12 12:55:22 +10:00
Andrew Poelstra 73dcc79763
hashes: split Hash trait into two 2024-06-24 13:28:54 +00:00
Andrew Poelstra 8869f35a69
hashes: drop the `all_zeros` method on arbitrary hashes
Manually implement it for Wtxid, Txid and BlockHash, where the all-zero
"hash" has a consensus meaning. But in general we should not be
implementing this method unless we have a good reason to do so. It can
be emulated or implemeted in terms of from_byte_array.

The use of Wtxid::all_zeros is obscure and specific enough that I am
tempted to drop it. But for txid and blockhash, the 0 hash appears in
actual blockdata and we should keep it.

All other uses of all_zeros were either in test code or in places where
the specific hash was not important and [u8; 32] was a more appropriate
type.
2024-06-22 15:09:28 +00:00
Fmt Bot 4745b55cae 2024-06-16 automated rustfmt nightly 2024-06-16 01:09:27 +00:00
Tobin C. Harding 6b7d02e5ae
Add inherent functions to hashes
Currently we have a trait `Hash` that is required for `Hmac`, `Hkdf`,
and other use cases. However, it is unegonomic for users who just want
to do a simple hash to have to import the trait.

Add inherent functions to all hash types including those created with
the new wrapper type macros.

This patch introduces some duplicate code but we are trying to make
progress in the hashes API re-write. We can come back and de-dublicate
later.

Includes making `to_byte_array`,`from_byte_array`, `as_byte_array`, and
`all_zeros` const where easily possible.
2024-06-14 10:17:00 +10:00
Tobin C. Harding ce1db3ea26
hashes: Move non-trait functions
The `hash_trait_impls` macro currently adds an impl block for `Hash` -
this is not what the docs say since and `impl Hash` block is nothing
to do with traits.

Move the impl block and add a duplicate of the functions to the
`sha256t::Hash` type.

This is a refactor, no API or logic changes. Note that wrapper types
currently do net get these functions - that will be
discussed/implemented separately.
2024-06-11 13:03:09 +10:00
Tobin C. Harding 71bb86232b
hashes: Do not import str
Depending on things being in scope for macros to use is bad form,
using the fully qualified path is the correct way.

Do not import `str` instead use the fully qualified path to the `core`
re-export.

Use fully qualified instead.
2024-04-06 06:49:07 +11:00
Tobin C. Harding 4bfb466bb9
Upgrade hex dependency
Upgrade to the new `hex v0.2.0` release.
2024-03-10 10:35:01 +11:00
Tobin C. Harding f0558e8eb9
Use fmt_hex_exact
Currently we have two functions for displaying forwards and backwards and
we also have `fmt_hex_exact`. I do not know why we added the functions.

In the latest version of hex we do not have the ability to construct a
`DisplayArray` type so we have to use `fmt_hex_exact`.

Make the change now, separate from the `hex` upgrade, to assist review.
2024-03-10 10:35:01 +11:00