module Crypto.PubKey.RSA.PKCS15 (
pad,
padSignature,
unpad,
decrypt,
decryptSafer,
sign,
signSafer,
signDigest,
signSaferDigest,
signDigestInfo,
signSaferDigestInfo,
decryptBlinded,
signDigestBlinded,
signDigestInfoBlinded,
encrypt,
verify,
verifyDigest,
verifyDigestInfo,
HashAlgorithmASN1,
) where
import Crypto.Hash
import Crypto.Number.Serialize (os2ip)
import Crypto.PubKey.Internal (and')
import Crypto.PubKey.RSA.Blinded.Internal
import Crypto.PubKey.RSA.Prim
import Crypto.PubKey.RSA.Types
import Crypto.Random.Types
import Data.Bits (complement, shiftR, (.&.), (.|.))
import Data.ByteString (ByteString)
import Data.Word
import Crypto.Internal.ByteArray (ByteArray, Bytes)
import qualified Crypto.Internal.ByteArray as B
import qualified Data.List as L
class HashAlgorithm hashAlg => HashAlgorithmASN1 hashAlg where
hashDigestASN1 :: ByteArray out => Digest hashAlg -> out
instance HashAlgorithmASN1 MD2 where
hashDigestASN1 :: forall out. ByteArray out => Digest MD2 -> out
hashDigestASN1 =
[Word8] -> Digest MD2 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x20
, Word8
0x30
, Word8
0x0c
, Word8
0x06
, Word8
0x08
, Word8
0x2a
, Word8
0x86
, Word8
0x48
, Word8
0x86
, Word8
0xf7
, Word8
0x0d
, Word8
0x02
, Word8
0x02
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x10
]
instance HashAlgorithmASN1 MD5 where
hashDigestASN1 :: forall out. ByteArray out => Digest MD5 -> out
hashDigestASN1 =
[Word8] -> Digest MD5 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x20
, Word8
0x30
, Word8
0x0c
, Word8
0x06
, Word8
0x08
, Word8
0x2a
, Word8
0x86
, Word8
0x48
, Word8
0x86
, Word8
0xf7
, Word8
0x0d
, Word8
0x02
, Word8
0x05
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x10
]
instance HashAlgorithmASN1 SHA1 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA1 -> out
hashDigestASN1 =
[Word8] -> Digest SHA1 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x21
, Word8
0x30
, Word8
0x09
, Word8
0x06
, Word8
0x05
, Word8
0x2b
, Word8
0x0e
, Word8
0x03
, Word8
0x02
, Word8
0x1a
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x14
]
instance HashAlgorithmASN1 SHA224 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA224 -> out
hashDigestASN1 =
[Word8] -> Digest SHA224 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x2d
, Word8
0x30
, Word8
0x0d
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x04
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x1c
]
instance HashAlgorithmASN1 SHA256 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA256 -> out
hashDigestASN1 =
[Word8] -> Digest SHA256 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x31
, Word8
0x30
, Word8
0x0d
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x01
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x20
]
instance HashAlgorithmASN1 SHA384 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA384 -> out
hashDigestASN1 =
[Word8] -> Digest SHA384 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x41
, Word8
0x30
, Word8
0x0d
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x02
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x30
]
instance HashAlgorithmASN1 SHA512 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA512 -> out
hashDigestASN1 =
[Word8] -> Digest SHA512 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x51
, Word8
0x30
, Word8
0x0d
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x03
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x40
]
instance HashAlgorithmASN1 SHA512t_224 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA512t_224 -> out
hashDigestASN1 =
[Word8] -> Digest SHA512t_224 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x2d
, Word8
0x30
, Word8
0x0d
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x05
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x1c
]
instance HashAlgorithmASN1 SHA512t_256 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA512t_256 -> out
hashDigestASN1 =
[Word8] -> Digest SHA512t_256 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x31
, Word8
0x30
, Word8
0x0d
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x06
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x20
]
instance HashAlgorithmASN1 SHA3_224 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA3_224 -> out
hashDigestASN1 =
[Word8] -> Digest SHA3_224 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x2b
, Word8
0x30
, Word8
0x0b
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x07
, Word8
0x04
, Word8
0x1c
]
instance HashAlgorithmASN1 SHA3_256 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA3_256 -> out
hashDigestASN1 =
[Word8] -> Digest SHA3_256 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x2f
, Word8
0x30
, Word8
0x0b
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x08
, Word8
0x04
, Word8
0x20
]
instance HashAlgorithmASN1 SHA3_384 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA3_384 -> out
hashDigestASN1 =
[Word8] -> Digest SHA3_384 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x3f
, Word8
0x30
, Word8
0x0b
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x09
, Word8
0x04
, Word8
0x30
]
instance HashAlgorithmASN1 SHA3_512 where
hashDigestASN1 :: forall out. ByteArray out => Digest SHA3_512 -> out
hashDigestASN1 =
[Word8] -> Digest SHA3_512 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x4f
, Word8
0x30
, Word8
0x0b
, Word8
0x06
, Word8
0x09
, Word8
0x60
, Word8
0x86
, Word8
0x48
, Word8
0x01
, Word8
0x65
, Word8
0x03
, Word8
0x04
, Word8
0x02
, Word8
0x0a
, Word8
0x04
, Word8
0x40
]
instance HashAlgorithmASN1 RIPEMD160 where
hashDigestASN1 :: forall out. ByteArray out => Digest RIPEMD160 -> out
hashDigestASN1 =
[Word8] -> Digest RIPEMD160 -> out
forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix
[ Word8
0x30
, Word8
0x21
, Word8
0x30
, Word8
0x09
, Word8
0x06
, Word8
0x05
, Word8
0x2b
, Word8
0x24
, Word8
0x03
, Word8
0x02
, Word8
0x01
, Word8
0x05
, Word8
0x00
, Word8
0x04
, Word8
0x14
]
addDigestPrefix :: ByteArray out => [Word8] -> Digest hashAlg -> out
addDigestPrefix :: forall out hashAlg.
ByteArray out =>
[Word8] -> Digest hashAlg -> out
addDigestPrefix [Word8]
prefix Digest hashAlg
digest =
[Word8] -> out
forall a. ByteArray a => [Word8] -> a
B.pack [Word8]
prefix out -> out -> out
forall bs. ByteArray bs => bs -> bs -> bs
`B.append` Digest hashAlg -> out
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert Digest hashAlg
digest
pad
:: (MonadRandom m, ByteArray message) => Int -> message -> m (Either Error message)
pad :: forall (m :: * -> *) message.
(MonadRandom m, ByteArray message) =>
Int -> message -> m (Either Error message)
pad Int
len message
m
| message -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length message
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
11 = Either Error message -> m (Either Error message)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Error -> Either Error message
forall a b. a -> Either a b
Left Error
MessageTooLong)
| Bool
otherwise = do
message
padding <- Int -> m message
forall bytearray (m :: * -> *).
(ByteArray bytearray, MonadRandom m) =>
Int -> m bytearray
getNonNullRandom (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- message -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length message
m Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
3)
Either Error message -> m (Either Error message)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error message -> m (Either Error message))
-> Either Error message -> m (Either Error message)
forall a b. (a -> b) -> a -> b
$ message -> Either Error message
forall a b. b -> Either a b
Right (message -> Either Error message)
-> message -> Either Error message
forall a b. (a -> b) -> a -> b
$ [message] -> message
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
[bin] -> bout
B.concat [[Word8] -> message
forall a. ByteArray a => [Word8] -> a
B.pack [Word8
0, Word8
2], message
padding, [Word8] -> message
forall a. ByteArray a => [Word8] -> a
B.pack [Word8
0], message
m]
where
getNonNullRandom :: (ByteArray bytearray, MonadRandom m) => Int -> m bytearray
getNonNullRandom :: forall bytearray (m :: * -> *).
(ByteArray bytearray, MonadRandom m) =>
Int -> m bytearray
getNonNullRandom Int
n = do
Bytes
bs0 <- Int -> m Bytes
forall byteArray. ByteArray byteArray => Int -> m byteArray
forall (m :: * -> *) byteArray.
(MonadRandom m, ByteArray byteArray) =>
Int -> m byteArray
getRandomBytes Int
n
let bytes :: bytearray
bytes = [Word8] -> bytearray
forall a. ByteArray a => [Word8] -> a
B.pack ([Word8] -> bytearray) -> [Word8] -> bytearray
forall a b. (a -> b) -> a -> b
$ (Word8 -> Bool) -> [Word8] -> [Word8]
forall a. (a -> Bool) -> [a] -> [a]
filter (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
0) ([Word8] -> [Word8]) -> [Word8] -> [Word8]
forall a b. (a -> b) -> a -> b
$ Bytes -> [Word8]
forall a. ByteArrayAccess a => a -> [Word8]
B.unpack (Bytes
bs0 :: Bytes)
left :: Int
left = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- bytearray -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length bytearray
bytes
if Int
left Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then bytearray -> m bytearray
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return bytearray
bytes
else do
bytearray
bend <- Int -> m bytearray
forall bytearray (m :: * -> *).
(ByteArray bytearray, MonadRandom m) =>
Int -> m bytearray
getNonNullRandom Int
left
bytearray -> m bytearray
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (bytearray
bytes bytearray -> bytearray -> bytearray
forall bs. ByteArray bs => bs -> bs -> bs
`B.append` bytearray
bend)
padSignature
:: ByteArray signature => Int -> signature -> Either Error signature
padSignature :: forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature Int
klen signature
signature
| Int
klen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
siglen Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
11 = Error -> Either Error signature
forall a b. a -> Either a b
Left Error
SignatureTooLong
| Bool
otherwise =
signature -> Either Error signature
forall a b. b -> Either a b
Right ([signature] -> signature
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
[bin] -> bout
B.concat [[Word8] -> signature
forall a. ByteArray a => [Word8] -> a
B.pack [Word8
0, Word8
1], Int -> Word8 -> signature
forall ba. ByteArray ba => Int -> Word8 -> ba
B.replicate (Int
klen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
siglen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
3) Word8
0xff, [Word8] -> signature
forall a. ByteArray a => [Word8] -> a
B.pack [Word8
0], signature
signature])
where
siglen :: Int
siglen = signature -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length signature
signature
unpad :: ByteArray bytearray => bytearray -> Either Error bytearray
unpad :: forall bytearray.
ByteArray bytearray =>
bytearray -> Either Error bytearray
unpad bytearray
packed
| Bool
paddingSuccess = bytearray -> Either Error bytearray
forall a b. b -> Either a b
Right bytearray
m
| Bool
otherwise = Error -> Either Error bytearray
forall a b. a -> Either a b
Left Error
MessageNotRecognized
where
len :: Int
len = bytearray -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length bytearray
packed
(bytearray
zt, bytearray
ps0m) = Int -> bytearray -> (bytearray, bytearray)
forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt Int
2 bytearray
packed
zeroIndex :: Word32
zeroIndex = (Word32, Word32) -> Word32
forall a b. (a, b) -> a
fst ((Word32, Word32) -> Word32) -> (Word32, Word32) -> Word32
forall a b. (a -> b) -> a -> b
$ ((Word32, Word32) -> (Word32, Word8) -> (Word32, Word32))
-> (Word32, Word32) -> [(Word32, Word8)] -> (Word32, Word32)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' (Word32, Word32) -> (Word32, Word8) -> (Word32, Word32)
forall {b}.
Integral b =>
(Word32, Word32) -> (Word32, b) -> (Word32, Word32)
step (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len :: Word32, Word32
1 :: Word32) [(Word32, Word8)]
indexed
indexed :: [(Word32, Word8)]
indexed = [Word32] -> [Word8] -> [(Word32, Word8)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Word32
2 ..] (bytearray -> [Word8]
forall a. ByteArrayAccess a => a -> [Word8]
B.unpack bytearray
ps0m)
step :: (Word32, Word32) -> (Word32, b) -> (Word32, Word32)
step (Word32
idx, Word32
unseen) (Word32
i, b
b) = (Word32 -> Word32 -> Word32 -> Word32
forall {a}. Bits a => a -> a -> a -> a
select Word32
found Word32
i Word32
idx, Word32
unseen Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32 -> Word32
forall a. Bits a => a -> a
complement Word32
found)
where
w :: Word32
w = b -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
b :: Word32
nonZero :: Word32
nonZero = (Word32
w Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Word32
forall a. Num a => a -> a
negate Word32
w) Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
31
found :: Word32
found = Word32 -> Word32
forall a. Num a => a -> a
negate (Word32
unseen Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32 -> Word32
forall a. Bits a => a -> a
complement Word32
nonZero)
select :: a -> a -> a -> a
select a
mask a
a a
b = (a
a a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
mask) a -> a -> a
forall a. Bits a => a -> a -> a
.|. (a
b a -> a -> a
forall a. Bits a => a -> a -> a
.&. a -> a
forall a. Bits a => a -> a
complement a
mask)
psLength :: Int
psLength = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
zeroIndex Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2 :: Int
m :: bytearray
m = Int -> bytearray -> bytearray
forall bs. ByteArray bs => Int -> bs -> bs
B.drop (Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
zeroIndex Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) bytearray
packed
paddingSuccess :: Bool
paddingSuccess =
[Bool] -> Bool
and'
[ bytearray
zt bytearray -> Bytes -> Bool
forall bs1 bs2.
(ByteArrayAccess bs1, ByteArrayAccess bs2) =>
bs1 -> bs2 -> Bool
`B.constEq` ([Word8] -> Bytes
forall a. ByteArray a => [Word8] -> a
B.pack [Word8
0, Word8
2] :: Bytes)
, Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
zeroIndex Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len
, Int
psLength Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
8
]
decrypt
:: ByteArray ba
=> Maybe Blinder
-> PrivateKey
-> ByteString
-> Either Error ba
decrypt :: forall ba.
ByteArray ba =>
Maybe Blinder -> PrivateKey -> ByteString -> Either Error ba
decrypt Maybe Blinder
blinder PrivateKey
pk ByteString
c
| ByteString -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ByteString
c Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= (PrivateKey -> Int
private_size PrivateKey
pk) = Error -> Either Error ba
forall a b. a -> Either a b
Left Error
MessageSizeIncorrect
| ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
c Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= PrivateKey -> Integer
private_n PrivateKey
pk = Error -> Either Error ba
forall a b. a -> Either a b
Left Error
MessageSizeIncorrect
| Bool
otherwise = ba -> Either Error ba
forall bytearray.
ByteArray bytearray =>
bytearray -> Either Error bytearray
unpad (ba -> Either Error ba) -> ba -> Either Error ba
forall a b. (a -> b) -> a -> b
$ Maybe Blinder -> PrivateKey -> ba -> ba
forall ba. ByteArray ba => Maybe Blinder -> PrivateKey -> ba -> ba
dp Maybe Blinder
blinder PrivateKey
pk (ba -> ba) -> ba -> ba
forall a b. (a -> b) -> a -> b
$ ByteString -> ba
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert ByteString
c
decryptSafer
:: (MonadRandom m, ByteArray ba)
=> PrivateKey
-> ByteString
-> m (Either Error ba)
decryptSafer :: forall (m :: * -> *) ba.
(MonadRandom m, ByteArray ba) =>
PrivateKey -> ByteString -> m (Either Error ba)
decryptSafer PrivateKey
pk ByteString
b
| ByteString -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ByteString
b Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= PrivateKey -> Int
private_size PrivateKey
pk = Either Error ba -> m (Either Error ba)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Error -> Either Error ba
forall a b. a -> Either a b
Left Error
MessageSizeIncorrect)
| ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
b Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= PrivateKey -> Integer
private_n PrivateKey
pk = Either Error ba -> m (Either Error ba)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Error -> Either Error ba
forall a b. a -> Either a b
Left Error
MessageSizeIncorrect)
| Bool
otherwise = do
Draw
d <- PrivateKey -> m Draw
forall (m :: * -> *). MonadRandom m => PrivateKey -> m Draw
drawFor PrivateKey
pk
Either Error ba -> m (Either Error ba)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error ba -> m (Either Error ba))
-> Either Error ba -> m (Either Error ba)
forall a b. (a -> b) -> a -> b
$ PrivateKey
-> Draw
-> ((Integer, Integer) -> Either Error ba)
-> Either Error ba
forall a. PrivateKey -> Draw -> ((Integer, Integer) -> a) -> a
withBlindingFor PrivateKey
pk Draw
d (((Integer, Integer) -> Either Error ba) -> Either Error ba)
-> ((Integer, Integer) -> Either Error ba) -> Either Error ba
forall a b. (a -> b) -> a -> b
$ \(Integer, Integer)
pair -> ba -> Either Error ba
forall bytearray.
ByteArray bytearray =>
bytearray -> Either Error bytearray
unpad ((Integer, Integer) -> PrivateKey -> ba -> ba
forall ba.
ByteArray ba =>
(Integer, Integer) -> PrivateKey -> ba -> ba
dpWithPair (Integer, Integer)
pair PrivateKey
pk (ByteString -> ba
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert ByteString
b))
decryptBlinded
:: (MonadRandom m, ByteArray ba)
=> BlindedKey
-> ByteString
-> m (Either Error ba, BlindedKey)
decryptBlinded :: forall (m :: * -> *) ba.
(MonadRandom m, ByteArray ba) =>
BlindedKey -> ByteString -> m (Either Error ba, BlindedKey)
decryptBlinded BlindedKey
bk ByteString
c
| ByteString -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ByteString
c Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= PrivateKey -> Int
private_size PrivateKey
pk = (Either Error ba, BlindedKey) -> m (Either Error ba, BlindedKey)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Error -> Either Error ba
forall a b. a -> Either a b
Left Error
MessageSizeIncorrect, BlindedKey
bk)
| ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
c Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= PrivateKey -> Integer
private_n PrivateKey
pk = (Either Error ba, BlindedKey) -> m (Either Error ba, BlindedKey)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Error -> Either Error ba
forall a b. a -> Either a b
Left Error
MessageSizeIncorrect, BlindedKey
bk)
| Bool
otherwise = do
(ba
m, BlindedKey
bk') <- BlindedKey -> ba -> m (ba, BlindedKey)
forall (m :: * -> *) ba.
(MonadRandom m, ByteArray ba) =>
BlindedKey -> ba -> m (ba, BlindedKey)
dpBlinded BlindedKey
bk (ByteString -> ba
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert ByteString
c)
(Either Error ba, BlindedKey) -> m (Either Error ba, BlindedKey)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ba -> Either Error ba
forall bytearray.
ByteArray bytearray =>
bytearray -> Either Error bytearray
unpad ba
m, BlindedKey
bk')
where
pk :: PrivateKey
pk = BlindedKey -> PrivateKey
blindedPrivateKey BlindedKey
bk
encrypt
:: (MonadRandom m, ByteArray ba) => PublicKey -> ba -> m (Either Error ByteString)
encrypt :: forall (m :: * -> *) ba.
(MonadRandom m, ByteArray ba) =>
PublicKey -> ba -> m (Either Error ByteString)
encrypt PublicKey
pk ba
m = do
Either Error ba
r <- Int -> ba -> m (Either Error ba)
forall (m :: * -> *) message.
(MonadRandom m, ByteArray message) =>
Int -> message -> m (Either Error message)
pad (PublicKey -> Int
public_size PublicKey
pk) ba
m
case Either Error ba
r of
Left Error
err -> Either Error ByteString -> m (Either Error ByteString)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error ByteString -> m (Either Error ByteString))
-> Either Error ByteString -> m (Either Error ByteString)
forall a b. (a -> b) -> a -> b
$ Error -> Either Error ByteString
forall a b. a -> Either a b
Left Error
err
Right ba
em -> Either Error ByteString -> m (Either Error ByteString)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error ByteString -> m (Either Error ByteString))
-> Either Error ByteString -> m (Either Error ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString -> Either Error ByteString
forall a b. b -> Either a b
Right (ba -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (ba -> ByteString) -> ba -> ByteString
forall a b. (a -> b) -> a -> b
$ PublicKey -> ba -> ba
forall ba. ByteArray ba => PublicKey -> ba -> ba
ep PublicKey
pk ba
em)
sign
:: HashAlgorithmASN1 hashAlg
=> Maybe Blinder
-> Maybe hashAlg
-> PrivateKey
-> ByteString
-> Either Error ByteString
sign :: forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe Blinder
-> Maybe hashAlg
-> PrivateKey
-> ByteString
-> Either Error ByteString
sign Maybe Blinder
blinder Maybe hashAlg
hashDescr PrivateKey
pk ByteString
m = Maybe Blinder -> PrivateKey -> ByteString -> ByteString
forall ba. ByteArray ba => Maybe Blinder -> PrivateKey -> ba -> ba
dp Maybe Blinder
blinder PrivateKey
pk (ByteString -> ByteString)
-> Either Error ByteString -> Either Error ByteString
forall a b. (a -> b) -> Either Error a -> Either Error b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Maybe hashAlg -> Int -> ByteString -> Either Error ByteString
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> Int -> ByteString -> Either Error ByteString
makeSignature Maybe hashAlg
hashDescr (PrivateKey -> Int
private_size PrivateKey
pk) ByteString
m
{-# DEPRECATED
sign
"Use signDigest, or signDigestInfo when the message is already a DigestInfo"
#-}
signSafer
:: (HashAlgorithmASN1 hashAlg, MonadRandom m)
=> Maybe hashAlg
-> PrivateKey
-> ByteString
-> m (Either Error ByteString)
signSafer :: forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
signSafer Maybe hashAlg
hashAlg PrivateKey
pk ByteString
m = do
Draw
d <- PrivateKey -> m Draw
forall (m :: * -> *). MonadRandom m => PrivateKey -> m Draw
drawFor PrivateKey
pk
Either Error ByteString -> m (Either Error ByteString)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error ByteString -> m (Either Error ByteString))
-> Either Error ByteString -> m (Either Error ByteString)
forall a b. (a -> b) -> a -> b
$ PrivateKey
-> Draw -> Either Error ByteString -> Either Error ByteString
signWithBlindingFor PrivateKey
pk Draw
d (Maybe hashAlg -> Int -> ByteString -> Either Error ByteString
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> Int -> ByteString -> Either Error ByteString
makeSignature Maybe hashAlg
hashAlg (PrivateKey -> Int
private_size PrivateKey
pk) ByteString
m)
{-# DEPRECATED
signSafer
"Use signSaferDigest, or signSaferDigestInfo when the message is already a DigestInfo"
#-}
verify
:: HashAlgorithmASN1 hashAlg
=> Maybe hashAlg
-> PublicKey
-> ByteString
-> ByteString
-> Bool
verify :: forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
verify Maybe hashAlg
hashAlg PublicKey
pk ByteString
m ByteString
sm =
PublicKey -> Either Error ByteString -> ByteString -> Bool
verifyEncoded PublicKey
pk (Maybe hashAlg -> Int -> ByteString -> Either Error ByteString
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> Int -> ByteString -> Either Error ByteString
makeSignature Maybe hashAlg
hashAlg (PublicKey -> Int
public_size PublicKey
pk) ByteString
m) ByteString
sm
{-# DEPRECATED
verify
"Use verifyDigest, or verifyDigestInfo when the message is already a DigestInfo"
#-}
verifyEncoded
:: PublicKey
-> Either Error ByteString
-> ByteString
-> Bool
verifyEncoded :: PublicKey -> Either Error ByteString -> ByteString -> Bool
verifyEncoded PublicKey
pk Either Error ByteString
expected ByteString
sm
| ByteString -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ByteString
sm Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= PublicKey -> Int
public_size PublicKey
pk = Bool
False
| ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
sm Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= PublicKey -> Integer
public_n PublicKey
pk = Bool
False
| Bool
otherwise =
case Either Error ByteString
expected of
Left Error
_ -> Bool
False
Right ByteString
s -> ByteString
s ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== PublicKey -> ByteString -> ByteString
forall ba. ByteArray ba => PublicKey -> ba -> ba
ep PublicKey
pk ByteString
sm
signDigest
:: HashAlgorithmASN1 hashAlg
=> Maybe Blinder
-> PrivateKey
-> Digest hashAlg
-> Either Error ByteString
signDigest :: forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe Blinder
-> PrivateKey -> Digest hashAlg -> Either Error ByteString
signDigest Maybe Blinder
blinder PrivateKey
pk Digest hashAlg
digest =
Maybe Blinder -> PrivateKey -> ByteString -> ByteString
forall ba. ByteArray ba => Maybe Blinder -> PrivateKey -> ba -> ba
dp Maybe Blinder
blinder PrivateKey
pk (ByteString -> ByteString)
-> Either Error ByteString -> Either Error ByteString
forall a b. (a -> b) -> Either Error a -> Either Error b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature (PrivateKey -> Int
private_size PrivateKey
pk) (Digest hashAlg -> ByteString
forall out. ByteArray out => Digest hashAlg -> out
forall hashAlg out.
(HashAlgorithmASN1 hashAlg, ByteArray out) =>
Digest hashAlg -> out
hashDigestASN1 Digest hashAlg
digest)
signSaferDigest
:: (HashAlgorithmASN1 hashAlg, MonadRandom m)
=> PrivateKey
-> Digest hashAlg
-> m (Either Error ByteString)
signSaferDigest :: forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
PrivateKey -> Digest hashAlg -> m (Either Error ByteString)
signSaferDigest PrivateKey
pk Digest hashAlg
digest = do
Draw
d <- PrivateKey -> m Draw
forall (m :: * -> *). MonadRandom m => PrivateKey -> m Draw
drawFor PrivateKey
pk
Either Error ByteString -> m (Either Error ByteString)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error ByteString -> m (Either Error ByteString))
-> Either Error ByteString -> m (Either Error ByteString)
forall a b. (a -> b) -> a -> b
$
PrivateKey
-> Draw -> Either Error ByteString -> Either Error ByteString
signWithBlindingFor PrivateKey
pk Draw
d (Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature (PrivateKey -> Int
private_size PrivateKey
pk) (Digest hashAlg -> ByteString
forall out. ByteArray out => Digest hashAlg -> out
forall hashAlg out.
(HashAlgorithmASN1 hashAlg, ByteArray out) =>
Digest hashAlg -> out
hashDigestASN1 Digest hashAlg
digest))
signDigestBlinded
:: (HashAlgorithmASN1 hashAlg, MonadRandom m)
=> BlindedKey
-> Digest hashAlg
-> m (Either Error ByteString, BlindedKey)
signDigestBlinded :: forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
BlindedKey
-> Digest hashAlg -> m (Either Error ByteString, BlindedKey)
signDigestBlinded BlindedKey
bk Digest hashAlg
digest =
BlindedKey
-> Either Error ByteString
-> m (Either Error ByteString, BlindedKey)
forall (m :: * -> *).
MonadRandom m =>
BlindedKey
-> Either Error ByteString
-> m (Either Error ByteString, BlindedKey)
signBlindedEncoded BlindedKey
bk (Either Error ByteString
-> m (Either Error ByteString, BlindedKey))
-> Either Error ByteString
-> m (Either Error ByteString, BlindedKey)
forall a b. (a -> b) -> a -> b
$
Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature (PrivateKey -> Int
private_size (BlindedKey -> PrivateKey
blindedPrivateKey BlindedKey
bk)) (Digest hashAlg -> ByteString
forall out. ByteArray out => Digest hashAlg -> out
forall hashAlg out.
(HashAlgorithmASN1 hashAlg, ByteArray out) =>
Digest hashAlg -> out
hashDigestASN1 Digest hashAlg
digest)
signDigestInfo
:: Maybe Blinder
-> PrivateKey
-> ByteString
-> Either Error ByteString
signDigestInfo :: Maybe Blinder
-> PrivateKey -> ByteString -> Either Error ByteString
signDigestInfo Maybe Blinder
blinder PrivateKey
pk ByteString
di =
Maybe Blinder -> PrivateKey -> ByteString -> ByteString
forall ba. ByteArray ba => Maybe Blinder -> PrivateKey -> ba -> ba
dp Maybe Blinder
blinder PrivateKey
pk (ByteString -> ByteString)
-> Either Error ByteString -> Either Error ByteString
forall a b. (a -> b) -> Either Error a -> Either Error b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature (PrivateKey -> Int
private_size PrivateKey
pk) ByteString
di
signSaferDigestInfo
:: MonadRandom m
=> PrivateKey
-> ByteString
-> m (Either Error ByteString)
signSaferDigestInfo :: forall (m :: * -> *).
MonadRandom m =>
PrivateKey -> ByteString -> m (Either Error ByteString)
signSaferDigestInfo PrivateKey
pk ByteString
di = do
Draw
d <- PrivateKey -> m Draw
forall (m :: * -> *). MonadRandom m => PrivateKey -> m Draw
drawFor PrivateKey
pk
Either Error ByteString -> m (Either Error ByteString)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error ByteString -> m (Either Error ByteString))
-> Either Error ByteString -> m (Either Error ByteString)
forall a b. (a -> b) -> a -> b
$ PrivateKey
-> Draw -> Either Error ByteString -> Either Error ByteString
signWithBlindingFor PrivateKey
pk Draw
d (Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature (PrivateKey -> Int
private_size PrivateKey
pk) ByteString
di)
signDigestInfoBlinded
:: MonadRandom m
=> BlindedKey
-> ByteString
-> m (Either Error ByteString, BlindedKey)
signDigestInfoBlinded :: forall (m :: * -> *).
MonadRandom m =>
BlindedKey -> ByteString -> m (Either Error ByteString, BlindedKey)
signDigestInfoBlinded BlindedKey
bk ByteString
di =
BlindedKey
-> Either Error ByteString
-> m (Either Error ByteString, BlindedKey)
forall (m :: * -> *).
MonadRandom m =>
BlindedKey
-> Either Error ByteString
-> m (Either Error ByteString, BlindedKey)
signBlindedEncoded BlindedKey
bk (Either Error ByteString
-> m (Either Error ByteString, BlindedKey))
-> Either Error ByteString
-> m (Either Error ByteString, BlindedKey)
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature (PrivateKey -> Int
private_size (BlindedKey -> PrivateKey
blindedPrivateKey BlindedKey
bk)) ByteString
di
signBlindedEncoded
:: MonadRandom m
=> BlindedKey
-> Either Error ByteString
-> m (Either Error ByteString, BlindedKey)
signBlindedEncoded :: forall (m :: * -> *).
MonadRandom m =>
BlindedKey
-> Either Error ByteString
-> m (Either Error ByteString, BlindedKey)
signBlindedEncoded BlindedKey
bk (Left Error
err) = (Either Error ByteString, BlindedKey)
-> m (Either Error ByteString, BlindedKey)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Error -> Either Error ByteString
forall a b. a -> Either a b
Left Error
err, BlindedKey
bk)
signBlindedEncoded BlindedKey
bk (Right ByteString
em) = do
(ByteString
s, BlindedKey
bk') <- BlindedKey -> ByteString -> m (ByteString, BlindedKey)
forall (m :: * -> *) ba.
(MonadRandom m, ByteArray ba) =>
BlindedKey -> ba -> m (ba, BlindedKey)
dpBlinded BlindedKey
bk ByteString
em
(Either Error ByteString, BlindedKey)
-> m (Either Error ByteString, BlindedKey)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either Error ByteString
forall a b. b -> Either a b
Right ByteString
s, BlindedKey
bk')
signWithBlindingFor
:: PrivateKey -> Draw -> Either Error ByteString -> Either Error ByteString
signWithBlindingFor :: PrivateKey
-> Draw -> Either Error ByteString -> Either Error ByteString
signWithBlindingFor PrivateKey
_ Draw
_ (Left Error
err) = Error -> Either Error ByteString
forall a b. a -> Either a b
Left Error
err
signWithBlindingFor PrivateKey
pk Draw
d (Right ByteString
em) = ByteString -> Either Error ByteString
forall a b. b -> Either a b
Right (PrivateKey
-> Draw -> ((Integer, Integer) -> ByteString) -> ByteString
forall a. PrivateKey -> Draw -> ((Integer, Integer) -> a) -> a
withBlindingFor PrivateKey
pk Draw
d (\(Integer, Integer)
pair -> (Integer, Integer) -> PrivateKey -> ByteString -> ByteString
forall ba.
ByteArray ba =>
(Integer, Integer) -> PrivateKey -> ba -> ba
dpWithPair (Integer, Integer)
pair PrivateKey
pk ByteString
em))
verifyDigest
:: HashAlgorithmASN1 hashAlg
=> PublicKey
-> Digest hashAlg
-> ByteString
-> Bool
verifyDigest :: forall hashAlg.
HashAlgorithmASN1 hashAlg =>
PublicKey -> Digest hashAlg -> ByteString -> Bool
verifyDigest PublicKey
pk Digest hashAlg
digest ByteString
sm =
PublicKey -> Either Error ByteString -> ByteString -> Bool
verifyEncoded PublicKey
pk (Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature (PublicKey -> Int
public_size PublicKey
pk) (Digest hashAlg -> ByteString
forall out. ByteArray out => Digest hashAlg -> out
forall hashAlg out.
(HashAlgorithmASN1 hashAlg, ByteArray out) =>
Digest hashAlg -> out
hashDigestASN1 Digest hashAlg
digest)) ByteString
sm
verifyDigestInfo
:: PublicKey
-> ByteString
-> ByteString
-> Bool
verifyDigestInfo :: PublicKey -> ByteString -> ByteString -> Bool
verifyDigestInfo PublicKey
pk ByteString
di ByteString
sm =
PublicKey -> Either Error ByteString -> ByteString -> Bool
verifyEncoded PublicKey
pk (Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature (PublicKey -> Int
public_size PublicKey
pk) ByteString
di) ByteString
sm
makeSignature
:: HashAlgorithmASN1 hashAlg
=> Maybe hashAlg
-> Int
-> ByteString
-> Either Error ByteString
makeSignature :: forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> Int -> ByteString -> Either Error ByteString
makeSignature Maybe hashAlg
Nothing Int
klen ByteString
m = Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature Int
klen ByteString
m
makeSignature (Just hashAlg
hashAlg) Int
klen ByteString
m = Int -> ByteString -> Either Error ByteString
forall signature.
ByteArray signature =>
Int -> signature -> Either Error signature
padSignature Int
klen (Digest hashAlg -> ByteString
forall out. ByteArray out => Digest hashAlg -> out
forall hashAlg out.
(HashAlgorithmASN1 hashAlg, ByteArray out) =>
Digest hashAlg -> out
hashDigestASN1 (Digest hashAlg -> ByteString) -> Digest hashAlg -> ByteString
forall a b. (a -> b) -> a -> b
$ hashAlg -> ByteString -> Digest hashAlg
forall ba alg.
(ByteArrayAccess ba, HashAlgorithm alg) =>
alg -> ba -> Digest alg
hashWith hashAlg
hashAlg ByteString
m)