This enables `InProgress<Unproven, Unauthorized>: Clone`, which allows
the bundle returned by `Builder::build` to be cloned. In pure-Rust
wallets this should not be necessary, but it is required for `zcashd`
due to FFI-crossing.
In the previous commit, we fixed a bug where padding was being added to
the state when the sponge was in squeezing mode. But there's no need to
assign a circuit region in which we add constant zeroes to the state :)
Sponge constructions pad the entire input message and then split it into
rate-sized chunks. The previous implementation was using an incorrect
duplex-like hybrid where padding was applied to each chunked input. We
now use an enum to distinguish message and padding words being absorbed
into the sponge.
This also fixes two previous bugs:
- If a `ConstantLength` hash had a length greater than the permutation's
rate but not a multiple of it, no padding would be generated and the
circuit would fail to create proofs.
- If a sponge usage required more output than the permutation's rate,
the squeeze-side permutations would in some cases incorrectly apply
padding, when it should instead use the prior state as-is. We now add
zeroes instead.
This change doesn't alter the Orchard circuit, because it doesn't need
any padding cells, only takes a single field element as output, and
padding is still assigned in the same region as before.
For almost all the sponge constructions defined in the Poseidon paper,
the domain can be defined completely statically. Variable-length hashing
requires knowledge of the message length, but that can be provided to
the fixed padding function in a subsequent commit, and in any case we
can't use variable-length inputs in a circuit.
The `Sponge` struct's API correctly enforces the properties of a sponge:
it can absorb an arbitrary number of elements, and then squeeze an
arbitrary number of elements, but cannot absorb after it has squeezed.
Co-authored-by: ying tong <yingtong@z.cash>
This is necessary because the blinding factor r can be zero with greater
than negligible probability in an adversarial case, which with incomplete
addition would cause the circuit to compute a commitment that is not on
the curve.