Haskell RSA Example
haskell, rsa
Solution
Your question worries me. Perhaps I am too familiar with Vincent's work, but I feel that if you understand the operations then using the library would be straight forward or you would at least have very specific questions. Below, I walk through the two examples you requested and try to stop and explain for each item that might be a "curve ball".
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Crypto.Cipher.RSA
import Crypto.Random.AESCtr
import Crypto.Random
import qualified Data.ByteString.Char8 as B
import Crypto.Hash.SHA256 (hash)
The packages we draw on are: cryptocipher (which you could have mentioned in your question), cprng-aes (for a secure random number generator), crypto-api (an interface to crypto routines, but we'll limit ourselves to just the RNG interface), bytestring, and cryptohash (sign/verify operations are typically parameterizable by hash function).
Now lets encrypt and decrypt a string, then verify this is identity.
main = do
g <- newGenIO :: IO AESRNG
The crypto-api interface is used for random number generation. Because this is an overloaded function we explicitly specify the desired type of random number generator, `AESRNG`.
let Right ((pub,priv),g1) = generate g (512 {- number of bits large -}) (3 {- a prime -})
msg = "This is my message"
Right (ct,g2) = encrypt g1 pub msg
Generating the key requires the bit size (we used an rather low value for this demo, 512 bits) and any prime over two will do for generation, I just picked 3.
print $ decrypt priv ct
print $ decrypt priv ct == Right msg
The result is as expected:
Right "This is my message"
True
Signing is not much different, just get a RNG, generate keys, and when you sign be sure to specify the hash function and any meta data you would like to bind. I selected SHA256 (see the import above) and no metadata (`B.empty`).
let Right sig = sign hash B.empty priv msg
print (verify hash B.empty pub msg sig)
The result is `Right True`.
I expect most users will make their own functions for some of these operations.
mySign q msg = sign hash B.empty q msg
myVerify p msg sig = verify hash B.empty p msg sig
Some things I think Vincent and I can do to help people in the future (please suggest additions to this list):
Not everyone follows the haddock link from `CryptoRandomGen` to the crypto-api and those that do could probably use a pointer to the `cprng-aes` and `drbg` packages.
Document all functions with examples (examples of poor documentation: The `Integer` value for `generation`? I read the source. The order of the two `ByteString` values for verify? I guessed convention and read the source to confirm.)
Provide a tutorial like this in Vincent's module.
Problem
I'm trying to use `Crypto.Cipher.RSA`, and I'm struggling with encryption and signing. I've looked at the hackage page. How should I implement a round-trip example, with both the `encrypt`/`decrypt` and `sign`/`verify` processes?