-- 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 1.2.2.0


-- | An implementation of RSA (PKCS #1) Cryptography, as described by the
--   RSA standard and RFC 3447.
module Codec.Crypto.RSA

-- | Randomly generate a key pair of the given modulus 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.
generateKeyPair :: CryptoRandomGen g => g -> Int -> (PublicKey, PrivateKey, g)

-- | 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 :: *

-- | Encrypt an arbitrarily-sized message using the defaults for RSA
--   encryption (specifically, using MGF1, SHA-256 as the hash function,
--   and not adding a label). If the message is longer than the underlying
--   encryption function can support, it is broken up into parts and each
--   part is encrypted.
encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)

-- | Decrypt an arbitrarily-sized message using the defaults for RSA
--   decryption (specifically, using MGF1, SHA-256 as the hash function,
--   and not adding a label). If the message is longer than the underlying
--   decryption function supports, it is assumed that the message was
--   generated by concatenating a series of blocks.
--   
--   While the encryption function, above, can take an arbitrarily-sized
--   message, this function cannot. The message passed must be a multiple
--   of the modulus length.
decrypt :: 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 ha_SHA256. If you want to use a different
--   function, simply use the pkcs function, below; it will accept
--   arbitrary-length messages.
sign :: PrivateKey -> ByteString -> ByteString

-- | Verity a signature for the given ByteString, using the SHA256
--   algorithm in the computation. Again, if you'd like to use a different
--   algorithm, use the rsassa_pkcs1_v1_5_verify function.
--   
--   The first bytestring is the message, the second is the signature to
--   check.
verify :: PublicKey -> ByteString -> ByteString -> Bool
data EncryptionOptions
UseOAEP :: HashFunction -> MGF -> ByteString -> EncryptionOptions

-- | The hash function to use.
oaep_hash :: EncryptionOptions -> HashFunction

-- | The mask generation function to use.
oaep_mgf :: EncryptionOptions -> MGF

-- | The label to annotate items with.
oaep_label :: EncryptionOptions -> ByteString
UsePKCS1_v1_5 :: EncryptionOptions

-- | Encrypt an arbitrarily-sized message using the given options.
encrypt' :: CryptoRandomGen g => EncryptionOptions -> g -> PublicKey -> ByteString -> (ByteString, g)

-- | Decrypt an arbitrarily-sized message using the given options. Well,
--   sort of arbitrarily sized; the message should be a multiple of the
--   modulus length.
decrypt' :: EncryptionOptions -> PrivateKey -> ByteString -> ByteString

-- | 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 -> ByteString

-- | The generalized implementation of RSAES-OAEP-ENCRYPT. Using the
--   default instantiontion of this, provided by the <a>encrypt</a>
--   function, is a pretty good plan if this makes no sense to you, as it
--   is instantiated with reasonable defaults.
--   
--   The arguments to this function are, in order: the hash function to
--   use, the mask generation function (MGF), the recipient's RSA public
--   key, a random seed, a label to associate with the message, and the
--   message to be encrypted.
--   
--   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.
--   
--   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 -> HashFunction -> MGF -> PublicKey -> ByteString -> ByteString -> (ByteString, g)

-- | The generalized implementation of RSAES-OAEP-DECRYPT. Again,
--   <a>decrypt</a> 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.
--   
--   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.
--   
--   The arguments to this function are the hash function to use, the mask
--   generation function (MGF), the recipient's private key, the optional
--   label whose association with this message should be verified, and the
--   ciphertext message.
rsaes_oaep_decrypt :: HashFunction -> MGF -> PrivateKey -> ByteString -> ByteString -> 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.
generate_MGF1 :: HashFunction -> MGF

-- | Implements RSAES-PKCS1-v1.5-Encrypt, as defined by the spec, for
--   completeness and possible 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 shouldn't.
--   
--   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, as defined by the spec, for
--   completeness and possible backward compatibility. Please see the notes
--   for rsaes_pkcs1_v1_5_encrypt regarding use of this function in new
--   applications without historical algorithm 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

-- | Generates a signature for the given message using the given private
--   key. This is obviously based on RSASSA-PKCS1-v1.5-Sign from the
--   specification. Note that in researching what was required for this
--   project, several independent sources suggested not using the same key
--   across sign<i>validate and encrypt</i>decrypt contexts.
--   
--   The output of this function is the signature only, not the message and
--   signature.
rsassa_pkcs1_v1_5_sign :: HashInfo -> PrivateKey -> ByteString -> ByteString

-- | Validates a signature for the given message using the given public
--   key. The arguments are, in order: the hash function to use, the public
--   key, the message, and the signature. 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
type HashFunction = ByteString -> ByteString
data HashInfo
HashInfo :: ByteString -> HashFunction -> HashInfo

-- | The ASN.1 DER encoding of the hash function identifier.
algorithmIdent :: HashInfo -> ByteString

-- | The hash function.
hashFunction :: HashInfo -> HashFunction
ha_MD5 :: HashInfo
ha_SHA1 :: HashInfo
ha_SHA256 :: HashInfo
ha_SHA384 :: HashInfo
ha_SHA512 :: HashInfo
instance Show EncryptionOptions
instance Binary PrivateKey
instance Binary PublicKey
