mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-06 15:53:10 +00:00
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.
34 lines
934 B
Rust
34 lines
934 B
Rust
use std::ops::Range;
|
|
|
|
use crate::circuit_data::CircuitConfig;
|
|
use crate::wire::Wire;
|
|
|
|
/// A location in the witness.
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum Target {
|
|
Wire(Wire),
|
|
/// A target that doesn't have any inherent location in the witness (but it can be copied to
|
|
/// another target that does). This is useful for representing intermediate values in witness
|
|
/// generation.
|
|
VirtualTarget {
|
|
index: usize,
|
|
},
|
|
}
|
|
|
|
impl Target {
|
|
pub fn wire(gate: usize, input: usize) -> Self {
|
|
Self::Wire(Wire { gate, input })
|
|
}
|
|
|
|
pub fn is_routable(&self, config: &CircuitConfig) -> bool {
|
|
match self {
|
|
Target::Wire(wire) => wire.is_routable(config),
|
|
Target::VirtualTarget { .. } => true,
|
|
}
|
|
}
|
|
|
|
pub fn wires_from_range(gate: usize, range: Range<usize>) -> Vec<Self> {
|
|
range.map(|i| Self::wire(gate, i)).collect()
|
|
}
|
|
}
|