summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-07-03 03:47:22 -0400
committerJoe Crayne <joe@jerkface.net>2019-07-03 03:47:22 -0400
commita35b7f7517b6d4c351d95acba3b87aa786c90f05 (patch)
tree8428daf69832da7457e9e05b9beefcacee9f1adb
parent660d5f111fee62ded78ffb622b063e4818c32928 (diff)
More big-num changes.
-rw-r--r--Data/OpenPGP.hs11
-rw-r--r--Data/OpenPGP/Internal.hs55
-rw-r--r--Data/OpenPGP/Util.hs2
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
1029listUntilEnd :: (BINARY_CLASS a) => Get [a] 1026listUntilEnd :: (BINARY_CLASS a) => Get [a]
1030listUntilEnd = do 1027listUntilEnd = 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 #-}
1module Data.OpenPGP.Internal where 2module Data.OpenPGP.Internal where
2 3
3import Data.Word 4import Data.Bits
4import Data.Bits 5import qualified Data.ByteString as BS
6import qualified Data.ByteString.Internal as BS
7import Data.Word
8import Foreign.ForeignPtr
9import Foreign.Ptr
10import Foreign.Storable
11import System.Endian
12import System.IO.Unsafe
13
5 14
6decode_s2k_count :: Word8 -> Word32 15decode_s2k_count :: Word8 -> Word32
7decode_s2k_count c = (16 + (fromIntegral c .&. 15)) `shiftL` 16decode_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
31getBigNum :: BS.ByteString -> Integer
32getBigNum 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{-
54unchunk :: L.ByteString -> BS.ByteString
55unchunk b = L.toStrict $ foldr reappend L.empty $ L.toChunks b
56
57reappend :: BS.ByteString -> BS.ByteString -> Maybe BS.ByteString
58reappend 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
65reconsChunk :: S.ByteString -> L.ByteString -> L.ByteString
66reconsChunk 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 @@
1module Data.OpenPGP.Util 1module Data.OpenPGP.Util
2 ( fingerprint 2 ( fingerprint
3 , decryptSecretKey 3 , decryptSecretKey
4 , encryptSecretKey 4 , encryptSecretKey