use pyo3::{
- prelude::*,
- types::{PyDict, PyList, PyLong, PyString},
-};
-
-use crate::{
- ast::{
- query::Queriable, Circuit, Constraint, ExposeOffset, FixedSignal, ForwardSignal,
- InternalSignal, Lookup, SharedSignal, StepType, StepTypeUUID, TransitionConstraint,
- },
- frontend::dsl::{StepTypeHandler, SuperCircuitContext},
- plonkish::{
- backend::halo2::{
- chiquito2Halo2, chiquitoSuperCircuit2Halo2, ChiquitoHalo2, ChiquitoHalo2Circuit,
- ChiquitoHalo2SuperCircuit,
- },
- compiler::{
- cell_manager::SingleRowCellManager, compile, config,
- step_selector::SimpleStepSelectorBuilder,
- },
- ir::{assignments::AssignmentGenerator, sc::MappingContext},
- },
- poly::Expr,
- util::{uuid, UUID},
- wit_gen::{StepInstance, TraceContext, TraceWitness},
-};
-
-use core::result::Result;
-use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr};
-use serde::de::{self, Deserialize, Deserializer, IgnoredAny, MapAccess, Visitor};
-use std::{cell::RefCell, collections::HashMap, fmt, rc::Rc};
-
-type CircuitMapStore = (
- Circuit<Fr, ()>,
- ChiquitoHalo2<Fr>,
- Option<AssignmentGenerator<Fr, ()>>,
-);
-type CircuitMap = RefCell<HashMap<UUID, CircuitMapStore>>;
-
-thread_local! {
- pub static CIRCUIT_MAP: CircuitMap = RefCell::new(HashMap::new());
-}
-
-pub fn chiquito_ast_to_halo2(ast_json: &str) -> UUID {
- let circuit: Circuit<Fr, ()> =
- serde_json::from_str(ast_json).expect("Json deserialization to Circuit failed.");
-
- let config = config(SingleRowCellManager {}, SimpleStepSelectorBuilder {});
- let (chiquito, assignment_generator) = compile(config, &circuit);
- let chiquito_halo2 = chiquito2Halo2(chiquito);
- let uuid = uuid();
-
- CIRCUIT_MAP.with(|circuit_map| {
- circuit_map
- .borrow_mut()
- .insert(uuid, (circuit, chiquito_halo2, assignment_generator));
- });
-
- uuid
-}
-
-pub fn chiquito_ast_map_store(ast_json: &str) -> UUID {
- let circuit: Circuit<Fr, ()> =
- serde_json::from_str(ast_json).expect("Json deserialization to Circuit failed.");
-
- let uuid = uuid();
-
- CIRCUIT_MAP.with(|circuit_map| {
- circuit_map
- .borrow_mut()
- .insert(uuid, (circuit, ChiquitoHalo2::default(), None));
- });
-
- uuid
-}
-
-fn add_assignment_generator_to_rust_id(
- assignment_generator: AssignmentGenerator<Fr, ()>,
- rust_id: UUID,
-) {
- CIRCUIT_MAP.with(|circuit_map| {
- let mut circuit_map = circuit_map.borrow_mut();
- let circuit_map_store = circuit_map.get_mut(&rust_id).unwrap();
- circuit_map_store.2 = Some(assignment_generator);
- });
-}
-
-pub fn chiquito_super_circuit_halo2_mock_prover(
- rust_ids: Vec<UUID>,
- super_witness: HashMap<UUID, &str>,
- k: usize,
-) {
- let mut super_circuit_ctx = SuperCircuitContext::<Fr, ()>::default();
-
- let config = config(SingleRowCellManager {}, SimpleStepSelectorBuilder {});
- for rust_id in rust_ids.clone() {
- let circuit_map_store = rust_id_to_halo2(rust_id);
- let (circuit, _, _) = circuit_map_store;
- let assignment = super_circuit_ctx.sub_circuit_with_ast(config.clone(), circuit);
- add_assignment_generator_to_rust_id(assignment, rust_id);
- }
-
- let super_circuit = super_circuit_ctx.compile();
- let compiled = chiquitoSuperCircuit2Halo2(&super_circuit);
-
- let mut mapping_ctx = MappingContext::default();
- for rust_id in rust_ids {
- let circuit_map_store = rust_id_to_halo2(rust_id);
- let (_, _, assignment_generator) = circuit_map_store;
-
- if let Some(witness_json) = super_witness.get(&rust_id) {
- let witness: TraceWitness<Fr> = serde_json::from_str(witness_json)
- .expect("Json deserialization to TraceWitness failed.");
- mapping_ctx.map_with_witness(&assignment_generator.unwrap(), witness);
- }
- }
-
- let super_assignments = mapping_ctx.get_super_assignments();
-
- let circuit = ChiquitoHalo2SuperCircuit::new(compiled, super_assignments);
-
- let prover = MockProver::<Fr>::run(k as u32, &circuit, circuit.instance()).unwrap();
-
- let result = prover.verify_par();
-
- println!("result = {:#?}", result);
-
- if let Err(failures) = &result {
- for failure in failures.iter() {
- println!("{}", failure);
- }
- }
-}
-
-fn rust_id_to_halo2(uuid: UUID) -> CircuitMapStore {
- CIRCUIT_MAP.with(|circuit_map| {
- let circuit_map = circuit_map.borrow();
- circuit_map.get(&uuid).unwrap().clone()
- })
-}
-
-pub fn chiquito_halo2_mock_prover(witness_json: &str, rust_id: UUID, k: usize) {
- let trace_witness: TraceWitness<Fr> =
- serde_json::from_str(witness_json).expect("Json deserialization to TraceWitness failed.");
- let (_, compiled, assignment_generator) = rust_id_to_halo2(rust_id);
- let circuit: ChiquitoHalo2Circuit<_> = ChiquitoHalo2Circuit::new(
- compiled,
- assignment_generator.map(|g| g.generate_with_witness(trace_witness)),
- );
-
- let prover = MockProver::<Fr>::run(k as u32, &circuit, circuit.instance()).unwrap();
-
- let result = prover.verify_par();
-
- println!("{:#?}", result);
-
- if let Err(failures) = &result {
- for failure in failures.iter() {
- println!("{}", failure);
- }
- }
-}
-
-struct CircuitVisitor;
-
-impl<'de> Visitor<'de> for CircuitVisitor {
- type Value = Circuit<Fr, ()>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("struct Cricuit")
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<Circuit<Fr, ()>, A::Error>
- where
- A: MapAccess<'de>,
- {
- let mut step_types = None;
- let mut forward_signals = None;
- let mut shared_signals = None;
- let mut fixed_signals = None;
- let mut exposed = None;
- let mut annotations = None;
- let mut fixed_assignments = None;
- let mut first_step = None;
- let mut last_step = None;
- let mut num_steps = None;
- let mut q_enable = None;
- let mut id = None;
-
- while let Some(key) = map.next_key::<String>()? {
- match key.as_str() {
- "step_types" => {
- if step_types.is_some() {
- return Err(de::Error::duplicate_field("step_types"));
- }
- step_types = Some(map.next_value::<HashMap<UUID, StepType<Fr>>>()?);
- }
- "forward_signals" => {
- if forward_signals.is_some() {
- return Err(de::Error::duplicate_field("forward_signals"));
- }
- forward_signals = Some(map.next_value::<Vec<ForwardSignal>>()?);
- }
- "shared_signals" => {
- if shared_signals.is_some() {
- return Err(de::Error::duplicate_field("shared_signals"));
- }
- shared_signals = Some(map.next_value::<Vec<SharedSignal>>()?);
- }
- "fixed_signals" => {
- if fixed_signals.is_some() {
- return Err(de::Error::duplicate_field("fixed_signals"));
- }
- fixed_signals = Some(map.next_value::<Vec<FixedSignal>>()?);
- }
- "exposed" => {
- if exposed.is_some() {
- return Err(de::Error::duplicate_field("exposed"));
- }
- exposed = Some(map.next_value::<Vec<(Queriable<Fr>, ExposeOffset)>>()?);
- }
- "annotations" => {
- if annotations.is_some() {
- return Err(de::Error::duplicate_field("annotations"));
- }
- annotations = Some(map.next_value::<HashMap<UUID, String>>()?);
- }
- "fixed_assignments" => {
- if fixed_assignments.is_some() {
- return Err(de::Error::duplicate_field("fixed_assignments"));
- }
- fixed_assignments =
- Some(map.next_value::<Option<HashMap<UUID, (Queriable<Fr>, Vec<Fr>)>>>()?);
- }
- "first_step" => {
- if first_step.is_some() {
- return Err(de::Error::duplicate_field("first_step"));
- }
- first_step = Some(map.next_value::<Option<StepTypeUUID>>()?);
- }
- "last_step" => {
- if last_step.is_some() {
- return Err(de::Error::duplicate_field("last_step"));
- }
- last_step = Some(map.next_value::<Option<StepTypeUUID>>()?);
- }
- "num_steps" => {
- if num_steps.is_some() {
- return Err(de::Error::duplicate_field("num_steps"));
- }
- num_steps = Some(map.next_value::<usize>()?);
- }
- "q_enable" => {
- if q_enable.is_some() {
- return Err(de::Error::duplicate_field("q_enable"));
- }
- q_enable = Some(map.next_value::<bool>()?);
- }
- "id" => {
- if id.is_some() {
- return Err(de::Error::duplicate_field("id"));
- }
- id = Some(map.next_value()?);
- }
- _ => {
- return Err(de::Error::unknown_field(
- &key,
- &[
- "step_types",
- "forward_signals",
- "shared_signals",
- "fixed_signals",
- "exposed",
- "annotations",
- "fixed_assignments",
- "first_step",
- "last_step",
- "num_steps",
- "q_enable",
- "id",
- ],
- ))
- }
- }
- }
- let step_types = step_types
- .ok_or_else(|| de::Error::missing_field("step_types"))?
- .into_iter()
- .map(|(k, v)| (k, Rc::new(v)))
- .collect();
- let forward_signals =
- forward_signals.ok_or_else(|| de::Error::missing_field("forward_signals"))?;
- let shared_signals =
- shared_signals.ok_or_else(|| de::Error::missing_field("shared_signals"))?;
- let fixed_signals =
- fixed_signals.ok_or_else(|| de::Error::missing_field("fixed_signals"))?;
- let exposed = exposed.ok_or_else(|| de::Error::missing_field("exposed"))?;
- let annotations = annotations.ok_or_else(|| de::Error::missing_field("annotations"))?;
- let fixed_assignments = fixed_assignments
- .ok_or_else(|| de::Error::missing_field("fixed_assignments"))?
- .map(|inner| inner.into_values().collect());
- let first_step = first_step.ok_or_else(|| de::Error::missing_field("first_step"))?;
- let last_step = last_step.ok_or_else(|| de::Error::missing_field("last_step"))?;
- let num_steps = num_steps.ok_or_else(|| de::Error::missing_field("num_steps"))?;
- let q_enable = q_enable.ok_or_else(|| de::Error::missing_field("q_enable"))?;
- let id = id.ok_or_else(|| de::Error::missing_field("id"))?;
-
- Ok(Circuit {
- step_types,
- forward_signals,
- shared_signals,
- fixed_signals,
- halo2_advice: Default::default(),
- halo2_fixed: Default::default(),
- exposed,
- num_steps,
- annotations,
- trace: Some(Rc::new(|_: &mut TraceContext<_>, _: _| {})),
- fixed_assignments,
- first_step,
- last_step,
- q_enable,
- id,
- })
- }
-}
-struct StepTypeVisitor;
-
-impl<'de> Visitor<'de> for StepTypeVisitor {
- type Value = StepType<Fr>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("struct StepType")
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<StepType<Fr>, A::Error>
- where
- A: MapAccess<'de>,
- {
- let mut id = None;
- let mut name = None;
- let mut signals = None;
- let mut constraints = None;
- let mut transition_constraints = None;
- let mut lookups = None;
- let mut annotations = None;
-
- while let Some(key) = map.next_key::<String>()? {
- match key.as_str() {
- "id" => {
- if id.is_some() {
- return Err(de::Error::duplicate_field("id"));
- }
- id = Some(map.next_value()?);
- }
- "name" => {
- if name.is_some() {
- return Err(de::Error::duplicate_field("name"));
- }
- name = Some(map.next_value::<String>()?);
- }
- "signals" => {
- if signals.is_some() {
- return Err(de::Error::duplicate_field("signals"));
- }
- signals = Some(map.next_value::<Vec<InternalSignal>>()?);
- }
- "constraints" => {
- if constraints.is_some() {
- return Err(de::Error::duplicate_field("constraints"));
- }
- constraints = Some(map.next_value::<Vec<Constraint<Fr>>>()?);
- }
- "transition_constraints" => {
- if transition_constraints.is_some() {
- return Err(de::Error::duplicate_field("transition_constraints"));
- }
- transition_constraints =
- Some(map.next_value::<Vec<TransitionConstraint<Fr>>>()?);
- }
- "lookups" => {
- if lookups.is_some() {
- return Err(de::Error::duplicate_field("lookups"));
- }
- lookups = Some(map.next_value::<Vec<Lookup<Fr>>>()?);
- }
- "annotations" => {
- if annotations.is_some() {
- return Err(de::Error::duplicate_field("annotations"));
- }
- annotations = Some(map.next_value::<HashMap<UUID, String>>()?);
- }
- _ => {
- return Err(de::Error::unknown_field(
- &key,
- &[
- "id",
- "name",
- "signals",
- "constraints",
- "transition_constraints",
- "lookups",
- "annotations",
- ],
- ))
- }
- }
- }
- let id = id.ok_or_else(|| de::Error::missing_field("id"))?;
- let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
- let signals = signals.ok_or_else(|| de::Error::missing_field("signals"))?;
- let constraints = constraints.ok_or_else(|| de::Error::missing_field("constraints"))?;
- let transition_constraints = transition_constraints
- .ok_or_else(|| de::Error::missing_field("transition_constraints"))?;
- let lookups = lookups.ok_or_else(|| de::Error::missing_field("lookups"))?;
- let annotations = annotations.ok_or_else(|| de::Error::missing_field("annotations"))?;
-
- let mut step_type = StepType::<Fr>::new(id, name);
- step_type.signals = signals;
- step_type.constraints = constraints;
- step_type.transition_constraints = transition_constraints;
- step_type.lookups = lookups;
- step_type.annotations = annotations;
-
- Ok(step_type)
- }
-}
-
-macro_rules! impl_visitor_constraint_transition {
- ($name:ident, $type:ty, $display:expr) => {
- struct $name;
-
- impl<'de> Visitor<'de> for $name {
- type Value = $type;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str($display)
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<$type, A::Error>
- where
- A: MapAccess<'de>,
- {
- let mut annotation = None;
- let mut expr = None;
- while let Some(key) = map.next_key::<String>()? {
- match key.as_str() {
- "annotation" => {
- if annotation.is_some() {
- return Err(de::Error::duplicate_field("annotation"));
- }
- annotation = Some(map.next_value::<String>()?);
- }
- "expr" => {
- if expr.is_some() {
- return Err(de::Error::duplicate_field("expr"));
- }
- expr = Some(map.next_value::<Expr<Fr, Queriable<Fr>>>()?);
- }
- _ => return Err(de::Error::unknown_field(&key, &["annotation", "expr"])),
- }
- }
- let annotation =
- annotation.ok_or_else(|| de::Error::missing_field("annotation"))?;
- let expr = expr.ok_or_else(|| de::Error::missing_field("expr"))?;
- Ok(Self::Value { annotation, expr })
- }
- }
- };
-}
-
-impl_visitor_constraint_transition!(ConstraintVisitor, Constraint<Fr>, "struct Constraint");
-impl_visitor_constraint_transition!(
- TransitionConstraintVisitor,
- TransitionConstraint<Fr>,
- "struct TransitionConstraint"
-);
-
-struct LookupVisitor;
-
-impl<'de> Visitor<'de> for LookupVisitor {
- type Value = Lookup<Fr>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("struct Lookup")
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<Lookup<Fr>, A::Error>
- where
- A: MapAccess<'de>,
- {
- let mut annotation = None;
- let mut exprs = None;
- let mut enable = None;
- while let Some(key) = map.next_key::<String>()? {
- match key.as_str() {
- "annotation" => {
- if annotation.is_some() {
- return Err(de::Error::duplicate_field("annotation"));
- }
- annotation = Some(map.next_value::<String>()?);
- }
- "exprs" => {
- if exprs.is_some() {
- return Err(de::Error::duplicate_field("exprs"));
- }
- exprs =
- Some(map.next_value::<Vec<(Constraint<Fr>, Expr<Fr, Queriable<Fr>>)>>()?);
- }
- "enable" => {
- if enable.is_some() {
- return Err(de::Error::duplicate_field("enable"));
- }
- enable = Some(map.next_value::<Option<Constraint<Fr>>>()?);
- }
- _ => {
- return Err(de::Error::unknown_field(
- &key,
- &["annotation", "exprs", "enable"],
- ))
- }
- }
- }
- let annotation = annotation.ok_or_else(|| de::Error::missing_field("annotation"))?;
- let exprs = exprs.ok_or_else(|| de::Error::missing_field("exprs"))?;
- let enable = enable.ok_or_else(|| de::Error::missing_field("enable"))?;
- Ok(Self::Value {
- annotation,
- exprs,
- enable,
- })
- }
-}
-
-struct ExprVisitor;
-
-impl<'de> Visitor<'de> for ExprVisitor {
- type Value = Expr<Fr, Queriable<Fr>>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("enum Expr")
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<Expr<Fr, Queriable<Fr>>, A::Error>
- where
- A: MapAccess<'de>,
- {
- let key: String = map
- .next_key()?
- .ok_or_else(|| de::Error::custom("map is empty"))?;
- match key.as_str() {
- "Const" => map.next_value().map(Expr::Const),
- "Sum" => map.next_value().map(Expr::Sum),
- "Mul" => map.next_value().map(Expr::Mul),
- "Neg" => map.next_value().map(Expr::Neg),
- "Pow" => map.next_value().map(|(expr, pow)| Expr::Pow(expr, pow)),
- "Internal" => map
- .next_value()
- .map(|signal| Expr::Query(Queriable::Internal(signal))),
- "Forward" => map
- .next_value()
- .map(|(signal, rotation)| Expr::Query(Queriable::Forward(signal, rotation))),
- "Shared" => map
- .next_value()
- .map(|(signal, rotation)| Expr::Query(Queriable::Shared(signal, rotation))),
- "Fixed" => map
- .next_value()
- .map(|(signal, rotation)| Expr::Query(Queriable::Fixed(signal, rotation))),
- "StepTypeNext" => map
- .next_value()
- .map(|step_type| Expr::Query(Queriable::StepTypeNext(step_type))),
- _ => Err(de::Error::unknown_variant(
- &key,
- &[
- "Const",
- "Sum",
- "Mul",
- "Neg",
- "Pow",
- "Internal",
- "Forward",
- "Shared",
- "Fixed",
- "StepTypeNext",
- ],
- )),
- }
- }
-}
-
-struct QueriableVisitor;
-
-impl<'de> Visitor<'de> for QueriableVisitor {
- type Value = Queriable<Fr>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("enum Queriable")
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<Queriable<Fr>, A::Error>
- where
- A: MapAccess<'de>,
- {
- let key: String = map
- .next_key()?
- .ok_or_else(|| de::Error::custom("map is empty"))?;
- match key.as_str() {
- "Internal" => map.next_value().map(Queriable::Internal),
- "Forward" => map
- .next_value()
- .map(|(signal, rotation)| Queriable::Forward(signal, rotation)),
- "Shared" => map
- .next_value()
- .map(|(signal, rotation)| Queriable::Shared(signal, rotation)),
- "Fixed" => map
- .next_value()
- .map(|(signal, rotation)| Queriable::Fixed(signal, rotation)),
- "StepTypeNext" => map.next_value().map(Queriable::StepTypeNext),
- _ => Err(de::Error::unknown_variant(
- &key,
- &["Internal", "Forward", "Shared", "Fixed", "StepTypeNext"],
- )),
- }
- }
-}
-
-struct ExposeOffsetVisitor;
-
-impl<'de> Visitor<'de> for ExposeOffsetVisitor {
- type Value = ExposeOffset;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("enum ExposeOffset")
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<ExposeOffset, A::Error>
- where
- A: MapAccess<'de>,
- {
- let key: String = map
- .next_key()?
- .ok_or_else(|| de::Error::custom("map is empty"))?;
- match key.as_str() {
- "First" => {
- let _ = map.next_value::<IgnoredAny>()?;
- Ok(ExposeOffset::First)
- }
- "Last" => {
- let _ = map.next_value::<IgnoredAny>()?;
- Ok(ExposeOffset::Last)
- }
- "Step" => map.next_value().map(ExposeOffset::Step),
- _ => Err(de::Error::unknown_variant(&key, &["First", "Last", "Step"])),
- }
- }
-}
-
-macro_rules! impl_visitor_internal_fixed_steptypehandler {
- ($name:ident, $type:ty, $display:expr) => {
- struct $name;
-
- impl<'de> Visitor<'de> for $name {
- type Value = $type;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str($display)
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<$type, A::Error>
- where
- A: MapAccess<'de>,
- {
- let mut id = None;
- let mut annotation = None;
- while let Some(key) = map.next_key::<String>()? {
- match key.as_str() {
- "id" => {
- if id.is_some() {
- return Err(de::Error::duplicate_field("id"));
- }
- id = Some(map.next_value()?);
- }
- "annotation" => {
- if annotation.is_some() {
- return Err(de::Error::duplicate_field("annotation"));
- }
- annotation = Some(map.next_value::<String>()?);
- }
- _ => return Err(de::Error::unknown_field(&key, &["id", "annotation"])),
- }
- }
- let id = id.ok_or_else(|| de::Error::missing_field("id"))?;
- let annotation =
- annotation.ok_or_else(|| de::Error::missing_field("annotation"))?;
- Ok(<$type>::new_with_id(id, annotation))
- }
- }
- };
-}
-
-impl_visitor_internal_fixed_steptypehandler!(
- InternalSignalVisitor,
- InternalSignal,
- "struct InternalSignal"
-);
-impl_visitor_internal_fixed_steptypehandler!(FixedSignalVisitor, FixedSignal, "struct FixedSignal");
-impl_visitor_internal_fixed_steptypehandler!(
- StepTypeHandlerVisitor,
- StepTypeHandler,
- "struct StepTypeHandler"
-);
-
-macro_rules! impl_visitor_forward_shared {
- ($name:ident, $type:ty, $display:expr) => {
- struct $name;
-
- impl<'de> Visitor<'de> for $name {
- type Value = $type;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str($display)
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<$type, A::Error>
- where
- A: MapAccess<'de>,
- {
- let mut id = None;
- let mut phase = None;
- let mut annotation = None;
- while let Some(key) = map.next_key::<String>()? {
- match key.as_str() {
- "id" => {
- if id.is_some() {
- return Err(de::Error::duplicate_field("id"));
- }
- id = Some(map.next_value()?);
- }
- "phase" => {
- if phase.is_some() {
- return Err(de::Error::duplicate_field("phase"));
- }
- phase = Some(map.next_value()?);
- }
- "annotation" => {
- if annotation.is_some() {
- return Err(de::Error::duplicate_field("annotation"));
- }
- annotation = Some(map.next_value::<String>()?);
- }
- _ => {
- return Err(de::Error::unknown_field(
- &key,
- &["id", "phase", "annotation"],
- ))
- }
- }
- }
- let id = id.ok_or_else(|| de::Error::missing_field("id"))?;
- let phase = phase.ok_or_else(|| de::Error::missing_field("phase"))?;
- let annotation =
- annotation.ok_or_else(|| de::Error::missing_field("annotation"))?;
- Ok(<$type>::new_with_id(id, phase, annotation))
- }
- }
- };
-}
-
-impl_visitor_forward_shared!(ForwardSignalVisitor, ForwardSignal, "struct ForwardSignal");
-impl_visitor_forward_shared!(SharedSignalVisitor, SharedSignal, "struct SharedSignal");
-
-struct TraceWitnessVisitor;
-
-impl<'de> Visitor<'de> for TraceWitnessVisitor {
- type Value = TraceWitness<Fr>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("struct TraceWitness")
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<TraceWitness<Fr>, A::Error>
- where
- A: MapAccess<'de>,
- {
- let mut step_instances = None;
-
- while let Some(key) = map.next_key::<String>()? {
- match key.as_str() {
- "step_instances" => {
- if step_instances.is_some() {
- return Err(de::Error::duplicate_field("step_instances"));
- }
- step_instances = Some(map.next_value()?);
- }
- _ => return Err(de::Error::unknown_field(&key, &["step_instances"])),
- }
- }
- let step_instances =
- step_instances.ok_or_else(|| de::Error::missing_field("step_instances"))?;
- Ok(Self::Value { step_instances })
- }
-}
-
-struct StepInstanceVisitor;
-
-impl<'de> Visitor<'de> for StepInstanceVisitor {
- type Value = StepInstance<Fr>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("struct StepInstance")
- }
-
- fn visit_map<A>(self, mut map: A) -> Result<StepInstance<Fr>, A::Error>
- where
- A: MapAccess<'de>,
- {
- let mut step_type_uuid = None;
- let mut assignments = None;
-
- while let Some(key) = map.next_key::<String>()? {
- match key.as_str() {
- "step_type_uuid" => {
- if step_type_uuid.is_some() {
- return Err(de::Error::duplicate_field("step_type_uuid"));
- }
- step_type_uuid = Some(map.next_value()?);
- }
- "assignments" => {
- if assignments.is_some() {
- return Err(de::Error::duplicate_field("assignments"));
- }
- assignments = Some(map.next_value::<HashMap<UUID, (Queriable<Fr>, Fr)>>()?);
- }
- _ => {
- return Err(de::Error::unknown_field(
- &key,
- &["step_type_uuid", "assignments"],
- ))
- }
- }
- }
- let step_type_uuid =
- step_type_uuid.ok_or_else(|| de::Error::missing_field("step_type_uuid"))?;
-
- let assignments: HashMap<Queriable<Fr>, Fr> = assignments
- .ok_or_else(|| de::Error::missing_field("assignments"))?
- .into_values()
- .collect();
-
- Ok(Self::Value {
- step_type_uuid,
- assignments,
- })
- }
-}
-
-macro_rules! impl_deserialize {
- ($name:ident, $type:ty) => {
- impl<'de> Deserialize<'de> for $type {
- fn deserialize<D>(deserializer: D) -> Result<$type, D::Error>
- where
- D: Deserializer<'de>,
- {
- deserializer.deserialize_map($name)
- }
- }
- };
-}
-
-impl_deserialize!(ExprVisitor, Expr<Fr, Queriable<Fr>>);
-impl_deserialize!(QueriableVisitor, Queriable<Fr>);
-impl_deserialize!(ExposeOffsetVisitor, ExposeOffset);
-impl_deserialize!(InternalSignalVisitor, InternalSignal);
-impl_deserialize!(FixedSignalVisitor, FixedSignal);
-impl_deserialize!(ForwardSignalVisitor, ForwardSignal);
-impl_deserialize!(SharedSignalVisitor, SharedSignal);
-impl_deserialize!(StepTypeHandlerVisitor, StepTypeHandler);
-impl_deserialize!(ConstraintVisitor, Constraint<Fr>);
-impl_deserialize!(TransitionConstraintVisitor, TransitionConstraint<Fr>);
-impl_deserialize!(StepTypeVisitor, StepType<Fr>);
-impl_deserialize!(TraceWitnessVisitor, TraceWitness<Fr>);
-impl_deserialize!(StepInstanceVisitor, StepInstance<Fr>);
-impl_deserialize!(LookupVisitor, Lookup<Fr>);
-
-impl<'de> Deserialize<'de> for Circuit<Fr, ()> {
- fn deserialize<D>(deserializer: D) -> Result<Circuit<Fr, ()>, D::Error>
- where
- D: Deserializer<'de>,
- {
- deserializer.deserialize_map(CircuitVisitor)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[test]
- fn test_trace_witness() {
- let json = r#"
- {
- "step_instances": [
- {
- "step_type_uuid": 270606747459021742275781620564109167114,
- "assignments": {
- "270606737951642240564318377467548666378": [
- {
- "Forward": [
- {
- "id": 270606737951642240564318377467548666378,
- "phase": 0,
- "annotation": "a"
- },
- false
- ]
- },
- [
- 55,
- 0,
- 0,
- 0
- ]
- ],
- "270606743497613616562965561253747624458": [
- {
- "Forward": [
- {
- "id": 270606743497613616562965561253747624458,
- "phase": 0,
- "annotation": "b"
- },
- false
- ]
- },
- [
- 89,
- 0,
- 0,
- 0
- ]
- ],
- "270606753004993118272949371872716917258": [
- {
- "Internal": {
- "id": 270606753004993118272949371872716917258,
- "annotation": "c"
- }
- },
- [
- 144,
- 0,
- 0,
- 0
- ]
- ]
- }
- },
- {
- "step_type_uuid": 270606783111694873693576112554652600842,
- "assignments": {
- "270606737951642240564318377467548666378": [
- {
- "Forward": [
- {
- "id": 270606737951642240564318377467548666378,
- "phase": 0,
- "annotation": "a"
- },
- false
- ]
- },
- [
- 89,
- 0,
- 0,
- 0
- ]
- ],
- "270606743497613616562965561253747624458": [
- {
- "Forward": [
- {
- "id": 270606743497613616562965561253747624458,
- "phase": 0,
- "annotation": "b"
- },
- false
- ]
- },
- [
- 144,
- 0,
- 0,
- 0
- ]
- ],
- "270606786280821374261518951164072823306": [
- {
- "Internal": {
- "id": 270606786280821374261518951164072823306,
- "annotation": "c"
- }
- },
- [
- 233,
- 0,
- 0,
- 0
- ]
- ]
- }
- }
- ]
- }
- "#;
- let trace_witness: TraceWitness<Fr> = serde_json::from_str(json).unwrap();
- println!("{:?}", trace_witness);
- }
-
- #[test]
- fn test_expose_offset() {
- let mut json = r#"
- {
- "Step": 1
- }
- "#;
- let _: ExposeOffset = serde_json::from_str(json).unwrap();
- json = r#"
- {
- "Last": -1
- }
- "#;
- let _: ExposeOffset = serde_json::from_str(json).unwrap();
- json = r#"
- {
- "First": 1
- }
- "#;
- let _: ExposeOffset = serde_json::from_str(json).unwrap();
- }
-
- #[test]
- fn test_circuit() {
- let json = r#"
- {
- "step_types": {
- "258869595755756204079859764249309612554": {
- "id": 258869595755756204079859764249309612554,
- "name": "fibo_first_step",
- "signals": [
- {
- "id": 258869599717164329791616633222308956682,
- "annotation": "c"
- }
- ],
- "constraints": [
- {
- "annotation": "(a == 1)",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869580702405326369584955980151130634,
- "phase": 0,
- "annotation": "a"
- },
- false
- ]
- },
- {
- "Neg": {
- "Const": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- }
- ]
- }
- },
- {
- "annotation": "(b == 1)",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- false
- ]
- },
- {
- "Neg": {
- "Const": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- }
- ]
- }
- },
- {
- "annotation": "((a + b) == c)",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869580702405326369584955980151130634,
- "phase": 0,
- "annotation": "a"
- },
- false
- ]
- },
- {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- false
- ]
- },
- {
- "Neg": {
- "Internal": {
- "id": 258869599717164329791616633222308956682,
- "annotation": "c"
- }
- }
- }
- ]
- }
- }
- ],
- "transition_constraints": [
- {
- "annotation": "(b == next(a))",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- false
- ]
- },
- {
- "Neg": {
- "Forward": [
- {
- "id": 258869580702405326369584955980151130634,
- "phase": 0,
- "annotation": "a"
- },
- true
- ]
- }
- }
- ]
- }
- },
- {
- "annotation": "(c == next(b))",
- "expr": {
- "Sum": [
- {
- "Internal": {
- "id": 258869599717164329791616633222308956682,
- "annotation": "c"
- }
- },
- {
- "Neg": {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- true
- ]
- }
- }
- ]
- }
- },
- {
- "annotation": "(n == next(n))",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869589417503202934383108674030275082,
- "phase": 0,
- "annotation": "n"
- },
- false
- ]
- },
- {
- "Neg": {
- "Forward": [
- {
- "id": 258869589417503202934383108674030275082,
- "phase": 0,
- "annotation": "n"
- },
- true
- ]
- }
- }
- ]
- }
- }
- ],
- "lookups": [],
- "annotations": {
- "258869599717164329791616633222308956682": "c"
- }
- },
- "258869628239302834927102989021255174666": {
- "id": 258869628239302834927102989021255174666,
- "name": "fibo_step",
- "signals": [
- {
- "id": 258869632200710960639812650790420089354,
- "annotation": "c"
- }
- ],
- "constraints": [
- {
- "annotation": "((a + b) == c)",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869580702405326369584955980151130634,
- "phase": 0,
- "annotation": "a"
- },
- false
- ]
- },
- {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- false
- ]
- },
- {
- "Neg": {
- "Internal": {
- "id": 258869632200710960639812650790420089354,
- "annotation": "c"
- }
- }
- }
- ]
- }
- }
- ],
- "transition_constraints": [
- {
- "annotation": "(b == next(a))",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- false
- ]
- },
- {
- "Neg": {
- "Forward": [
- {
- "id": 258869580702405326369584955980151130634,
- "phase": 0,
- "annotation": "a"
- },
- true
- ]
- }
- }
- ]
- }
- },
- {
- "annotation": "(c == next(b))",
- "expr": {
- "Sum": [
- {
- "Internal": {
- "id": 258869632200710960639812650790420089354,
- "annotation": "c"
- }
- },
- {
- "Neg": {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- true
- ]
- }
- }
- ]
- }
- },
- {
- "annotation": "(n == next(n))",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869589417503202934383108674030275082,
- "phase": 0,
- "annotation": "n"
- },
- false
- ]
- },
- {
- "Neg": {
- "Forward": [
- {
- "id": 258869589417503202934383108674030275082,
- "phase": 0,
- "annotation": "n"
- },
- true
- ]
- }
- }
- ]
- }
- }
- ],
- "lookups": [],
- "annotations": {
- "258869632200710960639812650790420089354": "c"
- }
- },
- "258869646461780213207493341245063432714": {
- "id": 258869646461780213207493341245063432714,
- "name": "padding",
- "signals": [],
- "constraints": [],
- "transition_constraints": [
- {
- "annotation": "(b == next(b))",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- false
- ]
- },
- {
- "Neg": {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- true
- ]
- }
- }
- ]
- }
- },
- {
- "annotation": "(n == next(n))",
- "expr": {
- "Sum": [
- {
- "Forward": [
- {
- "id": 258869589417503202934383108674030275082,
- "phase": 0,
- "annotation": "n"
- },
- false
- ]
- },
- {
- "Neg": {
- "Forward": [
- {
- "id": 258869589417503202934383108674030275082,
- "phase": 0,
- "annotation": "n"
- },
- true
- ]
- }
- }
- ]
- }
- }
- ],
- "lookups": [],
- "annotations": {}
- }
- },
- "forward_signals": [
- {
- "id": 258869580702405326369584955980151130634,
- "phase": 0,
- "annotation": "a"
- },
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- {
- "id": 258869589417503202934383108674030275082,
- "phase": 0,
- "annotation": "n"
- }
- ],
- "shared_signals": [],
- "fixed_signals": [],
- "exposed": [
- [
- {
- "Forward": [
- {
- "id": 258869587040658327507391136965088381450,
- "phase": 0,
- "annotation": "b"
- },
- false
- ]
- },
- {
- "Last": -1
- }
- ],
- [
- {
- "Forward": [
- {
- "id": 258869589417503202934383108674030275082,
- "phase": 0,
- "annotation": "n"
- },
- false
- ]
- },
- {
- "Last": -1
- }
- ]
- ],
- "annotations": {
- "258869580702405326369584955980151130634": "a",
- "258869587040658327507391136965088381450": "b",
- "258869589417503202934383108674030275082": "n",
- "258869595755756204079859764249309612554": "fibo_first_step",
- "258869628239302834927102989021255174666": "fibo_step",
- "258869646461780213207493341245063432714": "padding"
- },
- "fixed_assignments": null,
- "first_step": 258869595755756204079859764249309612554,
- "last_step": 258869646461780213207493341245063432714,
- "num_steps": 10,
- "q_enable": true,
- "id": 258867373405797678961444396351437277706
- }
- "#;
- let circuit: Circuit<Fr, ()> = serde_json::from_str(json).unwrap();
- println!("{:?}", circuit);
- }
-
- #[test]
- fn test_step_type() {
- let json = r#"
- {
- "id":1,
- "name":"fibo",
- "signals":[
- {
- "id":1,
- "annotation":"a"
- },
- {
- "id":2,
- "annotation":"b"
- }
- ],
- "constraints":[
- {
- "annotation":"constraint",
- "expr":{
- "Sum":[
- {
- "Const":[1, 0, 0, 0]
- },
- {
- "Mul":[
- {
- "Internal":{
- "id":3,
- "annotation":"c"
- }
- },
- {
- "Const":[3, 0, 0, 0]
- }
- ]
- }
- ]
- }
- },
- {
- "annotation":"constraint",
- "expr":{
- "Sum":[
- {
- "Const":[1, 0, 0, 0]
- },
- {
- "Mul":[
- {
- "Shared":[
- {
- "id":4,
- "phase":2,
- "annotation":"d"
- },
- 1
- ]
- },
- {
- "Const":[3, 0, 0, 0]
- }
- ]
- }
- ]
- }
- }
- ],
- "transition_constraints":[
- {
- "annotation":"trans",
- "expr":{
- "Sum":[
- {
- "Const":[1, 0, 0, 0]
- },
- {
- "Mul":[
- {
- "Forward":[
- {
- "id":5,
- "phase":1,
- "annotation":"e"
- },
- true
- ]
- },
- {
- "Const":[3, 0, 0, 0]
- }
- ]
- }
- ]
- }
- },
- {
- "annotation":"trans",
- "expr":{
- "Sum":[
- {
- "Const":[1, 0, 0, 0]
- },
- {
- "Mul":[
- {
- "Fixed":[
- {
- "id":6,
- "annotation":"e"
- },
- 2
- ]
- },
- {
- "Const":[3, 0, 0, 0]
- }
- ]
- }
- ]
- }
- }
- ],
- "lookups":[],
- "annotations":{
- "5":"a",
- "6":"b",
- "7":"c"
- }
- }
- "#;
- let step_type: StepType<Fr> = serde_json::from_str(json).unwrap();
- println!("{:?}", step_type);
- }
-
- #[test]
- fn test_constraint() {
- let json = r#"
- {"annotation": "constraint",
- "expr":
- {
- "Sum": [
- {
- "Internal": {
- "id": 27,
- "annotation": "a"
- }
- },
- {
- "Fixed": [
- {
- "id": 28,
- "annotation": "b"
- },
- 1
- ]
- },
- {
- "Shared": [
- {
- "id": 29,
- "phase": 1,
- "annotation": "c"
- },
- 2
- ]
- },
- {
- "Forward": [
- {
- "id": 30,
- "phase": 2,
- "annotation": "d"
- },
- true
- ]
- },
- {
- "StepTypeNext": {
- "id": 31,
- "annotation": "e"
- }
- },
- {
- "Const": [3, 0, 0, 0]
- },
- {
- "Mul": [
- {
- "Const": [4, 0, 0, 0]
- },
- {
- "Const": [5, 0, 0, 0]
- }
- ]
- },
- {
- "Neg": {
- "Const": [2, 0, 0, 0]
- }
- },
- {
- "Pow": [
- {
- "Const": [3, 0, 0, 0]
- },
- 4
- ]
- }
- ]
- }
- }"#;
- let constraint: Constraint<Fr> = serde_json::from_str(json).unwrap();
- println!("{:?}", constraint);
- let transition_constraint: TransitionConstraint<Fr> = serde_json::from_str(json).unwrap();
- println!("{:?}", transition_constraint);
- }
-
- #[test]
- fn test_expr() {
- let json = r#"
- {
- "Sum": [
- {
- "Internal": {
- "id": 27,
- "annotation": "a"
- }
- },
- {
- "Fixed": [
- {
- "id": 28,
- "annotation": "b"
- },
- 1
- ]
- },
- {
- "Shared": [
- {
- "id": 29,
- "phase": 1,
- "annotation": "c"
- },
- 2
- ]
- },
- {
- "Forward": [
- {
- "id": 30,
- "phase": 2,
- "annotation": "d"
- },
- true
- ]
- },
- {
- "StepTypeNext": {
- "id": 31,
- "annotation": "e"
- }
- },
- {
- "Const": [3, 0, 0, 0]
- },
- {
- "Mul": [
- {
- "Const": [4, 0, 0, 0]
- },
- {
- "Const": [5, 0, 0, 0]
- }
- ]
- },
- {
- "Neg": {
- "Const": [2, 0, 0, 0]
- }
- },
- {
- "Pow": [
- {
- "Const": [3, 0, 0, 0]
- },
- 4
- ]
- }
- ]
- }"#;
- let expr: Expr<Fr, Queriable<Fr>> = serde_json::from_str(json).unwrap();
- println!("{:?}", expr);
- }
-}
-
-#[pyfunction]
-fn convert_and_print_ast(json: &PyString) {
- let circuit: Circuit<Fr, ()> =
- serde_json::from_str(json.to_str().expect("PyString convertion failed."))
- .expect("Json deserialization to Circuit failed.");
- println!("{:?}", circuit);
-}
-
-#[pyfunction]
-fn convert_and_print_trace_witness(json: &PyString) {
- let trace_witness: TraceWitness<Fr> =
- serde_json::from_str(json.to_str().expect("PyString convertion failed."))
- .expect("Json deserialization to TraceWitness failed.");
- println!("{:?}", trace_witness);
-}
-
-#[pyfunction]
-fn ast_to_halo2(json: &PyString) -> u128 {
- let uuid = chiquito_ast_to_halo2(json.to_str().expect("PyString convertion failed."));
-
- uuid
-}
-
-#[pyfunction]
-fn ast_map_store(json: &PyString) -> u128 {
- let uuid = chiquito_ast_map_store(json.to_str().expect("PyString convertion failed."));
-
- uuid
-}
-
-#[pyfunction]
-fn halo2_mock_prover(witness_json: &PyString, rust_id: &PyLong, k: &PyLong) {
- chiquito_halo2_mock_prover(
- witness_json.to_str().expect("PyString convertion failed."),
- rust_id.extract().expect("PyLong convertion failed."),
- k.extract().expect("PyLong convertion failed."),
- );
-}
-
-#[pyfunction]
-fn super_circuit_halo2_mock_prover(rust_ids: &PyList, super_witness: &PyDict, k: &PyLong) {
- let uuids = rust_ids
- .iter()
- .map(|rust_id| {
- rust_id
- .downcast::<PyLong>()
- .expect("PyAny downcast failed.")
- .extract()
- .expect("PyLong convertion failed.")
- })
- .collect::<Vec<UUID>>();
-
- let super_witness = super_witness
- .iter()
- .map(|(key, value)| {
- (
- key.downcast::<PyLong>()
- .expect("PyAny downcast failed.")
- .extract()
- .expect("PyLong convertion failed."),
- value
- .downcast::<PyString>()
- .expect("PyAny downcast failed.")
- .to_str()
- .expect("PyString convertion failed."),
- )
- })
- .collect::<HashMap<u128, &str>>();
-
- chiquito_super_circuit_halo2_mock_prover(
- uuids,
- super_witness,
- k.extract().expect("PyLong convertion failed."),
- )
-}
-
-#[pymodule]
-fn rust_chiquito(_py: Python, m: &PyModule) -> PyResult<()> {
- m.add_function(wrap_pyfunction!(convert_and_print_ast, m)?)?;
- m.add_function(wrap_pyfunction!(convert_and_print_trace_witness, m)?)?;
- m.add_function(wrap_pyfunction!(ast_to_halo2, m)?)?;
- m.add_function(wrap_pyfunction!(ast_map_store, m)?)?;
- m.add_function(wrap_pyfunction!(halo2_mock_prover, m)?)?;
- m.add_function(wrap_pyfunction!(super_circuit_halo2_mock_prover, m)?)?;
- Ok(())
-}
-