With this approach, we don't need `Target::PublicInput`; any routable `Target` can be marked as a public input via `register_public_input`. The circuit itself hashes these targets, and routes the hash output to the first four wires of a `PublicInputGate`, which is placed at an arbitrary location in the circuit.
All gates have direct access to the purported hash of public inputs. We could think of them as accessing `PI_hash_i(x)` (as in Plonk), but these are now (four) constant functions, so they effectively have direct access to the hash itself.
`PublicInputGate` checks that its first four wires match this purported public input hash. The other gates ignore the hash.
Resolves#64.
As in plonky1. The semantics of virtual targets in plonky1 were rather weird, but I think it's somewhat better here, since we already separate `generate_copy` and `assert_equal` methods. Users now make more of an explicit choice -- they can use a `VirtualTarget` for the witness generation only using `generate_copy`, or they can involve it in copy constraints.