Permalink
Browse files

Fix alignment issue on pureMD5

Ignore-this: bf6516eda1075bc14eb3147c56cbaa74

darcs-hash:20090905214317-cef97-26c672ecc06fd9206dbef88c3db1f32e90c766b1.gz
  • Loading branch information...
1 parent 36c6ad1 commit 803bb070c2eb6acd6c64de1720ede1d475634437 @TomMD committed Sep 5, 2009
Showing with 30 additions and 8 deletions.
  1. +30 −8 Data/Digest/Pure/MD5.hs
View
38 Data/Digest/Pure/MD5.hs
@@ -118,16 +118,20 @@ blockAndDo !ctx bs =
-- context across calls to applyMD5Rounds.
performMD5Update :: MD5Context -> ByteString -> MD5Context
performMD5Update !ctx@(MD5Ctx !par@(MD5Par !a !b !c !d) _ !len) !bs = {-# SCC "performMD5Update" #-}
- let MD5Par a' b' c' d' = applyMD5Rounds par bs
+ let MD5Par a' b' c' d' = if isAligned bs
+ then applyMD5Rounds par bs getAlignedNthWord
+ else applyMD5Rounds par bs getUnalignedNthWord
in MD5Ctx {
mdPartial = MD5Par (a' + a) (b' + b) (c' + c) (d' + d),
mdLeftOver = B.empty,
mdTotalLen = len + blockSizeBits
}
+ where
+ isAligned (PS _ off _) = off `rem` 4 == 0
{-# INLINE performMD5Update #-}
-applyMD5Rounds :: MD5Partial -> ByteString -> MD5Partial
-applyMD5Rounds par@(MD5Par a b c d) w = {-# SCC "applyMD5Rounds" #-}
+applyMD5Rounds :: MD5Partial -> ByteString -> (Int -> ByteString -> Word32) -> MD5Partial
+applyMD5Rounds par@(MD5Par a b c d) w getNthWord = {-# SCC "applyMD5Rounds" #-}
let -- Round 1
!r0 = ff a b c d (w!!0) 7 3614090360
!r1 = ff d r0 b c (w!!1) 12 3905402710
@@ -228,13 +232,31 @@ applyMD5Rounds par@(MD5Par a b c d) w = {-# SCC "applyMD5Rounds" #-}
{-# INLINE ii #-}
(!!) word32s pos = getNthWord pos word32s
{-# INLINE (!!) #-}
- getNthWord n bs@(PS ptr off len) =
- inlinePerformIO $ withForeignPtr ptr $ \ptr' -> do
- let p = castPtr $ plusPtr ptr' off
- peekElemOff p n
- {-# INLINE getNthWord #-}
{-# INLINE applyMD5Rounds #-}
+-- getAlignedNthWord :: Word32 -> ByteString -> Word32
+getAlignedNthWord n bs@(PS ptr off len) =
+ inlinePerformIO $ withForeignPtr ptr $ \ptr' -> do
+ let p = castPtr $ plusPtr ptr' off
+ peekElemOff p n
+{-# INLINE getAlignedNthWord #-}
+
+-- getUnalignedNthWord :: Word32 -> ByteString -> Word32
+getUnalignedNthWord n bs@(PS ptr off len) =
+ inlinePerformIO $ withForeignPtr ptr $ \ptr' -> do
+ let p = castPtr $ plusPtr ptr' (off + n*4) :: Ptr Word8
+ w1 <- peekElemOff p 0
+ w2 <- peekElemOff p 1
+ w3 <- peekElemOff p 2
+ w4 <- peekElemOff p 3
+ let y = (w4 .<. 24 .|. w3 .<. 16 .|. w2 .<.8 .|. fromIntegral w1)
+ return y
+{-# INLINE getUnalignedNthWord #-}
+
+infix 9 .<.
+(.<.) :: Word8 -> Int -> Word32
+(.<.) w i = (fromIntegral w) `shiftL` i
+
----- Some quick and dirty instances follow -----
instance Show MD5Digest where

0 comments on commit 803bb07

Please sign in to comment.