{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ParallelListComp #-}
{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
module Documentation.SBV.Examples.Crypto.AES where
import Control.Monad (void)
import Data.SBV
import Data.SBV.Tools.CodeGen
import Data.SBV.Tools.Polynomial
import Data.List (transpose)
import Data.Maybe (fromJust)
import Numeric (showHex)
type GF28 = SWord 8
gf28Mult :: GF28 -> GF28 -> GF28
gf28Mult :: GF28 -> GF28 -> GF28
gf28Mult GF28
x GF28
y = forall a. Polynomial a => (a, a, [Int]) -> a
pMult (GF28
x, GF28
y, [Int
8, Int
4, Int
3, Int
1, Int
0])
gf28Pow :: GF28 -> Int -> GF28
gf28Pow :: GF28 -> Int -> GF28
gf28Pow GF28
n = forall {t}. (Integral t, Bits t) => t -> GF28
pow
where sq :: GF28 -> GF28
sq GF28
x = GF28
x GF28 -> GF28 -> GF28
`gf28Mult` GF28
x
pow :: t -> GF28
pow t
0 = GF28
1
pow t
i
| forall a. Integral a => a -> Bool
odd t
i = GF28
n GF28 -> GF28 -> GF28
`gf28Mult` GF28 -> GF28
sq (t -> GF28
pow (t
i forall a. Bits a => a -> Int -> a
`shiftR` Int
1))
| Bool
True = GF28 -> GF28
sq (t -> GF28
pow (t
i forall a. Bits a => a -> Int -> a
`shiftR` Int
1))
gf28Inverse :: GF28 -> GF28
gf28Inverse :: GF28 -> GF28
gf28Inverse GF28
x = GF28
x GF28 -> Int -> GF28
`gf28Pow` Int
254
type State = [SWord 32]
type Key = [SWord 32]
type KS = (Key, [Key], Key)
rotR :: [GF28] -> Int -> [GF28]
rotR :: [GF28] -> Int -> [GF28]
rotR [GF28
a, GF28
b, GF28
c, GF28
d] Int
1 = [GF28
d, GF28
a, GF28
b, GF28
c]
rotR [GF28
a, GF28
b, GF28
c, GF28
d] Int
2 = [GF28
c, GF28
d, GF28
a, GF28
b]
rotR [GF28
a, GF28
b, GF28
c, GF28
d] Int
3 = [GF28
b, GF28
c, GF28
d, GF28
a]
rotR [GF28]
xs Int
i = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"rotR: Unexpected input: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show ([GF28]
xs, Int
i)
roundConstants :: [GF28]
roundConstants :: [GF28]
roundConstants = GF28
0 forall a. a -> [a] -> [a]
: [ GF28 -> Int -> GF28
gf28Pow GF28
2 (Int
kforall a. Num a => a -> a -> a
-Int
1) | Int
k <- [Int
1 .. ] ]
invMixColumns :: State -> State
invMixColumns :: [SWord 32] -> [SWord 32]
invMixColumns [SWord 32]
state = forall a b. (a -> b) -> [a] -> [b]
map forall a. ByteConverter a => [GF28] -> a
fromBytes forall a b. (a -> b) -> a -> b
$ forall a. [[a]] -> [[a]]
transpose forall a b. (a -> b) -> a -> b
$ [[GF28]] -> [[GF28]]
mmult (forall a b. (a -> b) -> [a] -> [b]
map forall a. ByteConverter a => a -> [GF28]
toBytes [SWord 32]
state)
where dot :: [b -> c] -> [b] -> c
dot [b -> c]
f = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 forall a. Bits a => a -> a -> a
xor forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a b. (a -> b) -> a -> b
($) [b -> c]
f
mmult :: [[GF28]] -> [[GF28]]
mmult [[GF28]]
n = [forall a b. (a -> b) -> [a] -> [b]
map (forall {c} {b}. Bits c => [b -> c] -> [b] -> c
dot [GF28 -> GF28]
r) [[GF28]]
n | [GF28 -> GF28]
r <- [ [GF28 -> GF28
mE, GF28 -> GF28
mB, GF28 -> GF28
mD, GF28 -> GF28
m9]
, [GF28 -> GF28
m9, GF28 -> GF28
mE, GF28 -> GF28
mB, GF28 -> GF28
mD]
, [GF28 -> GF28
mD, GF28 -> GF28
m9, GF28 -> GF28
mE, GF28 -> GF28
mB]
, [GF28 -> GF28
mB, GF28 -> GF28
mD, GF28 -> GF28
m9, GF28 -> GF28
mE]
]]
mE :: GF28 -> GF28
mE = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [GF28]
mETable GF28
0
mB :: GF28 -> GF28
mB = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [GF28]
mBTable GF28
0
mD :: GF28 -> GF28
mD = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [GF28]
mDTable GF28
0
m9 :: GF28 -> GF28
m9 = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [GF28]
m9Table GF28
0
mETable :: [GF28]
mETable = forall a b. (a -> b) -> [a] -> [b]
map (GF28 -> GF28 -> GF28
gf28Mult GF28
0xE) [GF28
0..GF28
255]
mBTable :: [GF28]
mBTable = forall a b. (a -> b) -> [a] -> [b]
map (GF28 -> GF28 -> GF28
gf28Mult GF28
0xB) [GF28
0..GF28
255]
mDTable :: [GF28]
mDTable = forall a b. (a -> b) -> [a] -> [b]
map (GF28 -> GF28 -> GF28
gf28Mult GF28
0xD) [GF28
0..GF28
255]
m9Table :: [GF28]
m9Table = forall a b. (a -> b) -> [a] -> [b]
map (GF28 -> GF28 -> GF28
gf28Mult GF28
0x9) [GF28
0..GF28
255]
keyExpansion :: Int -> Key -> [Key]
keyExpansion :: Int -> [SWord 32] -> [[SWord 32]]
keyExpansion Int
nk [SWord 32]
key = forall a. [a] -> [[a]]
chop4 [SWord 32]
keys
where keys :: [SWord 32]
keys :: [SWord 32]
keys = [SWord 32]
key forall a. [a] -> [a] -> [a]
++ [Int -> SWord 32 -> SWord 32 -> SWord 32
nextWord Int
i SWord 32
prev SWord 32
old | Int
i <- [Int
nk ..] | SWord 32
prev <- forall a. Int -> [a] -> [a]
drop (Int
nkforall a. Num a => a -> a -> a
-Int
1) [SWord 32]
keys | SWord 32
old <- [SWord 32]
keys]
chop4 :: [a] -> [[a]]
chop4 :: forall a. [a] -> [[a]]
chop4 [a]
xs = let ([a]
f, [a]
r) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
4 [a]
xs in [a]
f forall a. a -> [a] -> [a]
: forall a. [a] -> [[a]]
chop4 [a]
r
nextWord :: Int -> SWord 32 -> SWord 32 -> SWord 32
nextWord :: Int -> SWord 32 -> SWord 32 -> SWord 32
nextWord Int
i SWord 32
prev SWord 32
old
| Int
i forall a. Integral a => a -> a -> a
`mod` Int
nk forall a. Eq a => a -> a -> Bool
== Int
0 = SWord 32
old forall a. Bits a => a -> a -> a
`xor` SWord 32 -> GF28 -> SWord 32
subWordRcon (SWord 32
prev forall a. Bits a => a -> Int -> a
`rotateL` Int
8) ([GF28]
roundConstants forall a. [a] -> Int -> a
!! (Int
i forall a. Integral a => a -> a -> a
`div` Int
nk))
| Int
i forall a. Integral a => a -> a -> a
`mod` Int
nk forall a. Eq a => a -> a -> Bool
== Int
4 Bool -> Bool -> Bool
&& Int
nk forall a. Ord a => a -> a -> Bool
> Int
6 = SWord 32
old forall a. Bits a => a -> a -> a
`xor` SWord 32 -> GF28 -> SWord 32
subWordRcon SWord 32
prev GF28
0
| Bool
True = SWord 32
old forall a. Bits a => a -> a -> a
`xor` SWord 32
prev
subWordRcon :: SWord 32 -> GF28 -> SWord 32
subWordRcon :: SWord 32 -> GF28 -> SWord 32
subWordRcon SWord 32
w GF28
rc = forall a. ByteConverter a => [GF28] -> a
fromBytes [GF28
a forall a. Bits a => a -> a -> a
`xor` GF28
rc, GF28
b, GF28
c, GF28
d]
where [GF28
a, GF28
b, GF28
c, GF28
d] = forall a b. (a -> b) -> [a] -> [b]
map GF28 -> GF28
sbox forall a b. (a -> b) -> a -> b
$ forall a. ByteConverter a => a -> [GF28]
toBytes SWord 32
w
sboxTable :: [GF28]
sboxTable :: [GF28]
sboxTable = [GF28 -> GF28
xformByte (GF28 -> GF28
gf28Inverse GF28
b) | GF28
b <- [GF28
0 .. GF28
255]]
where xformByte :: GF28 -> GF28
xformByte :: GF28 -> GF28
xformByte GF28
b = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall a. Bits a => a -> a -> a
xor GF28
0x63 [GF28
b forall a. Bits a => a -> Int -> a
`rotateR` Int
i | Int
i <- [Int
0, Int
4, Int
5, Int
6, Int
7]]
sbox :: GF28 -> GF28
sbox :: GF28 -> GF28
sbox = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [GF28]
sboxTable GF28
0
unSBoxTable :: [GF28]
unSBoxTable :: [GF28]
unSBoxTable = [GF28 -> GF28
gf28Inverse (GF28 -> GF28
xformByte GF28
b) | GF28
b <- [GF28
0 .. GF28
255]]
where xformByte :: GF28 -> GF28
xformByte :: GF28 -> GF28
xformByte GF28
b = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall a. Bits a => a -> a -> a
xor GF28
0x05 [GF28
b forall a. Bits a => a -> Int -> a
`rotateR` Int
i | Int
i <- [Int
2, Int
5, Int
7]]
unSBox :: GF28 -> GF28
unSBox :: GF28 -> GF28
unSBox = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [GF28]
unSBoxTable GF28
0
sboxInverseCorrect :: GF28 -> SBool
sboxInverseCorrect :: GF28 -> SBool
sboxInverseCorrect GF28
x = GF28 -> GF28
unSBox (GF28 -> GF28
sbox GF28
x) forall a. EqSymbolic a => a -> a -> SBool
.== GF28
x SBool -> SBool -> SBool
.&& GF28 -> GF28
sbox (GF28 -> GF28
unSBox GF28
x) forall a. EqSymbolic a => a -> a -> SBool
.== GF28
x
addRoundKey :: Key -> State -> State
addRoundKey :: [SWord 32] -> [SWord 32] -> [SWord 32]
addRoundKey = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Bits a => a -> a -> a
xor
t0Func :: GF28 -> [GF28]
t0Func :: GF28 -> [GF28]
t0Func GF28
a = [GF28
s GF28 -> GF28 -> GF28
`gf28Mult` GF28
2, GF28
s, GF28
s, GF28
s GF28 -> GF28 -> GF28
`gf28Mult` GF28
3] where s :: GF28
s = GF28 -> GF28
sbox GF28
a
t0 :: GF28 -> SWord 32
t0 :: GF28 -> SWord 32
t0 = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [SWord 32]
t0Table SWord 32
0 where t0Table :: [SWord 32]
t0Table = [forall a. ByteConverter a => [GF28] -> a
fromBytes (GF28 -> [GF28]
t0Func GF28
a) | GF28
a <- [GF28
0..GF28
255]]
t1 :: GF28 -> SWord 32
t1 :: GF28 -> SWord 32
t1 = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [SWord 32]
t1Table SWord 32
0 where t1Table :: [SWord 32]
t1Table = [forall a. ByteConverter a => [GF28] -> a
fromBytes (GF28 -> [GF28]
t0Func GF28
a [GF28] -> Int -> [GF28]
`rotR` Int
1) | GF28
a <- [GF28
0..GF28
255]]
t2 :: GF28 -> SWord 32
t2 :: GF28 -> SWord 32
t2 = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [SWord 32]
t2Table SWord 32
0 where t2Table :: [SWord 32]
t2Table = [forall a. ByteConverter a => [GF28] -> a
fromBytes (GF28 -> [GF28]
t0Func GF28
a [GF28] -> Int -> [GF28]
`rotR` Int
2) | GF28
a <- [GF28
0..GF28
255]]
t3 :: GF28 -> SWord 32
t3 :: GF28 -> SWord 32
t3 = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [SWord 32]
t3Table SWord 32
0 where t3Table :: [SWord 32]
t3Table = [forall a. ByteConverter a => [GF28] -> a
fromBytes (GF28 -> [GF28]
t0Func GF28
a [GF28] -> Int -> [GF28]
`rotR` Int
3) | GF28
a <- [GF28
0..GF28
255]]
u0Func :: GF28 -> [GF28]
u0Func :: GF28 -> [GF28]
u0Func GF28
a = [GF28
s GF28 -> GF28 -> GF28
`gf28Mult` GF28
0xE, GF28
s GF28 -> GF28 -> GF28
`gf28Mult` GF28
0x9, GF28
s GF28 -> GF28 -> GF28
`gf28Mult` GF28
0xD, GF28
s GF28 -> GF28 -> GF28
`gf28Mult` GF28
0xB] where s :: GF28
s = GF28 -> GF28
unSBox GF28
a
u0 :: GF28 -> SWord 32
u0 :: GF28 -> SWord 32
u0 = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [SWord 32]
t0Table SWord 32
0 where t0Table :: [SWord 32]
t0Table = [forall a. ByteConverter a => [GF28] -> a
fromBytes (GF28 -> [GF28]
u0Func GF28
a) | GF28
a <- [GF28
0..GF28
255]]
u1 :: GF28 -> SWord 32
u1 :: GF28 -> SWord 32
u1 = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [SWord 32]
t1Table SWord 32
0 where t1Table :: [SWord 32]
t1Table = [forall a. ByteConverter a => [GF28] -> a
fromBytes (GF28 -> [GF28]
u0Func GF28
a [GF28] -> Int -> [GF28]
`rotR` Int
1) | GF28
a <- [GF28
0..GF28
255]]
u2 :: GF28 -> SWord 32
u2 :: GF28 -> SWord 32
u2 = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [SWord 32]
t2Table SWord 32
0 where t2Table :: [SWord 32]
t2Table = [forall a. ByteConverter a => [GF28] -> a
fromBytes (GF28 -> [GF28]
u0Func GF28
a [GF28] -> Int -> [GF28]
`rotR` Int
2) | GF28
a <- [GF28
0..GF28
255]]
u3 :: GF28 -> SWord 32
u3 :: GF28 -> SWord 32
u3 = forall a b.
(Mergeable a, Ord b, SymVal b, Num b) =>
[a] -> a -> SBV b -> a
select [SWord 32]
t3Table SWord 32
0 where t3Table :: [SWord 32]
t3Table = [forall a. ByteConverter a => [GF28] -> a
fromBytes (GF28 -> [GF28]
u0Func GF28
a [GF28] -> Int -> [GF28]
`rotR` Int
3) | GF28
a <- [GF28
0..GF28
255]]
doRounds :: (Bool -> State -> Key -> State) -> KS -> State -> State
doRounds :: (Bool -> [SWord 32] -> [SWord 32] -> [SWord 32])
-> KS -> [SWord 32] -> [SWord 32]
doRounds Bool -> [SWord 32] -> [SWord 32] -> [SWord 32]
rnd ([SWord 32]
ikey, [[SWord 32]]
rkeys, [SWord 32]
fkey) [SWord 32]
sIn = Bool -> [SWord 32] -> [SWord 32] -> [SWord 32]
rnd Bool
True (forall a. [a] -> a
last [[SWord 32]]
rs) [SWord 32]
fkey
where s0 :: [SWord 32]
s0 = [SWord 32]
ikey [SWord 32] -> [SWord 32] -> [SWord 32]
`addRoundKey` [SWord 32]
sIn
rs :: [[SWord 32]]
rs = [SWord 32]
s0 forall a. a -> [a] -> [a]
: [Bool -> [SWord 32] -> [SWord 32] -> [SWord 32]
rnd Bool
False [SWord 32]
s [SWord 32]
k | [SWord 32]
s <- [[SWord 32]]
rs | [SWord 32]
k <- [[SWord 32]]
rkeys ]
aesRound :: Bool -> State -> Key -> State
aesRound :: Bool -> [SWord 32] -> [SWord 32] -> [SWord 32]
aesRound Bool
isFinal [SWord 32]
s [SWord 32]
key = [SWord 32]
d [SWord 32] -> [SWord 32] -> [SWord 32]
`addRoundKey` [SWord 32]
key
where d :: [SWord 32]
d = forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Int -> SWord 32
f Bool
isFinal) [Int
0..Int
3]
a :: [[GF28]]
a = forall a b. (a -> b) -> [a] -> [b]
map forall a. ByteConverter a => a -> [GF28]
toBytes [SWord 32]
s
f :: Bool -> Int -> SWord 32
f Bool
True Int
j = forall a. ByteConverter a => [GF28] -> a
fromBytes [ GF28 -> GF28
sbox ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
0) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
0)
, GF28 -> GF28
sbox ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
1) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
1)
, GF28 -> GF28
sbox ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
2) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
2)
, GF28 -> GF28
sbox ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
3) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
3)
]
f Bool
False Int
j = SWord 32
e0 forall a. Bits a => a -> a -> a
`xor` SWord 32
e1 forall a. Bits a => a -> a -> a
`xor` SWord 32
e2 forall a. Bits a => a -> a -> a
`xor` SWord 32
e3
where e0 :: SWord 32
e0 = GF28 -> SWord 32
t0 ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
0) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
0)
e1 :: SWord 32
e1 = GF28 -> SWord 32
t1 ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
1) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
1)
e2 :: SWord 32
e2 = GF28 -> SWord 32
t2 ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
2) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
2)
e3 :: SWord 32
e3 = GF28 -> SWord 32
t3 ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
3) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
3)
aesInvRound :: Bool -> State -> Key -> State
aesInvRound :: Bool -> [SWord 32] -> [SWord 32] -> [SWord 32]
aesInvRound Bool
isFinal [SWord 32]
s [SWord 32]
key = [SWord 32]
d [SWord 32] -> [SWord 32] -> [SWord 32]
`addRoundKey` [SWord 32]
key
where d :: [SWord 32]
d = forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Int -> SWord 32
f Bool
isFinal) [Int
0..Int
3]
a :: [[GF28]]
a = forall a b. (a -> b) -> [a] -> [b]
map forall a. ByteConverter a => a -> [GF28]
toBytes [SWord 32]
s
f :: Bool -> Int -> SWord 32
f Bool
True Int
j = forall a. ByteConverter a => [GF28] -> a
fromBytes [ GF28 -> GF28
unSBox ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
0) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
0)
, GF28 -> GF28
unSBox ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
3) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
1)
, GF28 -> GF28
unSBox ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
2) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
2)
, GF28 -> GF28
unSBox ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
1) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
3)
]
f Bool
False Int
j = SWord 32
e0 forall a. Bits a => a -> a -> a
`xor` SWord 32
e1 forall a. Bits a => a -> a -> a
`xor` SWord 32
e2 forall a. Bits a => a -> a -> a
`xor` SWord 32
e3
where e0 :: SWord 32
e0 = GF28 -> SWord 32
u0 ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
0) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
0)
e1 :: SWord 32
e1 = GF28 -> SWord 32
u1 ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
3) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
1)
e2 :: SWord 32
e2 = GF28 -> SWord 32
u2 ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
2) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
2)
e3 :: SWord 32
e3 = GF28 -> SWord 32
u3 ([[GF28]]
a forall a. [a] -> Int -> a
!! ((Int
jforall a. Num a => a -> a -> a
+Int
1) forall a. Integral a => a -> a -> a
`mod` Int
4) forall a. [a] -> Int -> a
!! Int
3)
aesKeySchedule :: Key -> (KS, KS)
aesKeySchedule :: [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
| Int
nk forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Int
4, Int
6, Int
8]
= (KS
encKS, KS
decKS)
| Bool
True
= forall a. HasCallStack => [Char] -> a
error [Char]
"aesKeySchedule: Invalid key size"
where nk :: Int
nk = forall (t :: * -> *) a. Foldable t => t a -> Int
length [SWord 32]
key
nr :: Int
nr = Int
nk forall a. Num a => a -> a -> a
+ Int
6
encKS :: KS
encKS@([SWord 32]
f, [[SWord 32]]
m, [SWord 32]
l) = (forall a. [a] -> a
head [[SWord 32]]
rKeys, forall a. Int -> [a] -> [a]
take (Int
nrforall a. Num a => a -> a -> a
-Int
1) (forall a. [a] -> [a]
tail [[SWord 32]]
rKeys), [[SWord 32]]
rKeys forall a. [a] -> Int -> a
!! Int
nr)
decKS :: KS
decKS = ([SWord 32]
l, forall a b. (a -> b) -> [a] -> [b]
map [SWord 32] -> [SWord 32]
invMixColumns (forall a. [a] -> [a]
reverse [[SWord 32]]
m), [SWord 32]
f)
rKeys :: [[SWord 32]]
rKeys = Int -> [SWord 32] -> [[SWord 32]]
keyExpansion Int
nk [SWord 32]
key
aesEncrypt :: [SWord 32] -> KS -> [SWord 32]
aesEncrypt :: [SWord 32] -> KS -> [SWord 32]
aesEncrypt [SWord 32]
pt KS
encKS
| forall (t :: * -> *) a. Foldable t => t a -> Int
length [SWord 32]
pt forall a. Eq a => a -> a -> Bool
== Int
4
= (Bool -> [SWord 32] -> [SWord 32] -> [SWord 32])
-> KS -> [SWord 32] -> [SWord 32]
doRounds Bool -> [SWord 32] -> [SWord 32] -> [SWord 32]
aesRound KS
encKS [SWord 32]
pt
| Bool
True
= forall a. HasCallStack => [Char] -> a
error [Char]
"aesEncrypt: Invalid plain-text size"
aesDecrypt :: [SWord 32] -> KS -> [SWord 32]
aesDecrypt :: [SWord 32] -> KS -> [SWord 32]
aesDecrypt [SWord 32]
ct KS
decKS
| forall (t :: * -> *) a. Foldable t => t a -> Int
length [SWord 32]
ct forall a. Eq a => a -> a -> Bool
== Int
4
= (Bool -> [SWord 32] -> [SWord 32] -> [SWord 32])
-> KS -> [SWord 32] -> [SWord 32]
doRounds Bool -> [SWord 32] -> [SWord 32] -> [SWord 32]
aesInvRound KS
decKS [SWord 32]
ct
| Bool
True
= forall a. HasCallStack => [Char] -> a
error [Char]
"aesDecrypt: Invalid cipher-text size"
t128Enc :: [SWord 32]
t128Enc :: [SWord 32]
t128Enc = [SWord 32] -> KS -> [SWord 32]
aesEncrypt [SWord 32]
pt KS
ks
where pt :: [SWord 32]
pt = [SWord 32
0x00112233, SWord 32
0x44556677, SWord 32
0x8899aabb, SWord 32
0xccddeeff]
key :: [SWord 32]
key = [SWord 32
0x00010203, SWord 32
0x04050607, SWord 32
0x08090a0b, SWord 32
0x0c0d0e0f]
(KS
ks, KS
_) = [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
t128Dec :: [SWord 32]
t128Dec :: [SWord 32]
t128Dec = [SWord 32] -> KS -> [SWord 32]
aesDecrypt [SWord 32]
ct KS
ks
where ct :: [SWord 32]
ct = [SWord 32
0x69c4e0d8, SWord 32
0x6a7b0430, SWord 32
0xd8cdb780, SWord 32
0x70b4c55a]
key :: [SWord 32]
key = [SWord 32
0x00010203, SWord 32
0x04050607, SWord 32
0x08090a0b, SWord 32
0x0c0d0e0f]
(KS
_, KS
ks) = [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
t192Enc :: [SWord 32]
t192Enc :: [SWord 32]
t192Enc = [SWord 32] -> KS -> [SWord 32]
aesEncrypt [SWord 32]
pt KS
ks
where pt :: [SWord 32]
pt = [SWord 32
0x00112233, SWord 32
0x44556677, SWord 32
0x8899aabb, SWord 32
0xccddeeff]
key :: [SWord 32]
key = [SWord 32
0x00010203, SWord 32
0x04050607, SWord 32
0x08090a0b, SWord 32
0x0c0d0e0f, SWord 32
0x10111213, SWord 32
0x14151617]
(KS
ks, KS
_) = [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
t192Dec :: [SWord 32]
t192Dec :: [SWord 32]
t192Dec = [SWord 32] -> KS -> [SWord 32]
aesDecrypt [SWord 32]
ct KS
ks
where ct :: [SWord 32]
ct = [SWord 32
0xdda97ca4, SWord 32
0x864cdfe0, SWord 32
0x6eaf70a0, SWord 32
0xec0d7191]
key :: [SWord 32]
key = [SWord 32
0x00010203, SWord 32
0x04050607, SWord 32
0x08090a0b, SWord 32
0x0c0d0e0f, SWord 32
0x10111213, SWord 32
0x14151617]
(KS
_, KS
ks) = [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
t256Enc :: [SWord 32]
t256Enc :: [SWord 32]
t256Enc = [SWord 32] -> KS -> [SWord 32]
aesEncrypt [SWord 32]
pt KS
ks
where pt :: [SWord 32]
pt = [SWord 32
0x00112233, SWord 32
0x44556677, SWord 32
0x8899aabb, SWord 32
0xccddeeff]
key :: [SWord 32]
key = [SWord 32
0x00010203, SWord 32
0x04050607, SWord 32
0x08090a0b, SWord 32
0x0c0d0e0f, SWord 32
0x10111213, SWord 32
0x14151617, SWord 32
0x18191a1b, SWord 32
0x1c1d1e1f]
(KS
ks, KS
_) = [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
t256Dec :: [SWord 32]
t256Dec :: [SWord 32]
t256Dec = [SWord 32] -> KS -> [SWord 32]
aesDecrypt [SWord 32]
ct KS
ks
where ct :: [SWord 32]
ct = [SWord 32
0x8ea2b7ca, SWord 32
0x516745bf, SWord 32
0xeafc4990, SWord 32
0x4b496089]
key :: [SWord 32]
key = [SWord 32
0x00010203, SWord 32
0x04050607, SWord 32
0x08090a0b, SWord 32
0x0c0d0e0f, SWord 32
0x10111213, SWord 32
0x14151617, SWord 32
0x18191a1b, SWord 32
0x1c1d1e1f]
(KS
_, KS
ks) = [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
aes128IsCorrect :: (SWord 32, SWord 32, SWord 32, SWord 32)
-> (SWord 32, SWord 32, SWord 32, SWord 32)
-> SBool
aes128IsCorrect :: (SWord 32, SWord 32, SWord 32, SWord 32)
-> (SWord 32, SWord 32, SWord 32, SWord 32) -> SBool
aes128IsCorrect (SWord 32
i0, SWord 32
i1, SWord 32
i2, SWord 32
i3) (SWord 32
k0, SWord 32
k1, SWord 32
k2, SWord 32
k3) = [SWord 32]
pt forall a. EqSymbolic a => a -> a -> SBool
.== [SWord 32]
pt'
where pt :: [SWord 32]
pt = [SWord 32
i0, SWord 32
i1, SWord 32
i2, SWord 32
i3]
key :: [SWord 32]
key = [SWord 32
k0, SWord 32
k1, SWord 32
k2, SWord 32
k3]
(KS
encKS, KS
decKS) = [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
ct :: [SWord 32]
ct = [SWord 32] -> KS -> [SWord 32]
aesEncrypt [SWord 32]
pt KS
encKS
pt' :: [SWord 32]
pt' = [SWord 32] -> KS -> [SWord 32]
aesDecrypt [SWord 32]
ct KS
decKS
cgAES128BlockEncrypt :: IO ()
cgAES128BlockEncrypt :: IO ()
cgAES128BlockEncrypt = forall a. Maybe [Char] -> [Char] -> SBVCodeGen a -> IO a
compileToC forall a. Maybe a
Nothing [Char]
"aes128BlockEncrypt" forall a b. (a -> b) -> a -> b
$ do
[SWord 32]
pt <- forall a. SymVal a => Int -> [Char] -> SBVCodeGen [SBV a]
cgInputArr Int
4 [Char]
"pt"
[SWord 32]
key <- forall a. SymVal a => Int -> [Char] -> SBVCodeGen [SBV a]
cgInputArr Int
4 [Char]
"key"
[Integer] -> SBVCodeGen ()
cgSetDriverValues forall a b. (a -> b) -> a -> b
$ [Integer
0x00112233, Integer
0x44556677, Integer
0x8899aabb, Integer
0xccddeeff]
forall a. [a] -> [a] -> [a]
++ [Integer
0x00010203, Integer
0x04050607, Integer
0x08090a0b, Integer
0x0c0d0e0f]
let (KS
encKs, KS
_) = [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
forall a. SymVal a => [Char] -> [SBV a] -> SBVCodeGen ()
cgOutputArr [Char]
"ct" forall a b. (a -> b) -> a -> b
$ [SWord 32] -> KS -> [SWord 32]
aesEncrypt [SWord 32]
pt KS
encKs
aesLibComponents :: Int -> [(String, SBVCodeGen ())]
aesLibComponents :: Int -> [([Char], SBVCodeGen ())]
aesLibComponents Int
sz = [ ([Char]
"aes" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
sz forall a. [a] -> [a] -> [a]
++ [Char]
"KeySchedule", SBVCodeGen ()
keySchedule)
, ([Char]
"aes" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
sz forall a. [a] -> [a] -> [a]
++ [Char]
"BlockEncrypt", SBVCodeGen ()
enc)
, ([Char]
"aes" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
sz forall a. [a] -> [a] -> [a]
++ [Char]
"BlockDecrypt", SBVCodeGen ()
dec)
]
where
nk :: Int
nk
| Int
sz forall a. Eq a => a -> a -> Bool
== Int
128 = Int
4
| Int
sz forall a. Eq a => a -> a -> Bool
== Int
192 = Int
6
| Int
sz forall a. Eq a => a -> a -> Bool
== Int
256 = Int
8
| Bool
True = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"aesLibComponents: Size must be one of 128, 192, or 256; received: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
sz
nr :: Int
nr = Int
nk forall a. Num a => a -> a -> a
+ Int
6
xk :: Int
xk = Int
4 forall a. Num a => a -> a -> a
* (Int
nr forall a. Num a => a -> a -> a
+ Int
1)
keySchedule :: SBVCodeGen ()
keySchedule = do [SWord 32]
key <- forall a. SymVal a => Int -> [Char] -> SBVCodeGen [SBV a]
cgInputArr Int
nk [Char]
"key"
let (KS
encKS, KS
decKS) = [SWord 32] -> (KS, KS)
aesKeySchedule [SWord 32]
key
forall a. SymVal a => [Char] -> [SBV a] -> SBVCodeGen ()
cgOutputArr [Char]
"encKS" (KS -> [SWord 32]
ksToXKey KS
encKS)
forall a. SymVal a => [Char] -> [SBV a] -> SBVCodeGen ()
cgOutputArr [Char]
"decKS" (KS -> [SWord 32]
ksToXKey KS
decKS)
enc :: SBVCodeGen ()
enc = do [SWord 32]
pt <- forall a. SymVal a => Int -> [Char] -> SBVCodeGen [SBV a]
cgInputArr Int
4 [Char]
"pt"
[SWord 32]
xkey <- forall a. SymVal a => Int -> [Char] -> SBVCodeGen [SBV a]
cgInputArr Int
xk [Char]
"xkey"
forall a. SymVal a => [Char] -> [SBV a] -> SBVCodeGen ()
cgOutputArr [Char]
"ct" forall a b. (a -> b) -> a -> b
$ [SWord 32] -> KS -> [SWord 32]
aesEncrypt [SWord 32]
pt ([SWord 32] -> KS
xkeyToKS [SWord 32]
xkey)
dec :: SBVCodeGen ()
dec = do [SWord 32]
pt <- forall a. SymVal a => Int -> [Char] -> SBVCodeGen [SBV a]
cgInputArr Int
4 [Char]
"ct"
[SWord 32]
xkey <- forall a. SymVal a => Int -> [Char] -> SBVCodeGen [SBV a]
cgInputArr Int
xk [Char]
"xkey"
forall a. SymVal a => [Char] -> [SBV a] -> SBVCodeGen ()
cgOutputArr [Char]
"pt" forall a b. (a -> b) -> a -> b
$ [SWord 32] -> KS -> [SWord 32]
aesDecrypt [SWord 32]
pt ([SWord 32] -> KS
xkeyToKS [SWord 32]
xkey)
xkeyToKS :: [SWord 32] -> KS
xkeyToKS :: [SWord 32] -> KS
xkeyToKS [SWord 32]
xs = ([SWord 32]
f, [[SWord 32]]
m, [SWord 32]
l)
where f :: [SWord 32]
f = forall a. Int -> [a] -> [a]
take Int
4 [SWord 32]
xs
m :: [[SWord 32]]
m = forall a. [a] -> [[a]]
chop4 (forall a. Int -> [a] -> [a]
take (Int
xk forall a. Num a => a -> a -> a
- Int
8) (forall a. Int -> [a] -> [a]
drop Int
4 [SWord 32]
xs))
l :: [SWord 32]
l = forall a. Int -> [a] -> [a]
drop (Int
xk forall a. Num a => a -> a -> a
- Int
4) [SWord 32]
xs
ksToXKey :: KS -> [SWord 32]
ksToXKey :: KS -> [SWord 32]
ksToXKey ([SWord 32]
f, [[SWord 32]]
m, [SWord 32]
l) = [SWord 32]
f forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[SWord 32]]
m forall a. [a] -> [a] -> [a]
++ [SWord 32]
l
chop4 :: [a] -> [[a]]
chop4 :: forall a. [a] -> [[a]]
chop4 [] = []
chop4 [a]
xs = let ([a]
f, [a]
r) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
4 [a]
xs in [a]
f forall a. a -> [a] -> [a]
: forall a. [a] -> [[a]]
chop4 [a]
r
cgAESLibrary :: Int -> Maybe FilePath -> IO ()
cgAESLibrary :: Int -> Maybe [Char] -> IO ()
cgAESLibrary Int
sz Maybe [Char]
mbd
| Int
sz forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Int
128, Int
192, Int
256] = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall a.
Maybe [Char] -> [Char] -> [([Char], SBVCodeGen a)] -> IO [a]
compileToCLib Maybe [Char]
mbd [Char]
nm (Int -> [([Char], SBVCodeGen ())]
aesLibComponents Int
sz)
| Bool
True = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"cgAESLibrary: Size must be one of 128, 192, or 256, received: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
sz
where nm :: [Char]
nm = [Char]
"aes" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
sz forall a. [a] -> [a] -> [a]
++ [Char]
"Lib"
cgAES128Library :: IO ()
cgAES128Library :: IO ()
cgAES128Library = Int -> Maybe [Char] -> IO ()
cgAESLibrary Int
128 forall a. Maybe a
Nothing
hex8 :: (SymVal a, Show a, Integral a) => SBV a -> String
hex8 :: forall a. (SymVal a, Show a, Integral a) => SBV a -> [Char]
hex8 SBV a
v = forall a. Int -> a -> [a]
replicate (Int
8 forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
s) Char
'0' forall a. [a] -> [a] -> [a]
++ [Char]
s
where s :: [Char]
s = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (Integral a, Show a) => a -> ShowS
showHex [Char]
"" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HasCallStack => Maybe a -> a
fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. SymVal a => SBV a -> Maybe a
unliteral forall a b. (a -> b) -> a -> b
$ SBV a
v
{-# ANN aesRound ("HLint: ignore Use head" :: String) #-}
{-# ANN aesInvRound ("HLint: ignore Use head" :: String) #-}