-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Implementation of RSA, using the padding schemes of PKCS#1 v2.1. -- -- This library implements the RSA encryption and signature algorithms -- for arbitrarily-sized ByteStrings. While the implementations work, -- they are not necessarily the fastest ones on the planet. Particularly -- key generation. The algorithms included are based of RFC 3447, or the -- Public-Key Cryptography Standard for RSA, version 2.1 (a.k.a, PKCS#1 -- v2.1). @package RSA @version 2.0.0 module Codec.Crypto.RSA.Pure data RSAError RSAError :: String -> RSAError RSAKeySizeTooSmall :: RSAError RSAIntegerTooLargeToPack :: RSAError RSAMessageRepOutOfRange :: RSAError RSACipherRepOutOfRange :: RSAError RSAMessageTooShort :: RSAError RSAMessageTooLong :: RSAError RSAMaskTooLong :: RSAError RSAIncorrectSigSize :: RSAError RSAIncorrectMsgSize :: RSAError RSADecryptionError :: RSAError RSAGenError :: GenError -> RSAError data HashInfo HashInfo :: ByteString -> (ByteString -> ByteString) -> HashInfo -- | The ASN.1 DER encoding of the hash function identifier. algorithmIdent :: HashInfo -> ByteString -- | The hash function hashFunction :: HashInfo -> ByteString -> ByteString -- | 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 :: * -- | Represent a RSA public key data PublicKey :: * -- | Randomly generate a key pair of the given modules length (in bits) to -- use in any of the following functions. Use of a good random number -- generator is of considerable importance when using this function. The -- input CryptoRandomGen should never be used again for any other -- purpose; either use the output'd generator or throw it all away. generateKeyPair :: CryptoRandomGen g => g -> Int -> Either RSAError (PublicKey, PrivateKey, g) -- | Encrypt an arbitrarily-sized message given the public key and -- reasonable options. This is equivalent to calling encryptOAEP with -- SHA-256 as the hash function, MGF1(SHA-256) as the mask generation -- function, and no label. NOTE: This hash choice means that your key -- size must be 1024 bits or larger. encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> Either RSAError (ByteString, g) -- | Encrypt an arbitrarily-sized message using OAEP encoding. This is the -- encouraged encoding for doing RSA encryption. Note that your key size -- must be greater than (2 * hash length + 2) * 8. (For example, the -- encrypt convenience function uses a 256 bit / 32 byte hash -- function. Thus, its key must be greater than (2 * 32 + 2) * 8 = 528 -- bits long, and we suggest 1024 as a lower bound.) encryptOAEP :: CryptoRandomGen g => g -> (ByteString -> ByteString) -> MGF -> ByteString -> PublicKey -> ByteString -> Either RSAError (ByteString, g) -- | Encrypt an arbitrarily-sized message using PKCS1 v1.5 encoding. This -- encoding is deprecated, and should only be used when interacting with -- legacy software that cannot be modified. encryptPKCS :: CryptoRandomGen g => g -> PublicKey -> ByteString -> Either RSAError (ByteString, g) -- | Decrypt an arbitrarily-sized message given the public key and -- reasonable options. This is equivalent to calling encryptOAEP with -- SHA-256 as the hash function, MGF1(SHA-256) as the mask generation -- function, and no label. decrypt :: PrivateKey -> ByteString -> Either RSAError ByteString -- | Decrypt an arbitrarily-sized message using OAEP encoding. This is the -- encouraged encoding for doing RSA encryption. decryptOAEP :: (ByteString -> ByteString) -> MGF -> ByteString -> PrivateKey -> ByteString -> Either RSAError ByteString -- | Decrypt an arbitrarily-sized message using PKCS1 v1.5 encoding. This -- encoding is deprecated, and should only be used when interacting with -- legacy software that cannot be modified. decryptPKCS :: PrivateKey -> ByteString -> Either RSAError ByteString -- | Compute a signature for the given ByteString, using the SHA256 -- algorithm in the computation. This is currently defined as -- rsassa_pkcs1_v1_5_sign hashSHA256. If you want to use a different -- function, simply use the PKCS function, below; it will accept -- arbitrarily-length messages. sign :: PrivateKey -> ByteString -> Either RSAError ByteString -- | Verify a signature for the given ByteString, using the SHA25 algorithm -- in the computation. Again, if you'd like to use a different algorithm, -- use the rsassa_pkcs1_v1_5_verify function. verify :: PublicKey -> ByteString -> ByteString -> Either RSAError Bool -- | A 'mask generation function'. The input is a bytestring, and the -- output is a hash of the given length. Unless you know what you're -- doing, you should probably use a MGF1 formulation created with -- generate_MGF1. type MGF = ByteString -> Int64 -> Either RSAError ByteString -- | Generate a mask generation function for the rsaes_oaep_*. As suggested -- by the name, the generated function is an instance of the MGF1 -- function. The arguments are the underlying hash function to use and -- the size of a hash in bytes. -- -- The bytestring passed to the generated function cannot be longer than -- 2^32 * hLen, where hLen is the passed length of the hash. generateMGF1 :: (ByteString -> ByteString) -> MGF -- | The generalized implementation of RSAES-OAEP-ENCRYPT. Using the -- default instantiontion of this, provided by the encrypt -- function, is a pretty good plan if this makes no sense to you, as it -- is instantiated with reasonable defaults. -- -- The message to be encrypted may not be longer then (k - 2*hLen - 2), -- where k is the length of the RSA modulus in bytes and hLen is the -- length of a hash in bytes. Passing in a larger message will generate -- an error, represented by the Left constructor. Note that this means -- that OAEP encryption cannot be used with keys smaller than 512 bits. -- -- I have not put in a check for the length of the label, because I don't -- expect you to use more than 2^32 bytes. So don't make me regret that, -- eh? rsaes_oaep_encrypt :: CryptoRandomGen g => g -> (ByteString -> ByteString) -> MGF -> PublicKey -> ByteString -> ByteString -> Either RSAError (ByteString, g) -- | The generalized implementation of RSAES-OAEP-DECRYPT. Again, -- decrypt initializes this with a pretty good set of defaults if -- you don't understand what all of the arguments involve. -- -- The ciphertext message passed to this function must be k bytes long, -- where k is the size of the modulus in bytes. If it is not, this -- function will generate an error, represented by the Left constructor. -- -- Futher, k (the length of the ciphertext in bytes) must be greater than -- or equal to (2 * hLen + 2), where hLen is the length of the output of -- the hash function in bytes. If this equation does not hold, a -- (different) error will be generated. -- -- Finally, there are any number of internal situations that may generate -- an error indicating that decryption failed. rsaes_oaep_decrypt :: (ByteString -> ByteString) -> MGF -> PrivateKey -> ByteString -> ByteString -> Either RSAError ByteString -- | Implements RSAES-PKCS1-v1.5-Encrypt, for completeness and backward -- compatibility. Also because I've already written everything else, so -- why not? -- -- This encryption / padding mechanism has several known attacks, which -- are described in the literature. So unless you absolutely need to use -- this for some historical reason, you should avoid it. -- -- The message to be encrypted must be less then or equal to (k - 11) -- bytes long, where k is the length of the key modulus in bytes. -- -- Because this function uses an unknown amount of randomly-generated -- data, it takes an instance of RandomGen rather than taking a random -- number as input, and returns the resultant generator as output. You -- should take care that you (a) do not reuse the input generator, thus -- losing important randomness, and (b) choose a decent instance of -- RandomGen for passing to this function. rsaes_pkcs1_v1_5_encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> Either RSAError (ByteString, g) -- | Implements RSAES-PKCS1-v1.5-Decrypt, for completeness and possible -- backward compatibility. Please see the notes for -- rsaes_pkcs_v1_5_encrypt regarding use of this function in new -- applications without backwards compatibility requirements. -- -- The ciphertext message passed to this function must be of length k, -- where k is the length of the key modulus in bytes. rsaes_pkcs1_v1_5_decrypt :: PrivateKey -> ByteString -> Either RSAError ByteString -- | Generate a signature for the given message using the given private -- key, using the RSASSA-PKCS1-v1.5-Sign algorithm. Note that in -- researching the requirements for this project, several independent -- sources suggested not using the same key across signvalidate and -- encryptdecrypt contexts. You've been warned. -- -- The output of this function is the signature only, not the message and -- the signature. -- -- SIZE CONSTRAINT: The size of the public key (in bytes) must be greater -- than or equal to the length of the hash identifier plus the length of -- a hash plus 1. Thus, for example, you cannot use a 256 bit RSA key -- with MD5: 32 (the size of a 256-bit RSA key in bytes) is less than 18 -- (the size of MD5's identier) + 16 (the size of an MD5 hash in bytes) + -- 1, or 35. -- -- Thus, * for MD5, SHA1, and SHA256, use 512+ bit keys * for SHA384 and -- SHA512, use 1024+ bit keys rsassa_pkcs1_v1_5_sign :: HashInfo -> PrivateKey -> ByteString -> Either RSAError ByteString -- | Validate a signature for the given message using the given public key. -- The signature must be exactly k bytes long, where k is the size of the -- RSA modulus IN BYTES. rsassa_pkcs1_v1_5_verify :: HashInfo -> PublicKey -> ByteString -> ByteString -> Either RSAError Bool hashMD5 :: HashInfo hashSHA1 :: HashInfo hashSHA224 :: HashInfo hashSHA256 :: HashInfo hashSHA384 :: HashInfo hashSHA512 :: HashInfo -- | Generate a large random prime of a given length in bytes. largeRandomPrime :: CryptoRandomGen g => g -> Int -> Either RSAError (Integer, g) generatePQ :: CryptoRandomGen g => g -> Int -> Either RSAError (Integer, Integer, g) chunkify :: ByteString -> Int64 -> [ByteString] os2ip :: ByteString -> Integer i2osp :: Integral a => a -> Int -> Either RSAError ByteString rsa_dp :: Integer -> Integer -> Integer -> Either RSAError Integer rsa_ep :: Integer -> Integer -> Integer -> Either RSAError Integer rsa_vp1 :: Integer -> Integer -> Integer -> Either RSAError Integer rsa_sp1 :: Integer -> Integer -> Integer -> Either RSAError Integer -- | Compute the modular inverse (d = e^-1 mod phi) via the extended -- euclidean algorithm. modular_inverse :: Integer -> Integer -> Integer -- | Computes a^b mod c using a moderately good algorithm. modular_exponentiation :: Integer -> Integer -> Integer -> Integer -- | Generate a random ByteString of the given length randomBS :: CryptoRandomGen g => g -> Int -> Either RSAError (ByteString, g) -- | Create a random bytestring of non-zero bytes of the given length. randomNZBS :: CryptoRandomGen g => g -> Int -> Either RSAError (ByteString, g) instance Typeable RSAError instance Show RSAError instance Binary PrivateKey instance Binary PublicKey instance RSAKey PrivateKey instance RSAKey PublicKey instance Show SystemRandom instance Exception RSAError module Codec.Crypto.RSA.Exceptions data RSAError RSAError :: String -> RSAError RSAKeySizeTooSmall :: RSAError RSAIntegerTooLargeToPack :: RSAError RSAMessageRepOutOfRange :: RSAError RSACipherRepOutOfRange :: RSAError RSAMessageTooShort :: RSAError RSAMessageTooLong :: RSAError RSAMaskTooLong :: RSAError RSAIncorrectSigSize :: RSAError RSAIncorrectMsgSize :: RSAError RSADecryptionError :: RSAError RSAGenError :: GenError -> RSAError data HashInfo HashInfo :: ByteString -> (ByteString -> ByteString) -> HashInfo -- | The ASN.1 DER encoding of the hash function identifier. algorithmIdent :: HashInfo -> ByteString -- | The hash function hashFunction :: HashInfo -> ByteString -> ByteString -- | 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 :: * -- | Represent a RSA public key data PublicKey :: * -- | Randomly generate a key pair of the given modules length (in bits) to -- use in any of the following functions. Use of a good random number -- generator is of considerable importance when using this function. The -- input CryptoRandomGen should never be used again for any other -- purpose; either use the output'd generator or throw it all away. generateKeyPair :: CryptoRandomGen g => g -> Int -> (PublicKey, PrivateKey, g) -- | Encrypt an arbitrarily-sized message given the public key and -- reasonable options. This is equivalent to calling encryptOAEP with -- SHA-256 as the hash function, MGF1(SHA-256) as the mask generation -- function, and no label. NOTE: This hash choice means that your key -- size must be 1024 bits or larger. encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g) -- | Encrypt an arbitrarily-sized message using OAEP encoding. This is the -- encouraged encoding for doing RSA encryption. Note that your key size -- must be greater than (2 * hash length + 2) * 8. (For example, the -- encrypt convenience function uses a 256 bit / 32 byte hash -- function. Thus, its key must be greater than (2 * 32 + 2) * 8 = 528 -- bits long, and we suggest 1024 as a lower bound.) encryptOAEP :: CryptoRandomGen g => g -> (ByteString -> ByteString) -> MGF -> ByteString -> PublicKey -> ByteString -> (ByteString, g) -- | Encrypt an arbitrarily-sized message using PKCS1 v1.5 encoding. This -- encoding is deprecated, and should only be used when interacting with -- legacy software that cannot be modified. encryptPKCS :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g) -- | Decrypt an arbitrarily-sized message given the public key and -- reasonable options. This is equivalent to calling encryptOAEP with -- SHA-256 as the hash function, MGF1(SHA-256) as the mask generation -- function, and no label. decrypt :: PrivateKey -> ByteString -> ByteString -- | Decrypt an arbitrarily-sized message using OAEP encoding. This is the -- encouraged encoding for doing RSA encryption. decryptOAEP :: (ByteString -> ByteString) -> MGF -> ByteString -> PrivateKey -> ByteString -> ByteString -- | Decrypt an arbitrarily-sized message using PKCS1 v1.5 encoding. This -- encoding is deprecated, and should only be used when interacting with -- legacy software that cannot be modified. decryptPKCS :: PrivateKey -> ByteString -> ByteString -- | Compute a signature for the given ByteString, using the SHA256 -- algorithm in the computation. This is currently defined as -- rsassa_pkcs1_v1_5_sign hashSHA256. If you want to use a different -- function, simply use the PKCS function, below; it will accept -- arbitrarily-length messages. sign :: PrivateKey -> ByteString -> ByteString -- | Verify a signature for the given ByteString, using the SHA25 algorithm -- in the computation. Again, if you'd like to use a different algorithm, -- use the rsassa_pkcs1_v1_5_verify function. verify :: PublicKey -> ByteString -> ByteString -> Bool -- | A 'mask generation function'. The input is a bytestring, and the -- output is a hash of the given length. Unless you know what you're -- doing, you should probably use a MGF1 formulation created with -- generate_MGF1. type MGF = ByteString -> Int64 -> Either RSAError ByteString -- | Generate a mask generation function for the rsaes_oaep_*. As suggested -- by the name, the generated function is an instance of the MGF1 -- function. The arguments are the underlying hash function to use and -- the size of a hash in bytes. -- -- The bytestring passed to the generated function cannot be longer than -- 2^32 * hLen, where hLen is the passed length of the hash. generateMGF1 :: (ByteString -> ByteString) -> MGF -- | The generalized implementation of RSAES-OAEP-ENCRYPT. Using the -- default instantiontion of this, provided by the encrypt -- function, is a pretty good plan if this makes no sense to you, as it -- is instantiated with reasonable defaults. -- -- The message to be encrypted may not be longer then (k - 2*hLen - 2), -- where k is the length of the RSA modulus in bytes and hLen is the -- length of a hash in bytes. Passing in a larger message will generate -- an error, represented by the Left constructor. Note that this means -- that OAEP encryption cannot be used with keys smaller than 512 bits. -- -- I have not put in a check for the length of the label, because I don't -- expect you to use more than 2^32 bytes. So don't make me regret that, -- eh? rsaes_oaep_encrypt :: CryptoRandomGen g => g -> (ByteString -> ByteString) -> MGF -> PublicKey -> ByteString -> ByteString -> (ByteString, g) -- | The generalized implementation of RSAES-OAEP-DECRYPT. Again, -- decrypt initializes this with a pretty good set of defaults if -- you don't understand what all of the arguments involve. -- -- The ciphertext message passed to this function must be k bytes long, -- where k is the size of the modulus in bytes. If it is not, this -- function will generate an error, represented by the Left constructor. -- -- Futher, k (the length of the ciphertext in bytes) must be greater than -- or equal to (2 * hLen + 2), where hLen is the length of the output of -- the hash function in bytes. If this equation does not hold, a -- (different) error will be generated. -- -- Finally, there are any number of internal situations that may generate -- an error indicating that decryption failed. rsaes_oaep_decrypt :: (ByteString -> ByteString) -> MGF -> PrivateKey -> ByteString -> ByteString -> ByteString -- | Implements RSAES-PKCS1-v1.5-Encrypt, for completeness and backward -- compatibility. Also because I've already written everything else, so -- why not? -- -- This encryption / padding mechanism has several known attacks, which -- are described in the literature. So unless you absolutely need to use -- this for some historical reason, you should avoid it. -- -- The message to be encrypted must be less then or equal to (k - 11) -- bytes long, where k is the length of the key modulus in bytes. -- -- Because this function uses an unknown amount of randomly-generated -- data, it takes an instance of RandomGen rather than taking a random -- number as input, and returns the resultant generator as output. You -- should take care that you (a) do not reuse the input generator, thus -- losing important randomness, and (b) choose a decent instance of -- RandomGen for passing to this function. rsaes_pkcs1_v1_5_encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g) -- | Implements RSAES-PKCS1-v1.5-Decrypt, for completeness and possible -- backward compatibility. Please see the notes for -- rsaes_pkcs_v1_5_encrypt regarding use of this function in new -- applications without backwards compatibility requirements. -- -- The ciphertext message passed to this function must be of length k, -- where k is the length of the key modulus in bytes. rsaes_pkcs1_v1_5_decrypt :: PrivateKey -> ByteString -> ByteString -- | Generate a signature for the given message using the given private -- key, using the RSASSA-PKCS1-v1.5-Sign algorithm. Note that in -- researching the requirements for this project, several independent -- sources suggested not using the same key across signvalidate and -- encryptdecrypt contexts. You've been warned. -- -- The output of this function is the signature only, not the message and -- the signature. -- -- SIZE CONSTRAINT: The size of the public key (in bytes) must be greater -- than or equal to the length of the hash identifier plus the length of -- a hash plus 1. Thus, for example, you cannot use a 256 bit RSA key -- with MD5: 32 (the size of a 256-bit RSA key in bytes) is less than 18 -- (the size of MD5's identier) + 16 (the size of an MD5 hash in bytes) + -- 1, or 35. -- -- Thus, * for MD5, SHA1, and SHA256, use 512+ bit keys * for SHA384 and -- SHA512, use 1024+ bit keys rsassa_pkcs1_v1_5_sign :: HashInfo -> PrivateKey -> ByteString -> ByteString -- | Validate a signature for the given message using the given public key. -- The signature must be exactly k bytes long, where k is the size of the -- RSA modulus IN BYTES. rsassa_pkcs1_v1_5_verify :: HashInfo -> PublicKey -> ByteString -> ByteString -> Bool hashMD5 :: HashInfo hashSHA1 :: HashInfo hashSHA224 :: HashInfo hashSHA256 :: HashInfo hashSHA384 :: HashInfo hashSHA512 :: HashInfo -- | Generate a large random prime of a given length in bytes. largeRandomPrime :: CryptoRandomGen g => g -> Int -> (Integer, g) generatePQ :: CryptoRandomGen g => g -> Int -> (Integer, Integer, g) chunkify :: ByteString -> Int64 -> [ByteString] os2ip :: ByteString -> Integer i2osp :: Integral a => a -> Int -> ByteString rsa_dp :: Integer -> Integer -> Integer -> Integer rsa_ep :: Integer -> Integer -> Integer -> Integer rsa_vp1 :: Integer -> Integer -> Integer -> Integer rsa_sp1 :: Integer -> Integer -> Integer -> Integer -- | Compute the modular inverse (d = e^-1 mod phi) via the extended -- euclidean algorithm. modular_inverse :: Integer -> Integer -> Integer -- | Computes a^b mod c using a moderately good algorithm. modular_exponentiation :: Integer -> Integer -> Integer -> Integer -- | Generate a random ByteString of the given length randomBS :: CryptoRandomGen g => g -> Int -> (ByteString, g) -- | Create a random bytestring of non-zero bytes of the given length. randomNZBS :: CryptoRandomGen g => g -> Int -> (ByteString, g) module Codec.Crypto.RSA