diff options
-rw-r--r-- | Data/OpenPGP.hs | 11 | ||||
-rw-r--r-- | Data/OpenPGP/Internal.hs | 55 | ||||
-rw-r--r-- | Data/OpenPGP/Util.hs | 2 |
3 files changed, 58 insertions, 10 deletions
diff --git a/Data/OpenPGP.hs b/Data/OpenPGP.hs index 74223b2..6667f1a 100644 --- a/Data/OpenPGP.hs +++ b/Data/OpenPGP.hs | |||
@@ -1005,9 +1005,7 @@ instance BINARY_CLASS MPI where | |||
1005 | put (MPI i) | 1005 | put (MPI i) |
1006 | | i >= 0 = do | 1006 | | i >= 0 = do |
1007 | put (bitl :: Word16) | 1007 | put (bitl :: Word16) |
1008 | flip fix (B.length bytes - 1) $ \loop j -> do | 1008 | putSomeByteString bytes |
1009 | put (B.index bytes j) | ||
1010 | when (j /= 0) $ loop (j - 1) | ||
1011 | | otherwise = fail $ "MPI is less than 0: " ++ show i | 1009 | | otherwise = fail $ "MPI is less than 0: " ++ show i |
1012 | where | 1010 | where |
1013 | (bytes, bitl) | 1011 | (bytes, bitl) |
@@ -1015,16 +1013,15 @@ instance BINARY_CLASS MPI where | |||
1015 | | otherwise = | 1013 | | otherwise = |
1016 | (bytes', (fromIntegral (B.length bytes') - 1) * 8 + sigBit) | 1014 | (bytes', (fromIntegral (B.length bytes') - 1) * 8 + sigBit) |
1017 | 1015 | ||
1018 | sigBit = fst $ until ((==0) . snd) | 1016 | sigBit = fromIntegral $ 8 - countLeadingZeros (B.index bytes 0) |
1019 | (first (+1) . second (`shiftR` 1)) (0,B.last bytes) | 1017 | bytes' = B.reverse $ B.unfoldr (\x -> |
1020 | bytes' = B.unfoldr (\x -> | ||
1021 | if x == 0 then Nothing else | 1018 | if x == 0 then Nothing else |
1022 | Just (fromIntegral x, x `shiftR` 8) | 1019 | Just (fromIntegral x, x `shiftR` 8) |
1023 | ) i | 1020 | ) i |
1024 | get = do | 1021 | get = do |
1025 | length <- fmap fromIntegral (get :: Get Word16) | 1022 | length <- fmap fromIntegral (get :: Get Word16) |
1026 | bytes <- getSomeByteString =<< assertProp (>0) ((length + 7) `div` 8) | 1023 | bytes <- getSomeByteString =<< assertProp (>0) ((length + 7) `div` 8) |
1027 | return $ MPI $ B.foldl (\a b -> (a `shiftL` 8) + fromIntegral b) 0 bytes | 1024 | return $ MPI $ getBigNum (B.toStrict bytes) |
1028 | 1025 | ||
1029 | listUntilEnd :: (BINARY_CLASS a) => Get [a] | 1026 | listUntilEnd :: (BINARY_CLASS a) => Get [a] |
1030 | listUntilEnd = do | 1027 | listUntilEnd = do |
diff --git a/Data/OpenPGP/Internal.hs b/Data/OpenPGP/Internal.hs index b2bd506..24330f1 100644 --- a/Data/OpenPGP/Internal.hs +++ b/Data/OpenPGP/Internal.hs | |||
@@ -1,7 +1,16 @@ | |||
1 | {-# LANGUAGE BangPatterns #-} | ||
1 | module Data.OpenPGP.Internal where | 2 | module Data.OpenPGP.Internal where |
2 | 3 | ||
3 | import Data.Word | 4 | import Data.Bits |
4 | import Data.Bits | 5 | import qualified Data.ByteString as BS |
6 | import qualified Data.ByteString.Internal as BS | ||
7 | import Data.Word | ||
8 | import Foreign.ForeignPtr | ||
9 | import Foreign.Ptr | ||
10 | import Foreign.Storable | ||
11 | import System.Endian | ||
12 | import System.IO.Unsafe | ||
13 | |||
5 | 14 | ||
6 | decode_s2k_count :: Word8 -> Word32 | 15 | decode_s2k_count :: Word8 -> Word32 |
7 | decode_s2k_count c = (16 + (fromIntegral c .&. 15)) `shiftL` | 16 | decode_s2k_count c = (16 + (fromIntegral c .&. 15)) `shiftL` |
@@ -18,3 +27,45 @@ encode_s2k_count iterations | |||
18 | encode_s2k_count' count c | 27 | encode_s2k_count' count c |
19 | | count < 32 = (count, c) | 28 | | count < 32 = (count, c) |
20 | | otherwise = encode_s2k_count' (count `shiftR` 1) (c+1) | 29 | | otherwise = encode_s2k_count' (count `shiftR` 1) (c+1) |
30 | |||
31 | getBigNum :: BS.ByteString -> Integer | ||
32 | getBigNum bytes = unsafeDupablePerformIO $ | ||
33 | let (fptr,offset,len) = BS.toForeignPtr bytes | ||
34 | in withForeignPtr fptr $ \ptr -> do | ||
35 | let p = ptr `plusPtr` offset :: Ptr Word64 | ||
36 | e = p `plusPtr` (len .&. complement 7) | ||
37 | e2 = e `plusPtr` (len .&. 7) | ||
38 | go !p !a | ||
39 | | p==e = return a | ||
40 | | otherwise = do | ||
41 | w64 <- fromBE64 <$> peek p | ||
42 | let a' = (a `shiftL` 64) + fromIntegral w64 | ||
43 | go (p `plusPtr` 8) a' | ||
44 | go2 !p !a | ||
45 | | p==e2 = return a | ||
46 | | otherwise = do | ||
47 | w8 <- peek p | ||
48 | let a' = a * 256 + fromIntegral w8 | ||
49 | go2 (p `plusPtr` 1) a' | ||
50 | a <- go p 0 | ||
51 | go2 (castPtr e :: Ptr Word8) a | ||
52 | |||
53 | {- | ||
54 | unchunk :: L.ByteString -> BS.ByteString | ||
55 | unchunk b = L.toStrict $ foldr reappend L.empty $ L.toChunks b | ||
56 | |||
57 | reappend :: BS.ByteString -> BS.ByteString -> Maybe BS.ByteString | ||
58 | reappend a b = | ||
59 | let (ap,ao,al) = BS.toForeignPtr a | ||
60 | (bp,bo,bl) = BS.toForeignPtr b | ||
61 | in if ap == bp && ao+al == bo | ||
62 | then Just $ BS.PS ap ao (al+bl) | ||
63 | else Nothing | ||
64 | |||
65 | reconsChunk :: S.ByteString -> L.ByteString -> L.ByteString | ||
66 | reconsChunk b bs = case L.toChunks bs of | ||
67 | (c:cs) -> case reappend b c of | ||
68 | Just x -> L.fromChunks (x:cs) | ||
69 | Nothing -> L.fromChunks (b:c:cs) | ||
70 | _ -> L.fromChunks [b] | ||
71 | -} | ||
diff --git a/Data/OpenPGP/Util.hs b/Data/OpenPGP/Util.hs index 6b1ebb1..1f9277d 100644 --- a/Data/OpenPGP/Util.hs +++ b/Data/OpenPGP/Util.hs | |||
@@ -1,4 +1,4 @@ | |||
1 | module Data.OpenPGP.Util | 1 | module Data.OpenPGP.Util |
2 | ( fingerprint | 2 | ( fingerprint |
3 | , decryptSecretKey | 3 | , decryptSecretKey |
4 | , encryptSecretKey | 4 | , encryptSecretKey |