Golf scores on ASAP7, a predictive 7 nm library: never fabricated, and like sky130's score it counts no wires. sky130, a real 130 nm process, is the default. How ASAP7 is scored, and its quirks.

Tasks / aes_sbox

AES S-box aes_sbox

The byte substitution of AES (FIPS 197): 8 bits in, 8 bits out.

open for submissions fixed size scored at the one fixed size

Par
3833µm²·nssbox_bp · 892.1 µm² × 4.30 ns
Record
2858µm²·nstower-shuffle · 890.9 µm² × 3.21 ns
Under par
−25%
Par
9.402µm²·nssbox_bp · 13.355 µm² × 0.704 ns
Record
7.458µm²·nstower-shuffle · 13.414 µm² × 0.556 ns
Under par
−21%

Score

ASAP7 · area × time · µm²·ns · lower is better
aes_sbox: the score of each entry by date3 entries by date (x) and score in µm²·ns (y); the line is the best score so far, the dashed line par, and 2 unproved baselines are labelled on the right. The table under the chart lists the same numbers.30004000500060007000800026 Oct2 Nov9 Novdate enteredscore (µm²·ns) · lower is bettersbox_table · baseline, not proved · Score: 7884 µm²·ns · Area: 3445.8 µm² · Delay: 2288 pssbox_bp_d16 · baseline, not proved · Score: 3494 µm²·ns · Area: 952.2 µm² · Delay: 3670 pspar: sbox_bp, 3833 µm²·nssbox_table7884 · not provedPAR3833 · provedsbox_bp_d163494 · not provedthe best score so farsbox_table · proved reference · 2026-10-31T17:41:41Z · Score: 7884 µm²·ns · Area: 3445.8 µm² · Delay: 2288 pssbox_bp · proved reference · par · 2026-10-30T22:46:45Z · Score: 3833 µm²·ns · Area: 892.1 µm² · Delay: 4297 pstower-shuffle · submission · 2026-11-05 · Score: 2858 µm²·ns · Area: 890.9 µm² · Delay: 3208 ps
aes_sbox: the score of each entry by date3 entries by date (x) and score in µm²·ns (y); the line is the best score so far, the dashed line par, and 2 unproved baselines are labelled on the right. The table under the chart lists the same numbers.40006000800026 Oct2 Nov9 Novdate enteredscore (µm²·ns) · lower is bettersbox_table · baseline, not proved · Score: 7884 µm²·ns · Area: 3445.8 µm² · Delay: 2288 pssbox_bp_d16 · baseline, not proved · Score: 3494 µm²·ns · Area: 952.2 µm² · Delay: 3670 pspar: sbox_bp, 3833 µm²·nsPARthe best score so farsbox_table · proved reference · 2026-10-31T17:41:41Z · Score: 7884 µm²·ns · Area: 3445.8 µm² · Delay: 2288 pssbox_bp · proved reference · par · 2026-10-30T22:46:45Z · Score: 3833 µm²·ns · Area: 892.1 µm² · Delay: 4297 pstower-shuffle · submission · 2026-11-05 · Score: 2858 µm²·ns · Area: 890.9 µm² · Delay: 3208 ps
  • submission
  • proved reference
  • the best score so far
  • par
  • a baseline's score (not proved)
Score = area × time: the sky130 cell area of the scored netlist in µm² times the critical-path delay in ns, from the pinned flow, so µm²·ns. Lower is better. It is the one ranked number: Par (the best proved reference's score, the bar to beat), Record (the best accepted score so far, par while no submission beats it), Under par (how far the record is below par, as a share of par's score) and the leaderboard use it. The Pareto front, area in GE (NAND2 gate equivalents), depth and the other numbers are for exploring, under compare the designs; reproduce a score says how to get the same numbers. Rated with Yosys 0.53 (git 53c22ab7, the Homebrew build for macOS arm64, clang++ 17, -O3) and its yosys-abc (ABC 1.01 of 6 May 2025): the flow is deterministic on that build (measured on 52 designs). Another build of the same version can break ABC's ties differently (measured: 3 fdivp designs, up to 2.9% in delay), so a number made on another platform may differ slightly: the build and its hashes. Dots are the entries by date; the proved references are the first entries, dated by when they joined the task. The dotted levels are baselines: scored, never proved.
every entry by date
datedesignkindscore (µm²·ns)area × time
2026-10-30sbox_bpproved reference · par3833892.1 µm² × 4.30 ns
2026-10-31sbox_tableproved reference78843445.8 µm² × 2.29 ns
2026-11-05tower-shufflesubmission2858890.9 µm² × 3.21 ns
–sbox_bp_d16baseline, not proved3494952.2 µm² × 3.67 ns
–sbox_tablebaseline, not proved78843445.8 µm² × 2.29 ns
aes_sbox: the score of each entry by date3 entries by date (x) and score in µm²·ns (y); the line is the best score so far, the dashed line par, and 2 unproved baselines are labelled on the right. The table under the chart lists the same numbers.7.51012.51517.52026 Oct2 Nov9 Novdate enteredscore (µm²·ns) · lower is bettersbox_table · baseline, not proved · Score: 19.33 µm²·ns · Area: 51.817 µm² · Delay: 373 pssbox_bp_d16 · baseline, not proved · Score: 8.931 µm²·ns · Area: 14.245 µm² · Delay: 627 pspar: sbox_bp, 9.402 µm²·nssbox_table19.33 · not provedPAR9.402 · provedsbox_bp_d168.931 · not provedthe best score so farsbox_table · proved reference · 2026-10-31T17:41:41Z · Score: 19.33 µm²·ns · Area: 51.817 µm² · Delay: 373 pssbox_bp · proved reference · par · 2026-10-30T22:46:45Z · Score: 9.402 µm²·ns · Area: 13.355 µm² · Delay: 704 pstower-shuffle · submission · 2026-11-05 · Score: 7.458 µm²·ns · Area: 13.414 µm² · Delay: 556 ps
aes_sbox: the score of each entry by date3 entries by date (x) and score in µm²·ns (y); the line is the best score so far, the dashed line par, and 2 unproved baselines are labelled on the right. The table under the chart lists the same numbers.10152026 Oct2 Nov9 Novdate enteredscore (µm²·ns) · lower is bettersbox_table · baseline, not proved · Score: 19.33 µm²·ns · Area: 51.817 µm² · Delay: 373 pssbox_bp_d16 · baseline, not proved · Score: 8.931 µm²·ns · Area: 14.245 µm² · Delay: 627 pspar: sbox_bp, 9.402 µm²·nsPARthe best score so farsbox_table · proved reference · 2026-10-31T17:41:41Z · Score: 19.33 µm²·ns · Area: 51.817 µm² · Delay: 373 pssbox_bp · proved reference · par · 2026-10-30T22:46:45Z · Score: 9.402 µm²·ns · Area: 13.355 µm² · Delay: 704 pstower-shuffle · submission · 2026-11-05 · Score: 7.458 µm²·ns · Area: 13.414 µm² · Delay: 556 ps
  • submission
  • proved reference
  • the best score so far
  • par
  • a baseline's score (not proved)
Score = area × time: the ASAP7 cell area of the scored netlist in µm² times the critical-path delay in ns, from the pinned flow, so µm²·ns. Lower is better. In this view Par (the best proved reference's score, the bar to beat), Record (the best accepted score so far, par while no submission beats it), Under par (how far the record is below par, as a share of par's score) and the leaderboard use it; the records' ranked score is sky130's, the default view. The Pareto front, area in GE (NAND2 gate equivalents), depth and the other numbers are for exploring, under compare the designs; reproduce a score says how to get the same numbers. ASAP7 view. These numbers are on ASAP7 (asap7sc7p5t), a predictive 7 nm library made for research: it has never been fabricated, so no chip can confirm them. Like sky130's score they count no wires. sky130, a real 130 nm process, is the default view (how ASAP7 is scored, and its quirks). Rated with Yosys 0.53 (git 53c22ab7, the Homebrew build for macOS arm64, clang++ 17, -O3) and its yosys-abc (ABC 1.01 of 6 May 2025): the flow is deterministic on that build (measured on 52 designs). Another build of the same version can break ABC's ties differently (measured: 3 fdivp designs, up to 2.9% in delay), so a number made on another platform may differ slightly: the build and its hashes. Dots are the entries by date; the proved references are the first entries, dated by when they joined the task. The dotted levels are baselines: scored, never proved.
every entry by date
datedesignkindscore (µm²·ns)area × time
2026-10-30sbox_bpproved reference · par9.40213.355 µm² × 0.704 ns
2026-10-31sbox_tableproved reference19.3351.817 µm² × 0.373 ns
2026-11-05tower-shufflesubmission7.45813.414 µm² × 0.556 ns
–sbox_bp_d16baseline, not proved8.93114.245 µm² × 0.627 ns
–sbox_tablebaseline, not proved19.3351.817 µm² × 0.373 ns

This text quotes sky130 numbers and compares the designs on sky130, the default library; the score, the boards and the charts of this page are on ASAP7, where the order of the designs can differ.

Compute the AES S-box (FIPS 197, Section 5.1.1): eight bits in, eight bits out, y = S(x). The statement defines S the way the standard does, algebraically (the multiplicative inverse in GF(2^8), then an affine map), so a lookup table and a gate network are judged against the same mathematics.

The task has one fixed size, bans no operator but the run-time / % ** every task bans, and its post-synthesis check covers all 256 inputs. The proved Boyar-Peralta 113-gate circuit has 892.1 µm² and a 4.30 ns critical path on sky130 (200.986 GE, depth 21), 3833 µm²·ns: par. The proved 256-entry table is almost four times larger and nearly twice as fast, 3445.8 µm² at 2.29 ns (786.894 GE, depth 11). The S-box is the most golfed Boolean function in cryptography, so the published circuits are strong comparison points.

Interface #

Write a module with exactly this header: port names, directions, widths and order matter, and so do the module's name and its parameters.

aes_sbox.sv
module aes_sbox (
  input  logic [7:0] x,
  output logic [7:0] y
);
portdirectionwidth (bits)
xinput8
youtput8

The trusted statement #

A proof must establish the task's trusted statement, the constant SvGolf.Tasks.AesSbox.Statement of Spec.lean (module tasks.aes_sbox.Spec). Below it is split into the properties a circuit must have, one card each: what the property guarantees in plain words, and its exact Lean text. Every proved reference has all of them. The last tab, what does not count, lists the designs the checker rejects.

Properties

A design meets the trusted statement exactly when it has all of the properties below. Lean checks that, together, they say exactly what the statement says, nothing less and nothing more (the theorem statement_iff_properties).

INTERFACEExactly these ports, in this order, with these widths.

The module has exactly the input port x (8 bits) and exactly the output port y (8 bits), with these widths, in this order. Nothing is missing and nothing is extra: an extra input could serve as a hidden mode pin, and the checker and the scoring tools drive and read the design by these names and widths.

Interface
/-- Exactly these ports, in this order, with these widths. -/
def Interface (d : Design2) : Prop :=
  inputPorts d = [("x", 8)] ∧ outputPorts d = [("y", 8)]
svgolf/tasks/aes_sbox/Properties.lean:17Open in code
UNCLOCKEDNo process runs at a clock edge (no always_ff, no always @(posedge …)).

No process of the design runs at a clock edge: no always_ff, no always @(posedge …), no asynchronous-reset block; only continuous assignments and always_comb blocks. The task is combinational, so it never needs one. The rule closes a gap between Lean's model of SystemVerilog, which the proof is about, and real tools: the model runs every clocked block once per cycle whatever its clock does, so a design that registers correct outputs on a clock nothing drives would look right there, while a simulator sees a clock that never ticks and synthesis removes the registers.

Unclocked
/-- No process runs at a clock edge (no `always_ff`, no `always @(posedge …)`). -/
def Unclocked (d : Design2) : Prop :=
  ∀ p ∈ d.processes.toList, p.isEdgePhase = false
svgolf/tasks/aes_sbox/Properties.lean:21Open in code
LOOP_FREENo combinational loop: the design lowers to continuous assigns (Design2.lowerComb) that are ranked (Acyclic): each reads only what lower-ranked ones write.

The design has no combinational loop: written as continuous assignments (each always_comb block becomes one), its processes can be ranked so that each reads only what lower-ranked ones write. A latch (an always_comb block that keeps a value on some path) is refused with it. Lean's model starts every signal at x and settles, so it would read a loop at one state, while a circuit powers up in any 0/1 state the loop can hold and keeps it; the rule removes that question instead of answering it. The ranking is of processes, not bits, so a process that reads a part of a signal it writes itself is refused too, even when no bit depends on itself: write such bits as separate assignments.

LoopFree
/-- No combinational loop: the design lowers to continuous assigns (`Design2.lowerComb`) that are
ranked (`Acyclic`): each reads only what lower-ranked ones write. -/
def LoopFree (d : Design2) : Prop :=
  ∃ d', d.lowerComb = some d' ∧ Acyclic d'
svgolf/tasks/aes_sbox/Properties.lean:25Open in code
TERMINATESUnder every schedule and every stimulus, the run completes.

Whatever order the simulator picks for processes that are ready at the same moment (the schedule), and whatever values the inputs take, simulating the design completes: every cycle settles. A combinational loop that oscillates fails this, and so does a design the tools could not read. It is also what gives the next property its teeth: that one is about completed runs, and a design with no completed run would satisfy it without computing anything.

Terminates
/-- Under every schedule and every stimulus, the run completes. -/
def Terminates (d : Design2) : Prop :=
  ∀ (σ : ScheduleOracle) (stim : List SvState), ∃ tr, Runs2 d σ stim tr
svgolf/tasks/aes_sbox/Properties.lean:30Open in code
COMPUTES_SBOXIn every completed run, every cycle whose stimulus drives x with a known value ends with y holding the AES S-box of x.

In every cycle in which the input x is driven with a known 0/1 value, the output y settles to S(x), the AES S-box of FIPS 197: the multiplicative inverse of x in GF(2^8) (with 0 mapped to 0) followed by the standard affine transformation. For example S(0x53) = 0xed, the standard's own worked example. The outputs must be fully known 0/1 values in every cycle of every run, whatever the earlier cycles were, so they cannot depend on history.

ComputesSbox
/-- In every completed run, every cycle whose stimulus drives `x` with a known value ends with
`y` holding the AES S-box of `x`. -/
def ComputesSbox (d : Design2) : Prop :=
  d ⊨₂ spec2 fun stim tr =>
    ∀ (c : Nat) (inputs st : SvState), stim[c]? = some inputs → tr[c]? = some st →
      ∀ (x : BitVec 8),
        HoldAll inputs [("x", 8)] (x, ()) →
        HoldAll st [("y", 8)] (sbox x, ())
svgolf/tasks/aes_sbox/Properties.lean:34Open in code

Definitions

The names the properties use, each with its Lean text. Trusted text is what a proof is about; a helper of Properties.lean is not trusted: Lean checks it as part of statement_iff_properties.

This task's trusted text

sboxSpec.leanThe AES S-box: affine (ginv x). Defined algebraically, as the standard defines it; the standard's 256-entry table is only a cross-check.
sbox
/-- **The AES S-box.** -/
def sbox (x : BitVec 8) : BitVec 8 := affine (ginv x)
svgolf/tasks/aes_sbox/Spec.lean:68Open in code
ginvSpec.leanThe multiplicative inverse in GF(2^8), computed as a^254 (0 for 0).
ginv
/-- The multiplicative inverse, `0` for `0`: `a^254 = a^2 * a^4 * ... * a^128` (the group has order 255). -/
def ginv (a : BitVec 8) : BitVec 8 :=
  let a2 := gmul a a
  let a4 := gmul a2 a2
  let a8 := gmul a4 a4
  let a16 := gmul a8 a8
  let a32 := gmul a16 a16
  let a64 := gmul a32 a32
  let a128 := gmul a64 a64
  gmul (gmul (gmul a2 a4) (gmul a8 a16)) (gmul (gmul a32 a64) a128)
