2021-06-22 15:34:50 +02:00
|
|
|
use std::ops::Range;
|
|
|
|
|
|
2021-07-29 22:00:29 -07:00
|
|
|
use crate::iop::wire::Wire;
|
|
|
|
|
use crate::plonk::circuit_data::CircuitConfig;
|
2021-02-09 21:25:21 -08:00
|
|
|
|
|
|
|
|
/// A location in the witness.
|
|
|
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
2021-02-26 13:18:41 -08:00
|
|
|
pub enum Target {
|
2021-02-09 21:25:21 -08:00
|
|
|
Wire(Wire),
|
2021-07-01 08:12:12 -07:00
|
|
|
/// 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.
|
2021-07-01 10:36:31 -07:00
|
|
|
VirtualTarget {
|
|
|
|
|
index: usize,
|
|
|
|
|
},
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
|
2021-02-26 13:18:41 -08:00
|
|
|
impl Target {
|
2021-02-09 21:25:21 -08:00
|
|
|
pub fn wire(gate: usize, input: usize) -> Self {
|
|
|
|
|
Self::Wire(Wire { gate, input })
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-07 11:30:03 +02:00
|
|
|
pub fn is_routable(&self, config: &CircuitConfig) -> bool {
|
2021-02-09 21:25:21 -08:00
|
|
|
match self {
|
2021-02-26 13:18:41 -08:00
|
|
|
Target::Wire(wire) => wire.is_routable(config),
|
2021-07-01 08:12:12 -07:00
|
|
|
Target::VirtualTarget { .. } => true,
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
}
|
2021-06-09 10:51:50 +02:00
|
|
|
|
|
|
|
|
pub fn wires_from_range(gate: usize, range: Range<usize>) -> Vec<Self> {
|
|
|
|
|
range.map(|i| Self::wire(gate, i)).collect()
|
|
|
|
|
}
|
2021-09-28 22:31:20 -07:00
|
|
|
|
|
|
|
|
pub fn index(&self, num_wires: usize, degree: usize) -> usize {
|
|
|
|
|
match self {
|
|
|
|
|
Target::Wire(Wire { gate, input }) => gate * num_wires + input,
|
|
|
|
|
Target::VirtualTarget { index } => degree * num_wires + index,
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
2021-08-14 08:53:39 -07:00
|
|
|
|
|
|
|
|
/// A `Target` which has already been constrained such that it can only be 0 or 1.
|
|
|
|
|
#[derive(Copy, Clone, Debug)]
|
2021-11-30 17:12:13 +01:00
|
|
|
#[allow(clippy::manual_non_exhaustive)]
|
2021-08-14 08:53:39 -07:00
|
|
|
pub struct BoolTarget {
|
|
|
|
|
pub target: Target,
|
|
|
|
|
/// This private field is here to force all instantiations to go through `new_unsafe`.
|
|
|
|
|
_private: (),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl BoolTarget {
|
|
|
|
|
pub fn new_unsafe(target: Target) -> BoolTarget {
|
|
|
|
|
BoolTarget {
|
|
|
|
|
target,
|
|
|
|
|
_private: (),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|