{-# LANGUAGE DeriveDataTypeable #-}
-- |
-- Module      : Crypto.Types.PubKey.RSA
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : Stable
-- Portability : Excellent
--
module Crypto.Types.PubKey.RSA
    ( PublicKey(..)
    , PrivateKey(..)
    , KeyPair(..)
    , private_size
    , private_n
    , toPublicKey
    , toPrivateKey
    ) where

import Data.Data
import Data.ASN1.Types
import Data.ASN1.BinaryEncoding (BER(BER))
import Data.ASN1.Encoding (decodeASN1')
import Data.Bits (shiftL, shiftR, complement, testBit, (.&.))
import Data.Word (Word8)

-- | Represent a RSA public key
data PublicKey = PublicKey
    { PublicKey -> Int
public_size :: Int      -- ^ size of key in bytes
    , PublicKey -> Integer
public_n    :: Integer  -- ^ public p*q
    , PublicKey -> Integer
public_e    :: Integer  -- ^ public exponant e
    } deriving (Int -> PublicKey -> ShowS
[PublicKey] -> ShowS
PublicKey -> String
(Int -> PublicKey -> ShowS)
-> (PublicKey -> String)
-> ([PublicKey] -> ShowS)
-> Show PublicKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PublicKey] -> ShowS
$cshowList :: [PublicKey] -> ShowS
show :: PublicKey -> String
$cshow :: PublicKey -> String
showsPrec :: Int -> PublicKey -> ShowS
$cshowsPrec :: Int -> PublicKey -> ShowS
Show,ReadPrec [PublicKey]
ReadPrec PublicKey
Int -> ReadS PublicKey
ReadS [PublicKey]
(Int -> ReadS PublicKey)
-> ReadS [PublicKey]
-> ReadPrec PublicKey
-> ReadPrec [PublicKey]
-> Read PublicKey
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PublicKey]
$creadListPrec :: ReadPrec [PublicKey]
readPrec :: ReadPrec PublicKey
$creadPrec :: ReadPrec PublicKey
readList :: ReadS [PublicKey]
$creadList :: ReadS [PublicKey]
readsPrec :: Int -> ReadS PublicKey
$creadsPrec :: Int -> ReadS PublicKey
Read,PublicKey -> PublicKey -> Bool
(PublicKey -> PublicKey -> Bool)
-> (PublicKey -> PublicKey -> Bool) -> Eq PublicKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PublicKey -> PublicKey -> Bool
$c/= :: PublicKey -> PublicKey -> Bool
== :: PublicKey -> PublicKey -> Bool
$c== :: PublicKey -> PublicKey -> Bool
Eq,Typeable PublicKey
Constr
DataType
Typeable PublicKey
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> PublicKey -> c PublicKey)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c PublicKey)
-> (PublicKey -> Constr)
-> (PublicKey -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c PublicKey))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey))
-> ((forall b. Data b => b -> b) -> PublicKey -> PublicKey)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> PublicKey -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> PublicKey -> r)
-> (forall u. (forall d. Data d => d -> u) -> PublicKey -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> PublicKey -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey)
-> Data PublicKey
PublicKey -> Constr
PublicKey -> DataType
(forall b. Data b => b -> b) -> PublicKey -> PublicKey
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PublicKey -> c PublicKey
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PublicKey
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> PublicKey -> u
forall u. (forall d. Data d => d -> u) -> PublicKey -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PublicKey
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PublicKey -> c PublicKey
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PublicKey)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey)
$cPublicKey :: Constr
$tPublicKey :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
gmapMp :: (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
gmapM :: (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
gmapQi :: Int -> (forall d. Data d => d -> u) -> PublicKey -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> PublicKey -> u
gmapQ :: (forall d. Data d => d -> u) -> PublicKey -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> PublicKey -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
gmapT :: (forall b. Data b => b -> b) -> PublicKey -> PublicKey
$cgmapT :: (forall b. Data b => b -> b) -> PublicKey -> PublicKey
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c PublicKey)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PublicKey)
dataTypeOf :: PublicKey -> DataType
$cdataTypeOf :: PublicKey -> DataType
toConstr :: PublicKey -> Constr
$ctoConstr :: PublicKey -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PublicKey
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PublicKey
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PublicKey -> c PublicKey
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PublicKey -> c PublicKey
$cp1Data :: Typeable PublicKey
Data,Typeable)

