module Crypto.Classical.Cipher.Affine where
import Control.Applicative
import Crypto.Classical.Types
import Crypto.Classical.Util
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Char
import Data.Modular
import Lens.Micro
import Lens.Micro.TH
newtype Affine a = Affine { _affine :: a } deriving (Eq,Show,Functor)
makeLenses ''Affine
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