{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
module Crypto.Classical.Cipher.Affine where
import Crypto.Classical.Types
import Crypto.Classical.Util
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Char
import Data.Modular
newtype Affine a = Affine { _affine :: a } deriving (Eq,Show,Functor)
instance Applicative Affine where
pure = Affine
Affine f <*> Affine a = Affine $ f a
instance Monad Affine where
return = pure
Affine a >>= f = f a
instance Cipher (ℤ/26,ℤ/26) Affine where
encrypt (a,b) = pure . B.map f
where f c | isLower c = f $ toUpper c
| not $ isLetter c = c
| otherwise = letter $ a * int c + b
decrypt (a,b) = pure . B.map f
where f c | isLower c = f $ toUpper c
| not $ isLetter c = c
| otherwise = letter $ (int c - b) * inverse a