instance ASN1Object PublicKey where
    toASN1 :: PublicKey -> ASN1S
toASN1 PublicKey
pubKey = \[ASN1]
xs -> ASN1ConstructionType -> ASN1
Start ASN1ConstructionType
Sequence
                         ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (PublicKey -> Integer
public_n PublicKey
pubKey)
                         ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (PublicKey -> Integer
public_e PublicKey
pubKey)
                         ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: ASN1ConstructionType -> ASN1
End ASN1ConstructionType
Sequence
                         ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: [ASN1]
xs
    fromASN1 :: [ASN1] -> Either String (PublicKey, [ASN1])
fromASN1 (Start ASN1ConstructionType
Sequence:IntVal Integer
smodulus:IntVal Integer
pubexp:End ASN1ConstructionType
Sequence:[ASN1]
xs) =
        (PublicKey, [ASN1]) -> Either String (PublicKey, [ASN1])
forall a b. b -> Either a b
Right (PublicKey :: Int -> Integer -> Integer -> PublicKey
PublicKey { public_size :: Int
public_size = Integer -> Int -> Int
forall t t. (Integral t, Num t, Ord t) => t -> t -> t
calculate_modulus Integer
modulus Int
1
                         , public_n :: Integer
public_n    = Integer
modulus
                         , public_e :: Integer
public_e    = Integer
pubexp
                         }
              , [ASN1]
xs)
        where calculate_modulus :: t -> t -> t
calculate_modulus t
n t
i = if (t
2 t -> t -> t
forall a b. (Num a, Integral b) => a -> b -> a
^ (t
i t -> t -> t
forall a. Num a => a -> a -> a
* t
8)) t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
n then t
i else t -> t -> t
calculate_modulus t
n (t
it -> t -> t
forall a. Num a => a -> a -> a
+t
1)
              -- some bad implementation will not serialize ASN.1 integer properly, leading
              -- to negative modulus. if that's the case, we correct it.
              modulus :: Integer
modulus = Integer -> Integer
toPositive Integer
smodulus
    fromASN1 ( Start ASN1ConstructionType
Sequence
             : IntVal Integer
0
             : Start ASN1ConstructionType
Sequence
             : OID [Integer
1, Integer
2, Integer
840, Integer
113549, Integer
1, Integer
1, Integer
1]
             : ASN1
Null
             : End ASN1ConstructionType
Sequence
             : OctetString ByteString
bs
             : [ASN1]
xs
             ) = let inner :: Either String (PublicKey, [ASN1])
inner = (ASN1Error -> Either String (PublicKey, [ASN1]))
-> ([ASN1] -> Either String (PublicKey, [ASN1]))
-> Either ASN1Error [ASN1]
-> Either String (PublicKey, [ASN1])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ASN1Error -> Either String (PublicKey, [ASN1])
forall b. ASN1Error -> Either String b
strError [ASN1] -> Either String (PublicKey, [ASN1])
forall a. ASN1Object a => [ASN1] -> Either String (a, [ASN1])
fromASN1 (Either ASN1Error [ASN1] -> Either String (PublicKey, [ASN1]))
-> Either ASN1Error [ASN1] -> Either String (PublicKey, [ASN1])
forall a b. (a -> b) -> a -> b
$ BER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
bs
                     strError :: ASN1Error -> Either String b
