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