p3q-tsql / lean /AESVerification.lean
SNAPKITTYWEST's picture
Upload folder using huggingface_hub
667cbc1 verified
Raw History Blame Contribute Delete
1.78 kB
-- ============================================================================
-- AES MixColumns Formal Verification β€” Lean 4
-- Canonical test vector and linearity properties
-- Authors: Ahmad Ali Parr, Jessica L. Williams (SNAPKITTYWEST)
-- ============================================================================
import Mathlib.Data.BitVec.Basic
namespace AESVerification
-- GF(2^8) xtime: multiply by x mod (x^8 + x^4 + x^3 + x + 1)
def xtime (b : BitVec 8) : BitVec 8 :=
let msb : Bool := b.getMsbD 0
let shifted : BitVec 8 := b <<< 1
if msb then shifted ^^^ 27 else shifted
-- Row 0 of MixColumns: y0 = a0 βŠ• t βŠ• xtime(a0βŠ•a1)
-- where t = a0βŠ•a1βŠ•a2βŠ•a3
def mix_col_r0 (a0 a1 a2 a3 : BitVec 8) : BitVec 8 :=
let t := a0 ^^^ a1 ^^^ a2 ^^^ a3
a0 ^^^ t ^^^ xtime (a0 ^^^ a1)
-- Canonical test vector: D4 BF 5D 30 β†’ row0 = 04
def canonical_a0 : BitVec 8 := 0xD4
def canonical_a1 : BitVec 8 := 0xBF
def canonical_a2 : BitVec 8 := 0x5D
def canonical_a3 : BitVec 8 := 0x30
theorem canonical_r0_correct :
mix_col_r0 canonical_a0 canonical_a1 canonical_a2 canonical_a3 = 0x04 := by
decide
-- Zero vector: MixColumns(0,0,0,0) = (0,0,0,0)
theorem zero_column :
mix_col_r0 0 0 0 0 = 0 := by decide
-- Repeated byte: MixColumns(k,k,k,k)[0] = k (linearity: all differences cancel)
-- t = 0, xtime(0) = 0, so y0 = k βŠ• 0 βŠ• 0 = k
theorem repeated_byte (k : BitVec 8) :
mix_col_r0 k k k k = k := by
simp [mix_col_r0, xtime]
-- Linearity: xtime(a βŠ• b) = xtime(a) βŠ• xtime(b)
-- (GF(2^8) multiplication is a linear map over GF(2))
theorem xtime_linear (a b : BitVec 8) :
xtime (a ^^^ b) = xtime a ^^^ xtime b := by
simp [xtime]
split <;> split <;> split <;> simp_all [BitVec.xor_assoc]
all_goals decide
end AESVerification