strError = String -> Either String b
forall a b. a -> Either a b
Left (String -> Either String b)
-> (ASN1Error -> String) -> ASN1Error -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                                (String
"fromASN1: RSA.PublicKey: " String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> (ASN1Error -> String) -> ASN1Error -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Error -> String
forall a. Show a => a -> String
show
                 in (String -> Either String (PublicKey, [ASN1]))
-> ((PublicKey, [ASN1]) -> Either String (PublicKey, [ASN1]))
-> Either String (PublicKey, [ASN1])
-> Either String (PublicKey, [ASN1])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Either String (PublicKey, [ASN1])
forall a b. a -> Either a b
Left (\(PublicKey
k, [ASN1]
_) -> (PublicKey, [ASN1]) -> Either String (PublicKey, [ASN1])
forall a b. b -> Either a b
Right (PublicKey
k, [ASN1]
xs)) Either String (PublicKey, [ASN1])
inner
    fromASN1 [ASN1]
_ =
        String -> Either String (PublicKey, [ASN1])
forall a b. a -> Either a b
Left String
"fromASN1: RSA.PublicKey: unexpected format"

-- | Represent a RSA private key.
-- 
-- Only the pub, d fields are mandatory to fill.
--
-- p, q, dP, dQ, qinv are by-product during RSA generation,
-- but are useful to record here to speed up massively
-- the decrypt and sign operation.
--
-- implementations can leave optional fields to 0.
--
data PrivateKey = PrivateKey
    { PrivateKey -> PublicKey
private_pub  :: PublicKey -- ^ public part of a private key (size, n and e)
    , PrivateKey -> Integer
private_d    :: Integer   -- ^ private exponant d
    , PrivateKey -> Integer
private_p    :: Integer   -- ^ p prime number
    , PrivateKey -> Integer
private_q    :: Integer   -- ^ q prime number
    , PrivateKey -> Integer
private_dP   :: Integer   -- ^ d mod (p-1)
    , PrivateKey -> Integer
private_dQ   :: Integer   -- ^ d mod (q-1)
    , PrivateKey -> Integer
private_qinv :: Integer   -- ^ q^(-1) mod p
    } deriving (Int -> PrivateKey -> ShowS
[PrivateKey] -> ShowS
PrivateKey -> String
(Int -> PrivateKey -> ShowS)
-> (PrivateKey -> String)
-> ([PrivateKey] -> ShowS)
-> Show PrivateKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PrivateKey] -> ShowS
$cshowList :: [PrivateKey] -> ShowS
show :: PrivateKey -> String
$cshow :: PrivateKey -> String
showsPrec :: Int -> PrivateKey -> ShowS
$cshowsPrec :: Int -> PrivateKey -> ShowS
Show,ReadPrec [PrivateKey]
ReadPrec PrivateKey
Int -> ReadS PrivateKey
ReadS [PrivateKey]
(Int -> ReadS PrivateKey)
-> ReadS [PrivateKey]
-> ReadPrec PrivateKey
-> ReadPrec [PrivateKey]
-> Read PrivateKey
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PrivateKey]
$creadListPrec :: ReadPrec [PrivateKey]
readPrec :: ReadPrec PrivateKey
$creadPrec :: ReadPrec PrivateKey
readList :: ReadS [PrivateKey]
$creadList :: ReadS [PrivateKey]
readsPrec :: Int -> ReadS PrivateKey
$creadsPrec :: Int -> ReadS PrivateKey
Read,PrivateKey -> PrivateKey -> Bool
(PrivateKey -> PrivateKey -> Bool)
-> (PrivateKey -> PrivateKey -> Bool) -> Eq PrivateKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PrivateKey -> PrivateKey -> Bool
$c/= :: PrivateKey -> PrivateKey -> Bool
== :: PrivateKey -> PrivateKey -> Bool
$c== :: PrivateKey -> PrivateKey -> Bool
Eq,Typeable PrivateKey
Constr
DataType
Typeable PrivateKey
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> PrivateKey -> c PrivateKey)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c PrivateKey)
-> (PrivateKey -> Constr)
-> (PrivateKey -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c PrivateKey))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c PrivateKey))
-> ((forall b. Data b => b -> b) -> PrivateKey -> PrivateKey)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> PrivateKey -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> PrivateKey -> r)
-> (forall u. (forall d. Data d => d -> u) -> PrivateKey -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> PrivateKey -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey)
-> Data PrivateKey
PrivateKey -> Constr
PrivateKey -> DataType
(forall b. Data b => b -> b) -> PrivateKey -> PrivateKey
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PrivateKey -> c PrivateKey
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PrivateKey
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> PrivateKey -> u
forall u. (forall d. Data d => d -> u) -> PrivateKey -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PrivateKey -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PrivateKey -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PrivateKey
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PrivateKey -> c PrivateKey
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PrivateKey)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PrivateKey)
$cPrivateKey :: Constr
$tPrivateKey :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey
gmapMp :: (forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey
gmapM :: (forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey
gmapQi :: Int -> (forall d. Data d => d -> u) -> PrivateKey -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> PrivateKey -> u
gmapQ :: (forall d. Data d => d -> u) -> PrivateKey -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> PrivateKey -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PrivateKey -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PrivateKey -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PrivateKey -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PrivateKey -> r
gmapT :: (forall b. Data b => b -> b) -> PrivateKey -> PrivateKey
$cgmapT :: (forall b. Data b => b -> b) -> PrivateKey -> PrivateKey
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PrivateKey)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PrivateKey)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c PrivateKey)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PrivateKey)
dataTypeOf :: PrivateKey -> DataType
$cdataTypeOf :: PrivateKey -> DataType
toConstr :: PrivateKey -> Constr
$ctoConstr :: PrivateKey -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PrivateKey
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PrivateKey
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PrivateKey -> c PrivateKey
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PrivateKey -> c PrivateKey
$cp1Data :: Typeable PrivateKey
Data,Typeable)

