add missing modules
This commit is contained in:
parent
b1e222cf3d
commit
b556bdb649
@ -5,7 +5,6 @@
|
|||||||
-- Stability : experimental
|
-- Stability : experimental
|
||||||
-- Portability : Good
|
-- Portability : Good
|
||||||
--
|
--
|
||||||
{-# LANGUAGE DeriveDataTypeable #-}
|
|
||||||
module Crypto.PubKey.RSA
|
module Crypto.PubKey.RSA
|
||||||
( Error(..)
|
( Error(..)
|
||||||
, PublicKey(..)
|
, PublicKey(..)
|
||||||
@ -18,7 +17,6 @@ module Crypto.PubKey.RSA
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Bits
|
import Data.Bits
|
||||||
import Data.Data
|
|
||||||
import Data.Word
|
import Data.Word
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Crypto.Random.Types
|
import Crypto.Random.Types
|
||||||
@ -27,56 +25,6 @@ import Crypto.Number.Generate (generateMax)
|
|||||||
import Crypto.Number.Prime (generatePrime)
|
import Crypto.Number.Prime (generatePrime)
|
||||||
import Crypto.PubKey.RSA.Types
|
import Crypto.PubKey.RSA.Types
|
||||||
|
|
||||||
-- | Represent a RSA public key
|
|
||||||
data PublicKey = PublicKey
|
|
||||||
{ public_size :: Int -- ^ size of key in bytes
|
|
||||||
, public_n :: Integer -- ^ public p*q
|
|
||||||
, public_e :: Integer -- ^ public exponant e
|
|
||||||
} deriving (Show,Read,Eq,Data,Typeable)
|
|
||||||
|
|
||||||
-- | 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
|
|
||||||
{ private_pub :: PublicKey -- ^ public part of a private key (size, n and e)
|
|
||||||
, private_d :: Integer -- ^ private exponant d
|
|
||||||
, private_p :: Integer -- ^ p prime number
|
|
||||||
, private_q :: Integer -- ^ q prime number
|
|
||||||
, private_dP :: Integer -- ^ d mod (p-1)
|
|
||||||
, private_dQ :: Integer -- ^ d mod (q-1)
|
|
||||||
, private_qinv :: Integer -- ^ q^(-1) mod p
|
|
||||||
} deriving (Show,Read,Eq,Data,Typeable)
|
|
||||||
|
|
||||||
-- | get the size in bytes from a private key
|
|
||||||
private_size = public_size . private_pub
|
|
||||||
|
|
||||||
-- | get n from a private key
|
|
||||||
private_n = public_n . private_pub
|
|
||||||
|
|
||||||
-- | get e from a private key
|
|
||||||
private_e = public_e . private_pub
|
|
||||||
|
|
||||||
-- | Represent RSA KeyPair
|
|
||||||
--
|
|
||||||
-- note the RSA private key contains already an instance of public key for efficiency
|
|
||||||
newtype KeyPair = KeyPair PrivateKey
|
|
||||||
deriving (Show,Read,Eq,Data,Typeable)
|
|
||||||
|
|
||||||
-- | Public key of a RSA KeyPair
|
|
||||||
toPublicKey :: KeyPair -> PublicKey
|
|
||||||
toPublicKey (KeyPair priv) = private_pub priv
|
|
||||||
|
|
||||||
-- | Private key of a RSA KeyPair
|
|
||||||
toPrivateKey :: KeyPair -> PrivateKey
|
|
||||||
toPrivateKey (KeyPair priv) = priv
|
|
||||||
|
|
||||||
-- some bad implementation will not serialize ASN.1 integer properly, leading
|
-- some bad implementation will not serialize ASN.1 integer properly, leading
|
||||||
-- to negative modulus.
|
-- to negative modulus.
|
||||||
-- TODO : Find a better place for this
|
-- TODO : Find a better place for this
|
||||||
|
|||||||
@ -21,12 +21,11 @@ module Crypto.PubKey.RSA.OAEP
|
|||||||
, decryptSafer
|
, decryptSafer
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Crypto.Random
|
import Crypto.Random.Types
|
||||||
import Crypto.Types.PubKey.RSA
|
import Crypto.PubKey.RSA.Types
|
||||||
import Crypto.PubKey.HashDescr
|
import Crypto.PubKey.HashDescr
|
||||||
import Crypto.PubKey.MaskGenFunction
|
import Crypto.PubKey.MaskGenFunction
|
||||||
import Crypto.PubKey.RSA.Prim
|
import Crypto.PubKey.RSA.Prim
|
||||||
import Crypto.PubKey.RSA.Types
|
|
||||||
import Crypto.PubKey.RSA (generateBlinder)
|
import Crypto.PubKey.RSA (generateBlinder)
|
||||||
import Crypto.PubKey.Internal (and')
|
import Crypto.PubKey.Internal (and')
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
@ -77,16 +76,17 @@ encryptWithSeed seed oaep pk msg
|
|||||||
em = B.concat [B.singleton 0x0,maskedSeed,maskedDB]
|
em = B.concat [B.singleton 0x0,maskedSeed,maskedDB]
|
||||||
|
|
||||||
-- | Encrypt a message using OAEP
|
-- | Encrypt a message using OAEP
|
||||||
encrypt :: CPRG g
|
encrypt :: MonadRandom m
|
||||||
=> g -- ^ random number generator.
|
=> OAEPParams -- ^ OAEP params to use for encryption.
|
||||||
-> OAEPParams -- ^ OAEP params to use for encryption.
|
|
||||||
-> PublicKey -- ^ Public key.
|
-> PublicKey -- ^ Public key.
|
||||||
-> ByteString -- ^ Message to encrypt
|
-> ByteString -- ^ Message to encrypt
|
||||||
-> (Either Error ByteString, g)
|
-> m (Either Error ByteString)
|
||||||
encrypt g oaep pk msg = (encryptWithSeed seed oaep pk msg, g')
|
encrypt oaep pk msg = do
|
||||||
where hashF = oaepHash oaep
|
seed <- getRandomBytes hashLen
|
||||||
hashLen = B.length (hashF B.empty)
|
return (encryptWithSeed seed oaep pk msg)
|
||||||
(seed, g') = cprgGenerate hashLen g
|
where
|
||||||
|
hashF = oaepHash oaep
|
||||||
|
hashLen = B.length (hashF B.empty)
|
||||||
|
|
||||||
-- | un-pad a OAEP encoded message.
|
-- | un-pad a OAEP encoded message.
|
||||||
--
|
--
|
||||||
@ -141,11 +141,11 @@ decrypt blinder oaep pk cipher
|
|||||||
hashLen = B.length (hashF B.empty)
|
hashLen = B.length (hashF B.empty)
|
||||||
|
|
||||||
-- | Decrypt a ciphertext using OAEP and by automatically generating a blinder.
|
-- | Decrypt a ciphertext using OAEP and by automatically generating a blinder.
|
||||||
decryptSafer :: CPRG g
|
decryptSafer :: MonadRandom m
|
||||||
=> g -- ^ random number generator
|
=> OAEPParams -- ^ OAEP params to use for decryption
|
||||||
-> OAEPParams -- ^ OAEP params to use for decryption
|
|
||||||
-> PrivateKey -- ^ Private key
|
-> PrivateKey -- ^ Private key
|
||||||
-> ByteString -- ^ Cipher text
|
-> ByteString -- ^ Cipher text
|
||||||
-> (Either Error ByteString, g)
|
-> m (Either Error ByteString)
|
||||||
decryptSafer rng oaep pk cipher = (decrypt (Just blinder) oaep pk cipher, rng')
|
decryptSafer oaep pk cipher = do
|
||||||
where (blinder, rng') = generateBlinder rng (private_n pk)
|
blinder <- generateBlinder (private_n pk)
|
||||||
|
return (decrypt (Just blinder) oaep pk cipher)
|
||||||
|
|||||||
@ -22,34 +22,33 @@ module Crypto.PubKey.RSA.PKCS15
|
|||||||
, verify
|
, verify
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Crypto.Random
|
import Crypto.Random.Types
|
||||||
import Crypto.PubKey.Internal (and')
|
import Crypto.PubKey.Internal (and')
|
||||||
import Crypto.Types.PubKey.RSA
|
import Crypto.PubKey.RSA.Types
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import Crypto.PubKey.RSA.Prim
|
import Crypto.PubKey.RSA.Prim
|
||||||
import Crypto.PubKey.RSA.Types
|
|
||||||
import Crypto.PubKey.RSA (generateBlinder)
|
import Crypto.PubKey.RSA (generateBlinder)
|
||||||
import Crypto.PubKey.HashDescr
|
import Crypto.PubKey.HashDescr
|
||||||
|
|
||||||
-- | This produce a standard PKCS1.5 padding for encryption
|
-- | This produce a standard PKCS1.5 padding for encryption
|
||||||
pad :: CPRG g => g -> Int -> ByteString -> Either Error (ByteString, g)
|
pad :: MonadRandom m => Int -> ByteString -> m (Either Error ByteString)
|
||||||
pad rng len m
|
pad len m
|
||||||
| B.length m > len - 11 = Left MessageTooLong
|
| B.length m > len - 11 = return (Left MessageTooLong)
|
||||||
| otherwise =
|
| otherwise = do
|
||||||
let (padding, rng') = getNonNullRandom rng (len - B.length m - 3)
|
padding <- getNonNullRandom (len - B.length m - 3)
|
||||||
in Right (B.concat [ B.singleton 0, B.singleton 2, padding, B.singleton 0, m ], rng')
|
return $ Right $ B.concat [ B.singleton 0, B.singleton 2, padding, B.singleton 0, m ]
|
||||||
|
|
||||||
where {- get random non-null bytes -}
|
where {- get random non-null bytes -}
|
||||||
getNonNullRandom :: CPRG g => g -> Int -> (ByteString, g)
|
getNonNullRandom :: MonadRandom m => Int -> m ByteString
|
||||||
getNonNullRandom g n =
|
getNonNullRandom n = do
|
||||||
let (bs0,g') = cprgGenerate n g
|
bs0 <- getRandomBytes n
|
||||||
bytes = B.pack $ filter (/= 0) $ B.unpack $ bs0
|
let bytes = B.pack $ filter (/= 0) $ B.unpack $ bs0
|
||||||
left = (n - B.length bytes)
|
left = n - B.length bytes
|
||||||
in if left == 0
|
if left == 0
|
||||||
then (bytes, g')
|
then return bytes
|
||||||
else let (bend, g'') = getNonNullRandom g' left
|
else do bend <- getNonNullRandom left
|
||||||
in (bytes `B.append` bend, g'')
|
return (bytes `B.append` bend)
|
||||||
|
|
||||||
-- | Produce a standard PKCS1.5 padding for signature
|
-- | Produce a standard PKCS1.5 padding for signature
|
||||||
padSignature :: Int -> ByteString -> Either Error ByteString
|
padSignature :: Int -> ByteString -> Either Error ByteString
|
||||||
@ -89,23 +88,23 @@ decrypt blinder pk c
|
|||||||
| otherwise = unpad $ dp blinder pk c
|
| otherwise = unpad $ dp blinder pk c
|
||||||
|
|
||||||
-- | decrypt message using the private key and by automatically generating a blinder.
|
-- | decrypt message using the private key and by automatically generating a blinder.
|
||||||
decryptSafer :: CPRG g
|
decryptSafer :: MonadRandom m
|
||||||
=> g -- ^ random generator
|
=> PrivateKey -- ^ RSA private key
|
||||||
-> PrivateKey -- ^ RSA private key
|
|
||||||
-> ByteString -- ^ cipher text
|
-> ByteString -- ^ cipher text
|
||||||
-> (Either Error ByteString, g)
|
-> m (Either Error ByteString)
|
||||||
decryptSafer rng pk b =
|
decryptSafer pk b = do
|
||||||
let (blinder, rng') = generateBlinder rng (private_n pk)
|
blinder <- generateBlinder (private_n pk)
|
||||||
in (decrypt (Just blinder) pk b, rng')
|
return (decrypt (Just blinder) pk b)
|
||||||
|
|
||||||
-- | encrypt a bytestring using the public key and a CPRG random generator.
|
-- | encrypt a bytestring using the public key and a CPRG random generator.
|
||||||
--
|
--
|
||||||
-- the message need to be smaller than the key size - 11
|
-- the message need to be smaller than the key size - 11
|
||||||
encrypt :: CPRG g => g -> PublicKey -> ByteString -> (Either Error ByteString, g)
|
encrypt :: MonadRandom m => PublicKey -> ByteString -> m (Either Error ByteString)
|
||||||
encrypt rng pk m = do
|
encrypt pk m = do
|
||||||
case pad rng (public_size pk) m of
|
r <- pad (public_size pk) m
|
||||||
Left err -> (Left err, rng)
|
case r of
|
||||||
Right (em, rng') -> (Right (ep pk em), rng')
|
Left err -> return $ Left err
|
||||||
|
Right em -> return $ Right (ep pk em)
|
||||||
|
|
||||||
-- | sign message using private key, a hash and its ASN1 description
|
-- | sign message using private key, a hash and its ASN1 description
|
||||||
--
|
--
|
||||||
@ -121,15 +120,14 @@ sign :: Maybe Blinder -- ^ optional blinder
|
|||||||
sign blinder hashDescr pk m = dp blinder pk `fmap` makeSignature hashDescr (private_size pk) m
|
sign blinder hashDescr pk m = dp blinder pk `fmap` makeSignature hashDescr (private_size pk) m
|
||||||
|
|
||||||
-- | sign message using the private key and by automatically generating a blinder.
|
-- | sign message using the private key and by automatically generating a blinder.
|
||||||
signSafer :: CPRG g
|
signSafer :: MonadRandom m
|
||||||
=> g -- ^ random generator
|
=> HashDescr -- ^ Hash descriptor
|
||||||
-> HashDescr -- ^ Hash descriptor
|
|
||||||
-> PrivateKey -- ^ private key
|
-> PrivateKey -- ^ private key
|
||||||
-> ByteString -- ^ message to sign
|
-> ByteString -- ^ message to sign
|
||||||
-> (Either Error ByteString, g)
|
-> m (Either Error ByteString)
|
||||||
signSafer rng hashDescr pk m =
|
signSafer hashDescr pk m = do
|
||||||
let (blinder, rng') = generateBlinder rng (private_n pk)
|
blinder <- generateBlinder (private_n pk)
|
||||||
in (sign (Just blinder) hashDescr pk m, rng')
|
return (sign (Just blinder) hashDescr pk m)
|
||||||
|
|
||||||
-- | verify message with the signed message
|
-- | verify message with the signed message
|
||||||
verify :: HashDescr -> PublicKey -> ByteString -> ByteString -> Bool
|
verify :: HashDescr -> PublicKey -> ByteString -> ByteString -> Bool
|
||||||
|
|||||||
@ -16,8 +16,8 @@ module Crypto.PubKey.RSA.PSS
|
|||||||
, verify
|
, verify
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Crypto.Random
|
import Crypto.Random.Types
|
||||||
import Crypto.Types.PubKey.RSA
|
import Crypto.PubKey.RSA.Types
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import Data.Byteable
|
import Data.Byteable
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
@ -78,25 +78,25 @@ signWithSalt salt blinder params pk m
|
|||||||
em = B.concat [maskedDB, h, B.singleton (pssTrailerField params)]
|
em = B.concat [maskedDB, h, B.singleton (pssTrailerField params)]
|
||||||
|
|
||||||
-- | Sign using the PSS Parameters
|
-- | Sign using the PSS Parameters
|
||||||
sign :: CPRG g
|
sign :: MonadRandom m
|
||||||
=> g -- ^ random generator to use to generate the salt
|
=> Maybe Blinder -- ^ optional blinder to use
|
||||||
-> Maybe Blinder -- ^ optional blinder to use
|
|
||||||
-> PSSParams -- ^ PSS Parameters to use
|
-> PSSParams -- ^ PSS Parameters to use
|
||||||
-> PrivateKey -- ^ RSA Private Key
|
-> PrivateKey -- ^ RSA Private Key
|
||||||
-> ByteString -- ^ Message to sign
|
-> ByteString -- ^ Message to sign
|
||||||
-> (Either Error ByteString, g)
|
-> m (Either Error ByteString)
|
||||||
sign rng blinder params pk m = (signWithSalt salt blinder params pk m, rng')
|
sign blinder params pk m = do
|
||||||
where (salt,rng') = cprgGenerate (pssSaltLength params) rng
|
salt <- getRandomBytes (pssSaltLength params)
|
||||||
|
return (signWithSalt salt blinder params pk m)
|
||||||
|
|
||||||
-- | Sign using the PSS Parameters and an automatically generated blinder.
|
-- | Sign using the PSS Parameters and an automatically generated blinder.
|
||||||
signSafer :: CPRG g
|
signSafer :: MonadRandom m
|
||||||
=> g -- ^ random generator
|
=> PSSParams -- ^ PSS Parameters to use
|
||||||
-> PSSParams -- ^ PSS Parameters to use
|
|
||||||
-> PrivateKey -- ^ private key
|
-> PrivateKey -- ^ private key
|
||||||
-> ByteString -- ^ message to sign
|
-> ByteString -- ^ message to sign
|
||||||
-> (Either Error ByteString, g)
|
-> m (Either Error ByteString)
|
||||||
signSafer rng params pk m = sign rng' (Just blinder) params pk m
|
signSafer params pk m = do
|
||||||
where (blinder, rng') = generateBlinder rng (private_n pk)
|
blinder <- generateBlinder (private_n pk)
|
||||||
|
sign (Just blinder) params pk m
|
||||||
|
|
||||||
-- | Verify a signature using the PSS Parameters
|
-- | Verify a signature using the PSS Parameters
|
||||||
verify :: PSSParams -- ^ PSS Parameters to use to verify,
|
verify :: PSSParams -- ^ PSS Parameters to use to verify,
|
||||||
|
|||||||
@ -14,8 +14,7 @@ module Crypto.PubKey.RSA.Prim
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import Crypto.PubKey.RSA.Types (Blinder(..))
|
import Crypto.PubKey.RSA.Types
|
||||||
import Crypto.Types.PubKey.RSA
|
|
||||||
import Crypto.Number.ModArithmetic (expFast, expSafe)
|
import Crypto.Number.ModArithmetic (expFast, expSafe)
|
||||||
import Crypto.Number.Serialize (os2ip, i2ospOf_)
|
import Crypto.Number.Serialize (os2ip, i2ospOf_)
|
||||||
|
|
||||||
|
|||||||
@ -5,11 +5,21 @@
|
|||||||
-- Stability : experimental
|
-- Stability : experimental
|
||||||
-- Portability : Good
|
-- Portability : Good
|
||||||
--
|
--
|
||||||
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
module Crypto.PubKey.RSA.Types
|
module Crypto.PubKey.RSA.Types
|
||||||
( Error(..)
|
( Error(..)
|
||||||
, Blinder(..)
|
, Blinder(..)
|
||||||
|
, PublicKey(..)
|
||||||
|
, PrivateKey(..)
|
||||||
|
, KeyPair(..)
|
||||||
|
, private_size
|
||||||
|
, private_n
|
||||||
|
, private_e
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Data.Data
|
||||||
|
import Data.Typeable
|
||||||
|
|
||||||
-- | Blinder which is used to obfuscate the timing
|
-- | Blinder which is used to obfuscate the timing
|
||||||
-- of the decryption primitive (used by decryption and signing).
|
-- of the decryption primitive (used by decryption and signing).
|
||||||
data Blinder = Blinder !Integer !Integer
|
data Blinder = Blinder !Integer !Integer
|
||||||
@ -24,3 +34,53 @@ data Error =
|
|||||||
| InvalidParameters -- ^ some parameters lead to breaking assumptions.
|
| InvalidParameters -- ^ some parameters lead to breaking assumptions.
|
||||||
deriving (Show,Eq)
|
deriving (Show,Eq)
|
||||||
|
|
||||||
|
-- | Represent a RSA public key
|
||||||
|
data PublicKey = PublicKey
|
||||||
|
{ public_size :: Int -- ^ size of key in bytes
|
||||||
|
, public_n :: Integer -- ^ public p*q
|
||||||
|
, public_e :: Integer -- ^ public exponant e
|
||||||
|
} deriving (Show,Read,Eq,Data,Typeable)
|
||||||
|
|
||||||
|
-- | 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
|
||||||
|
{ private_pub :: PublicKey -- ^ public part of a private key (size, n and e)
|
||||||
|
, private_d :: Integer -- ^ private exponant d
|
||||||
|
, private_p :: Integer -- ^ p prime number
|
||||||
|
, private_q :: Integer -- ^ q prime number
|
||||||
|
, private_dP :: Integer -- ^ d mod (p-1)
|
||||||
|
, private_dQ :: Integer -- ^ d mod (q-1)
|
||||||
|
, private_qinv :: Integer -- ^ q^(-1) mod p
|
||||||
|
} deriving (Show,Read,Eq,Data,Typeable)
|
||||||
|
|
||||||
|
-- | get the size in bytes from a private key
|
||||||
|
private_size = public_size . private_pub
|
||||||
|
|
||||||
|
-- | get n from a private key
|
||||||
|
private_n = public_n . private_pub
|
||||||
|
|
||||||
|
-- | get e from a private key
|
||||||
|
private_e = public_e . private_pub
|
||||||
|
|
||||||
|
-- | Represent RSA KeyPair
|
||||||
|
--
|
||||||
|
-- note the RSA private key contains already an instance of public key for efficiency
|
||||||
|
newtype KeyPair = KeyPair PrivateKey
|
||||||
|
deriving (Show,Read,Eq,Data,Typeable)
|
||||||
|
|
||||||
|
-- | Public key of a RSA KeyPair
|
||||||
|
toPublicKey :: KeyPair -> PublicKey
|
||||||
|
toPublicKey (KeyPair priv) = private_pub priv
|
||||||
|
|
||||||
|
-- | Private key of a RSA KeyPair
|
||||||
|
toPrivateKey :: KeyPair -> PrivateKey
|
||||||
|
toPrivateKey (KeyPair priv) = priv
|
||||||
|
|
||||||
|
|||||||
@ -69,6 +69,10 @@ Library
|
|||||||
Crypto.PubKey.ECC.ECDSA
|
Crypto.PubKey.ECC.ECDSA
|
||||||
Crypto.PubKey.ECC.Types
|
Crypto.PubKey.ECC.Types
|
||||||
Crypto.PubKey.RSA
|
Crypto.PubKey.RSA
|
||||||
|
Crypto.PubKey.RSA.PKCS15
|
||||||
|
Crypto.PubKey.RSA.Prim
|
||||||
|
Crypto.PubKey.RSA.PSS
|
||||||
|
Crypto.PubKey.RSA.OAEP
|
||||||
Crypto.PubKey.RSA.Types
|
Crypto.PubKey.RSA.Types
|
||||||
Crypto.Random
|
Crypto.Random
|
||||||
Crypto.Random.Types
|
Crypto.Random.Types
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user