This task
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.
module aes_sbox (
input logic [7:0] x,
output logic [7:0] y
);| port | direction | width (bits) |
|---|---|---|
x | input | 8 |
y | output | 8 |
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.
/-- Exactly these ports, in this order, with these widths. -/
def Interface (d : Design2) : Prop :=
inputPorts d = [("x", 8)] ∧ outputPorts d = [("y", 8)]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.
/-- No process runs at a clock edge (no `always_ff`, no `always @(posedge …)`). -/
def Unclocked (d : Design2) : Prop :=
∀ p ∈ d.processes.toList, p.isEdgePhase = falseLOOP_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.
/-- 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'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.
/-- Under every schedule and every stimulus, the run completes. -/
def Terminates (d : Design2) : Prop :=
∀ (σ : ScheduleOracle) (stim : List SvState), ∃ tr, Runs2 d σ stim trCOMPUTES_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.
/-- 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, ())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.
/-- **The AES S-box.** -/
def sbox (x : BitVec 8) : BitVec 8 := affine (ginv x)ginvSpec.leanThe multiplicative inverse in GF(2^8), computed as a^254 (0 for 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)gmulSpec.leanMultiplication in GF(2^8) = GF(2)[x]/(x^8 + x^4 + x^3 + x + 1), by shift and add.
/-- Multiplication in GF(2^8) (FIPS 197, Section 4.2). -/
def gmul (a b : BitVec 8) : BitVec 8 := gmulAux 8 a b 0affineSpec.leanThe affine transformation of the standard: b XOR (b rotated left by 1, 2, 3 and 4) XOR 0x63.
/-- 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#8StatementSpec.leanThe trusted challenge statement that these properties restate, part by part.
/-- **The challenge statement** for the parameterless design `Submission.design.sem : Design2`. -/
abbrev Statement : LeanModels.Sv.Design2 → Prop := task.StatementFixedtaskSpec.leanThe task as data: the parameter range, the ports at each parameter value, and the function the outputs must compute.
/-- 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 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.
/-- 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 dinputPortsTask.leanThe design's input ports, each with its declared width, in declaration order.
/-- 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 noneoutputPortsTask.leanThe design's output ports, each with its declared width, in declaration order.
/-- 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 noneHoldAllTask.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 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⊨₂Spec2.leand ⊨₂ P: in every completed run of the design d, under every schedule and every stimulus, the stimulus and the trace satisfy P.
/-- `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 " ⊨₂ " => Models2spec2Spec2.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.
/-- 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 trRuns2Spec2.leanRuns2 d σ stim tr: simulating d under the schedule σ on the stimulus stim completes, with the trace tr.
/-- 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 trScheduleOracleSemantics.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.
/-- 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 readyProcess2.isEdgePhaseSem2.leanTrue for the processes that run at the clock edge: always_ff, always @(posedge …) and asynchronous-reset blocks.
/-- 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
| _ => falseWhat 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: 7 designs (by stage:
source4,extract1,banlist1,fourstate1) - Rejected at the proof: 4 designs (by stage:
solution4)
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 atsource): A table that sends one input to adefaultofx, 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 endmoduleunique_case_partial.sv(attack, stopped atsource): Aunique casetable 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 endmoduleunique_zero_ge.sv(attack, stopped atsource): A correct S-box followed by aunique casearm 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 endmodulex_default.sv(negative, stopped atsource): A correct table with an unreachabledefaultthat assignsx.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 endmodulewrong_names.sv(negative, stopped atextract): The right circuit on ports namedaandsinstead ofxandy.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; endmodulecase_missing_nodefault.sv(attack, stopped atbanlist): A table missing one entry and itsdefault, 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 endmoduleundriven_bit.sv(negative, stopped atfourstate): Output bity[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 atsolution): 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 endmoduleno_constant.sv(negative, stopped atsolution): Forgets the affine constant0x63, 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; endmoduleone_entry.sv(negative, stopped atsolution): A table with one wrong entry:S(0x53) = 0xecinstead of0xed.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 endmodulereversed_bits.sv(negative, stopped atsolution): 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.
| module | role | lines | sha256 |
|---|---|---|---|
tasks.aes_sbox.Spec | task statement | 134 | 86844849d794 |
How to participate #
- Write a circuit with the task's exact interface.
- Prove in Lean 4 that it meets the trusted statement; Start a new design, below, gives the route, and the proving guide shows how.
- 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.
- Beat par: an accepted design whose score (area × time) is below that of the best proved reference. The leaderboard ranks by it.