-- | get the size in bytes from a private key
private_size :: PrivateKey -> Int
private_size = PublicKey -> Int
public_size (PublicKey -> Int)
-> (PrivateKey -> PublicKey) -> PrivateKey -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrivateKey -> PublicKey
private_pub

-- | get n from a private key
private_n :: PrivateKey -> Integer
private_n    = PublicKey -> Integer
public_n (PublicKey -> Integer)
-> (PrivateKey -> PublicKey) -> PrivateKey -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrivateKey -> PublicKey
private_pub

-- | get e from a private key
private_e :: PrivateKey -> Integer
private_e    = PublicKey -> Integer
public_e (PublicKey -> Integer)
-> (PrivateKey -> PublicKey) -> PrivateKey -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrivateKey -> PublicKey
private_pub

instance ASN1Object PrivateKey where
    toASN1 :: PrivateKey -> ASN1S
toASN1 PrivateKey
privKey = \[ASN1]
xs -> ASN1ConstructionType -> ASN1
Start ASN1ConstructionType
Sequence
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal Integer
0
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (PublicKey -> Integer
public_n (PublicKey -> Integer) -> PublicKey -> Integer
forall a b. (a -> b) -> a -> b
$ PrivateKey -> PublicKey
private_pub PrivateKey
privKey)
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (PublicKey -> Integer
public_e (PublicKey -> Integer) -> PublicKey -> Integer
forall a b. (a -> b) -> a -> b
$ PrivateKey -> PublicKey
private_pub PrivateKey
privKey)
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (PrivateKey -> Integer
private_d PrivateKey
privKey)
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (PrivateKey -> Integer
private_p PrivateKey
privKey)
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (PrivateKey -> Integer
private_q PrivateKey
privKey)
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (PrivateKey -> Integer
private_dP PrivateKey
privKey)
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (PrivateKey -> Integer
private_dQ PrivateKey
privKey)
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: Integer -> ASN1
IntVal (Integer -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ PrivateKey -> Integer
private_qinv PrivateKey
privKey)
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: ASN1ConstructionType -> ASN1
End ASN1ConstructionType
Sequence
                          ASN1 -> ASN1S
forall a. a -> [a] -> [a]
: [ASN1]
xs
    fromASN1 :: [ASN1] -> Either String (PrivateKey, [ASN1])
fromASN1 (Start ASN1ConstructionType
Sequence
             : IntVal Integer
0
             : IntVal Integer
n
             : IntVal Integer
e
             : IntVal Integer
d
             : IntVal Integer
p1
             : IntVal Integer
p2
             : IntVal Integer
pexp1
             : IntVal Integer
pexp2
             : IntVal Integer
pcoef
             : End ASN1ConstructionType
Sequence
             : [ASN1]
xs) = (PrivateKey, [ASN1]) -> Either String (PrivateKey, [ASN1])
forall a b. b -> Either a b
Right (PrivateKey
privKey, [ASN1]
xs)
        where calculate_modulus :: t -> t -> t
calculate_modulus t
n t
i = if (t
2 t -> t -> t
forall a b. (Num a, Integral b) => a -> b -> a
^ (t
i t -> t -> t
forall a. Num a => a -> a -> a
* t
8)) t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
n then t
i else t -> t -> t
calculate_modulus t
n (t
it -> t -> t
forall a. Num a => a -> a -> a
+t
1)
              privKey :: PrivateKey
