
Thomas DuBuisson wrote:
Sorry, the example was all messed up, even if it did communicate what I wanted its just so broken I must fix.
Slightly contrived example:
buildAgreementMessage :: (Monad m, CryptoRandomGen g, ASymetricCipher k) => g -> k -> m (B.ByteString, (k,k), g) buildAgreementMessages g k = do ((p,q),g') <- eitherToFail (buildKeyPair g) let pBS = encode p msg = runPut $ do putByteString agreementHeader putWord16be (B.length pBS) putByteString pBS return $ (sign msg k, (p,q), g')
Again, this is simply trying to re-enforce the fact that buildKeyPair (formerly 'generateKeyPair') does have a place.
Granted. However, the key feature of your example is that a new key is derived from an old key, i.e. the function used is type BuildKeyPair g k = CryptoRandomGen g => g -> ((k,k),g) buildKeyPair' :: k -> BuildKeyPair g k Thanks to the additional argument, this can be added to the Key record data Key = Key { cipher :: BuildKeyPair g k , ... } In other words, the Key can also store a method to generate new keys with the same cipher algorithm. All examples that use buildKeyPair and type classes can be reformulated in terms of Key with this additional field. That's because buildKeyPair actually expects a type argument; the cipher filed merely shifts that argument to the value level. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com