There's a (negligble) chance that we could generate (or be sent
adversarially) a RandomSeed which derives esk == 0. It's not hard to
detect and reject, in order to satisfy the type system.
This was missed from zcash/orchard#49, but could not have caused a
consensus failure or loss-of-funds because `alpha` _was_ being sampled
and used to derive `rk`, meaning that the signatures would fail to
validate.
`prf_expand{_vec}` have been replaced by the `PrfExpand` enum, which
has `PrfExpand::{expand, with_ad, with_ad_slices}` methods for use
within each domain as necessary.
Spec version 2021.1.24 added the diversifier key to the encoding of an
incoming viewing key (to make them more usable). As a result, we now
have two separate types:
- `KeyAgreementPrivateKey`: what was previously `IncomingViewingKey`,
corresponding to the `ivk` type in the protocol spec. It is now
crate-internal.
- `IncomingViewingKey`: the user-facing type that encompasses `dk` and
`ivk`.
This requires exposing the ⊥ case throughout the return types. We
prevent it from propagating into the Orchard note and key types by
ensuring that:
- When we generate keys or notes, if we encounter ⊥ we discard and
re-generate.
- When we construct keys or notes via any other pathway (e.g. parsing
from bytes), we check for and reject ⊥.
This makes diversified address generation fallible (though with
negligible probability). We expose this to users, so they can decide how
to handle it (either just unwrapping, or incrementing the diversifier
index).
We alter spending key construction to reject spending keys that would
not result in a default address (with diversifier index 0).
There was push-back on having this crate require these traits, due to the
additional complexity within this crate. My rationale for including them
was to make it simpler to reason about what is responsible for enforcing
chain-specific constraints, and to reduce duplication (by enabling the
wrapping chain implementation to use type definitions and leverage all
built-in behaviour, instead of newtypes and needing to add a bunch of
wrapping logic and boilerplate, some of which would encode chain-specific
logic).
We'll try working within the requirement that this crate enforces minimal
base constraints and hard-codes any constants, and then have the wrapping
chain provide encoding prefixes and additional value constraints where
necessary.