privKey = PrivateKey :: PublicKey
-> Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> PrivateKey
PrivateKey
                        { private_pub :: PublicKey
private_pub  = PublicKey :: Int -> Integer -> Integer -> PublicKey
PublicKey { public_size :: Int
public_size = Integer -> Int -> Int
forall t t. (Integral t, Num t, Ord t) => t -> t -> t
calculate_modulus Integer
n Int
1
                                                   , public_n :: Integer
public_n    = Integer
n
                                                   , public_e :: Integer
public_e    = Integer
e
                                                   }
                        , private_d :: Integer
private_d    = Integer
d
                        , private_p :: Integer
private_p    = Integer
p1
                        , private_q :: Integer
private_q    = Integer
p2
                        , private_dP :: Integer
private_dP   = Integer
pexp1
                        , private_dQ :: Integer
private_dQ   = Integer
pexp2
                        , private_qinv :: Integer
private_qinv = Integer
pcoef
                        }

    fromASN1 ( Start ASN1ConstructionType
Sequence
             : IntVal Integer
0
             : Start ASN1ConstructionType
Sequence
             : OID [Integer
1, Integer
2, Integer
840, Integer
113549, Integer
1, Integer
1, Integer
1]
             : ASN1
Null
             : End ASN1ConstructionType
Sequence
             : OctetString ByteString
bs
             : [ASN1]
xs
             ) = let inner :: Either String (PrivateKey, [ASN1])
inner = (ASN1Error -> Either String (PrivateKey, [ASN1]))
-> ([ASN1] -> Either String (PrivateKey, [ASN1]))
-> Either ASN1Error [ASN1]
-> Either String (PrivateKey, [ASN1])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ASN1Error -> Either String (PrivateKey, [ASN1])
forall b. ASN1Error -> Either String b
strError [ASN1] -> Either String (PrivateKey, [ASN1])
forall a. ASN1Object a => [ASN1] -> Either String (a, [ASN1])
fromASN1 (Either ASN1Error [ASN1] -> Either String (PrivateKey, [ASN1]))
-> Either ASN1Error [ASN1] -> Either String (PrivateKey, [ASN1])
forall a b. (a -> b) -> a -> b
$ BER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
bs
                     strError :: ASN1Error -> Either String b
