module Crypto.Longshot.TH where
import Control.Monad
import Data.Foldable
import Language.Haskell.TH
import Crypto.Longshot
bruteforceN :: Int -> Q Exp -> Q Exp -> Q Exp -> Q Exp -> Q Exp
bruteforceN numBind chars hex hasher prefix = do
names <- replicateM numBind (newName "names")
let pats = varP <$> names
let bytes = [| $( prefix ) <>
$( foldl' (\a b -> [| $a <> $b |])
[| mempty |]
(varE <$> names)
)
|]
let cond = condE [| $( appE hasher bytes ) == $(hex) |]
[| Just (toKey $( bytes )) |]
[| Nothing |]
let stmts = ((`bindS` chars) <$> pats) <> [noBindS cond]
[| foldl' (<|>) empty $( compE stmts ) |]
funcGenerator :: Q [Dec]
funcGenerator = forM [0 .. defNumBind] funcG where
funcG numBind = do
let name = mkName $ "bruteforce" <> show numBind
chars <- newName "chars"
hex <- newName "hex"
hasher <- newName "hasher"
prefix <- newName "prefix"
funD name
[ clause [varP chars, varP hex, varP hasher, varP prefix]
(normalB (bruteforceN numBind (varE chars) (varE hex) (varE hasher) (varE prefix)))
[]
]
funcList :: Q Exp
funcList = listE (varE . mkName . ("bruteforce" <>) . show <$> [0 .. defNumBind])