From 9b7304fe8a6bf4ef3d39f9d4c502207a25e516a9 Mon Sep 17 00:00:00 2001 From: Steve Wang Date: Mon, 21 Aug 2023 17:06:28 +0800 Subject: [PATCH 1/2] added support for lookup and fixed gen; created mimc7 example --- examples/mimc7.py | 243 ++++++++++++++++++++++++++++++++ python/chiquito/cb.py | 16 ++- python/chiquito/chiquito_ast.py | 65 ++++++++- python/chiquito/dsl.py | 49 ++++--- python/chiquito/expr.py | 2 +- python/chiquito/lb.py | 101 +++++++++++++ python/chiquito/query.py | 2 +- python/chiquito/wit_gen.py | 13 +- src/chiquito | 2 +- 9 files changed, 451 insertions(+), 42 deletions(-) create mode 100644 examples/mimc7.py create mode 100644 python/chiquito/lb.py diff --git a/examples/mimc7.py b/examples/mimc7.py new file mode 100644 index 0000000..eec0651 --- /dev/null +++ b/examples/mimc7.py @@ -0,0 +1,243 @@ +from dsl import Circuit, StepType +from cb import eq, table +from util import F +from chiquito_ast import Last + +ROUNDS = 91 + + +class Mimc7Constants(Circuit): + def setup(self): + self.pragma_num_steps(ROUNDS) + self.lookup_row = self.fixed("constant row") + self.lookup_c = self.fixed("constant value") + self.new_table(table().add(self.lookup_row).add(self.lookup_c)) + + def fixed_gen(self): + for i, round_key in enumerate(ROUND_KEYS): + self.assign(self.lookup_row, F(i)) + self.assign(self.lookup_c, F(round_key)) + + +class Mimc7Circuit(Circuit): + def setup(self): + self.x = self.forward("x") + self.k = self.forward("k") + self.c = self.forward("c") + self.row = self.forward("row") + + self.mimc7_first_step = self.step_type(Mimc7FirstStep(self, "mimc7_first_step")) + self.mimc7_step = self.step_type(Mimc7Step(self, "mimc7_step")) + self.mimc7_last_step = self.step_type(Mimc7LastStep(self, "mimc7_last_step")) + + self.pragma_first_step(self.mimc7_first_step) + self.pragma_last_step(self.mimc7_last_step) + self.pragma_num_steps(ROUNDS + 2 - 1) + + def trace(self, args): + x_in_value, k_value = args + + c_value = ROUND_KEYS[0] + x_value = x_in_value + row_value = F(0) + + self.add(self.mimc7_first_step, (x_value, k_value, c_value, row_value)) + + for i in range(1, ROUND_KEYS): + row_value += F(1) + x_value += k_value + c_value + x_value = F(x_value ** 7) + c_value = F(ROUND_KEYS[i]) + + self.add(self.mimc_step, (x_value, k_value, c_value, row_value)) + + row_value += F(1) + x_value += k_value + c_value + x_value = F(x_value ** 7) + + self.add(self.mimc7_last_step, (x_value, k_value, c_value, row_value)) + +class Mimc7FirstStep(StepType): + def setup(self): + self.xkc = self.internal("xkc") + self.y = self.internal("y") + + self.constr(eq(self.circuit.x + self.circuit.k + self.circuit.c, self.xkc)) + self.constr( + eq( + self.xkc + * self.xkc + * self.xkc + * self.xkc + * self.xkc + * self.xkc + * self.xkc, + self.y, + ) + ) + + self.transition(eq(self.y, self.circuit.x.next())) + self.transition(eq(self.circuit.k, self.circuit.k.next())) + self.transition(eq(self.circuit.row, 0)) + self.transition(eq(self.circuit.row + 1, self.circuit.row.next())) + + self.add_lookup(constants.apply(self.circuit.row).apply(self.circuit.c)) + + def wg(self, args): + x_value, k_value, c_value, row_value = args + self.assign(self.circuit.x, F(x_value)) + self.assign(self.circuit.k, F(k_value)) + self.assign(self.circuit.c, F(c_value)) + self.assign(self.circuit.row, F(row_value)) + + xkc_value = x_value + k_value + c_value + self.assign(self.xkc, F(xkc_value)) + self.assign(self.y, F(xkc_value ** 7)) + +class Mimc7Step(StepType): + def setup(self): + self.xkc = self.internal("xkc") + self.y = self.internal("y") + + self.constr(eq(self.circuit.x + self.circuit.k + self.circuit.c, self.xkc)) + self.constr( + eq( + self.xkc + * self.xkc + * self.xkc + * self.xkc + * self.xkc + * self.xkc + * self.xkc, + self.y, + ) + ) + + self.transition(eq(self.y, self.circuit.x.next())) + self.transition(eq(self.circuit.k, self.circuit.k.next())) + self.transition(eq(self.circuit.row + 1, self.circuit.row.next())) + + self.add_lookup(constants.apply(self.circuit.row).apply(self.circuit.c)) + + def wg(self, args): + x_value, k_value, c_value, row_value = args + self.assign(self.circuit.x, F(x_value)) + self.assign(self.circuit.k, F(k_value)) + self.assign(self.circuit.c, F(c_value)) + self.assign(self.circuit.row, F(row_value)) + + xkc_value = x_value + k_value + c_value + self.assign(self.xkc, F(xkc_value)) + self.assign(self.y, F(xkc_value ** 7)) + +class Mimc7LastStep(StepType): + def setup(self): + self.out = self.internal("out") + + self.constr(eq(self.circuit.x + self.circuit.k, self.out)) + + def wg(self, args): + x_value, k_value, _, row_value = args + self.assign(self.circuit.x, F(x_value)) + self.assign(self.circuit.k, F(k_value)) + self.assign(self.circuit.row, F(row_value)) + self.assign(self.out, F(x_value + k_value)) + + +fibo = Fibonacci() +fibo_witness = fibo.gen_witness(7) +fibo.halo2_mock_prover(fibo_witness) + +ROUND_KEYS = [ + 0, + 20888961410941983456478427210666206549300505294776164667214940546594746570981, + 15265126113435022738560151911929040668591755459209400716467504685752745317193, + 8334177627492981984476504167502758309043212251641796197711684499645635709656, + 1374324219480165500871639364801692115397519265181803854177629327624133579404, + 11442588683664344394633565859260176446561886575962616332903193988751292992472, + 2558901189096558760448896669327086721003508630712968559048179091037845349145, + 11189978595292752354820141775598510151189959177917284797737745690127318076389, + 3262966573163560839685415914157855077211340576201936620532175028036746741754, + 17029914891543225301403832095880481731551830725367286980611178737703889171730, + 4614037031668406927330683909387957156531244689520944789503628527855167665518, + 19647356996769918391113967168615123299113119185942498194367262335168397100658, + 5040699236106090655289931820723926657076483236860546282406111821875672148900, + 2632385916954580941368956176626336146806721642583847728103570779270161510514, + 17691411851977575435597871505860208507285462834710151833948561098560743654671, + 11482807709115676646560379017491661435505951727793345550942389701970904563183, + 8360838254132998143349158726141014535383109403565779450210746881879715734773, + 12663821244032248511491386323242575231591777785787269938928497649288048289525, + 3067001377342968891237590775929219083706800062321980129409398033259904188058, + 8536471869378957766675292398190944925664113548202769136103887479787957959589, + 19825444354178182240559170937204690272111734703605805530888940813160705385792, + 16703465144013840124940690347975638755097486902749048533167980887413919317592, + 13061236261277650370863439564453267964462486225679643020432589226741411380501, + 10864774797625152707517901967943775867717907803542223029967000416969007792571, + 10035653564014594269791753415727486340557376923045841607746250017541686319774, + 3446968588058668564420958894889124905706353937375068998436129414772610003289, + 4653317306466493184743870159523234588955994456998076243468148492375236846006, + 8486711143589723036499933521576871883500223198263343024003617825616410932026, + 250710584458582618659378487568129931785810765264752039738223488321597070280, + 2104159799604932521291371026105311735948154964200596636974609406977292675173, + 16313562605837709339799839901240652934758303521543693857533755376563489378839, + 6032365105133504724925793806318578936233045029919447519826248813478479197288, + 14025118133847866722315446277964222215118620050302054655768867040006542798474, + 7400123822125662712777833064081316757896757785777291653271747396958201309118, + 1744432620323851751204287974553233986555641872755053103823939564833813704825, + 8316378125659383262515151597439205374263247719876250938893842106722210729522, + 6739722627047123650704294650168547689199576889424317598327664349670094847386, + 21211457866117465531949733809706514799713333930924902519246949506964470524162, + 13718112532745211817410303291774369209520657938741992779396229864894885156527, + 5264534817993325015357427094323255342713527811596856940387954546330728068658, + 18884137497114307927425084003812022333609937761793387700010402412840002189451, + 5148596049900083984813839872929010525572543381981952060869301611018636120248, + 19799686398774806587970184652860783461860993790013219899147141137827718662674, + 19240878651604412704364448729659032944342952609050243268894572835672205984837, + 10546185249390392695582524554167530669949955276893453512788278945742408153192, + 5507959600969845538113649209272736011390582494851145043668969080335346810411, + 18177751737739153338153217698774510185696788019377850245260475034576050820091, + 19603444733183990109492724100282114612026332366576932662794133334264283907557, + 10548274686824425401349248282213580046351514091431715597441736281987273193140, + 1823201861560942974198127384034483127920205835821334101215923769688644479957, + 11867589662193422187545516240823411225342068709600734253659804646934346124945, + 18718569356736340558616379408444812528964066420519677106145092918482774343613, + 10530777752259630125564678480897857853807637120039176813174150229243735996839, + 20486583726592018813337145844457018474256372770211860618687961310422228379031, + 12690713110714036569415168795200156516217175005650145422920562694422306200486, + 17386427286863519095301372413760745749282643730629659997153085139065756667205, + 2216432659854733047132347621569505613620980842043977268828076165669557467682, + 6309765381643925252238633914530877025934201680691496500372265330505506717193, + 20806323192073945401862788605803131761175139076694468214027227878952047793390, + 4037040458505567977365391535756875199663510397600316887746139396052445718861, + 19948974083684238245321361840704327952464170097132407924861169241740046562673, + 845322671528508199439318170916419179535949348988022948153107378280175750024, + 16222384601744433420585982239113457177459602187868460608565289920306145389382, + 10232118865851112229330353999139005145127746617219324244541194256766741433339, + 6699067738555349409504843460654299019000594109597429103342076743347235369120, + 6220784880752427143725783746407285094967584864656399181815603544365010379208, + 6129250029437675212264306655559561251995722990149771051304736001195288083309, + 10773245783118750721454994239248013870822765715268323522295722350908043393604, + 4490242021765793917495398271905043433053432245571325177153467194570741607167, + 19596995117319480189066041930051006586888908165330319666010398892494684778526, + 837850695495734270707668553360118467905109360511302468085569220634750561083, + 11803922811376367215191737026157445294481406304781326649717082177394185903907, + 10201298324909697255105265958780781450978049256931478989759448189112393506592, + 13564695482314888817576351063608519127702411536552857463682060761575100923924, + 9262808208636973454201420823766139682381973240743541030659775288508921362724, + 173271062536305557219323722062711383294158572562695717740068656098441040230, + 18120430890549410286417591505529104700901943324772175772035648111937818237369, + 20484495168135072493552514219686101965206843697794133766912991150184337935627, + 19155651295705203459475805213866664350848604323501251939850063308319753686505, + 11971299749478202793661982361798418342615500543489781306376058267926437157297, + 18285310723116790056148596536349375622245669010373674803854111592441823052978, + 7069216248902547653615508023941692395371990416048967468982099270925308100727, + 6465151453746412132599596984628739550147379072443683076388208843341824127379, + 16143532858389170960690347742477978826830511669766530042104134302796355145785, + 19362583304414853660976404410208489566967618125972377176980367224623492419647, + 1702213613534733786921602839210290505213503664731919006932367875629005980493, + 10781825404476535814285389902565833897646945212027592373510689209734812292327, + 4212716923652881254737947578600828255798948993302968210248673545442808456151, + 7594017890037021425366623750593200398174488805473151513558919864633711506220, + 18979889247746272055963929241596362599320706910852082477600815822482192194401, + 13602139229813231349386885113156901793661719180900395818909719758150455500533, +] diff --git a/python/chiquito/cb.py b/python/chiquito/cb.py index f6058b6..c801878 100644 --- a/python/chiquito/cb.py +++ b/python/chiquito/cb.py @@ -3,10 +3,11 @@ from enum import Enum, auto from typing import List -from chiquito.util import F -from chiquito.expr import Expr, Const, Neg, to_expr, ToExpr -from chiquito.query import StepTypeNext -from chiquito.chiquito_ast import ASTStepType +from util import F +from expr import Expr, Const, Neg, to_expr, ToExpr +from query import StepTypeNext +from chiquito_ast import ASTStepType +from lb import InPlaceLookupBuilder, LookupTable class Typing(Enum): @@ -197,7 +198,12 @@ def rlc(exprs: List[ToExpr], randomness: Expr) -> Expr: return Expr(Const(F(0))) -# TODO: Implement lookup table after the lookup abstraction PR is merged. +def lookup() -> InPlaceLookupBuilder: + return InPlaceLookupBuilder() + + +def table() -> LookupTable: + return LookupTable() ToConstraint = Constraint | Expr | int | F diff --git a/python/chiquito/chiquito_ast.py b/python/chiquito/chiquito_ast.py index 1fbbcf1..3117a5f 100644 --- a/python/chiquito/chiquito_ast.py +++ b/python/chiquito/chiquito_ast.py @@ -2,10 +2,10 @@ from typing import Callable, List, Dict, Optional, Tuple from dataclasses import dataclass, field, asdict -from chiquito.wit_gen import FixedGenContext -from chiquito.expr import Expr -from chiquito.util import uuid -from chiquito.query import Queriable +from wit_gen import FixedGenContext +from expr import Expr +from util import uuid +from query import Queriable # pub struct Circuit { @@ -173,6 +173,7 @@ class ASTStepType: signals: List[InternalSignal] constraints: List[ASTConstraint] transition_constraints: List[TransitionConstraint] + lookups: List[Lookup] annotations: Dict[int, str] def new(name: str) -> ASTStepType: @@ -200,6 +201,13 @@ def __str__(self): if self.transition_constraints else "" ) + lookups_str = ( + "\n\t\t\t\t" + + ",\n\t\t\t\t".join(str(lookup) for lookup in self.lookups) + + "\n\t\t\t" + if self.lookups + else "" + ) annotations_str = ( "\n\t\t\t\t" + ",\n\t\t\t\t".join(f"{k}: {v}" for k, v in self.annotations.items()) @@ -215,6 +223,7 @@ def __str__(self): f"\t\t\tsignals=[{signals_str}],\n" f"\t\t\tconstraints=[{constraints_str}],\n" f"\t\t\ttransition_constraints=[{transition_constraints_str}],\n" + f"\t\t\tlookups=[{lookups_str}],\n" f"\t\t\tannotations={{{annotations_str}}}\n" f"\t\t)" ) @@ -228,6 +237,7 @@ def __json__(self): "transition_constraints": [ x.__json__() for x in self.transition_constraints ], + "lookups": [x.__json__() for x in self.lookups], "annotations": self.annotations, } @@ -383,3 +393,50 @@ def __str__(self: InternalSignal): def __json__(self: InternalSignal): return asdict(self) + + +@dataclass +class Lookup: + annotation: str = "" + exprs: List[Tuple[ASTConstraint, Expr]] = field(default_factory=list) + enable: Optional[ASTConstraint] = None + + def add( + self: Lookup, + constraint_annotation: str, + constraint_expr: Expr, + expression: Expr, + ): + constraint = ASTConstraint(constraint_annotation, constraint_expr) + self.annotation += f"match({constraint.annotation} => {str(expression)}) " + if self.enable is None: + self.exprs.append((constraint, expression)) + else: + self.exprs.append( + (self.multiply_constraints(self.enable, constraint), expression) + ) + + def enable(self: Lookup, enable_annotation: str, enable_expr: Expr): + enable = ASTConstraint(enable_annotation, enable_expr) + if self.enable is None: + for constraint, _ in self.exprs: + constraint = self.multiply_constraints(enable, constraint) + self.enable = enable + self.annotation = f"if {enable_annotation}, {self.annotation}" + else: + raise ValueError("Lookup: enable() can only be called once.") + + def multiply_constraints( + enable: ASTConstraint, constraint: ASTConstraint + ) -> ASTConstraint: + return ASTConstraint(constraint.annotation, enable.expr * constraint.expr) + + def __str__(self: Lookup): + return f"Lookup({self.annotation})" + + def __json__(self: Lookup): + return { + "annotation": self.annotation, + "exprs": [[x.__json__(), y.__json__()] for (x, y) in self.exprs], + "enable": self.enable.__json__() if self.enable is not None else None, + } diff --git a/python/chiquito/dsl.py b/python/chiquito/dsl.py index 45be3ec..dd4e15b 100644 --- a/python/chiquito/dsl.py +++ b/python/chiquito/dsl.py @@ -1,29 +1,36 @@ from __future__ import annotations from enum import Enum from typing import Callable, Any +from chiquito import rust_chiquito # rust bindings import json -from chiquito.chiquito_ast import ASTCircuit, ASTStepType, ExposeOffset -from chiquito.query import Internal, Forward, Queriable, Shared, Fixed -from chiquito.wit_gen import FixedGenContext, StepInstance, TraceWitness -from chiquito.cb import Constraint, Typing, ToConstraint, to_constraint -from chiquito.util import CustomEncoder, F -from chiquito.rust_chiquito import ast_to_halo2, halo2_mock_prover +from chiquito_ast import ASTCircuit, ASTStepType, ExposeOffset +from query import Internal, Forward, Queriable, Shared, Fixed +from wit_gen import FixedGenContext, StepInstance, TraceWitness +from cb import Constraint, Typing, ToConstraint, to_constraint +from util import CustomEncoder, F +from lb import LookupTableRegistry, LookupTable, LookupTableBuilder, InPlaceLookupBuilder class CircuitMode(Enum): NoMode = 0 SETUP = 1 Trace = 2 + FixedGen = 3 class Circuit: def __init__(self: Circuit): self.ast = ASTCircuit() + self.tables = LookupTableRegistry() self.witness = TraceWitness() + self.fixed_assignments = FixedGenContext() self.rust_ast_id = 0 self.mode = CircuitMode.SETUP self.setup() + if hasattr(self, "fixed_gen") and callable(self.fixed_gen): + self.mode = CircuitMode.FixedGen + self.fixed_gen() def forward(self: Circuit, name: str) -> Forward: assert self.mode == CircuitMode.SETUP @@ -61,9 +68,6 @@ def step_type_def(self: StepType) -> StepType: assert self.mode == CircuitMode.SETUP self.ast.add_step_type_def() - def fixed_gen(self: Circuit, fixed_gen_def: Callable[[FixedGenContext], None]): - self.ast.set_fixed_gen(fixed_gen_def) - def pragma_first_step(self: Circuit, step_type: StepType) -> None: assert self.mode == CircuitMode.SETUP self.ast.first_step = step_type.step_type.id @@ -80,19 +84,21 @@ def pragma_disable_q_enable(self: Circuit) -> None: assert self.mode == CircuitMode.SETUP self.ast.q_enable = False + def new_table(self: Circuit, table: LookupTable) -> LookupTable: + assert self.mode == CircuitMode.SETUP + self.tables.add(table) + return table + + # called under trace() def add(self: Circuit, step_type: StepType, args: Any): assert self.mode == CircuitMode.Trace - if len(self.witness.step_instances) >= self.ast.num_steps: - raise ValueError(f"Number of step instances exceeds {self.ast.num_steps}") step_instance: StepInstance = step_type.gen_step_instance(args) self.witness.step_instances.append(step_instance) - def needs_padding(self: Circuit) -> bool: - return len(self.witness.step_instances) < self.ast.num_steps - - def padding(self: Circuit, step_type: StepType, args: Any): - while self.needs_padding(): - self.add(step_type, args) + # called under fixed_gen() + def assign(self: Circuit, offset: int, lhs: Queriable, rhs: F): + assert self.mode == CircuitMode.FixedGen + self.fixed_assignments.assign(offset, lhs, rhs) def gen_witness(self: Circuit, args: Any) -> TraceWitness: self.mode = CircuitMode.Trace @@ -109,9 +115,9 @@ def get_ast_json(self: Circuit) -> str: def halo2_mock_prover(self: Circuit, witness: TraceWitness): if self.rust_ast_id == 0: ast_json: str = self.get_ast_json() - self.rust_ast_id: int = ast_to_halo2(ast_json) + self.rust_ast_id: int = rust_chiquito.ast_to_halo2(ast_json) witness_json: str = witness.get_witness_json() - halo2_mock_prover(witness_json, self.rust_ast_id) + rust_chiquito.halo2_mock_prover(witness_json, self.rust_ast_id) def __str__(self: Circuit) -> str: return self.ast.__str__() @@ -169,4 +175,7 @@ def assign(self: StepType, lhs: Queriable, rhs: F): self.step_instance.assign(lhs, rhs) - # TODO: Implement add_lookup after lookup abstraction PR is merged. + def add_lookup(self: StepType, lookup_builder: LookupBuilder): + self.step_type.lookups.append(lookup_builder.build(self)) + +LookupBuilder = LookupTableBuilder | InPlaceLookupBuilder diff --git a/python/chiquito/expr.py b/python/chiquito/expr.py index 52f9936..32fd988 100644 --- a/python/chiquito/expr.py +++ b/python/chiquito/expr.py @@ -2,7 +2,7 @@ from typing import List from dataclasses import dataclass -from chiquito.util import F +from util import F # pub enum Expr { diff --git a/python/chiquito/lb.py b/python/chiquito/lb.py new file mode 100644 index 0000000..19ba7a1 --- /dev/null +++ b/python/chiquito/lb.py @@ -0,0 +1,101 @@ +from __future__ import annotations +from dataclasses import dataclass, field +from enum import Enum, auto +from typing import List, Dict, Optional + +from util import F, uuid +from expr import Expr, Const, Neg, to_expr, ToExpr +from query import StepTypeNext +from chiquito_ast import ASTStepType, Lookup +from cb import ToConstraint, to_constraint, Constraint + +# from dsl import Circuit, StepType + + +@dataclass +class LookupTableRegistry: + tables: Dict[int, LookupTable] = field(default_factory=dict) + + def add(self: LookupTableRegistry, table: LookupTable): + self.tables[table.uuid] = table + + def get(self: LookupTableRegistry, uuid: int) -> LookupTable: + return self.tables[uuid] + + +@dataclass +class LookupTable: + uuid: int = 0 + dest: List[Expr] = field(default_factory=list) + + def __init__(self: LookupTable): + self.uuid: int = uuid() + + def add(self: LookupTable, expr: ToExpr) -> LookupTable: + self.dest.append(to_expr(expr)) + return self + + def apply(self: LookupTable, constraint: ToConstraint) -> LookupTableBuilder: + return LookupTableBuilder(self.uuid).apply(constraint) + + def when(self: LookupTable, enable: ToConstraint) -> LookupTableBuilder: + return LookupTableBuilder(self.uuid).when(enable) + + +@dataclass +class LookupTableBuilder: + uuid: int + src: List[Constraint] = field(default_factory=list) + enable: Optional[Constraint] = None + + def __init__(self: LookupTableBuilder, uuid: int): + self.uuid: int = uuid + + def apply(self: LookupTableBuilder, constraint: ToConstraint) -> LookupTableBuilder: + self.src.append(to_constraint(constraint)) + return self + + def when(self: LookupTableBuilder, enable: ToConstraint) -> LookupTableBuilder: + if self.enable is not None: + raise ValueError("LookupTableBuilder: when() can only be called once.") + self.enable = to_constraint(enable) + return self + + def build(self: LookupTableBuilder, step_type: StepType) -> Lookup: + table = step_type.tables.get(self.id) + if self.src.len() != table.dest.len(): + raise ValueError( + "LookupTableBuilder: build() has different number of source columns and destination columns." + ) + + lookup = Lookup() + + if self.enable is not None: + lookup.enable(self.enable.annotation, self.enable.expr) + + for i in range(self.src.len()): + lookup.add(self.src[i].annotation, self.src[i].expr, table.dest[i]) + + return lookup + + +@dataclass +class InPlaceLookupBuilder: + lookup: Lookup = field(default_factory=Lookup) + + def build(self: InPlaceLookupBuilder, _: StepType) -> Lookup: + return self.lookup + + def add( + self: InPlaceLookupBuilder, constraint: ToConstraint, expression: ToExpr + ) -> InPlaceLookupBuilder: + constraint = to_constraint(constraint) + self.lookup.add(constraint.annotation, constraint.expr, to_expr(expression)) + return self + + def enable( + self: InPlaceLookupBuilder, enable: ToConstraint + ) -> InPlaceLookupBuilder: + enable = to_constraint(enable) + self.lookup.enable(enable.annotation, enable.expr) + return self diff --git a/python/chiquito/query.py b/python/chiquito/query.py index 9dafb6c..a4ff2b1 100644 --- a/python/chiquito/query.py +++ b/python/chiquito/query.py @@ -1,6 +1,6 @@ from __future__ import annotations -from chiquito.expr import Expr +from expr import Expr # Commented out to avoid circular reference # from chiquito_ast import InternalSignal, ForwardSignal, SharedSignal, FixedSignal, ASTStepType diff --git a/python/chiquito/wit_gen.py b/python/chiquito/wit_gen.py index 2b8af91..59817ca 100644 --- a/python/chiquito/wit_gen.py +++ b/python/chiquito/wit_gen.py @@ -3,8 +3,8 @@ from typing import Dict, List import json -from chiquito.query import Queriable, Fixed -from chiquito.util import F, CustomEncoder +from query import Queriable, Fixed +from util import F, CustomEncoder # Commented out to avoid circular reference # from dsl import Circuit, StepType @@ -106,17 +106,10 @@ def new(num_steps: int) -> FixedGenContext: return FixedGenContext({}, num_steps) def assign(self: FixedGenContext, offset: int, lhs: Queriable, rhs: F): - if not FixedGenContext.is_fixed_queriable(lhs): + if not isinstance(lhs, Fixed): raise ValueError(f"Cannot assign to non-fixed signal.") if lhs in self.assignments.keys(): self.assignments[lhs][offset] = rhs else: self.assignments[lhs] = [F.zero()] * self.num_steps self.assignments[lhs][offset] = rhs - - def is_fixed_queriable(q: Queriable) -> bool: - match q.enum: - case Fixed(_, _): - return True - case _: - return False diff --git a/src/chiquito b/src/chiquito index f6a4cb0..a18816d 160000 --- a/src/chiquito +++ b/src/chiquito @@ -1 +1 @@ -Subproject commit f6a4cb0f494d24ad6251bd13ba0d4064a42539a0 +Subproject commit a18816d2092c9788dba7610c0ba00fa0fce29e11 From 746e96c1a0c58d132436d6e71d894a73fa355933 Mon Sep 17 00:00:00 2001 From: Steve Wang Date: Mon, 21 Aug 2023 17:19:52 +0800 Subject: [PATCH 2/2] added offsets for fixed gen --- examples/mimc7.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/mimc7.py b/examples/mimc7.py index eec0651..84664b2 100644 --- a/examples/mimc7.py +++ b/examples/mimc7.py @@ -15,8 +15,8 @@ def setup(self): def fixed_gen(self): for i, round_key in enumerate(ROUND_KEYS): - self.assign(self.lookup_row, F(i)) - self.assign(self.lookup_c, F(round_key)) + self.assign(i, self.lookup_row, F(i)) + self.assign(i, self.lookup_c, F(round_key)) class Mimc7Circuit(Circuit):