strError = String -> Either String b
forall a b. a -> Either a b
Left (String -> Either String b)
-> (ASN1Error -> String) -> ASN1Error -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                                (String
"fromASN1: RSA.PrivateKey: " String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> (ASN1Error -> String) -> ASN1Error -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Error -> String
forall a. Show a => a -> String
show
                 in (String -> Either String (PrivateKey, [ASN1]))
-> ((PrivateKey, [ASN1]) -> Either String (PrivateKey, [ASN1]))
-> Either String (PrivateKey, [ASN1])
-> Either String (PrivateKey, [ASN1])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Either String (PrivateKey, [ASN1])
forall a b. a -> Either a b
Left (\(PrivateKey
k, [ASN1]
_) -> (PrivateKey, [ASN1]) -> Either String (PrivateKey, [ASN1])
forall a b. b -> Either a b
Right (PrivateKey
k, [ASN1]
xs)) Either String (PrivateKey, [ASN1])
inner
    fromASN1 [ASN1]
_ =
        String -> Either String (PrivateKey, [ASN1])
forall a b. a -> Either a b
Left String
"fromASN1: RSA.PrivateKey: unexpected format"

-- | Represent RSA KeyPair
--
-- note the RSA private key contains already an instance of public key for efficiency
newtype KeyPair = KeyPair PrivateKey
    deriving (Int -> KeyPair -> ShowS
[KeyPair] -> ShowS
KeyPair -> String
(Int -> KeyPair -> ShowS)
-> (KeyPair -> String) -> ([KeyPair] -> ShowS) -> Show KeyPair
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KeyPair] -> ShowS
$cshowList :: [KeyPair] -> ShowS
show :: KeyPair -> String
$cshow :: KeyPair -> String
showsPrec :: Int -> KeyPair -> ShowS
$cshowsPrec :: Int -> KeyPair -> ShowS
Show,ReadPrec [KeyPair]
ReadPrec KeyPair
Int -> ReadS KeyPair
ReadS [KeyPair]
(Int -> ReadS KeyPair)
-> ReadS [KeyPair]
-> ReadPrec KeyPair
-> ReadPrec [KeyPair]
-> Read KeyPair
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [KeyPair]
$creadListPrec :: ReadPrec [KeyPair]
readPrec :: ReadPrec KeyPair
$creadPrec :: ReadPrec KeyPair
readList :: ReadS [KeyPair]
$creadList :: ReadS [KeyPair]
readsPrec :: Int -> ReadS KeyPair
$creadsPrec :: Int -> ReadS KeyPair
Read,KeyPair -> KeyPair -> Bool
(KeyPair -> KeyPair -> Bool)
-> (KeyPair -> KeyPair -> Bool) -> Eq KeyPair
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KeyPair -> KeyPair -> Bool
$c/= :: KeyPair -> KeyPair -> Bool
== :: KeyPair -> KeyPair -> Bool
$c== :: KeyPair -> KeyPair -> Bool
Eq,Typeable KeyPair
Constr
DataType
Typeable KeyPair
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> KeyPair -> c KeyPair)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c KeyPair)
-> (KeyPair -> Constr)
-> (KeyPair -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c KeyPair))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c KeyPair))
-> ((forall b. Data b => b -> b) -> KeyPair -> KeyPair)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> KeyPair -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> KeyPair -> r)
-> (forall u. (forall d. Data d => d -> u) -> KeyPair -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> KeyPair -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> KeyPair -> m KeyPair)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> KeyPair -> m KeyPair)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> KeyPair -> m KeyPair)
-> Data KeyPair
KeyPair -> Constr
KeyPair -> DataType
(forall b. Data b => b -> b) -> KeyPair -> KeyPair
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> KeyPair -> c KeyPair
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c KeyPair
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> KeyPair -> u
forall u. (forall d. Data d => d -> u) -> KeyPair -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> KeyPair -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> KeyPair -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> KeyPair -> m KeyPair
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> KeyPair -> m KeyPair
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c KeyPair
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> KeyPair -> c KeyPair
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c KeyPair)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c KeyPair)
$cKeyPair :: Constr
$tKeyPair :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> KeyPair -> m KeyPair
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> KeyPair -> m KeyPair
gmapMp :: (forall d. Data d => d -> m d) -> KeyPair -> m KeyPair
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> KeyPair -> m KeyPair
gmapM :: (forall d. Data d => d -> m d) -> KeyPair -> m KeyPair
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> KeyPair -> m KeyPair
gmapQi :: Int -> (forall d. Data d => d -> u) -> KeyPair -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> KeyPair -> u
gmapQ :: (forall d. Data d => d -> u) -> KeyPair -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> KeyPair -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> KeyPair -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> KeyPair -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> KeyPair -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> KeyPair -> r
gmapT :: (forall b. Data b => b -> b) -> KeyPair -> KeyPair
$cgmapT :: (forall b. Data b => b -> b) -> KeyPair -> KeyPair
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c KeyPair)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c KeyPair)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c KeyPair)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c KeyPair)
dataTypeOf :: KeyPair -> DataType
$cdataTypeOf :: KeyPair -> DataType
toConstr :: KeyPair -> Constr
$ctoConstr :: KeyPair -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c KeyPair
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c KeyPair
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> KeyPair -> c KeyPair
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> KeyPair -> c KeyPair
$cp1Data :: Typeable KeyPair
Data,Typeable)

instance ASN1Object KeyPair where
    toASN1 :: KeyPair -> ASN1S
toASN1 (KeyPair PrivateKey
pkey) = PrivateKey -> ASN1S
forall a. ASN1Object a => a -> ASN1S
toASN1 PrivateKey
pkey
    fromASN1 :: [ASN1] -> Either String (KeyPair, [ASN1])
fromASN1 = (String -> Either String (KeyPair, [ASN1]))
-> ((PrivateKey, [ASN1]) -> Either String (KeyPair, [ASN1]))
-> Either String (PrivateKey, [ASN1])
-> Either String (KeyPair, [ASN1])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Either String (KeyPair, [ASN1])
forall a b. a -> Either a b
Left (\(PrivateKey
k,[ASN1]
s) -> (KeyPair, [ASN1]) -> Either String (KeyPair, [ASN1])
forall a b. b -> Either a b
Right (PrivateKey -> KeyPair
KeyPair PrivateKey
k, [ASN1]
s)) (Either String (PrivateKey, [ASN1])
 -> Either String (KeyPair, [ASN1]))
