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.
There's a restriction that for structs containing unsized types the
unsized type has to be the last field. `sha256t::Hash` is not an unsized
type but we are going to introduce a macro that will assume this order
to work equally well with both sized and unsized types. Thus we swap it
upfront here.
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`.
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.
We would like to do away with the `GeneralHash` trait. Currently we
bound `Hmac` and `HmacEngine` on it but this is unnecessary now that we
have added `HashEngine::finalize` and `HashEngine::Hash`.
Bound the `HmacEngine` on `HashEngine` (which has an associated `Hash`
type returned by `finilalize`).
Bound `Hmac` type on `T::Hash` where `T` is `HashEngine`.
Includes some minor shortening of local variable names around hmac
engine usage.
Note this means that `Hmac` no longer implements `GeneralHash`.
Add an associated const `Hash` to the `HashEngine` trait. Also add a
`finalize` method that converts the engine to the associated hash.
For now just use the existent `from_engine` stuff. We can refactor
later.
Implementors of the Tag trait had to use the #[derive(Clone)] attribute.
This change eliminates this need by removing the Clone trait
bound from the Tag trait.
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
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>
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>`.
This function is meant to be used in conjunction with the
`general_hash_type` macro but the `sha256t` module does not use that
macro.
Inline the function. Internal change only.
Now we have an associated const we can do away with the `engine` trait
method all together. Users can call `Hash<FooTag>::engine` instead. This
is better because its an API more similar to the other hash types and
therefor easier to discover and remember.
Instead of requiring users of the `Tag` trait to implement the `engine`
method we can have an associated const and provide an `engine` method
with a default implementation.
Use an associated const for the pre-tagged hash engine. Fro now keep the
`engine` trait method but have a default impl that returns the const. We
will remove it as a separate patch to assist review.
This macro is a maintenance burden. We would like to put a tag on the
hash engine but doing so would require breaking this macro anyway so
lets just delete it.
In preparation for removing a bunch of macros move all the modules to
`<mod>/mod.rs`.
Do so by running the following shell:
```bash
for mod in hash160 ripemd160 sha1 sha256 sha256d sha256t \
sha384 sha512 sha512_256 siphash24 hkdf hmac; do
mkdir $mod
mv "$mod.rs" "$mod/mod.rs"
done
```
Internal change only.