An implementation of RSA (PKCS #1) Cryptography, as described by the RSA standard and RFC 3447.
 data PublicKey = PublicKey {}
 data PrivateKey = PrivateKey {}
 generateKeyPair :: RandomGen g => g > Int > (PublicKey, PrivateKey, g)
 encrypt :: RandomGen g => g > PublicKey > ByteString > (ByteString, g)
 decrypt :: PrivateKey > ByteString > ByteString
 sign :: PrivateKey > ByteString > ByteString
 verify :: PublicKey > ByteString > ByteString > Bool
 data EncryptionOptions
 = UseOAEP { }
  UsePKCS1_v1_5
 encrypt' :: RandomGen g => EncryptionOptions > g > PublicKey > ByteString > (ByteString, g)
 decrypt' :: EncryptionOptions > PrivateKey > ByteString > ByteString
 type MGF = ByteString > Int64 > ByteString
 rsaes_oaep_encrypt :: HashFunction > MGF > PublicKey > Integer > ByteString > ByteString > ByteString
 rsaes_oaep_decrypt :: HashFunction > MGF > PrivateKey > ByteString > ByteString > ByteString
 generate_MGF1 :: HashFunction > MGF
 rsaes_pkcs1_v1_5_encrypt :: RandomGen g => g > PublicKey > ByteString > (ByteString, g)
 rsaes_pkcs1_v1_5_decrypt :: PrivateKey > ByteString > ByteString
 rsassa_pkcs1_v1_5_sign :: HashInfo > PrivateKey > ByteString > ByteString
 rsassa_pkcs1_v1_5_verify :: HashInfo > PublicKey > ByteString > ByteString > Bool
 type HashFunction = ByteString > ByteString
 data HashInfo = HashInfo {}
 ha_MD5 :: HashInfo
 ha_SHA1 :: HashInfo
 ha_SHA256 :: HashInfo
 ha_SHA384 :: HashInfo
 ha_SHA512 :: HashInfo
Keys and key generations
generateKeyPair :: RandomGen g => g > Int > (PublicKey, PrivateKey, g)Source
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 RandomGen should never be used again for any other purpose.
Highlevel encryption and signing functions
encrypt :: RandomGen g => g > PublicKey > ByteString > (ByteString, g)Source
Encrypt an arbitrarilysized message using the defaults for RSA encryption (specifically, using MGF1, SHA256 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.
decrypt :: PrivateKey > ByteString > ByteStringSource
Decrypt an arbitrarilysized message using the defaults for RSA decryption (specifically, using MGF1, SHA256 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 arbitrarilysized message, this function cannot. The message passed must be a multiple of the modulus length.
sign :: PrivateKey > ByteString > ByteStringSource
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 arbitrarylength messages.
verify :: PublicKey > ByteString > ByteString > BoolSource
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.
data EncryptionOptions Source
UseOAEP  
 
UsePKCS1_v1_5 
encrypt' :: RandomGen g => EncryptionOptions > g > PublicKey > ByteString > (ByteString, g)Source
Encrypt an arbitrarilysized message using the given options.
decrypt' :: EncryptionOptions > PrivateKey > ByteString > ByteStringSource
Decrypt an arbitrarilysized message using the given options. Well, sort of arbitrarily sized; the message should be a multiple of the modulus length.
Core OAEP Routines
type MGF = ByteString > Int64 > ByteStringSource
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.
rsaes_oaep_encrypt :: HashFunction > MGF > PublicKey > Integer > ByteString > ByteString > ByteStringSource
The generalized implementation of RSAESOAEPENCRYPT. 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 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_decrypt :: HashFunction > MGF > PrivateKey > ByteString > ByteString > ByteStringSource
The generalized implementation of RSAESOAEPDECRYPT. 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.
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.
generate_MGF1 :: HashFunction > MGFSource
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.
Core PSS Routines
RSASSAPSSSign, RSASSAPSSVerify, and the related functions are not included because they are covered by U.S. Patent 7036014, and it's not clear what the restrictions on implementations are.
Core PKCS1 (v1.5) Routines
rsaes_pkcs1_v1_5_encrypt :: RandomGen g => g > PublicKey > ByteString > (ByteString, g)Source
Implements RSAESPKCS1v1.5Encrypt, 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 randomlygenerated 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_decrypt :: PrivateKey > ByteString > ByteStringSource
Implements RSAESPKCS1v1.5Decrypt, 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.
rsassa_pkcs1_v1_5_sign :: HashInfo > PrivateKey > ByteString > ByteStringSource
Generates a signature for the given message using the given private key. This is obviously based on RSASSAPKCS1v1.5Sign from the specification. Note that in researching what was required for this project, several independent sources suggested not using the same key across signvalidate and encryptdecrypt contexts.
The output of this function is the signature only, not the message and signature.
rsassa_pkcs1_v1_5_verify :: HashInfo > PublicKey > ByteString > ByteString > BoolSource
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.
Hashing algorithm declarations for use in RSA functions
type HashFunction = ByteString > ByteStringSource
HashInfo  