-> ([ASN1] -> Either String (PrivateKey, [ASN1]))
-> [ASN1]
-> Either String (KeyPair, [ASN1])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ASN1] -> Either String (PrivateKey, [ASN1])
forall a. ASN1Object a => [ASN1] -> Either String (a, [ASN1])
fromASN1

-- | Public key of a RSA KeyPair
toPublicKey :: KeyPair -> PublicKey
toPublicKey :: KeyPair -> PublicKey
toPublicKey (KeyPair PrivateKey
priv) = PrivateKey -> PublicKey
private_pub PrivateKey
priv

-- | Private key of a RSA KeyPair
toPrivateKey :: KeyPair -> PrivateKey
toPrivateKey :: KeyPair -> PrivateKey
toPrivateKey (KeyPair PrivateKey
priv) = PrivateKey
priv

toPositive :: Integer -> Integer
toPositive :: Integer -> Integer
toPositive Integer
int
    | Integer
int Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0   = [Word8] -> Integer
uintOfBytes ([Word8] -> Integer) -> [Word8] -> Integer
forall a b. (a -> b) -> a -> b
$ Integer -> [Word8]
bytesOfInt Integer
int
    | Bool
otherwise = Integer
int
  where uintOfBytes :: [Word8] -> Integer
uintOfBytes = (Integer -> Word8 -> Integer) -> Integer -> [Word8] -> Integer
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\Integer
acc Word8
n -> (Integer
acc Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Word8 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
n) Integer
0
        bytesOfInt :: Integer -> [Word8]
        bytesOfInt :: Integer -> [Word8]
bytesOfInt Integer
n = if Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit ([Word8] -> Word8
forall a. [a] -> a
head [Word8]
nints) Int
7 then [Word8]
nints else Word8
0xff Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: [Word8]
nints
          where nints :: [Word8]
nints = [Word8] -> [Word8]
forall a. [a] -> [a]
reverse ([Word8] -> [Word8]) -> [Word8] -> [Word8]
forall a b. (a -> b) -> a -> b
$ [Word8] -> [Word8]
forall a. (Num a, Eq a) => [a] -> [a]
plusOne ([Word8] -> [Word8]) -> [Word8] -> [Word8]
forall a b. (a -> b) -> a -> b
$ [Word8] -> [Word8]
forall a. [a] -> [a]
reverse ([Word8] -> [Word8]) -> [Word8] -> [Word8]
forall a b. (a -> b) -> a -> b
$ (Word8 -> Word8) -> [Word8] -> [Word8]
forall a b. (a -> b) -> [a] -> [b]
map Word8 -> Word8
forall a. Bits a => a -> a
complement ([Word8] -> [Word8]) -> [Word8] -> [Word8]
forall a b. (a -> b) -> a -> b
$ Integer -> [Word8]
forall t a. (Integral t, Bits a, Bits t, Num a) => t -> [a]
bytesOfUInt (Integer -> Integer
forall a. Num a => a -> a
abs Integer
n)
                plusOne :: [a] -> [a]
plusOne []     = [a
1]
                plusOne (a
x:[a]
xs) = if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xff then a
0 a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
plusOne [a]
xs else (a
xa -> a -> a
forall a. Num a => a -> a -> a
+a
1) a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
xs
                bytesOfUInt :: t -> [a]
bytesOfUInt t
x = [a] -> [a]
forall a. [a] -> [a]
reverse (t -> [a]
forall t a. (Integral t, Num a, Bits a, Bits t) => t -> [a]
list t
x)
                  where list :: t -> [a]
list t
i = if t
i t -> t -> Bool
forall a. Ord a => a -> a -> Bool
<= t
0xff then [t -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral t
i] else (t -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral t
i a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
0xff) a -> [a] -> [a]
forall a. a -> [a] -> [a]
: t -> [a]
list (t
i t -> Int -> t
forall a. Bits a => a -> Int -> a
`shiftR` Int
8)