svgolf/tasks/aes_sbox/Spec.lean:52Open in code
gmulSpec.leanMultiplication in GF(2^8) = GF(2)[x]/(x^8 + x^4 + x^3 + x + 1), by shift and add.
gmul
/-- Multiplication in GF(2^8) (FIPS 197, Section 4.2). -/
def gmul (a b : BitVec 8) : BitVec 8 := gmulAux 8 a b 0
svgolf/tasks/aes_sbox/Spec.lean:49Open in code
affineSpec.leanThe affine transformation of the standard: b XOR (b rotated left by 1, 2, 3 and 4) XOR 0x63.
affine
/-- The affine transformation of Section 5.1.1, Equations (5.3) and (5.4) of the 2023 edition:
`b'_i = b_i ^ b_(i+4) ^ b_(i+5) ^ b_(i+6) ^ b_(i+7) ^ c_i` with `c = 0x63` (indices mod 8). -/
def affine (b : BitVec 8) : BitVec 8 :=
  b ^^^ b.rotateLeft 1 ^^^ b.rotateLeft 2 ^^^ b.rotateLeft 3 ^^^ b.rotateLeft 4 ^^^ 0x63#8
svgolf/tasks/aes_sbox/Spec.lean:63Open in code
StatementSpec.leanThe trusted challenge statement that these properties restate, part by part.
Statement
/-- **The challenge statement** for the parameterless design `Submission.design.sem : Design2`. -/
abbrev Statement : LeanModels.Sv.Design2 → Prop := task.StatementFixed
svgolf/tasks/aes_sbox/Spec.lean:80Open in code
taskSpec.leanThe task as data: the parameter range, the ports at each parameter value, and the function the outputs must compute.
task
/-- The task: input `x : BitVec 8`, output `y = sbox x`. Fixed size (statement at `N = 0`). -/
def task : CombTask where
  inRange N := N = 0
  inputs _ := [("x", 8)]
  outputs _ := [("y", 8)]
  fn _ := fun (x, ()) => (sbox x, ())
svgolf/tasks/aes_sbox/Spec.lean:73Open in code

The shared trusted base

CombTask.SatisfiedAtTask.leanThe trusted form of a combinational statement at one parameter value: the interface, then no clock and termination, then the function.
SatisfiedAt
/-- The statement at one parameter value: interface; no clocked process, no
combinational loop and termination; function. Conjunct 2 is the triple
`Unclocked d ∧ LoopFree d ∧ Terminates2 d`. -/
def SatisfiedAt (N : Nat) (d : Design2) : Prop :=
  t.Interface N d ∧ (Unclocked d ∧ LoopFree d ∧ Terminates2 d) ∧ t.Computes N d
svgolf/SvGolf/Task.lean:262Open in code
inputPortsTask.leanThe design's input ports, each with its declared width, in declaration order.
inputPorts
/-- The input ports of `d` with their declared widths, in declaration order.
`instantiate2` lists the ports first, in port-list order. A declaration is
an input port iff its `isInput` flag is set. -/
def inputPorts (d : Design2) : List Sig :=
  d.decls.toList.filterMap fun dc => if dc.isInput then some (dc.name, dc.width) else none
svgolf/SvGolf/Task.lean:178Open in code
outputPortsTask.leanThe design's output ports, each with its declared width, in declaration order.
outputPorts
/-- The output ports of `d` with their declared widths, in declaration order.
A declaration is an output port iff its `isOutput` flag is set. -/
def outputPorts (d : Design2) : List Sig :=
  d.decls.toList.filterMap fun dc => if dc.isOutput then some (dc.name, dc.width) else none
svgolf/SvGolf/Task.lean:184Open in code
HoldAllTask.leanHoldAll st ports values: in the state st, every listed port holds its value as a known bit vector (no x, no z) of exactly the port's width.
HoldAll
/-- `HoldAll st sigs v`: in state `st`, every port `(n, w)` of `sigs` is bound
to the fully known `w`-bit vector that `v` assigns it. -/
def HoldAll (st : SvState) : (sigs : List Sig) → Vals (sigs.map Prod.snd) → Prop
  | [], _ => True
  | (n, _) :: sigs, v => SvState.lookup st n = some (LVec.ofBitVec v.1) ∧ HoldAll st sigs v.2
svgolf/SvGolf/Task.lean:197Open in code
⊨₂Spec2.leand ⊨₂ P: in every completed run of the design d, under every schedule and every stimulus, the stimulus and the trace satisfy P.
Models2
/-- `d ⊨₂ P` — for **every** legal schedule, every stimulus, and every
completed run (`Runs2`), the trace satisfies `P`. Introduce from a raw
∀-fuel fact with `Models2.of_run`; eliminate against a concrete run with
`Models2.run` / `Models2.runs`. Says nothing about whether runs complete —
pair it with `Terminates2`. -/
def Models2 (d : Design2) (P : TraceProp2) : Prop :=
  ∀ (σ : ScheduleOracle) (stim tr : List SvState), Runs2 d σ stim tr → P d stim tr

@[inherit_doc] scoped infix:50 " ⊨₂ " => Models2
LeanModels/Sv/Spec2.lean:141Open in code
spec2Spec2.leanTurns a property of a stimulus (one input entry per cycle) and a trace (one snapshot of every signal per cycle) into the form ⊨₂ takes.
spec2
/-- Lift a design-agnostic stimulus/trace predicate into `⊨₂`
(`d ⊨₂ spec2 fun stim tr => …`). -/
def spec2 (P : List SvState → List SvState → Prop) : TraceProp2 := fun _ stim tr => P stim tr
LeanModels/Sv/Spec2.lean:151Open in code
Runs2Spec2.leanRuns2 d σ stim tr: simulating d under the schedule σ on the stimulus stim completes, with the trace tr.
Runs2
/-- The fuel-abstracted Design2 run judgment: *some* fuel completes the run
of `d` under schedule `σ` and stimulus `stim` with trace `tr`. The only place
fuel appears in a Design2 spec. -/
def Runs2 (d : Design2) (σ : ScheduleOracle) (stim tr : List SvState) : Prop :=
  ∃ fuel, run2 d σ fuel stim = .ok tr
LeanModels/Sv/Spec2.lean:121Open in code
ScheduleOracleSemantics.leanA legal schedule: the order in which the simulator runs the processes that are ready at the same moment. The statement quantifies over all of them.
ScheduleOracle
/-- A legal schedule: at invocation `k`, orders the ready process list.
`choose_perm` is the legality proof — every invocation is a permutation of
the ready list — so `∀ σ : ScheduleOracle` ranges over exactly the legal
schedules. See the module docstring for the invocation-counter protocol. -/
structure ScheduleOracle where
  /-- Invocation counter and ready process indices in, execution order out. -/
  choose : Nat → List Nat → List Nat
  /-- Every invocation yields a permutation of the ready list. -/
  choose_perm : ∀ (k : Nat) (ready : List Nat), (choose k ready).Perm ready
LeanModels/Sv/Semantics.lean:151Open in code
Process2.isEdgePhaseSem2.leanTrue for the processes that run at the clock edge: always_ff, always @(posedge …) and asynchronous-reset blocks.
isEdgePhase
/-- Edge-phase processes: every posedge-clocked block, INCLUDING the
async-reset ones (the posedge fires with reset asserted too — the body's
reset branch is what holds the state, pin3 CYCLE 4). -/
def Process2.isEdgePhase : Process2 → Bool
  | .alwaysFF _ _ | .alwaysPlain _ _ | .alwaysFFR _ _ _ _ => true
  | _ => false
LeanModels/Sv/Sem2.lean:650Open in code

What does not count

Designs that try to score without meeting the statement (negatives), or that exploit a place where the proof's reading and the scored netlist could differ (attacks). The checker stops at the first stage that refuses; each design is listed with that stage.

Refused before any proof is tried

