This enables us to construct Bundles at various stages of
authorization:
- `Bundle<Unauthorized>`: A bundle with all effecting data but no
proofs or signatures.
- `Bundle<Authorized>`: A bundle with all proofs and signatures,
suitable for inclusion in a block.
- `Bundle<Partial>`: Example of some in-progress bundle authorization,
for example during a FROST threshold multisignature protocol.
Also adds the bundle flags field from ZIP 225.
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.
We examined the nullifier designs more closely, and determined that the
previously-selected design was actually fine, but for a somewhat-subtle
reason: even though an adversary with knowledge of a victim's full viewing
key could choose psi to cancel out Hash_nk(rho), the nullifier still
directly depends on rho via the note commitment.
The previously-selected design was broken because an adversary with
knowledge of a victim's full viewing key could perform a Faerie Gold
attack: given knowledge of nk, they can choose psi to cancel out
Hash_nk(rho) and cause a collision.
Some of this content may move into the concepts section, or possibly into
a dedicated specification area, but for now the design section includes
our choices alongside the reasoning.