[Haskell-cafe] a monad for secret information

Robert Dockins robdockins at fastmail.fm
Tue Oct 10 12:27:38 EDT 2006

On Oct 10, 2006, at 12:04 PM, Seth Gordon wrote:

>> data Secret a = Secret {password :: String, value :: a}
>> classify :: String -> a -> Secret a
>> classify = Secret
>> declassify :: String -> Secret a -> Maybe a
>> declassify guess (Secret pw v) | guess == pw = Just v
>>                                             | otherwise = Nothing
>> Put that in a module, do not export the Secret data type, and you're
>> good to go. I'm unsure what a Monad is giving you....
> I was just curious if I could do that within a monad.
> If the answer to my question is "no, you can't", then I'll pick up the
> shattered pieces of my life and move on.  :-)

I think you can.  Your original monad is just a little too  
simplistic.  Try something like this (untested):

import Control.Monad.State

type Password = String
type Secret s a = State (Password -> Maybe s) a

classify :: Password -> s -> Secret s ()
classify pw s = put (\x -> if x == pw then Just s else Nothing)

declassify :: Password -> Secret s (Maybe s)
declassify pw = get >>= \f -> return (f pw)

runSecret :: Secret s a -> a
runSecret m = runState m (const Nothing)

Note how this relies on "opaque" functions to hide the secret.  This  
wouldn't work if Haskell had intensional observation of functions,  
although you could still use a newtype in that case.

Slightly related: I've sometimes wondered about a monadic API for  
cryptographic primitives.  With compiler support you could do nifty  
things like make sure to use non-swappable memory for encryption keys  
and use fancy special purpose hardware for cryptographic primitives,  
if available.  The API would give a nice way to ensure proper  
information hiding policy.  Has anything like this been done or studied?

Rob Dockins

Speak softly and drive a Sherman tank.
Laugh hard; it's a long way to the bank.
           -- TMBG

More information about the Haskell-Cafe mailing list