The checker's static stages read the text itself and refuse it: an operator the task bans, a construct that two tools read differently, an unknown (x or z) value that could arise, or a program the language forbids.

  • case_missing_x.sv (attack, stopped at source): A table that sends one input to a default of x, which Yosys may fill with any value.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      always_comb begin
        case (x)
          8'd0: y = 8'd99;
          8'd1: y = 8'd124;
          8'd2: y = 8'd119;
          8'd3: y = 8'd123;
          8'd4: y = 8'd242;
          8'd5: y = 8'd107;
          8'd6: y = 8'd111;
          8'd7: y = 8'd197;
          8'd8: y = 8'd48;
          8'd9: y = 8'd1;
          8'd10: y = 8'd103;
          8'd11: y = 8'd43;
          8'd12: y = 8'd254;
          8'd13: y = 8'd215;
          8'd14: y = 8'd171;
          8'd15: y = 8'd118;
          8'd16: y = 8'd202;
          8'd17: y = 8'd130;
          8'd18: y = 8'd201;
          8'd19: y = 8'd125;
          8'd20: y = 8'd250;
          8'd21: y = 8'd89;
          8'd22: y = 8'd71;
          8'd23: y = 8'd240;
          8'd24: y = 8'd173;
          8'd25: y = 8'd212;
          8'd26: y = 8'd162;
          8'd27: y = 8'd175;
          8'd28: y = 8'd156;
          8'd29: y = 8'd164;
          8'd30: y = 8'd114;
          8'd31: y = 8'd192;
          8'd32: y = 8'd183;
          8'd33: y = 8'd253;
          8'd34: y = 8'd147;
          8'd35: y = 8'd38;
          8'd36: y = 8'd54;
          8'd37: y = 8'd63;
          8'd38: y = 8'd247;
          8'd39: y = 8'd204;
          8'd40: y = 8'd52;
          8'd41: y = 8'd165;
          8'd42: y = 8'd229;
          8'd43: y = 8'd241;
          8'd44: y = 8'd113;
          8'd45: y = 8'd216;
          8'd46: y = 8'd49;
          8'd47: y = 8'd21;
          8'd48: y = 8'd4;
          8'd49: y = 8'd199;
          8'd50: y = 8'd35;
          8'd51: y = 8'd195;
          8'd52: y = 8'd24;
          8'd53: y = 8'd150;
          8'd54: y = 8'd5;
          8'd55: y = 8'd154;
          8'd56: y = 8'd7;
          8'd57: y = 8'd18;
          8'd58: y = 8'd128;
          8'd59: y = 8'd226;
          8'd60: y = 8'd235;
          8'd61: y = 8'd39;
          8'd62: y = 8'd178;
          8'd63: y = 8'd117;
          8'd64: y = 8'd9;
          8'd65: y = 8'd131;
          8'd66: y = 8'd44;
          8'd67: y = 8'd26;
          8'd68: y = 8'd27;
          8'd69: y = 8'd110;
          8'd70: y = 8'd90;
          8'd71: y = 8'd160;
          8'd72: y = 8'd82;
          8'd73: y = 8'd59;
          8'd74: y = 8'd214;
          8'd75: y = 8'd179;
          8'd76: y = 8'd41;
          8'd77: y = 8'd227;
          8'd78: y = 8'd47;
          8'd79: y = 8'd132;
          8'd80: y = 8'd83;
          8'd81: y = 8'd209;
          8'd82: y = 8'd0;
          8'd84: y = 8'd32;
          8'd85: y = 8'd252;
          8'd86: y = 8'd177;
          8'd87: y = 8'd91;
          8'd88: y = 8'd106;
          8'd89: y = 8'd203;
          8'd90: y = 8'd190;
          8'd91: y = 8'd57;
          8'd92: y = 8'd74;
          8'd93: y = 8'd76;
          8'd94: y = 8'd88;
          8'd95: y = 8'd207;
          8'd96: y = 8'd208;
          8'd97: y = 8'd239;
          8'd98: y = 8'd170;
          8'd99: y = 8'd251;
          8'd100: y = 8'd67;
          8'd101: y = 8'd77;
          8'd102: y = 8'd51;
          8'd103: y = 8'd133;
          8'd104: y = 8'd69;
          8'd105: y = 8'd249;
          8'd106: y = 8'd2;
          8'd107: y = 8'd127;
          8'd108: y = 8'd80;
          8'd109: y = 8'd60;
          8'd110: y = 8'd159;
          8'd111: y = 8'd168;
          8'd112: y = 8'd81;
          8'd113: y = 8'd163;
          8'd114: y = 8'd64;
          8'd115: y = 8'd143;
          8'd116: y = 8'd146;
          8'd117: y = 8'd157;
          8'd118: y = 8'd56;
          8'd119: y = 8'd245;
          8'd120: y = 8'd188;
          8'd121: y = 8'd182;
          8'd122: y = 8'd218;
          8'd123: y = 8'd33;
          8'd124: y = 8'd16;
          8'd125: y = 8'd255;
          8'd126: y = 8'd243;
          8'd127: y = 8'd210;
          8'd128: y = 8'd205;
          8'd129: y = 8'd12;
          8'd130: y = 8'd19;
          8'd131: y = 8'd236;
          8'd132: y = 8'd95;
          8'd133: y = 8'd151;
          8'd134: y = 8'd68;
          8'd135: y = 8'd23;
          8'd136: y = 8'd196;
          8'd137: y = 8'd167;
          8'd138: y = 8'd126;
          8'd139: y = 8'd61;
          8'd140: y = 8'd100;
          8'd141: y = 8'd93;
          8'd142: y = 8'd25;
          8'd143: y = 8'd115;
          8'd144: y = 8'd96;
          8'd145: y = 8'd129;
          8'd146: y = 8'd79;
          8'd147: y = 8'd220;
          8'd148: y = 8'd34;
          8'd149: y = 8'd42;
          8'd150: y = 8'd144;
          8'd151: y = 8'd136;
          8'd152: y = 8'd70;
          8'd153: y = 8'd238;
          8'd154: y = 8'd184;
          8'd155: y = 8'd20;
          8'd156: y = 8'd222;
          8'd157: y = 8'd94;
          8'd158: y = 8'd11;
          8'd159: y = 8'd219;
          8'd160: y = 8'd224;
          8'd161: y = 8'd50;
          8'd162: y = 8'd58;
          8'd163: y = 8'd10;
          8'd164: y = 8'd73;
          8'd165: y = 8'd6;
          8'd166: y = 8'd36;
          8'd167: y = 8'd92;
          8'd168: y = 8'd194;
          8'd169: y = 8'd211;
          8'd170: y = 8'd172;
          8'd171: y = 8'd98;
          8'd172: y = 8'd145;
          8'd173: y = 8'd149;
          8'd174: y = 8'd228;
          8'd175: y = 8'd121;
          8'd176: y = 8'd231;
          8'd177: y = 8'd200;
          8'd178: y = 8'd55;
          8'd179: y = 8'd109;
          8'd180: y = 8'd141;
          8'd181: y = 8'd213;
          8'd182: y = 8'd78;
          8'd183: y = 8'd169;
          8'd184: y = 8'd108;
          8'd185: y = 8'd86;
          8'd186: y = 8'd244;
          8'd187: y = 8'd234;
          8'd188: y = 8'd101;
          8'd189: y = 8'd122;
          8'd190: y = 8'd174;
          8'd191: y = 8'd8;
          8'd192: y = 8'd186;
          8'd193: y = 8'd120;
          8'd194: y = 8'd37;
          8'd195: y = 8'd46;
          8'd196: y = 8'd28;
          8'd197: y = 8'd166;
          8'd198: y = 8'd180;
          8'd199: y = 8'd198;
          8'd200: y = 8'd232;
          8'd201: y = 8'd221;
          8'd202: y = 8'd116;
          8'd203: y = 8'd31;
          8'd204: y = 8'd75;
          8'd205: y = 8'd189;
          8'd206: y = 8'd139;
          8'd207: y = 8'd138;
          8'd208: y = 8'd112;
          8'd209: y = 8'd62;
          8'd210: y = 8'd181;
          8'd211: y = 8'd102;
          8'd212: y = 8'd72;
          8'd213: y = 8'd3;
          8'd214: y = 8'd246;
          8'd215: y = 8'd14;
          8'd216: y = 8'd97;
          8'd217: y = 8'd53;
          8'd218: y = 8'd87;
          8'd219: y = 8'd185;
          8'd220: y = 8'd134;
          8'd221: y = 8'd193;
          8'd222: y = 8'd29;
          8'd223: y = 8'd158;
          8'd224: y = 8'd225;
          8'd225: y = 8'd248;
          8'd226: y = 8'd152;
          8'd227: y = 8'd17;
          8'd228: y = 8'd105;
          8'd229: y = 8'd217;
          8'd230: y = 8'd142;
          8'd231: y = 8'd148;
          8'd232: y = 8'd155;
          8'd233: y = 8'd30;
          8'd234: y = 8'd135;
          8'd235: y = 8'd233;
          8'd236: y = 8'd206;
          8'd237: y = 8'd85;
          8'd238: y = 8'd40;
          8'd239: y = 8'd223;
          8'd240: y = 8'd140;
          8'd241: y = 8'd161;
          8'd242: y = 8'd137;
          8'd243: y = 8'd13;
          8'd244: y = 8'd191;
          8'd245: y = 8'd230;
          8'd246: y = 8'd66;
          8'd247: y = 8'd104;
          8'd248: y = 8'd65;
          8'd249: y = 8'd153;
          8'd250: y = 8'd45;
          8'd251: y = 8'd15;
          8'd252: y = 8'd176;
          8'd253: y = 8'd84;
          8'd254: y = 8'd187;
          8'd255: y = 8'd22;
          default: y = 8'bx;
        endcase
      end
    endmodule
    
  • unique_case_partial.sv (attack, stopped at source): A unique case table missing one entry, which Yosys may then fill with any value.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      always_comb begin
        unique case (x)
          8'd0: y = 8'd99;
          8'd1: y = 8'd124;
          8'd2: y = 8'd119;
          8'd3: y = 8'd123;
          8'd4: y = 8'd242;
          8'd5: y = 8'd107;
          8'd6: y = 8'd111;
          8'd7: y = 8'd197;
          8'd8: y = 8'd48;
          8'd9: y = 8'd1;
          8'd10: y = 8'd103;
          8'd11: y = 8'd43;
          8'd12: y = 8'd254;
          8'd13: y = 8'd215;
          8'd14: y = 8'd171;
          8'd15: y = 8'd118;
          8'd16: y = 8'd202;
          8'd17: y = 8'd130;
          8'd18: y = 8'd201;
          8'd19: y = 8'd125;
          8'd20: y = 8'd250;
          8'd21: y = 8'd89;
          8'd22: y = 8'd71;
          8'd23: y = 8'd240;
          8'd24: y = 8'd173;
          8'd25: y = 8'd212;
          8'd26: y = 8'd162;
          8'd27: y = 8'd175;
          8'd28: y = 8'd156;
          8'd29: y = 8'd164;
          8'd30: y = 8'd114;
          8'd31: y = 8'd192;
          8'd32: y = 8'd183;
          8'd33: y = 8'd253;
          8'd34: y = 8'd147;
          8'd35: y = 8'd38;
          8'd36: y = 8'd54;
          8'd37: y = 8'd63;
          8'd38: y = 8'd247;
          8'd39: y = 8'd204;
          8'd40: y = 8'd52;
          8'd41: y = 8'd165;
          8'd42: y = 8'd229;
          8'd43: y = 8'd241;
          8'd44: y = 8'd113;
          8'd45: y = 8'd216;
          8'd46: y = 8'd49;
          8'd47: y = 8'd21;
          8'd48: y = 8'd4;
          8'd49: y = 8'd199;
          8'd50: y = 8'd35;
          8'd51: y = 8'd195;
          8'd52: y = 8'd24;
          8'd53: y = 8'd150;
          8'd54: y = 8'd5;
          8'd55: y = 8'd154;
          8'd56: y = 8'd7;
          8'd57: y = 8'd18;
          8'd58: y = 8'd128;
          8'd59: y = 8'd226;
          8'd60: y = 8'd235;
          8'd61: y = 8'd39;
          8'd62: y = 8'd178;
          8'd63: y = 8'd117;
          8'd64: y = 8'd9;
          8'd65: y = 8'd131;
          8'd66: y = 8'd44;
          8'd67: y = 8'd26;
          8'd68: y = 8'd27;
          8'd69: y = 8'd110;
          8'd70: y = 8'd90;
          8'd71: y = 8'd160;
          8'd72: y = 8'd82;
          8'd73: y = 8'd59;
          8'd74: y = 8'd214;
          8'd75: y = 8'd179;
          8'd76: y = 8'd41;
          8'd77: y = 8'd227;
          8'd78: y = 8'd47;
          8'd79: y = 8'd132;
          8'd80: y = 8'd83;
          8'd81: y = 8'd209;
          8'd82: y = 8'd0;
          8'd84: y = 8'd32;
          8'd85: y = 8'd252;
          8'd86: y = 8'd177;
          8'd87: y = 8'd91;
          8'd88: y = 8'd106;
          8'd89: y = 8'd203;
          8'd90: y = 8'd190;
          8'd91: y = 8'd57;
          8'd92: y = 8'd74;
          8'd93: y = 8'd76;
          8'd94: y = 8'd88;
          8'd95: y = 8'd207;
          8'd96: y = 8'd208;
          8'd97: y = 8'd239;
          8'd98: y = 8'd170;
          8'd99: y = 8'd251;
          8'd100: y = 8'd67;
          8'd101: y = 8'd77;
          8'd102: y = 8'd51;
          8'd103: y = 8'd133;
          8'd104: y = 8'd69;
          8'd105: y = 8'd249;
          8'd106: y = 8'd2;
          8'd107: y = 8'd127;
          8'd108: y = 8'd80;
          8'd109: y = 8'd60;
          8'd110: y = 8'd159;
          8'd111: y = 8'd168;
          8'd112: y = 8'd81;
          8'd113: y = 8'd163;
          8'd114: y = 8'd64;
          8'd115: y = 8'd143;
          8'd116: y = 8'd146;
          8'd117: y = 8'd157;
          8'd118: y = 8'd56;
          8'd119: y = 8'd245;
          8'd120: y = 8'd188;
          8'd121: y = 8'd182;
          8'd122: y = 8'd218;
          8'd123: y = 8'd33;
          8'd124: y = 8'd16;
          8'd125: y = 8'd255;
          8'd126: y = 8'd243;
          8'd127: y = 8'd210;
          8'd128: y = 8'd205;
          8'd129: y = 8'd12;
          8'd130: y = 8'd19;
          8'd131: y = 8'd236;
          8'd132: y = 8'd95;
          8'd133: y = 8'd151;
          8'd134: y = 8'd68;
          8'd135: y = 8'd23;
          8'd136: y = 8'd196;
          8'd137: y = 8'd167;
          8'd138: y = 8'd126;
          8'd139: y = 8'd61;
          8'd140: y = 8'd100;
          8'd141: y = 8'd93;
          8'd142: y = 8'd25;
          8'd143: y = 8'd115;
          8'd144: y = 8'd96;
          8'd145: y = 8'd129;
          8'd146: y = 8'd79;
          8'd147: y = 8'd220;
          8'd148: y = 8'd34;
          8'd149: y = 8'd42;
          8'd150: y = 8'd144;
          8'd151: y = 8'd136;
          8'd152: y = 8'd70;
          8'd153: y = 8'd238;
          8'd154: y = 8'd184;
          8'd155: y = 8'd20;
          8'd156: y = 8'd222;
          8'd157: y = 8'd94;
          8'd158: y = 8'd11;
          8'd159: y = 8'd219;
          8'd160: y = 8'd224;
          8'd161: y = 8'd50;
          8'd162: y = 8'd58;
          8'd163: y = 8'd10;
          8'd164: y = 8'd73;
          8'd165: y = 8'd6;
          8'd166: y = 8'd36;
          8'd167: y = 8'd92;
          8'd168: y = 8'd194;
          8'd169: y = 8'd211;
          8'd170: y = 8'd172;
          8'd171: y = 8'd98;
          8'd172: y = 8'd145;
          8'd173: y = 8'd149;
          8'd174: y = 8'd228;
          8'd175: y = 8'd121;
          8'd176: y = 8'd231;
          8'd177: y = 8'd200;
          8'd178: y = 8'd55;
          8'd179: y = 8'd109;
          8'd180: y = 8'd141;
          8'd181: y = 8'd213;
          8'd182: y = 8'd78;
          8'd183: y = 8'd169;
          8'd184: y = 8'd108;
          8'd185: y = 8'd86;
          8'd186: y = 8'd244;
          8'd187: y = 8'd234;
          8'd188: y = 8'd101;
          8'd189: y = 8'd122;
          8'd190: y = 8'd174;
          8'd191: y = 8'd8;
          8'd192: y = 8'd186;
          8'd193: y = 8'd120;
          8'd194: y = 8'd37;
          8'd195: y = 8'd46;
          8'd196: y = 8'd28;
          8'd197: y = 8'd166;
          8'd198: y = 8'd180;
          8'd199: y = 8'd198;
          8'd200: y = 8'd232;
          8'd201: y = 8'd221;
          8'd202: y = 8'd116;
          8'd203: y = 8'd31;
          8'd204: y = 8'd75;
          8'd205: y = 8'd189;
          8'd206: y = 8'd139;
          8'd207: y = 8'd138;
          8'd208: y = 8'd112;
          8'd209: y = 8'd62;
          8'd210: y = 8'd181;
          8'd211: y = 8'd102;
          8'd212: y = 8'd72;
          8'd213: y = 8'd3;
          8'd214: y = 8'd246;
          8'd215: y = 8'd14;
          8'd216: y = 8'd97;
          8'd217: y = 8'd53;
          8'd218: y = 8'd87;
          8'd219: y = 8'd185;
          8'd220: y = 8'd134;
          8'd221: y = 8'd193;
          8'd222: y = 8'd29;
          8'd223: y = 8'd158;
          8'd224: y = 8'd225;
          8'd225: y = 8'd248;
          8'd226: y = 8'd152;
          8'd227: y = 8'd17;
          8'd228: y = 8'd105;
          8'd229: y = 8'd217;
          8'd230: y = 8'd142;
          8'd231: y = 8'd148;
          8'd232: y = 8'd155;
          8'd233: y = 8'd30;
          8'd234: y = 8'd135;
          8'd235: y = 8'd233;
          8'd236: y = 8'd206;
          8'd237: y = 8'd85;
          8'd238: y = 8'd40;
          8'd239: y = 8'd223;
          8'd240: y = 8'd140;
          8'd241: y = 8'd161;
          8'd242: y = 8'd137;
          8'd243: y = 8'd13;
          8'd244: y = 8'd191;
          8'd245: y = 8'd230;
          8'd246: y = 8'd66;
          8'd247: y = 8'd104;
          8'd248: y = 8'd65;
          8'd249: y = 8'd153;
          8'd250: y = 8'd45;
          8'd251: y = 8'd15;
          8'd252: y = 8'd176;
          8'd253: y = 8'd84;
          8'd254: y = 8'd187;
          8'd255: y = 8'd22;
        endcase
      end
    endmodule
    
  • unique_zero_ge.sv (attack, stopped at source): A correct S-box followed by a unique case arm that never matches, which lets Yosys replace the output with a constant (0 GE).

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      logic [7:0] s;
      logic y4, tc5, tc12, tc20, tc26, t37, t27, t4, y10, t23, tc1, y5, t40, z8, t5, t25, z10, t3, y9, t30, y11, t15, y8, t0, tc18, t28, t1, t9, tc7, z17, y3, t45, y6, z5, y18, tc10, t43, t26, t41, t31, z12, t29, t36, z13, tc17, tc13, y15, z7, t13, t44, tc16, y17, z2, z16, t12, t11, z9, y14, y2, z6, tc21, t17, t6, t34, t35, y16, z3, t33, y20, t2, y13, t8, z0, t42, tc2, tc9, tc3, t24, t18, t21, z1, t10, tc11, z4, t7, t32, t39, y12, y21, tc8, t20, y7, t22, z11, z14, t19, t38, y1, y19, z15, tc14, t14, tc6, tc4, t16;
      assign y14 = x[4] ^ x[2];
      assign y13 = x[7] ^ x[1];
      assign y9 = x[7] ^ x[4];
      assign y8 = x[7] ^ x[2];
      assign t0 = x[6] ^ x[5];
      assign y1 = t0 ^ x[0];
      assign y4 = y1 ^ x[4];
      assign y12 = y13 ^ y14;
      assign y2 = y1 ^ x[7];
      assign y5 = y1 ^ x[1];
      assign y3 = y5 ^ y8;
      assign t1 = x[3] ^ y12;
      assign y15 = t1 ^ x[2];
      assign y20 = t1 ^ x[6];
      assign y6 = y15 ^ x[0];
      assign y10 = y15 ^ t0;
      assign y11 = y20 ^ y9;
      assign y7 = x[0] ^ y11;
      assign y17 = y10 ^ y11;
      assign y19 = y10 ^ y8;
      assign y16 = t0 ^ y11;
      assign y21 = y13 ^ y16;
      assign y18 = x[7] ^ y16;
      assign t2 = y12 & y15;
      assign t3 = y3 & y6;
      assign t4 = t3 ^ t2;
      assign t5 = y4 & x[0];
      assign t6 = t5 ^ t2;
      assign t7 = y13 & y16;
      assign t8 = y5 & y1;
      assign t9 = t8 ^ t7;
      assign t10 = y2 & y7;
      assign t11 = t10 ^ t7;
      assign t12 = y9 & y11;
      assign t13 = y14 & y17;
      assign t14 = t13 ^ t12;
      assign t15 = y8 & y10;
      assign t16 = t15 ^ t12;
      assign t17 = t4 ^ y20;
      assign t18 = t6 ^ t16;
      assign t19 = t9 ^ t14;
      assign t20 = t11 ^ t16;
      assign t21 = t17 ^ t14;
      assign t22 = t18 ^ y19;
      assign t23 = t19 ^ y21;
      assign t24 = t20 ^ y18;
      assign t25 = t21 ^ t22;
      assign t26 = t21 & t23;
      assign t27 = t24 ^ t26;
      assign t28 = t25 & t27;
      assign t29 = t28 ^ t22;
      assign t30 = t23 ^ t24;
      assign t31 = t22 ^ t26;
      assign t32 = t31 & t30;
      assign t33 = t32 ^ t24;
      assign t34 = t23 ^ t33;
      assign t35 = t27 ^ t33;
      assign t36 = t24 & t35;
      assign t37 = t36 ^ t34;
      assign t38 = t27 ^ t36;
      assign t39 = t29 & t38;
      assign t40 = t25 ^ t39;
      assign t41 = t40 ^ t37;
      assign t42 = t29 ^ t33;
      assign t43 = t29 ^ t40;
      assign t44 = t33 ^ t37;
      assign t45 = t42 ^ t41;
      assign z0 = t44 & y15;
      assign z1 = t37 & y6;
      assign z2 = t33 & x[0];
      assign z3 = t43 & y16;
      assign z4 = t40 & y1;
      assign z5 = t29 & y7;
      assign z6 = t42 & y11;
      assign z7 = t45 & y17;
      assign z8 = t41 & y10;
      assign z9 = t44 & y12;
      assign z10 = t37 & y3;
      assign z11 = t33 & y4;
      assign z12 = t43 & y13;
      assign z13 = t40 & y5;
      assign z14 = t29 & y2;
      assign z15 = t42 & y9;
      assign z16 = t45 & y14;
      assign z17 = t41 & y8;
      assign tc1 = z15 ^ z16;
      assign tc2 = z10 ^ tc1;
      assign tc3 = z9 ^ tc2;
      assign tc4 = z0 ^ z2;
      assign tc5 = z1 ^ z0;
      assign tc6 = z3 ^ z4;
      assign tc7 = z12 ^ tc4;
      assign tc8 = z7 ^ tc6;
      assign tc9 = z8 ^ tc7;
      assign tc10 = tc8 ^ tc9;
      assign tc11 = tc6 ^ tc5;
      assign tc12 = z3 ^ z5;
      assign tc13 = z13 ^ tc1;
      assign tc14 = tc4 ^ tc12;
      assign s[4] = tc3 ^ tc11;
      assign tc16 = z6 ^ tc8;
      assign tc17 = z14 ^ tc10;
      assign tc18 = tc13 ^ tc14;
      assign s[0] = z12 ^ tc18 ^ 1'b1;
      assign tc20 = z15 ^ tc16;
      assign tc21 = tc2 ^ z11;
      assign s[7] = tc3 ^ tc16;
      assign s[1] = tc10 ^ tc18 ^ 1'b1;
      assign s[3] = tc14 ^ s[4];
      assign s[6] = s[4] ^ tc16 ^ 1'b1;
      assign tc26 = tc17 ^ tc20;
      assign s[5] = tc26 ^ z17 ^ 1'b1;
      assign s[2] = tc21 ^ tc17;
      always_comb begin
        y = s;
        unique case (1'b1)
          (x[0] & ~x[0]): y = 8'd0;
        endcase
      end
    endmodule
    
  • x_default.sv (negative, stopped at source): A correct table with an unreachable default that assigns x.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      always_comb begin
        case (x)
          8'd0: y = 8'd99;
          8'd1: y = 8'd124;
          8'd2: y = 8'd119;
          8'd3: y = 8'd123;
          8'd4: y = 8'd242;
          8'd5: y = 8'd107;
          8'd6: y = 8'd111;
          8'd7: y = 8'd197;
          8'd8: y = 8'd48;
          8'd9: y = 8'd1;
          8'd10: y = 8'd103;
          8'd11: y = 8'd43;
          8'd12: y = 8'd254;
          8'd13: y = 8'd215;
          8'd14: y = 8'd171;
          8'd15: y = 8'd118;
          8'd16: y = 8'd202;
          8'd17: y = 8'd130;
          8'd18: y = 8'd201;
          8'd19: y = 8'd125;
          8'd20: y = 8'd250;
          8'd21: y = 8'd89;
          8'd22: y = 8'd71;
          8'd23: y = 8'd240;
          8'd24: y = 8'd173;
          8'd25: y = 8'd212;
          8'd26: y = 8'd162;
          8'd27: y = 8'd175;
          8'd28: y = 8'd156;
          8'd29: y = 8'd164;
          8'd30: y = 8'd114;
          8'd31: y = 8'd192;
          8'd32: y = 8'd183;
          8'd33: y = 8'd253;
          8'd34: y = 8'd147;
          8'd35: y = 8'd38;
          8'd36: y = 8'd54;
          8'd37: y = 8'd63;
          8'd38: y = 8'd247;
          8'd39: y = 8'd204;
          8'd40: y = 8'd52;
          8'd41: y = 8'd165;
          8'd42: y = 8'd229;
          8'd43: y = 8'd241;
          8'd44: y = 8'd113;
          8'd45: y = 8'd216;
          8'd46: y = 8'd49;
          8'd47: y = 8'd21;
          8'd48: y = 8'd4;
          8'd49: y = 8'd199;
          8'd50: y = 8'd35;
          8'd51: y = 8'd195;
          8'd52: y = 8'd24;
          8'd53: y = 8'd150;
          8'd54: y = 8'd5;
          8'd55: y = 8'd154;
          8'd56: y = 8'd7;
          8'd57: y = 8'd18;
          8'd58: y = 8'd128;
          8'd59: y = 8'd226;
          8'd60: y = 8'd235;
          8'd61: y = 8'd39;
          8'd62: y = 8'd178;
          8'd63: y = 8'd117;
          8'd64: y = 8'd9;
          8'd65: y = 8'd131;
          8'd66: y = 8'd44;
          8'd67: y = 8'd26;
          8'd68: y = 8'd27;
          8'd69: y = 8'd110;
          8'd70: y = 8'd90;
          8'd71: y = 8'd160;
          8'd72: y = 8'd82;
          8'd73: y = 8'd59;
          8'd74: y = 8'd214;
          8'd75: y = 8'd179;
          8'd76: y = 8'd41;
          8'd77: y = 8'd227;
          8'd78: y = 8'd47;
          8'd79: y = 8'd132;
          8'd80: y = 8'd83;
          8'd81: y = 8'd209;
          8'd82: y = 8'd0;
          8'd83: y = 8'd237;
          8'd84: y = 8'd32;
          8'd85: y = 8'd252;
          8'd86: y = 8'd177;
          8'd87: y = 8'd91;
          8'd88: y = 8'd106;
          8'd89: y = 8'd203;
          8'd90: y = 8'd190;
          8'd91: y = 8'd57;
          8'd92: y = 8'd74;
          8'd93: y = 8'd76;
          8'd94: y = 8'd88;
          8'd95: y = 8'd207;
          8'd96: y = 8'd208;
          8'd97: y = 8'd239;
          8'd98: y = 8'd170;
          8'd99: y = 8'd251;
          8'd100: y = 8'd67;
          8'd101: y = 8'd77;
          8'd102: y = 8'd51;
          8'd103: y = 8'd133;
          8'd104: y = 8'd69;
          8'd105: y = 8'd249;
          8'd106: y = 8'd2;
          8'd107: y = 8'd127;
          8'd108: y = 8'd80;
          8'd109: y = 8'd60;
          8'd110: y = 8'd159;
          8'd111: y = 8'd168;
          8'd112: y = 8'd81;
          8'd113: y = 8'd163;
          8'd114: y = 8'd64;
          8'd115: y = 8'd143;
          8'd116: y = 8'd146;
          8'd117: y = 8'd157;
          8'd118: y = 8'd56;
          8'd119: y = 8'd245;
          8'd120: y = 8'd188;
          8'd121: y = 8'd182;
          8'd122: y = 8'd218;
          8'd123: y = 8'd33;
          8'd124: y = 8'd16;
          8'd125: y = 8'd255;
          8'd126: y = 8'd243;
          8'd127: y = 8'd210;
          8'd128: y = 8'd205;
          8'd129: y = 8'd12;
          8'd130: y = 8'd19;
          8'd131: y = 8'd236;
          8'd132: y = 8'd95;
          8'd133: y = 8'd151;
          8'd134: y = 8'd68;
          8'd135: y = 8'd23;
          8'd136: y = 8'd196;
          8'd137: y = 8'd167;
          8'd138: y = 8'd126;
          8'd139: y = 8'd61;
          8'd140: y = 8'd100;
          8'd141: y = 8'd93;
          8'd142: y = 8'd25;
          8'd143: y = 8'd115;
          8'd144: y = 8'd96;
          8'd145: y = 8'd129;
          8'd146: y = 8'd79;
          8'd147: y = 8'd220;
          8'd148: y = 8'd34;
          8'd149: y = 8'd42;
          8'd150: y = 8'd144;
          8'd151: y = 8'd136;
          8'd152: y = 8'd70;
          8'd153: y = 8'd238;
          8'd154: y = 8'd184;
          8'd155: y = 8'd20;
          8'd156: y = 8'd222;
          8'd157: y = 8'd94;
          8'd158: y = 8'd11;
          8'd159: y = 8'd219;
          8'd160: y = 8'd224;
          8'd161: y = 8'd50;
          8'd162: y = 8'd58;
          8'd163: y = 8'd10;
          8'd164: y = 8'd73;
          8'd165: y = 8'd6;
          8'd166: y = 8'd36;
          8'd167: y = 8'd92;
          8'd168: y = 8'd194;
          8'd169: y = 8'd211;
          8'd170: y = 8'd172;
          8'd171: y = 8'd98;
          8'd172: y = 8'd145;
          8'd173: y = 8'd149;
          8'd174: y = 8'd228;
          8'd175: y = 8'd121;
          8'd176: y = 8'd231;
          8'd177: y = 8'd200;
          8'd178: y = 8'd55;
          8'd179: y = 8'd109;
          8'd180: y = 8'd141;
          8'd181: y = 8'd213;
          8'd182: y = 8'd78;
          8'd183: y = 8'd169;
          8'd184: y = 8'd108;
          8'd185: y = 8'd86;
          8'd186: y = 8'd244;
          8'd187: y = 8'd234;
          8'd188: y = 8'd101;
          8'd189: y = 8'd122;
          8'd190: y = 8'd174;
          8'd191: y = 8'd8;
          8'd192: y = 8'd186;
          8'd193: y = 8'd120;
          8'd194: y = 8'd37;
          8'd195: y = 8'd46;
          8'd196: y = 8'd28;
          8'd197: y = 8'd166;
          8'd198: y = 8'd180;
          8'd199: y = 8'd198;
          8'd200: y = 8'd232;
          8'd201: y = 8'd221;
          8'd202: y = 8'd116;
          8'd203: y = 8'd31;
          8'd204: y = 8'd75;
          8'd205: y = 8'd189;
          8'd206: y = 8'd139;
          8'd207: y = 8'd138;
          8'd208: y = 8'd112;
          8'd209: y = 8'd62;
          8'd210: y = 8'd181;
          8'd211: y = 8'd102;
          8'd212: y = 8'd72;
          8'd213: y = 8'd3;
          8'd214: y = 8'd246;
          8'd215: y = 8'd14;
          8'd216: y = 8'd97;
          8'd217: y = 8'd53;
          8'd218: y = 8'd87;
          8'd219: y = 8'd185;
          8'd220: y = 8'd134;
          8'd221: y = 8'd193;
          8'd222: y = 8'd29;
          8'd223: y = 8'd158;
          8'd224: y = 8'd225;
          8'd225: y = 8'd248;
          8'd226: y = 8'd152;
          8'd227: y = 8'd17;
          8'd228: y = 8'd105;
          8'd229: y = 8'd217;
          8'd230: y = 8'd142;
          8'd231: y = 8'd148;
          8'd232: y = 8'd155;
          8'd233: y = 8'd30;
          8'd234: y = 8'd135;
          8'd235: y = 8'd233;
          8'd236: y = 8'd206;
          8'd237: y = 8'd85;
          8'd238: y = 8'd40;
          8'd239: y = 8'd223;
          8'd240: y = 8'd140;
          8'd241: y = 8'd161;
          8'd242: y = 8'd137;
          8'd243: y = 8'd13;
          8'd244: y = 8'd191;
          8'd245: y = 8'd230;
          8'd246: y = 8'd66;
          8'd247: y = 8'd104;
          8'd248: y = 8'd65;
          8'd249: y = 8'd153;
          8'd250: y = 8'd45;
          8'd251: y = 8'd15;
          8'd252: y = 8'd176;
          8'd253: y = 8'd84;
          8'd254: y = 8'd187;
          8'd255: y = 8'd22;
          default: y = 8'bxxxxxxxx;
        endcase
      end
    endmodule
    
  • wrong_names.sv (negative, stopped at extract): The right circuit on ports named a and s instead of x and y.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] a, output logic [7:0] s);
      logic y4, tc5, tc12, tc20, tc26, t37, t27, t4, y10, t23, tc1, y5, t40, z8, t5, t25, z10, t3, y9, t30, y11, t15, y8, t0, tc18, t28, t1, t9, tc7, z17, y3, t45, y6, z5, y18, tc10, t43, t26, t41, t31, z12, t29, t36, z13, tc17, tc13, y15, z7, t13, t44, tc16, y17, z2, z16, t12, t11, z9, y14, y2, z6, tc21, t17, t6, t34, t35, y16, z3, t33, y20, t2, y13, t8, z0, t42, tc2, tc9, tc3, t24, t18, t21, z1, t10, tc11, z4, t7, t32, t39, y12, y21, tc8, t20, y7, t22, z11, z14, t19, t38, y1, y19, z15, tc14, t14, tc6, tc4, t16;
      assign y14 = a[4] ^ a[2];
      assign y13 = a[7] ^ a[1];
      assign y9 = a[7] ^ a[4];
      assign y8 = a[7] ^ a[2];
      assign t0 = a[6] ^ a[5];
      assign y1 = t0 ^ a[0];
      assign y4 = y1 ^ a[4];
      assign y12 = y13 ^ y14;
      assign y2 = y1 ^ a[7];
      assign y5 = y1 ^ a[1];
      assign y3 = y5 ^ y8;
      assign t1 = a[3] ^ y12;
      assign y15 = t1 ^ a[2];
      assign y20 = t1 ^ a[6];
      assign y6 = y15 ^ a[0];
      assign y10 = y15 ^ t0;
      assign y11 = y20 ^ y9;
      assign y7 = a[0] ^ y11;
      assign y17 = y10 ^ y11;
      assign y19 = y10 ^ y8;
      assign y16 = t0 ^ y11;
      assign y21 = y13 ^ y16;
      assign y18 = a[7] ^ y16;
      assign t2 = y12 & y15;
      assign t3 = y3 & y6;
      assign t4 = t3 ^ t2;
      assign t5 = y4 & a[0];
      assign t6 = t5 ^ t2;
      assign t7 = y13 & y16;
      assign t8 = y5 & y1;
      assign t9 = t8 ^ t7;
      assign t10 = y2 & y7;
      assign t11 = t10 ^ t7;
      assign t12 = y9 & y11;
      assign t13 = y14 & y17;
      assign t14 = t13 ^ t12;
      assign t15 = y8 & y10;
      assign t16 = t15 ^ t12;
      assign t17 = t4 ^ y20;
      assign t18 = t6 ^ t16;
      assign t19 = t9 ^ t14;
      assign t20 = t11 ^ t16;
      assign t21 = t17 ^ t14;
      assign t22 = t18 ^ y19;
      assign t23 = t19 ^ y21;
      assign t24 = t20 ^ y18;
      assign t25 = t21 ^ t22;
      assign t26 = t21 & t23;
      assign t27 = t24 ^ t26;
      assign t28 = t25 & t27;
      assign t29 = t28 ^ t22;
      assign t30 = t23 ^ t24;
      assign t31 = t22 ^ t26;
      assign t32 = t31 & t30;
      assign t33 = t32 ^ t24;
      assign t34 = t23 ^ t33;
      assign t35 = t27 ^ t33;
      assign t36 = t24 & t35;
      assign t37 = t36 ^ t34;
      assign t38 = t27 ^ t36;
      assign t39 = t29 & t38;
      assign t40 = t25 ^ t39;
      assign t41 = t40 ^ t37;
      assign t42 = t29 ^ t33;
      assign t43 = t29 ^ t40;
      assign t44 = t33 ^ t37;
      assign t45 = t42 ^ t41;
      assign z0 = t44 & y15;
      assign z1 = t37 & y6;
      assign z2 = t33 & a[0];
      assign z3 = t43 & y16;
      assign z4 = t40 & y1;
      assign z5 = t29 & y7;
      assign z6 = t42 & y11;
      assign z7 = t45 & y17;
      assign z8 = t41 & y10;
      assign z9 = t44 & y12;
      assign z10 = t37 & y3;
      assign z11 = t33 & y4;
      assign z12 = t43 & y13;
      assign z13 = t40 & y5;
      assign z14 = t29 & y2;
      assign z15 = t42 & y9;
      assign z16 = t45 & y14;
      assign z17 = t41 & y8;
      assign tc1 = z15 ^ z16;
      assign tc2 = z10 ^ tc1;
      assign tc3 = z9 ^ tc2;
      assign tc4 = z0 ^ z2;
      assign tc5 = z1 ^ z0;
      assign tc6 = z3 ^ z4;
      assign tc7 = z12 ^ tc4;
      assign tc8 = z7 ^ tc6;
      assign tc9 = z8 ^ tc7;
      assign tc10 = tc8 ^ tc9;
      assign tc11 = tc6 ^ tc5;
      assign tc12 = z3 ^ z5;
      assign tc13 = z13 ^ tc1;
      assign tc14 = tc4 ^ tc12;
      assign s[4] = tc3 ^ tc11;
      assign tc16 = z6 ^ tc8;
      assign tc17 = z14 ^ tc10;
      assign tc18 = tc13 ^ tc14;
      assign s[0] = z12 ^ tc18 ^ 1'b1;
      assign tc20 = z15 ^ tc16;
      assign tc21 = tc2 ^ z11;
      assign s[7] = tc3 ^ tc16;
      assign s[1] = tc10 ^ tc18 ^ 1'b1;
      assign s[3] = tc14 ^ s[4];
      assign s[6] = s[4] ^ tc16 ^ 1'b1;
      assign tc26 = tc17 ^ tc20;
      assign s[5] = tc26 ^ z17 ^ 1'b1;
      assign s[2] = tc21 ^ tc17;
    endmodule
    
  • case_missing_nodefault.sv (attack, stopped at banlist): A table missing one entry and its default, so synthesis infers a latch.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      always_comb begin
        case (x)
          8'd0: y = 8'd99;
          8'd1: y = 8'd124;
          8'd2: y = 8'd119;
          8'd3: y = 8'd123;
          8'd4: y = 8'd242;
          8'd5: y = 8'd107;
          8'd6: y = 8'd111;
          8'd7: y = 8'd197;
          8'd8: y = 8'd48;
          8'd9: y = 8'd1;
          8'd10: y = 8'd103;
          8'd11: y = 8'd43;
          8'd12: y = 8'd254;
          8'd13: y = 8'd215;
          8'd14: y = 8'd171;
          8'd15: y = 8'd118;
          8'd16: y = 8'd202;
          8'd17: y = 8'd130;
          8'd18: y = 8'd201;
          8'd19: y = 8'd125;
          8'd20: y = 8'd250;
          8'd21: y = 8'd89;
          8'd22: y = 8'd71;
          8'd23: y = 8'd240;
          8'd24: y = 8'd173;
          8'd25: y = 8'd212;
          8'd26: y = 8'd162;
          8'd27: y = 8'd175;
          8'd28: y = 8'd156;
          8'd29: y = 8'd164;
          8'd30: y = 8'd114;
          8'd31: y = 8'd192;
          8'd32: y = 8'd183;
          8'd33: y = 8'd253;
          8'd34: y = 8'd147;
          8'd35: y = 8'd38;
          8'd36: y = 8'd54;
          8'd37: y = 8'd63;
          8'd38: y = 8'd247;
          8'd39: y = 8'd204;
          8'd40: y = 8'd52;
          8'd41: y = 8'd165;
          8'd42: y = 8'd229;
          8'd43: y = 8'd241;
          8'd44: y = 8'd113;
          8'd45: y = 8'd216;
          8'd46: y = 8'd49;
          8'd47: y = 8'd21;
          8'd48: y = 8'd4;
          8'd49: y = 8'd199;
          8'd50: y = 8'd35;
          8'd51: y = 8'd195;
          8'd52: y = 8'd24;
          8'd53: y = 8'd150;
          8'd54: y = 8'd5;
          8'd55: y = 8'd154;
          8'd56: y = 8'd7;
          8'd57: y = 8'd18;
          8'd58: y = 8'd128;
          8'd59: y = 8'd226;
          8'd60: y = 8'd235;
          8'd61: y = 8'd39;
          8'd62: y = 8'd178;
          8'd63: y = 8'd117;
          8'd64: y = 8'd9;
          8'd65: y = 8'd131;
          8'd66: y = 8'd44;
          8'd67: y = 8'd26;
          8'd68: y = 8'd27;
          8'd69: y = 8'd110;
          8'd70: y = 8'd90;
          8'd71: y = 8'd160;
          8'd72: y = 8'd82;
          8'd73: y = 8'd59;
          8'd74: y = 8'd214;
          8'd75: y = 8'd179;
          8'd76: y = 8'd41;
          8'd77: y = 8'd227;
          8'd78: y = 8'd47;
          8'd79: y = 8'd132;
          8'd80: y = 8'd83;
          8'd81: y = 8'd209;
          8'd82: y = 8'd0;
          8'd84: y = 8'd32;
          8'd85: y = 8'd252;
          8'd86: y = 8'd177;
          8'd87: y = 8'd91;
          8'd88: y = 8'd106;
          8'd89: y = 8'd203;
          8'd90: y = 8'd190;
          8'd91: y = 8'd57;
          8'd92: y = 8'd74;
          8'd93: y = 8'd76;
          8'd94: y = 8'd88;
          8'd95: y = 8'd207;
          8'd96: y = 8'd208;
          8'd97: y = 8'd239;
          8'd98: y = 8'd170;
          8'd99: y = 8'd251;
          8'd100: y = 8'd67;
          8'd101: y = 8'd77;
          8'd102: y = 8'd51;
          8'd103: y = 8'd133;
          8'd104: y = 8'd69;
          8'd105: y = 8'd249;
          8'd106: y = 8'd2;
          8'd107: y = 8'd127;
          8'd108: y = 8'd80;
          8'd109: y = 8'd60;
          8'd110: y = 8'd159;
          8'd111: y = 8'd168;
          8'd112: y = 8'd81;
          8'd113: y = 8'd163;
          8'd114: y = 8'd64;
          8'd115: y = 8'd143;
          8'd116: y = 8'd146;
          8'd117: y = 8'd157;
          8'd118: y = 8'd56;
          8'd119: y = 8'd245;
          8'd120: y = 8'd188;
          8'd121: y = 8'd182;
          8'd122: y = 8'd218;
          8'd123: y = 8'd33;
          8'd124: y = 8'd16;
          8'd125: y = 8'd255;
          8'd126: y = 8'd243;
          8'd127: y = 8'd210;
          8'd128: y = 8'd205;
          8'd129: y = 8'd12;
          8'd130: y = 8'd19;
          8'd131: y = 8'd236;
          8'd132: y = 8'd95;
          8'd133: y = 8'd151;
          8'd134: y = 8'd68;
          8'd135: y = 8'd23;
          8'd136: y = 8'd196;
          8'd137: y = 8'd167;
          8'd138: y = 8'd126;
          8'd139: y = 8'd61;
          8'd140: y = 8'd100;
          8'd141: y = 8'd93;
          8'd142: y = 8'd25;
          8'd143: y = 8'd115;
          8'd144: y = 8'd96;
          8'd145: y = 8'd129;
          8'd146: y = 8'd79;
          8'd147: y = 8'd220;
          8'd148: y = 8'd34;
          8'd149: y = 8'd42;
          8'd150: y = 8'd144;
          8'd151: y = 8'd136;
          8'd152: y = 8'd70;
          8'd153: y = 8'd238;
          8'd154: y = 8'd184;
          8'd155: y = 8'd20;
          8'd156: y = 8'd222;
          8'd157: y = 8'd94;
          8'd158: y = 8'd11;
          8'd159: y = 8'd219;
          8'd160: y = 8'd224;
          8'd161: y = 8'd50;
          8'd162: y = 8'd58;
          8'd163: y = 8'd10;
          8'd164: y = 8'd73;
          8'd165: y = 8'd6;
          8'd166: y = 8'd36;
          8'd167: y = 8'd92;
          8'd168: y = 8'd194;
          8'd169: y = 8'd211;
          8'd170: y = 8'd172;
          8'd171: y = 8'd98;
          8'd172: y = 8'd145;
          8'd173: y = 8'd149;
          8'd174: y = 8'd228;
          8'd175: y = 8'd121;
          8'd176: y = 8'd231;
          8'd177: y = 8'd200;
          8'd178: y = 8'd55;
          8'd179: y = 8'd109;
          8'd180: y = 8'd141;
          8'd181: y = 8'd213;
          8'd182: y = 8'd78;
          8'd183: y = 8'd169;
          8'd184: y = 8'd108;
          8'd185: y = 8'd86;
          8'd186: y = 8'd244;
          8'd187: y = 8'd234;
          8'd188: y = 8'd101;
          8'd189: y = 8'd122;
          8'd190: y = 8'd174;
          8'd191: y = 8'd8;
          8'd192: y = 8'd186;
          8'd193: y = 8'd120;
          8'd194: y = 8'd37;
          8'd195: y = 8'd46;
          8'd196: y = 8'd28;
          8'd197: y = 8'd166;
          8'd198: y = 8'd180;
          8'd199: y = 8'd198;
          8'd200: y = 8'd232;
          8'd201: y = 8'd221;
          8'd202: y = 8'd116;
          8'd203: y = 8'd31;
          8'd204: y = 8'd75;
          8'd205: y = 8'd189;
          8'd206: y = 8'd139;
          8'd207: y = 8'd138;
          8'd208: y = 8'd112;
          8'd209: y = 8'd62;
          8'd210: y = 8'd181;
          8'd211: y = 8'd102;
          8'd212: y = 8'd72;
          8'd213: y = 8'd3;
          8'd214: y = 8'd246;
          8'd215: y = 8'd14;
          8'd216: y = 8'd97;
          8'd217: y = 8'd53;
          8'd218: y = 8'd87;
          8'd219: y = 8'd185;
          8'd220: y = 8'd134;
          8'd221: y = 8'd193;
          8'd222: y = 8'd29;
          8'd223: y = 8'd158;
          8'd224: y = 8'd225;
          8'd225: y = 8'd248;
          8'd226: y = 8'd152;
          8'd227: y = 8'd17;
          8'd228: y = 8'd105;
          8'd229: y = 8'd217;
          8'd230: y = 8'd142;
          8'd231: y = 8'd148;
          8'd232: y = 8'd155;
          8'd233: y = 8'd30;
          8'd234: y = 8'd135;
          8'd235: y = 8'd233;
          8'd236: y = 8'd206;
          8'd237: y = 8'd85;
          8'd238: y = 8'd40;
          8'd239: y = 8'd223;
          8'd240: y = 8'd140;
          8'd241: y = 8'd161;
          8'd242: y = 8'd137;
          8'd243: y = 8'd13;
          8'd244: y = 8'd191;
          8'd245: y = 8'd230;
          8'd246: y = 8'd66;
          8'd247: y = 8'd104;
          8'd248: y = 8'd65;
          8'd249: y = 8'd153;
          8'd250: y = 8'd45;
          8'd251: y = 8'd15;
          8'd252: y = 8'd176;
          8'd253: y = 8'd84;
          8'd254: y = 8'd187;
          8'd255: y = 8'd22;
        endcase
      end
    endmodule
    
  • undriven_bit.sv (negative, stopped at fourstate): Output bit y[0] is never assigned.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      logic y4, tc5, tc12, tc20, tc26, t37, t27, t4, y10, t23, tc1, y5, t40, z8, t5, t25, z10, t3, y9, t30, y11, t15, y8, t0, tc18, t28, t1, t9, tc7, z17, y3, t45, y6, z5, y18, tc10, t43, t26, t41, t31, z12, t29, t36, z13, tc17, tc13, y15, z7, t13, t44, tc16, y17, z2, z16, t12, t11, z9, y14, y2, z6, tc21, t17, t6, t34, t35, y16, z3, t33, y20, t2, y13, t8, z0, t42, tc2, tc9, tc3, t24, t18, t21, z1, t10, tc11, z4, t7, t32, t39, y12, y21, tc8, t20, y7, t22, z11, z14, t19, t38, y1, y19, z15, tc14, t14, tc6, tc4, t16;
      assign y14 = x[4] ^ x[2];
      assign y13 = x[7] ^ x[1];
      assign y9 = x[7] ^ x[4];
      assign y8 = x[7] ^ x[2];
      assign t0 = x[6] ^ x[5];
      assign y1 = t0 ^ x[0];
      assign y4 = y1 ^ x[4];
      assign y12 = y13 ^ y14;
      assign y2 = y1 ^ x[7];
      assign y5 = y1 ^ x[1];
      assign y3 = y5 ^ y8;
      assign t1 = x[3] ^ y12;
      assign y15 = t1 ^ x[2];
      assign y20 = t1 ^ x[6];
      assign y6 = y15 ^ x[0];
      assign y10 = y15 ^ t0;
      assign y11 = y20 ^ y9;
      assign y7 = x[0] ^ y11;
      assign y17 = y10 ^ y11;
      assign y19 = y10 ^ y8;
      assign y16 = t0 ^ y11;
      assign y21 = y13 ^ y16;
      assign y18 = x[7] ^ y16;
      assign t2 = y12 & y15;
      assign t3 = y3 & y6;
      assign t4 = t3 ^ t2;
      assign t5 = y4 & x[0];
      assign t6 = t5 ^ t2;
      assign t7 = y13 & y16;
      assign t8 = y5 & y1;
      assign t9 = t8 ^ t7;
      assign t10 = y2 & y7;
      assign t11 = t10 ^ t7;
      assign t12 = y9 & y11;
      assign t13 = y14 & y17;
      assign t14 = t13 ^ t12;
      assign t15 = y8 & y10;
      assign t16 = t15 ^ t12;
      assign t17 = t4 ^ y20;
      assign t18 = t6 ^ t16;
      assign t19 = t9 ^ t14;
      assign t20 = t11 ^ t16;
      assign t21 = t17 ^ t14;
      assign t22 = t18 ^ y19;
      assign t23 = t19 ^ y21;
      assign t24 = t20 ^ y18;
      assign t25 = t21 ^ t22;
      assign t26 = t21 & t23;
      assign t27 = t24 ^ t26;
      assign t28 = t25 & t27;
      assign t29 = t28 ^ t22;
      assign t30 = t23 ^ t24;
      assign t31 = t22 ^ t26;
      assign t32 = t31 & t30;
      assign t33 = t32 ^ t24;
      assign t34 = t23 ^ t33;
      assign t35 = t27 ^ t33;
      assign t36 = t24 & t35;
      assign t37 = t36 ^ t34;
      assign t38 = t27 ^ t36;
      assign t39 = t29 & t38;
      assign t40 = t25 ^ t39;
      assign t41 = t40 ^ t37;
      assign t42 = t29 ^ t33;
      assign t43 = t29 ^ t40;
      assign t44 = t33 ^ t37;
      assign t45 = t42 ^ t41;
      assign z0 = t44 & y15;
      assign z1 = t37 & y6;
      assign z2 = t33 & x[0];
      assign z3 = t43 & y16;
      assign z4 = t40 & y1;
      assign z5 = t29 & y7;
      assign z6 = t42 & y11;
      assign z7 = t45 & y17;
      assign z8 = t41 & y10;
      assign z9 = t44 & y12;
      assign z10 = t37 & y3;
      assign z11 = t33 & y4;
      assign z12 = t43 & y13;
      assign z13 = t40 & y5;
      assign z14 = t29 & y2;
      assign z15 = t42 & y9;
      assign z16 = t45 & y14;
      assign z17 = t41 & y8;
      assign tc1 = z15 ^ z16;
      assign tc2 = z10 ^ tc1;
      assign tc3 = z9 ^ tc2;
      assign tc4 = z0 ^ z2;
      assign tc5 = z1 ^ z0;
      assign tc6 = z3 ^ z4;
      assign tc7 = z12 ^ tc4;
      assign tc8 = z7 ^ tc6;
      assign tc9 = z8 ^ tc7;
      assign tc10 = tc8 ^ tc9;
      assign tc11 = tc6 ^ tc5;
      assign tc12 = z3 ^ z5;
      assign tc13 = z13 ^ tc1;
      assign tc14 = tc4 ^ tc12;
      assign y[4] = tc3 ^ tc11;
      assign tc16 = z6 ^ tc8;
      assign tc17 = z14 ^ tc10;
      assign tc18 = tc13 ^ tc14;
      assign tc20 = z15 ^ tc16;
      assign tc21 = tc2 ^ z11;
      assign y[7] = tc3 ^ tc16;
      assign y[1] = tc10 ^ tc18 ^ 1'b1;
      assign y[3] = tc14 ^ y[4];
      assign y[6] = y[4] ^ tc16 ^ 1'b1;
      assign tc26 = tc17 ^ tc20;
      assign y[5] = tc26 ^ z17 ^ 1'b1;
      assign y[2] = tc21 ^ tc17;
    endmodule
    
