module HAppS.Crypto.W64 where
import HAppS.Crypto.DES
import HAppS.Crypto.SHA1
import Data.List
import Numeric(readHex)
#ifdef TEST
import Test.QuickCheck
#endif
pad x = padding++x
where
padLength = 4 (length x) `mod` 4
padding = (toEnum padLength) : (take (padLength1) $ repeat 'A')
unpad x = drop (fromEnum $ head x) x
prop_PadUnPad x = x==(unpad $ pad x)
is4Char x = length x==4
quadCharToW64 x = fromInteger $ impl $ map (fromIntegral.fromEnum) x
where impl [a,b,c,d]=(a*2^24+b*2^16+c*2^8+d)
w64ToQuadChar w64 =
map (toEnum.fromIntegral) $! reverse $! take 4 $! v ++ (repeat 0)
where v = w64ToQuadNum w64
w64ToQuadNum w64 = unfoldr (\x->if x==0 then Nothing else
Just (x `mod` 256,x `div` 256))
w64
#ifdef TEST
prop_quadCharW64 x = is4Char x ==> x == (w64ToQuadChar $ quadCharToW64 x)
#endif
toQuadChars [] = []
toQuadChars (a:b:c:d:rest) = [a,b,c,d]:toQuadChars rest
stringToW64s x = map quadCharToW64 $ toQuadChars $ pad x
w64sToString x = unpad $ concat $ map w64ToQuadChar x
prop_stringW64 x = x == (w64sToString $ stringToW64s x)
hexToW64 x = fromInteger $ fst $ head $ readHex $ take 16 x
stringToKey x = hexToW64 $ sha1 x
des_encrypt key v = map (flip des_enc $ stringToKey key) $ stringToW64s v
des_decrypt key v =
w64sToString $
map (toInteger . flip des_dec (stringToKey key))
v
prop_DES key val = val == (des_decrypt key $ des_encrypt key val)