This repository has been archived by the owner on Sep 20, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 139
/
Gen.hs
143 lines (124 loc) · 6.7 KB
/
Gen.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Main where
import System.FilePath
import System.Directory
import Control.Applicative
import Control.Monad
import Template
readTemplate templateFile = parseTemplate <$> readFile templateFile
writeTemplate file vars multi template = writeFile file (renderTemplate template vars multi)
-- print a loud error if the conversion is losing information
divSafe :: Int -> Int -> Int
divSafe a b
| r == 0 = d
| otherwise = error ("cannot safely convert values: trying to divide " ++ show a ++ " by " ++ show b ++ " remainder: " ++ show r)
where
(d,r) = a `divMod` b
newtype Bits = Bits Int
deriving (Show,Eq,Num)
newtype Bytes = Bytes Int
deriving (Show,Eq,Num)
bitsToBytes :: Bits -> Bytes
bitsToBytes (Bits b) = Bytes (b `divSafe` 8)
class SizedNum a where
showBytes :: a -> String
showBits :: a -> String
showW64 :: a -> String
instance SizedNum Bytes where
showBits (Bytes b) = show (b * 8)
showBytes (Bytes b) = show b
showW64 (Bytes b) = show (b `divSafe` 8)
instance SizedNum Bits where
showBits (Bits b) = show b
showBytes (Bits b) = show (b `divSafe` 8)
showW64 (Bits b) = show (b `divSafe` 64)
data GenHashModule = GenHashModule
{ ghmModuleName :: String
, ghmHeaderFile :: String
, ghmHashName :: String
, ghmContextSize :: Bytes
, ghmCustomizable :: HashCustom
}
data Prop =
VarCtx (Bits -> Bytes)
data HashCustom =
HashSimple Bits -- digest size in bits
Bytes -- block length in bytes
| HashMulti [Prop] [(Bits, Bytes)] -- list of (digest output size in *bits*, block size in bytes)
hashModules =
-- module header hash ctx dg blk
[ GenHashModule "Blake2s" "blake2.h" "blake2s" 136 (HashMulti [] [(160, 64), (224,64), (256,64)])
, GenHashModule "Blake2sp" "blake2.h" "blake2sp" 1752 (HashMulti [] [(224,64), (256,64)])
, GenHashModule "Blake2b" "blake2.h" "blake2b" 248 (HashMulti [] [(160, 128), (224, 128), (256, 128), (384, 128), (512,128)])
, GenHashModule "Blake2bp" "blake2.h" "blake2bp" 1768 (HashMulti [] [(512,128)])
, GenHashModule "MD2" "md2.h" "md2" 96 (HashSimple 128 16)
, GenHashModule "MD4" "md4.h" "md4" 96 (HashSimple 128 64)
, GenHashModule "MD5" "md5.h" "md5" 96 (HashSimple 128 64)
, GenHashModule "SHA1" "sha1.h" "sha1" 96 (HashSimple 160 64)
, GenHashModule "SHA224" "sha256.h" "sha224" 192 (HashSimple 224 64)
, GenHashModule "SHA256" "sha256.h" "sha256" 192 (HashSimple 256 64)
, GenHashModule "SHA384" "sha512.h" "sha384" 256 (HashSimple 384 128)
, GenHashModule "SHA512" "sha512.h" "sha512" 256 (HashSimple 512 128)
, GenHashModule "SHA512t" "sha512.h" "sha512t" 256 (HashMulti [] [(224,128),(256,128)])
, GenHashModule "Keccak" "keccak.h" "keccak" 352 (HashMulti [VarCtx sha3CtxSize] [(224,144),(256,136),(384,104),(512,72)])
, GenHashModule "SHA3" "sha3.h" "sha3" 352 (HashMulti [VarCtx sha3CtxSize] [(224,144),(256,136),(384,104),(512,72)])
, GenHashModule "RIPEMD160" "ripemd.h" "ripemd160" 128 (HashSimple 160 64)
, GenHashModule "Skein256" "skein256.h" "skein256" 96 (HashMulti [] [(224,32),(256,32)])
, GenHashModule "Skein512" "skein512.h" "skein512" 160 (HashMulti [] [(224,64),(256,64),(384,64),(512,64)])
, GenHashModule "Tiger" "tiger.h" "tiger" 96 (HashSimple 192 64)
, GenHashModule "Whirlpool" "whirlpool.h" "whirlpool" 168 (HashSimple 512 64)
]
sha3CtxSize :: Bits -> Bytes
sha3CtxSize bitLen = 4 + 4 + 8 * 25 -- generic context
+ sha3BlockSize bitLen -- variable buffer
sha3BlockSize :: Bits -> Bytes
sha3BlockSize bitLen = 200 - 2 * bitsToBytes bitLen
renderHashModules genOpts = do
hashTemplate <- readTemplate "template/hash.hs"
hashLenTemplate <- readTemplate "template/hash-len.hs"
forM_ hashModules $ \ghm -> do
let baseVars = [ ("MODULENAME" , ghmModuleName ghm)
, ("HEADER_FILE" , ghmHeaderFile ghm)
, ("HASHNAME" , ghmHashName ghm)
, ("CTX_SIZE_BYTES" , showBytes (ghmContextSize ghm))
, ("CTX_SIZE_WORD64" , showW64 (ghmContextSize ghm))
] :: Attrs
let mainDir = "Crypto/Hash"
mainName = mainDir </> (ghmModuleName ghm ++ ".hs")
createDirectoryIfMissing True mainDir
let (tpl, addVars, multiVars) =
case ghmCustomizable ghm of
HashSimple digestSize blockLength ->
(hashTemplate,
[ ("DIGEST_SIZE_BITS" , showBits digestSize)
, ("DIGEST_SIZE_BYTES", showBytes digestSize)
, ("BLOCK_SIZE_BYTES" , showBytes blockLength)
]
, []
)
HashMulti props customSizes ->
let customCtxSize =
let getVarCtx _ (VarCtx p) = Just p
getVarCtx x _ = x
in case foldl getVarCtx Nothing props of
Nothing -> \_ ->
[ ("CUSTOM_CTX_SIZE_BYTES" , showBytes (ghmContextSize ghm))
, ("CUSTOM_CTX_SIZE_WORD64" , showW64 (ghmContextSize ghm))
]
Just prop -> \outputSize ->
[ ("CUSTOM_CTX_SIZE_BYTES" , showBytes $ prop outputSize)
, ("CUSTOM_CTX_SIZE_WORD64" , showW64 $ prop outputSize)
]
in (hashLenTemplate, [],
[ ("CUSTOMIZABLE", map (\(outputSizeBits, customBlockSize) ->
[ ("CUSTOM_BITSIZE", showBits outputSizeBits)
, ("CUSTOM_DIGEST_SIZE_BITS", showBits outputSizeBits)
, ("CUSTOM_DIGEST_SIZE_BYTES", showBytes outputSizeBits)
, ("CUSTOM_BLOCK_SIZE_BYTES", showBytes customBlockSize)
] ++ customCtxSize outputSizeBits) customSizes
)
]
)
writeTemplate mainName (baseVars ++ addVars) multiVars tpl
main = do
renderHashModules ()