Rejected at the proof

These pass every static check. The proof that comes with each one does not compile, or does not prove the statement: a design that is wrong somewhere in the task's range (or has other ports) has no proof at all, and a proof that leaves a goal unproved is never accepted.

  • inverse_sbox.sv (negative, stopped at solution): The inverse S-box (the decryption table) instead of the S-box.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      always_comb begin
        case (x)
          8'd0: y = 8'd82;
          8'd1: y = 8'd9;
          8'd2: y = 8'd106;
          8'd3: y = 8'd213;
          8'd4: y = 8'd48;
          8'd5: y = 8'd54;
          8'd6: y = 8'd165;
          8'd7: y = 8'd56;
          8'd8: y = 8'd191;
          8'd9: y = 8'd64;
          8'd10: y = 8'd163;
          8'd11: y = 8'd158;
          8'd12: y = 8'd129;
          8'd13: y = 8'd243;
          8'd14: y = 8'd215;
          8'd15: y = 8'd251;
          8'd16: y = 8'd124;
          8'd17: y = 8'd227;
          8'd18: y = 8'd57;
          8'd19: y = 8'd130;
          8'd20: y = 8'd155;
          8'd21: y = 8'd47;
          8'd22: y = 8'd255;
          8'd23: y = 8'd135;
          8'd24: y = 8'd52;
          8'd25: y = 8'd142;
          8'd26: y = 8'd67;
          8'd27: y = 8'd68;
          8'd28: y = 8'd196;
          8'd29: y = 8'd222;
          8'd30: y = 8'd233;
          8'd31: y = 8'd203;
          8'd32: y = 8'd84;
          8'd33: y = 8'd123;
          8'd34: y = 8'd148;
          8'd35: y = 8'd50;
          8'd36: y = 8'd166;
          8'd37: y = 8'd194;
          8'd38: y = 8'd35;
          8'd39: y = 8'd61;
          8'd40: y = 8'd238;
          8'd41: y = 8'd76;
          8'd42: y = 8'd149;
          8'd43: y = 8'd11;
          8'd44: y = 8'd66;
          8'd45: y = 8'd250;
          8'd46: y = 8'd195;
          8'd47: y = 8'd78;
          8'd48: y = 8'd8;
          8'd49: y = 8'd46;
          8'd50: y = 8'd161;
          8'd51: y = 8'd102;
          8'd52: y = 8'd40;
          8'd53: y = 8'd217;
          8'd54: y = 8'd36;
          8'd55: y = 8'd178;
          8'd56: y = 8'd118;
          8'd57: y = 8'd91;
          8'd58: y = 8'd162;
          8'd59: y = 8'd73;
          8'd60: y = 8'd109;
          8'd61: y = 8'd139;
          8'd62: y = 8'd209;
          8'd63: y = 8'd37;
          8'd64: y = 8'd114;
          8'd65: y = 8'd248;
          8'd66: y = 8'd246;
          8'd67: y = 8'd100;
          8'd68: y = 8'd134;
          8'd69: y = 8'd104;
          8'd70: y = 8'd152;
          8'd71: y = 8'd22;
          8'd72: y = 8'd212;
          8'd73: y = 8'd164;
          8'd74: y = 8'd92;
          8'd75: y = 8'd204;
          8'd76: y = 8'd93;
          8'd77: y = 8'd101;
          8'd78: y = 8'd182;
          8'd79: y = 8'd146;
          8'd80: y = 8'd108;
          8'd81: y = 8'd112;
          8'd82: y = 8'd72;
          8'd83: y = 8'd80;
          8'd84: y = 8'd253;
          8'd85: y = 8'd237;
          8'd86: y = 8'd185;
          8'd87: y = 8'd218;
          8'd88: y = 8'd94;
          8'd89: y = 8'd21;
          8'd90: y = 8'd70;
          8'd91: y = 8'd87;
          8'd92: y = 8'd167;
          8'd93: y = 8'd141;
          8'd94: y = 8'd157;
          8'd95: y = 8'd132;
          8'd96: y = 8'd144;
          8'd97: y = 8'd216;
          8'd98: y = 8'd171;
          8'd99: y = 8'd0;
          8'd100: y = 8'd140;
          8'd101: y = 8'd188;
          8'd102: y = 8'd211;
          8'd103: y = 8'd10;
          8'd104: y = 8'd247;
          8'd105: y = 8'd228;
          8'd106: y = 8'd88;
          8'd107: y = 8'd5;
          8'd108: y = 8'd184;
          8'd109: y = 8'd179;
          8'd110: y = 8'd69;
          8'd111: y = 8'd6;
          8'd112: y = 8'd208;
          8'd113: y = 8'd44;
          8'd114: y = 8'd30;
          8'd115: y = 8'd143;
          8'd116: y = 8'd202;
          8'd117: y = 8'd63;
          8'd118: y = 8'd15;
          8'd119: y = 8'd2;
          8'd120: y = 8'd193;
          8'd121: y = 8'd175;
          8'd122: y = 8'd189;
          8'd123: y = 8'd3;
          8'd124: y = 8'd1;
          8'd125: y = 8'd19;
          8'd126: y = 8'd138;
          8'd127: y = 8'd107;
          8'd128: y = 8'd58;
          8'd129: y = 8'd145;
          8'd130: y = 8'd17;
          8'd131: y = 8'd65;
          8'd132: y = 8'd79;
          8'd133: y = 8'd103;
          8'd134: y = 8'd220;
          8'd135: y = 8'd234;
          8'd136: y = 8'd151;
          8'd137: y = 8'd242;
          8'd138: y = 8'd207;
          8'd139: y = 8'd206;
          8'd140: y = 8'd240;
          8'd141: y = 8'd180;
          8'd142: y = 8'd230;
          8'd143: y = 8'd115;
          8'd144: y = 8'd150;
          8'd145: y = 8'd172;
          8'd146: y = 8'd116;
          8'd147: y = 8'd34;
          8'd148: y = 8'd231;
          8'd149: y = 8'd173;
          8'd150: y = 8'd53;
          8'd151: y = 8'd133;
          8'd152: y = 8'd226;
          8'd153: y = 8'd249;
          8'd154: y = 8'd55;
          8'd155: y = 8'd232;
          8'd156: y = 8'd28;
          8'd157: y = 8'd117;
          8'd158: y = 8'd223;
          8'd159: y = 8'd110;
          8'd160: y = 8'd71;
          8'd161: y = 8'd241;
          8'd162: y = 8'd26;
          8'd163: y = 8'd113;
          8'd164: y = 8'd29;
          8'd165: y = 8'd41;
          8'd166: y = 8'd197;
          8'd167: y = 8'd137;
          8'd168: y = 8'd111;
          8'd169: y = 8'd183;
          8'd170: y = 8'd98;
          8'd171: y = 8'd14;
          8'd172: y = 8'd170;
          8'd173: y = 8'd24;
          8'd174: y = 8'd190;
          8'd175: y = 8'd27;
          8'd176: y = 8'd252;
          8'd177: y = 8'd86;
          8'd178: y = 8'd62;
          8'd179: y = 8'd75;
          8'd180: y = 8'd198;
          8'd181: y = 8'd210;
          8'd182: y = 8'd121;
          8'd183: y = 8'd32;
          8'd184: y = 8'd154;
          8'd185: y = 8'd219;
          8'd186: y = 8'd192;
          8'd187: y = 8'd254;
          8'd188: y = 8'd120;
          8'd189: y = 8'd205;
          8'd190: y = 8'd90;
          8'd191: y = 8'd244;
          8'd192: y = 8'd31;
          8'd193: y = 8'd221;
          8'd194: y = 8'd168;
          8'd195: y = 8'd51;
          8'd196: y = 8'd136;
          8'd197: y = 8'd7;
          8'd198: y = 8'd199;
          8'd199: y = 8'd49;
          8'd200: y = 8'd177;
          8'd201: y = 8'd18;
          8'd202: y = 8'd16;
          8'd203: y = 8'd89;
          8'd204: y = 8'd39;
          8'd205: y = 8'd128;
          8'd206: y = 8'd236;
          8'd207: y = 8'd95;
          8'd208: y = 8'd96;
          8'd209: y = 8'd81;
          8'd210: y = 8'd127;
          8'd211: y = 8'd169;
          8'd212: y = 8'd25;
          8'd213: y = 8'd181;
          8'd214: y = 8'd74;
          8'd215: y = 8'd13;
          8'd216: y = 8'd45;
          8'd217: y = 8'd229;
          8'd218: y = 8'd122;
          8'd219: y = 8'd159;
          8'd220: y = 8'd147;
          8'd221: y = 8'd201;
          8'd222: y = 8'd156;
          8'd223: y = 8'd239;
          8'd224: y = 8'd160;
          8'd225: y = 8'd224;
          8'd226: y = 8'd59;
          8'd227: y = 8'd77;
          8'd228: y = 8'd174;
          8'd229: y = 8'd42;
          8'd230: y = 8'd245;
          8'd231: y = 8'd176;
          8'd232: y = 8'd200;
          8'd233: y = 8'd235;
          8'd234: y = 8'd187;
          8'd235: y = 8'd60;
          8'd236: y = 8'd131;
          8'd237: y = 8'd83;
          8'd238: y = 8'd153;
          8'd239: y = 8'd97;
          8'd240: y = 8'd23;
          8'd241: y = 8'd43;
          8'd242: y = 8'd4;
          8'd243: y = 8'd126;
          8'd244: y = 8'd186;
          8'd245: y = 8'd119;
          8'd246: y = 8'd214;
          8'd247: y = 8'd38;
          8'd248: y = 8'd225;
          8'd249: y = 8'd105;
          8'd250: y = 8'd20;
          8'd251: y = 8'd99;
          8'd252: y = 8'd85;
          8'd253: y = 8'd33;
          8'd254: y = 8'd12;
          8'd255: y = 8'd125;
          default: y = 8'd0;
        endcase
      end
    endmodule
    
  • no_constant.sv (negative, stopped at solution): Forgets the affine constant 0x63, so every output is off by that XOR.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      logic y4, tc5, tc12, tc20, tc26, t37, t27, t4, y10, t23, tc1, y5, t40, z8, t5, t25, z10, t3, y9, t30, y11, t15, y8, t0, tc18, t28, t1, t9, tc7, z17, y3, t45, y6, z5, y18, tc10, t43, t26, t41, t31, z12, t29, t36, z13, tc17, tc13, y15, z7, t13, t44, tc16, y17, z2, z16, t12, t11, z9, y14, y2, z6, tc21, t17, t6, t34, t35, y16, z3, t33, y20, t2, y13, t8, z0, t42, tc2, tc9, tc3, t24, t18, t21, z1, t10, tc11, z4, t7, t32, t39, y12, y21, tc8, t20, y7, t22, z11, z14, t19, t38, y1, y19, z15, tc14, t14, tc6, tc4, t16;
      assign y14 = x[4] ^ x[2];
      assign y13 = x[7] ^ x[1];
      assign y9 = x[7] ^ x[4];
      assign y8 = x[7] ^ x[2];
      assign t0 = x[6] ^ x[5];
      assign y1 = t0 ^ x[0];
      assign y4 = y1 ^ x[4];
      assign y12 = y13 ^ y14;
      assign y2 = y1 ^ x[7];
      assign y5 = y1 ^ x[1];
      assign y3 = y5 ^ y8;
      assign t1 = x[3] ^ y12;
      assign y15 = t1 ^ x[2];
      assign y20 = t1 ^ x[6];
      assign y6 = y15 ^ x[0];
      assign y10 = y15 ^ t0;
      assign y11 = y20 ^ y9;
      assign y7 = x[0] ^ y11;
      assign y17 = y10 ^ y11;
      assign y19 = y10 ^ y8;
      assign y16 = t0 ^ y11;
      assign y21 = y13 ^ y16;
      assign y18 = x[7] ^ y16;
      assign t2 = y12 & y15;
      assign t3 = y3 & y6;
      assign t4 = t3 ^ t2;
      assign t5 = y4 & x[0];
      assign t6 = t5 ^ t2;
      assign t7 = y13 & y16;
      assign t8 = y5 & y1;
      assign t9 = t8 ^ t7;
      assign t10 = y2 & y7;
      assign t11 = t10 ^ t7;
      assign t12 = y9 & y11;
      assign t13 = y14 & y17;
      assign t14 = t13 ^ t12;
      assign t15 = y8 & y10;
      assign t16 = t15 ^ t12;
      assign t17 = t4 ^ y20;
      assign t18 = t6 ^ t16;
      assign t19 = t9 ^ t14;
      assign t20 = t11 ^ t16;
      assign t21 = t17 ^ t14;
      assign t22 = t18 ^ y19;
      assign t23 = t19 ^ y21;
      assign t24 = t20 ^ y18;
      assign t25 = t21 ^ t22;
      assign t26 = t21 & t23;
      assign t27 = t24 ^ t26;
      assign t28 = t25 & t27;
      assign t29 = t28 ^ t22;
      assign t30 = t23 ^ t24;
      assign t31 = t22 ^ t26;
      assign t32 = t31 & t30;
      assign t33 = t32 ^ t24;
      assign t34 = t23 ^ t33;
      assign t35 = t27 ^ t33;
      assign t36 = t24 & t35;
      assign t37 = t36 ^ t34;
      assign t38 = t27 ^ t36;
      assign t39 = t29 & t38;
      assign t40 = t25 ^ t39;
      assign t41 = t40 ^ t37;
      assign t42 = t29 ^ t33;
      assign t43 = t29 ^ t40;
      assign t44 = t33 ^ t37;
      assign t45 = t42 ^ t41;
      assign z0 = t44 & y15;
      assign z1 = t37 & y6;
      assign z2 = t33 & x[0];
      assign z3 = t43 & y16;
      assign z4 = t40 & y1;
      assign z5 = t29 & y7;
      assign z6 = t42 & y11;
      assign z7 = t45 & y17;
      assign z8 = t41 & y10;
      assign z9 = t44 & y12;
      assign z10 = t37 & y3;
      assign z11 = t33 & y4;
      assign z12 = t43 & y13;
      assign z13 = t40 & y5;
      assign z14 = t29 & y2;
      assign z15 = t42 & y9;
      assign z16 = t45 & y14;
      assign z17 = t41 & y8;
      assign tc1 = z15 ^ z16;
      assign tc2 = z10 ^ tc1;
      assign tc3 = z9 ^ tc2;
      assign tc4 = z0 ^ z2;
      assign tc5 = z1 ^ z0;
      assign tc6 = z3 ^ z4;
      assign tc7 = z12 ^ tc4;
      assign tc8 = z7 ^ tc6;
      assign tc9 = z8 ^ tc7;
      assign tc10 = tc8 ^ tc9;
      assign tc11 = tc6 ^ tc5;
      assign tc12 = z3 ^ z5;
      assign tc13 = z13 ^ tc1;
      assign tc14 = tc4 ^ tc12;
      assign y[4] = tc3 ^ tc11;
      assign tc16 = z6 ^ tc8;
      assign tc17 = z14 ^ tc10;
      assign tc18 = tc13 ^ tc14;
      assign y[0] = z12 ^ tc18;
      assign tc20 = z15 ^ tc16;
      assign tc21 = tc2 ^ z11;
      assign y[7] = tc3 ^ tc16;
      assign y[1] = tc10 ^ tc18;
      assign y[3] = tc14 ^ y[4];
      assign y[6] = y[4] ^ tc16;
      assign tc26 = tc17 ^ tc20;
      assign y[5] = tc26 ^ z17;
      assign y[2] = tc21 ^ tc17;
    endmodule
    
  • one_entry.sv (negative, stopped at solution): A table with one wrong entry: S(0x53) = 0xec instead of 0xed.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      always_comb begin
        case (x)
          8'd0: y = 8'd99;
          8'd1: y = 8'd124;
          8'd2: y = 8'd119;
          8'd3: y = 8'd123;
          8'd4: y = 8'd242;
          8'd5: y = 8'd107;
          8'd6: y = 8'd111;
          8'd7: y = 8'd197;
          8'd8: y = 8'd48;
          8'd9: y = 8'd1;
          8'd10: y = 8'd103;
          8'd11: y = 8'd43;
          8'd12: y = 8'd254;
          8'd13: y = 8'd215;
          8'd14: y = 8'd171;
          8'd15: y = 8'd118;
          8'd16: y = 8'd202;
          8'd17: y = 8'd130;
          8'd18: y = 8'd201;
          8'd19: y = 8'd125;
          8'd20: y = 8'd250;
          8'd21: y = 8'd89;
          8'd22: y = 8'd71;
          8'd23: y = 8'd240;
          8'd24: y = 8'd173;
          8'd25: y = 8'd212;
          8'd26: y = 8'd162;
          8'd27: y = 8'd175;
          8'd28: y = 8'd156;
          8'd29: y = 8'd164;
          8'd30: y = 8'd114;
          8'd31: y = 8'd192;
          8'd32: y = 8'd183;
          8'd33: y = 8'd253;
          8'd34: y = 8'd147;
          8'd35: y = 8'd38;
          8'd36: y = 8'd54;
          8'd37: y = 8'd63;
          8'd38: y = 8'd247;
          8'd39: y = 8'd204;
          8'd40: y = 8'd52;
          8'd41: y = 8'd165;
          8'd42: y = 8'd229;
          8'd43: y = 8'd241;
          8'd44: y = 8'd113;
          8'd45: y = 8'd216;
          8'd46: y = 8'd49;
          8'd47: y = 8'd21;
          8'd48: y = 8'd4;
          8'd49: y = 8'd199;
          8'd50: y = 8'd35;
          8'd51: y = 8'd195;
          8'd52: y = 8'd24;
          8'd53: y = 8'd150;
          8'd54: y = 8'd5;
          8'd55: y = 8'd154;
          8'd56: y = 8'd7;
          8'd57: y = 8'd18;
          8'd58: y = 8'd128;
          8'd59: y = 8'd226;
          8'd60: y = 8'd235;
          8'd61: y = 8'd39;
          8'd62: y = 8'd178;
          8'd63: y = 8'd117;
          8'd64: y = 8'd9;
          8'd65: y = 8'd131;
          8'd66: y = 8'd44;
          8'd67: y = 8'd26;
          8'd68: y = 8'd27;
          8'd69: y = 8'd110;
          8'd70: y = 8'd90;
          8'd71: y = 8'd160;
          8'd72: y = 8'd82;
          8'd73: y = 8'd59;
          8'd74: y = 8'd214;
          8'd75: y = 8'd179;
          8'd76: y = 8'd41;
          8'd77: y = 8'd227;
          8'd78: y = 8'd47;
          8'd79: y = 8'd132;
          8'd80: y = 8'd83;
          8'd81: y = 8'd209;
          8'd82: y = 8'd0;
          8'd83: y = 8'd236;
          8'd84: y = 8'd32;
          8'd85: y = 8'd252;
          8'd86: y = 8'd177;
          8'd87: y = 8'd91;
          8'd88: y = 8'd106;
          8'd89: y = 8'd203;
          8'd90: y = 8'd190;
          8'd91: y = 8'd57;
          8'd92: y = 8'd74;
          8'd93: y = 8'd76;
          8'd94: y = 8'd88;
          8'd95: y = 8'd207;
          8'd96: y = 8'd208;
          8'd97: y = 8'd239;
          8'd98: y = 8'd170;
          8'd99: y = 8'd251;
          8'd100: y = 8'd67;
          8'd101: y = 8'd77;
          8'd102: y = 8'd51;
          8'd103: y = 8'd133;
          8'd104: y = 8'd69;
          8'd105: y = 8'd249;
          8'd106: y = 8'd2;
          8'd107: y = 8'd127;
          8'd108: y = 8'd80;
          8'd109: y = 8'd60;
          8'd110: y = 8'd159;
          8'd111: y = 8'd168;
          8'd112: y = 8'd81;
          8'd113: y = 8'd163;
          8'd114: y = 8'd64;
          8'd115: y = 8'd143;
          8'd116: y = 8'd146;
          8'd117: y = 8'd157;
          8'd118: y = 8'd56;
          8'd119: y = 8'd245;
          8'd120: y = 8'd188;
          8'd121: y = 8'd182;
          8'd122: y = 8'd218;
          8'd123: y = 8'd33;
          8'd124: y = 8'd16;
          8'd125: y = 8'd255;
          8'd126: y = 8'd243;
          8'd127: y = 8'd210;
          8'd128: y = 8'd205;
          8'd129: y = 8'd12;
          8'd130: y = 8'd19;
          8'd131: y = 8'd236;
          8'd132: y = 8'd95;
          8'd133: y = 8'd151;
          8'd134: y = 8'd68;
          8'd135: y = 8'd23;
          8'd136: y = 8'd196;
          8'd137: y = 8'd167;
          8'd138: y = 8'd126;
          8'd139: y = 8'd61;
          8'd140: y = 8'd100;
          8'd141: y = 8'd93;
          8'd142: y = 8'd25;
          8'd143: y = 8'd115;
          8'd144: y = 8'd96;
          8'd145: y = 8'd129;
          8'd146: y = 8'd79;
          8'd147: y = 8'd220;
          8'd148: y = 8'd34;
          8'd149: y = 8'd42;
          8'd150: y = 8'd144;
          8'd151: y = 8'd136;
          8'd152: y = 8'd70;
          8'd153: y = 8'd238;
          8'd154: y = 8'd184;
          8'd155: y = 8'd20;
          8'd156: y = 8'd222;
          8'd157: y = 8'd94;
          8'd158: y = 8'd11;
          8'd159: y = 8'd219;
          8'd160: y = 8'd224;
          8'd161: y = 8'd50;
          8'd162: y = 8'd58;
          8'd163: y = 8'd10;
          8'd164: y = 8'd73;
          8'd165: y = 8'd6;
          8'd166: y = 8'd36;
          8'd167: y = 8'd92;
          8'd168: y = 8'd194;
          8'd169: y = 8'd211;
          8'd170: y = 8'd172;
          8'd171: y = 8'd98;
          8'd172: y = 8'd145;
          8'd173: y = 8'd149;
          8'd174: y = 8'd228;
          8'd175: y = 8'd121;
          8'd176: y = 8'd231;
          8'd177: y = 8'd200;
          8'd178: y = 8'd55;
          8'd179: y = 8'd109;
          8'd180: y = 8'd141;
          8'd181: y = 8'd213;
          8'd182: y = 8'd78;
          8'd183: y = 8'd169;
          8'd184: y = 8'd108;
          8'd185: y = 8'd86;
          8'd186: y = 8'd244;
          8'd187: y = 8'd234;
          8'd188: y = 8'd101;
          8'd189: y = 8'd122;
          8'd190: y = 8'd174;
          8'd191: y = 8'd8;
          8'd192: y = 8'd186;
          8'd193: y = 8'd120;
          8'd194: y = 8'd37;
          8'd195: y = 8'd46;
          8'd196: y = 8'd28;
          8'd197: y = 8'd166;
          8'd198: y = 8'd180;
          8'd199: y = 8'd198;
          8'd200: y = 8'd232;
          8'd201: y = 8'd221;
          8'd202: y = 8'd116;
          8'd203: y = 8'd31;
          8'd204: y = 8'd75;
          8'd205: y = 8'd189;
          8'd206: y = 8'd139;
          8'd207: y = 8'd138;
          8'd208: y = 8'd112;
          8'd209: y = 8'd62;
          8'd210: y = 8'd181;
          8'd211: y = 8'd102;
          8'd212: y = 8'd72;
          8'd213: y = 8'd3;
          8'd214: y = 8'd246;
          8'd215: y = 8'd14;
          8'd216: y = 8'd97;
          8'd217: y = 8'd53;
          8'd218: y = 8'd87;
          8'd219: y = 8'd185;
          8'd220: y = 8'd134;
          8'd221: y = 8'd193;
          8'd222: y = 8'd29;
          8'd223: y = 8'd158;
          8'd224: y = 8'd225;
          8'd225: y = 8'd248;
          8'd226: y = 8'd152;
          8'd227: y = 8'd17;
          8'd228: y = 8'd105;
          8'd229: y = 8'd217;
          8'd230: y = 8'd142;
          8'd231: y = 8'd148;
          8'd232: y = 8'd155;
          8'd233: y = 8'd30;
          8'd234: y = 8'd135;
          8'd235: y = 8'd233;
          8'd236: y = 8'd206;
          8'd237: y = 8'd85;
          8'd238: y = 8'd40;
          8'd239: y = 8'd223;
          8'd240: y = 8'd140;
          8'd241: y = 8'd161;
          8'd242: y = 8'd137;
          8'd243: y = 8'd13;
          8'd244: y = 8'd191;
          8'd245: y = 8'd230;
          8'd246: y = 8'd66;
          8'd247: y = 8'd104;
          8'd248: y = 8'd65;
          8'd249: y = 8'd153;
          8'd250: y = 8'd45;
          8'd251: y = 8'd15;
          8'd252: y = 8'd176;
          8'd253: y = 8'd84;
          8'd254: y = 8'd187;
          8'd255: y = 8'd22;
          default: y = 8'd0;
        endcase
      end
    endmodule
    
  • reversed_bits.sv (negative, stopped at solution): The right circuit fed the input bits in reverse order.

    the design, with its comments left out
    module aes_sbox (input logic [7:0] x, output logic [7:0] y);
      logic y4, tc5, tc12, tc20, tc26, t37, t27, t4, y10, t23, tc1, y5, t40, z8, t5, t25, z10, t3, y9, t30, y11, t15, y8, t0, tc18, t28, t1, t9, tc7, z17, y3, t45, y6, z5, y18, tc10, t43, t26, t41, t31, z12, t29, t36, z13, tc17, tc13, y15, z7, t13, t44, tc16, y17, z2, z16, t12, t11, z9, y14, y2, z6, tc21, t17, t6, t34, t35, y16, z3, t33, y20, t2, y13, t8, z0, t42, tc2, tc9, tc3, t24, t18, t21, z1, t10, tc11, z4, t7, t32, t39, y12, y21, tc8, t20, y7, t22, z11, z14, t19, t38, y1, y19, z15, tc14, t14, tc6, tc4, t16;
      assign y14 = x[3] ^ x[5];
      assign y13 = x[0] ^ x[6];
      assign y9 = x[0] ^ x[3];
      assign y8 = x[0] ^ x[5];
      assign t0 = x[1] ^ x[2];
      assign y1 = t0 ^ x[7];
      assign y4 = y1 ^ x[3];
      assign y12 = y13 ^ y14;
      assign y2 = y1 ^ x[0];
      assign y5 = y1 ^ x[6];
      assign y3 = y5 ^ y8;
      assign t1 = x[4] ^ y12;
      assign y15 = t1 ^ x[5];
      assign y20 = t1 ^ x[1];
      assign y6 = y15 ^ x[7];
      assign y10 = y15 ^ t0;
      assign y11 = y20 ^ y9;
      assign y7 = x[7] ^ y11;
      assign y17 = y10 ^ y11;
      assign y19 = y10 ^ y8;
      assign y16 = t0 ^ y11;
      assign y21 = y13 ^ y16;
      assign y18 = x[0] ^ y16;
      assign t2 = y12 & y15;
      assign t3 = y3 & y6;
      assign t4 = t3 ^ t2;
      assign t5 = y4 & x[7];
      assign t6 = t5 ^ t2;
      assign t7 = y13 & y16;
      assign t8 = y5 & y1;
      assign t9 = t8 ^ t7;
      assign t10 = y2 & y7;
      assign t11 = t10 ^ t7;
      assign t12 = y9 & y11;
      assign t13 = y14 & y17;
      assign t14 = t13 ^ t12;
      assign t15 = y8 & y10;
      assign t16 = t15 ^ t12;
      assign t17 = t4 ^ y20;
      assign t18 = t6 ^ t16;
      assign t19 = t9 ^ t14;
      assign t20 = t11 ^ t16;
      assign t21 = t17 ^ t14;
      assign t22 = t18 ^ y19;
      assign t23 = t19 ^ y21;
      assign t24 = t20 ^ y18;
      assign t25 = t21 ^ t22;
      assign t26 = t21 & t23;
      assign t27 = t24 ^ t26;
      assign t28 = t25 & t27;
      assign t29 = t28 ^ t22;
      assign t30 = t23 ^ t24;
      assign t31 = t22 ^ t26;
      assign t32 = t31 & t30;
      assign t33 = t32 ^ t24;
      assign t34 = t23 ^ t33;
      assign t35 = t27 ^ t33;
      assign t36 = t24 & t35;
      assign t37 = t36 ^ t34;
      assign t38 = t27 ^ t36;
      assign t39 = t29 & t38;
      assign t40 = t25 ^ t39;
      assign t41 = t40 ^ t37;
      assign t42 = t29 ^ t33;
      assign t43 = t29 ^ t40;
      assign t44 = t33 ^ t37;
      assign t45 = t42 ^ t41;
      assign z0 = t44 & y15;
      assign z1 = t37 & y6;
      assign z2 = t33 & x[7];
      assign z3 = t43 & y16;
      assign z4 = t40 & y1;
      assign z5 = t29 & y7;
      assign z6 = t42 & y11;
      assign z7 = t45 & y17;
      assign z8 = t41 & y10;
      assign z9 = t44 & y12;
      assign z10 = t37 & y3;
      assign z11 = t33 & y4;
      assign z12 = t43 & y13;
      assign z13 = t40 & y5;
      assign z14 = t29 & y2;
      assign z15 = t42 & y9;
      assign z16 = t45 & y14;
      assign z17 = t41 & y8;
      assign tc1 = z15 ^ z16;
      assign tc2 = z10 ^ tc1;
      assign tc3 = z9 ^ tc2;
      assign tc4 = z0 ^ z2;
      assign tc5 = z1 ^ z0;
      assign tc6 = z3 ^ z4;
      assign tc7 = z12 ^ tc4;
      assign tc8 = z7 ^ tc6;
      assign tc9 = z8 ^ tc7;
      assign tc10 = tc8 ^ tc9;
      assign tc11 = tc6 ^ tc5;
      assign tc12 = z3 ^ z5;
      assign tc13 = z13 ^ tc1;
      assign tc14 = tc4 ^ tc12;
      assign y[4] = tc3 ^ tc11;
      assign tc16 = z6 ^ tc8;
      assign tc17 = z14 ^ tc10;
      assign tc18 = tc13 ^ tc14;
      assign y[0] = z12 ^ tc18 ^ 1'b1;
      assign tc20 = z15 ^ tc16;
      assign tc21 = tc2 ^ z11;
      assign y[7] = tc3 ^ tc16;
      assign y[1] = tc10 ^ tc18 ^ 1'b1;
      assign y[3] = tc14 ^ y[4];
      assign y[6] = y[4] ^ tc16 ^ 1'b1;
      assign tc26 = tc17 ^ tc20;
      assign y[5] = tc26 ^ z17 ^ 1'b1;
      assign y[2] = tc21 ^ tc17;
    endmodule
    
Spec.lean, verbatim (134 lines)
import SvGolf.Task

/-!
# Task `aes_sbox`: the AES S-box (TRUSTED)

The AES S-box (FIPS 197 Section 5.1.1), fixed size: eight bits in, eight bits out. Module (no
parameter; port order as written):

```systemverilog
module aes_sbox (
  input  logic [7:0] x,
  output logic [7:0] y
);
```

Statement: the design has exactly the ports `x` (input, 8 bits) and `y` (output, 8 bits), every run
terminates, no process is clocked, there is no combinational loop, and in every cycle whose stimulus
drives `x` with a known value
the snapshot's `y` is `sbox x`: the multiplicative inverse in
GF(2^8) = GF(2)[x]/(x^8+x^4+x^3+x+1) (with 0 mapped to 0) followed by the affine transformation
`b ^ rotl b 1 ^ rotl b 2 ^ rotl b 3 ^ rotl b 4 ^ 0x63`. It is `CombTask.StatementFixed` of
`SvGolf/Task.lean` (the statement at the one "parameter value" `0`, which the task's interface and
function ignore). Bit order: `BitVec 8`, `x[7]` is the most significant bit, as in the standard.

The function is DEFINED algebraically (below), the way the standard defines it; the 256-entry table
of FIPS 197 (Table 4 of the 2023 edition, Figure 7 of the 2001 one) appears only as a cross-check
(`sboxTable`, an `example` that the algebra reproduces it, and the standard's own worked values).
Sources used to cross-check (none trusted): `oracle.py` (the same algebra in Python), the
independently derived 113-gate Boyar-Peralta circuit (`reference/sbox_bp.sv`, equal to the table on
all 256 inputs), and a textbook AES-128 that reproduces the FIPS 197 (2001) Appendix C.1 ciphertext
through this S-box and agrees with OpenSSL on random blocks (`tests/aes_sbox/validate/validate.py`);
the table itself was compared with Table 4 parsed from the NIST PDF.
-/

namespace SvGolf.Tasks.AesSbox

open SvGolf

/-! ## GF(2^8) -/

/-- Multiplication by `x` in GF(2^8) (FIPS 197, XTIMES, Equation (4.5), Section 4.2). -/
def xtime (a : BitVec 8) : BitVec 8 := (a <<< 1) ^^^ (if a.msb then 0x1b#8 else 0#8)

/-- `gmulAux n a b acc`: shift-and-add multiplication, `n` steps (FIPS 197, Section 4.2). -/
def gmulAux : Nat → BitVec 8 → BitVec 8 → BitVec 8 → BitVec 8
  | 0, _, _, acc => acc
  | n + 1, a, b, acc => gmulAux n (xtime a) (b >>> 1) (if b.getLsbD 0 then acc ^^^ a else acc)

/-- Multiplication in GF(2^8) (FIPS 197, Section 4.2). -/
def gmul (a b : BitVec 8) : BitVec 8 := gmulAux 8 a b 0

/-- The multiplicative inverse, `0` for `0`: `a^254 = a^2 * a^4 * ... * a^128` (the group has order 255). -/
def ginv (a : BitVec 8) : BitVec 8 :=
  let a2 := gmul a a
  let a4 := gmul a2 a2
  let a8 := gmul a4 a4
  let a16 := gmul a8 a8
  let a32 := gmul a16 a16
  let a64 := gmul a32 a32
  let a128 := gmul a64 a64
  gmul (gmul (gmul a2 a4) (gmul a8 a16)) (gmul (gmul a32 a64) a128)

/-- The affine transformation of Section 5.1.1, Equations (5.3) and (5.4) of the 2023 edition:
`b'_i = b_i ^ b_(i+4) ^ b_(i+5) ^ b_(i+6) ^ b_(i+7) ^ c_i` with `c = 0x63` (indices mod 8). -/
def affine (b : BitVec 8) : BitVec 8 :=
  b ^^^ b.rotateLeft 1 ^^^ b.rotateLeft 2 ^^^ b.rotateLeft 3 ^^^ b.rotateLeft 4 ^^^ 0x63#8

/-- **The AES S-box.** -/
def sbox (x : BitVec 8) : BitVec 8 := affine (ginv x)

/-! ## The task -/

/-- The task: input `x : BitVec 8`, output `y = sbox x`. Fixed size (statement at `N = 0`). -/
def task : CombTask where
  inRange N := N = 0
  inputs _ := [("x", 8)]
  outputs _ := [("y", 8)]
  fn _ := fun (x, ()) => (sbox x, ())

/-- **The challenge statement** for the parameterless design `Submission.design.sem : Design2`. -/
abbrev Statement : LeanModels.Sv.Design2 → Prop := task.StatementFixed

/-! ## Sanity checks (closed; `decide +kernel` is kernel evaluation, no axiom) -/

example : task.inRange 0 := rfl

/-- The statement's point `N = 0` is the task's (only) point, and the interface is `x : 8` in,
`y : 8` out. -/
example : task.inputs 0 = [("x", 8)] ∧ task.outputs 0 = [("y", 8)] := ⟨rfl, rfl⟩

/-- The input names are distinct (the non-vacuity theorem `CombTask.SatisfiedAt.exists_run` needs
it). -/
example : ((task.inputs 0).map Prod.fst).Nodup := by decide

/-- The function on concrete values (the standard's own worked example, Section 5.1.1: `S(53) = ed`,
and the two ends of Table 4). -/
example : (task.fn 0 (0x53#8, ())).1 = 0xed#8 := by decide +kernel
example : (task.fn 0 (0x00#8, ())).1 = 0x63#8 := by decide +kernel
example : (task.fn 0 (0xff#8, ())).1 = 0x16#8 := by decide +kernel

/-- FIPS 197 (2023) Section 4.2, Equation (4.7): `{57} * {13} = {fe}`; (2001 edition) Section 4.2: `{57} * {83} = {c1}`. -/
example : gmul 0x57#8 0x83#8 = 0xc1#8 ∧ gmul 0x57#8 0x13#8 = 0xfe#8 := by decide

/-- FIPS 197 Section 5.1.1 and Table 4: `S(00) = 63`, `S(53) = ed` (the standard's own example), `S(ff) = 16`. -/
example : sbox 0x00#8 = 0x63#8 ∧ sbox 0x53#8 = 0xed#8 ∧ sbox 0xff#8 = 0x16#8 := by decide +kernel

/-- The table of FIPS 197 Table 4 (row-major, `S(16 r + c)` at index `16 r + c`), as a cross-check only. -/
def sboxTable : List Nat :=
  [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]

set_option maxRecDepth 100000 in
/-- The algebra reproduces the table on all 256 inputs. -/
example : ∀ x : Fin 256, (sbox (BitVec.ofNat 8 x.val)).toNat = sboxTable.getD x.val 0 := by decide +kernel

set_option maxRecDepth 100000 in
/-- The S-box is a permutation of the bytes (a sanity check of the spec, not a part of the statement). -/
example : ((List.range 256).map fun x => (sbox (BitVec.ofNat 8 x)).toNat).Nodup := by decide +kernel

end SvGolf.Tasks.AesSbox

Its trusted text

The modules specific to this task. Like every task, it also rests on the shared trusted base (the ls-sv semantics of SystemVerilog and svGolf's statement helpers), and a proof may import any module of the ls-sv library. Nothing else is trusted: proof helpers are kernel-checked like any submission.

modulerolelinessha256
tasks.aes_sbox.Specsvgolf/tasks/aes_sbox/Spec.leantask statement13486844849d794

How to participate #

  1. Write a circuit with the task's exact interface.
  2. Prove in Lean 4 that it meets the trusted statement; Start a new design, below, gives the route, and the proving guide shows how.
  3. Check and record it (how to submit): the checker accepts the pair or says which stage refused it, as it does for each design under what does not count.
  4. Beat par: an accepted design whose score (area × time) is below that of the best proved reference. The leaderboard ranks by it.

How to submit

You hand in two files: solution.sv, a module with the exact header under Interface, and Solution.lean, a Lean 4 proof that it meets the trusted statement.

Step 0, once per machine. Install:

  • elan, which installs the Lean toolchain that lean-toolchain pins (leanprover/lean4:v4.33.0-rc1) on first use;
  • Yosys 0.53 with its yosys-abc (every pinned tool and file: Reproduce a score);
  • Verilator 5, a C++ compiler and make, for the post-synthesis check (it compiles Verilator's model of the netlist);
  • Python 3.12 with python3.12 -m pip install -r requirements.txt (pyslang==11.0.0, the extractor's SystemVerilog frontend).
step 0
git clone https://github.com/thomasnormal/svgolf
cd svgolf
python3.12 -m pip install -r requirements.txt
# the trusted Lean and the checker's evaluator
lake build
# the pinned sky130 liberty, checked by its hash
python3.12 score/ppa.py --fetch-liberty

lake build takes about 6 minutes and 1 GB of disk the first time, on a laptop that already had the Lean toolchain (README.md's Step 0 says what was measured where; elan's first download of the toolchain comes on top): Lake clones proglib (formerly lean-surfaces) and its packages from github.com, so it needs network access there, and builds the LeanModels.Sv modules svGolf uses; Mathlib is cloned, never built.

Start from the reference pair under Files, sbox_bp, a complete and accepted one: copy it, from the same directory:

shell
cp tasks/aes_sbox/reference/sbox_bp.sv solution.sv
cp tasks/aes_sbox/reference/sbox_bp.lean Solution.lean

Then, for each design, from the same directory: find it without Lean and check it once without a proof (the golfing loop and step 1), write its proof (Start a new design, below, gives the route), then check the pair and record it (steps 2 and 3):

shell
# the golfing loop, no Lean: area, delay and the critical
#    path, about a second
python3.12 score/ppa.py solution.sv --task tasks/aes_sbox \
    --no-mapped --path
# 1. no proof needed; never accepts; exits 0 when every
#    stage passed, ending with area x time and par
python3.12 check.py tasks/aes_sbox solution.sv --unproved \
    --tactics
# 2. the real check: prints "accepted": true; its
#    post-synthesis check is LIGHT by default (a subset of
#    the vectors, for local feedback), so stderr also says
#    "accepted, but the check was INCOMPLETE ... rerun with
#    --postsynth full": expected, since step 3 runs the
#    full one itself
python3.12 check.py tasks/aes_sbox solution.sv Solution.lean
# 3. record it: the whole check again, full and sandboxed
python3.12 leaderboard/leaderboard.py add --task aes_sbox \
    --player YOUR_HANDLE --assisted-by "TOOL OR MODEL" \
    --sv solution.sv --lean Solution.lean \
    --notes "YOUR DESIGN IN ONE LINE"

Done: step 3 prints added aes_sbox/HASH: YOUR_HANDLE, … once the pair has passed the whole check, full and sandboxed, and its record is written (what it writes, and where: below); otherwise it prints REFUSED with the reasons and records nothing. Step 2's "accepted": true, with its INCOMPLETE line, is feedback for you, not a record.

The golfing loop and step 1, the first two commands above. The second command runs every stage that needs no proof, all 256 inputs against the task's oracle included, and says whether the proof tactics read the design (tactics.in_fragment).

score/ppa.py is the inner loop of golfing; its ranked numbers are area_um2_sky130 and delay_ps_sky130 in what it prints. It runs only the source gate and the pinned flow: it does not check the banlist, the 4-state rules, whether ls-sv can read the design, the post-synthesis simulation or the task's function. Step 1 does, still without a proof.

The Lean file. The checker extracts your .sv itself and writes the trusted module Submission.Design; Goal unfolds to SvGolf.Tasks.AesSbox.Statement Submission.design.sem, the task's statement of your design:

Submission.Design (generated: you never write it)
import LeanModels.Sv.Ingest2
import tasks.aes_sbox.Spec

namespace Submission
load_design_sv2 design from "<the envelope of your .sv>"
abbrev Goal : Prop := SvGolf.Tasks.AesSbox.Statement design.sem
end Submission

Your Solution.lean imports it and proves Goal, as the whole Solution.lean in Start a new design shows. File names and paths are free (here solution.sv and Solution.lean); the module name Submission, the import Submission.Design header and the theorem solution : Goal (in namespace Submission, theorem Submission.solution : Submission.Goal) are fixed.

Step 3 writes your record's three files (.json, .sv and .lean, named by the record's hash) to leaderboard/data/aes_sbox/, the directory a pull request adds. Then open a pull request against https://github.com/thomasnormal/svgolf that adds them; CI re-verifies it. There is no submission server: nothing is sent anywhere by these commands. For a private trial, add --data-dir DIR: the record then goes to DIR and the board stays as it is. Repeat --assisted-by for each tool or AI system that helped, or leave it out.

YOUR_HANDLE is your public name: the board and the record's page show it. It is 1 to 32 characters, letters, digits, ., _ or -, the first a letter or a digit ([A-Za-z0-9][A-Za-z0-9._-]{0,31}). --notes is optional: one line on the design (at most 2000 characters), shown on the record's page. In a private trial (--data-dir DIR), add --from-check RESULT.json records the JSON that a check.py … --postsynth full --ppa require run printed instead of checking again; the board's own leaderboard/data/ refuses a stored result.

the sandbox, and machines without one

leaderboard.py add runs the check with --sandbox require: the proof's Lean, the extractor, Yosys and Verilator must run inside the operating system's sandbox (Seatbelt on macOS, bubblewrap on Linux). Where that sandbox is missing or fails its self-test, the check stops with an infrastructure error and nothing is recorded. On such a machine, --sandbox auto runs the check without it (and says so on stderr), and --sandbox off skips it: your proof file then runs with your own privileges, and the record is for your own use, since an official record is made with the sandbox or not at all. add also weighs the ranked sky130 numbers, which need the pinned liberty (Step 0). On a shared machine whose Lean calls go through a wrapper, set SVGOLF_LEAN_WRAP; check.py and leaderboard.py both read it, and SVGOLF_LEAN_WRAP_ONCE=1 takes the wrapper once for a whole run.

Leaderboard

by score · ASAP7
  1. 1
    2026-11-05
    2858890.9 µm² × 3.21 ns
  2. ⚑
    par proved reference
    3833892.1 µm² × 4.30 ns
every column: area, time, proof lines, assisted by, files
#playerdatescore (µm²·ns)area (µm²)time (ps)area (GE)depthproof linesassisted byrecordfiles
1tower-shuffle2026-11-052858890.93208204.659167Claude Opus 5.5 (Anthropic)d2880a7160dd.sv .lean
  1. 1
    2026-11-05
    7.45813.414 µm² × 0.556 ns
  2. ⚑
    par proved reference
    9.40213.355 µm² × 0.704 ns
every column: area, time, proof lines, assisted by, files
#playerdatescore (µm²·ns)area (µm²)time (ps)area (GE)depthproof linesassisted byrecordfiles
1tower-shuffle2026-11-057.45813.414556204.659167Claude Opus 5.5 (Anthropic)d2880a7160dd.sv .lean
score: area × time, µm²·nspar

At a glance

top module
aes_sbox
parameters
none: one fixed size
scoring point
the one fixed size
depth budget
none
banned run-time operators
/ % **

No task-specific ban: a lookup table, + - * and everything else are legal and simply score what they score. Run-time / % ** are banned here as in every task: a zero divisor makes an unknown value from known inputs, which the proof and the synthesized circuit resolve differently.

allowed axioms
propext, Classical.choice, Quot.sound
proof time limit
300 s of CPU time (a wall-clock backstop of 1500 s stops a proof that waits)

Start a new design

A new flat netlist needs no proof engineering here: sv_exhaustive reads the design, compiles it into a gate program and decides y = sbox x on all 256 inputs by kernel evaluation.

The route: sv_exhaustive, the whole Solution.lean (the shipped reference/sbox_table.lean is the same proof; a tower-field S-box of 82 assigns was accepted with this file on 2026-11-05):

import Submission.Design
import SvGolf.Comb
import LeanModels.Sv.CombExhaustiveTactic

namespace Submission

set_option maxHeartbeats 0 in
theorem solution : Goal := by sv_exhaustive

end Submission
The proof in detailWrite the design so sv_exhaustive takes it · Past the budget · Library lemmas that exist today

Write the design so sv_exhaustive takes it (LeanModels/Sv/CombExhaustiveTactic.lean and CombExhaustive.lean):

  • a flat netlist: continuous assigns, no generate loop, of &, |, ^, ~, literals and constants (no ?:), every read inside its declared width; or an always_comb with a plain case table over literals (reference/sbox_table.sv);
  • at most about 90 assigns, until the tactic's cost is fixed: its cost grows steeply with the number of assigns. Measured 2026-11-05 under load: 82 assigns proved in 70.6 s of the 120 s limit of the time; 139 assigns did not finish within it; the 113-assign sbox_bp.sv and the 139-assign netlist did not finish in a 21-minute probe. Inlining every net read only once into its reader cut the tower-field netlist from 139 to 82 assigns;
  • inlining and reordering move the score (deterministically, like operand order and gate forms): after inlining, search statement orders again with score/ppa.py, a second or two per order. Using the pinned Yosys and ABC to restructure a netlist and writing the result back as & | ^ ~ assigns is golf too (end a custom abc -script with map, or ABC returns lookup tables).

Past the budget: the proved reference sbox_bp.sv (113 assigns) takes the route of PROVING.md, section 12 instead, the four sv_comb parts with a straight-line program over a packed Nat checked by the kernel (reference/sbox_bp.lean, generated by tests/aes_sbox/validate/gen_bp_proof.py, which is written for that netlist).

Library lemmas that exist today: none is needed on the one-line route; sv_exhaustive is the library. reference/sbox_bp.lean holds the pieces of the long route (the packed program and its induction).

Compare the designs

ASAP7 · any two numbers · lower is better
  • submission
  • proved reference
  • baseline (not proved)
  • the Pareto front of the proved designs
Lower is better on both axes. The step line joins the proved designs that no other proved design beats on both; baselines are shown for scale. Choose any two numbers to find the best design for your own trade-off. 5 of 5 designs have both numbers.
every design with all its numbers, by score
designScore (µm²·ns)Area (µm²)Delay (ps)Area (GE)Depth (gates)GatesProof (lines)
tower-shuffle submission2858890.93208204.659161227
sbox_bp_d16 not proved3494952.23670216.32218131–
sbox_bp par3833892.14297200.98621123202
sbox_table reference78843445.82288786.894116129
sbox_table not proved78843445.82288786.89411612–
  • submission
  • proved reference
  • baseline (not proved)
  • the Pareto front of the proved designs
Lower is better on both axes. The step line joins the proved designs that no other proved design beats on both; baselines are shown for scale. Choose any two numbers to find the best design for your own trade-off. 5 of 5 designs have both numbers.
every design with all its numbers, by score
designScore (µm²·ns)Area (µm²)Delay (ps)Area (GE)Depth (gates)GatesProof (lines)
tower-shuffle submission7.45813.414556204.659161227
sbox_bp_d16 not proved8.93114.245627216.32218131–
sbox_bp par9.40213.355704200.98621123202
sbox_table reference19.3351.817373786.894116129
sbox_table not proved19.3351.817373786.89411612–

Proved references

Proved and accepted designs that ship with the task, written or adapted by the maintainers. They are the first entries, and par, the bar to beat, is the one with the best score (area × time, µm²·ns, from the sky130ASAP7 area and time; a design without a sky130an ASAP7 weighing has no score and comes after, by its extra GE columns). A reference that was also recorded links its record under its name: the record holds that reference's design and proof, matched by the sha256 of both files.

designscore (µm²·ns)area (µm²)time (ps)GE · depthvs parproof linesfiles
sbox_bp parparThe Boyar-Peralta 113-gate circuit, translated gate for gate from the authors' netlist.tactics: decide, induction, omega, simp, sv_equations, sv_interface, sv_structurerecord: baa9fb38c98538339.402892.113.3554297704200.986 · 21parpar202.sv .lean
sbox_table The 256-entry table of FIPS 197 as one case statement.record: 78eafaad6144788419.333445.851.8172288373786.894 · 11+105.7%+105.6%9.sv .lean

Baselines

Not entries. Designs scored by the pinned flow (with the banlist lifted) but never accepted: unproved, simulation-only, or using an operator the task bans. They show how much room there is.

designscore (µm²·ns)area (µm²)time (ps)GE · depthvs parfile
sbox_bp_d16 The Boyar-Peralta depth-16 circuit of 125 gates, translated gate for gate, checked by simulation.34948.931952.214.2453670627216.322 · 18−8.8%−5.0%.sv
sbox_table The 256-entry case table, the naive design, checked by simulation (now also proved: the reference sbox_table).788419.333445.851.8172288373786.894 · 11+105.7%+105.6%.sv