Crypto-API is stabilizing

All, Crypto-API - a unified interface to which I hope hash and cipher algorithms will adhere - has recently gotten a reasonable amount of polish work. I continue to welcome all comments! A blog on its current interface is online [1] as are darcs repositories of the crypto-api package [2]. Recent changes includes added block cipher modes, platform-independent RNG, tests, a simplistic benchmark framework, and minor tweaks of the classes. I've made experimental hash, block cipher and stream cipher instances. Almost no optimizations have been made as of yet! Thanks to everyone for their past comments! I have made numerous changes based on input received. If you feel I didn't respond properly to your suggestion then please ping me again - this is purely a spare time effort and things do fall through the cracks. Cheers, Thomas [1] http://tommd.wordpress.com/2010/08/23/a-haskell-api-for-cryptographic-algori... [2] http://community.haskell.org/~tommd/crypto/ (If you're wondering why you're BCCed its probably because you worked on a crypto-related Haskell package)

Thomas DuBuisson wrote:
[1] http://tommd.wordpress.com/2010/08/23/a-haskell-api-for-cryptographic-algori...
class (Binary p, Serialize p) => AsymCipher p where generateKeypair :: RandomGen g => g -> BitLength -> Maybe ((p,p),g) encryptAsym :: p -> B.ByteString -> B.ByteString decryptAsym :: p -> B.ByteString -> B.ByteString asymKeyLength :: p -> BitLength
Regarding AsymCipher: Some algorithms do not lend themselves to encryption/decryption or have special properties which differentiate their use in enc/dec an signing/verifying. I propose the following two additions for the class: signAsym :: p -> B.ByteString -> B.ByteString verifyAsym :: p -> B.ByteString -> Bool This way algorithms can leave parts undefined which do not apply to them or hide their different behaviour. Another possibility would be a split of AsymCipher into AsymCipherEnc (which is just like the old AsymCipher) and AsymCipherSig for Signatures. Textbook-RSA is special, since it can implement both classes with a minimum of effort, but a clean separation would be nice (and there wouldn't be that many undefined functions). Another thing: A central interface to get the output of a PRNG would be nice, preferably not constrained to Int like RandomGen. MonadRandom has with getRandomR a nice function, since it takes an interval (possibly using type Integer), which is very comfortable for asymmetric cipher usage. A central interface could spare AsymCipher-implementers the effort of duplicated work - we are lazy after all. ;-) Also: Sorry for entering this late into the discussion! Have a nice day, Marcel -- Marcel Fourné OpenPGP-Key-ID: 0x74545C72 A good library is preferable to a tool, except when you just need that one tool.

class (Binary p, Serialize p) => AsymCipher p where generateKeypair :: RandomGen g => g -> BitLength -> Maybe ((p,p),g) encryptAsym :: p -> B.ByteString -> B.ByteString decryptAsym :: p -> B.ByteString -> B.ByteString asymKeyLength :: p -> BitLength
Regarding AsymCipher: Some algorithms do not lend themselves to encryption/decryption or have special properties which differentiate their use in enc/dec an signing/verifying.
I propose the following two additions for the class: signAsym :: p -> B.ByteString -> B.ByteString verifyAsym :: p -> B.ByteString -> Bool
This way algorithms can leave parts undefined which do not apply to them or hide their different behaviour.
I am strongly against classes for which we already know instanes will need a good deal of undefined routines.
Another possibility would be a split of AsymCipher into AsymCipherEnc (which is just like the old AsymCipher) and AsymCipherSig for Signatures. Textbook-RSA is special, since it can implement both classes with a minimum of effort, but a clean separation would be nice (and there wouldn't be that many undefined functions).
Perhaps even zero undefined functions. I like this suggestion, though I'm not aware of any haskell implementations that will take advantage of a "Signature" class yet. Unless someone can point to something like a DSA or ECDSA on hackage I'll probably release crypto-api 0.1 without this class (it would still likely appear in a later version after further consideration).
Another thing: A central interface to get the output of a PRNG would be nice, preferably not constrained to Int like RandomGen.
Designing a random interface that provides something as high a level as monad random, is easy enough to make instances for (like RandomGen) and is feature rich enough to allow reseeding, additional entropy input, personalization, and failure is a non-trivial design task. Having ran into the dilemma of how to provide a reasonable high-level interface for DRBG, I agree with your statement but don't know how a solution would look. FYI, BOS had a similar suggestion (on the blog) of moving away from RandomGen but I'm not clear on what I'd move toward. Cheers, Thomas

Marcel noted:
A central interface to get the output of a PRNG would be nice, preferably not constrained to Int like RandomGen.
While BOS said:
Also, don’t use RandomGen for your asymmetric PRNG. The default implementation in System.Random gives absolutely disastrous performance, and the typeclass is just misdesigned (the split function shouldn’t be present).
Ok, ok. I never liked RandomGen either - I start this whole thing because of my PRNG and it doesn't fit RandomGen one bit. I've build Data.Crypto.Random.RandomGenerator - a new class that fixes the aspects of RandomGen I don't like. This is something I was considering anyway, so it's probably best now and not as an API upset in a couple months. There is a blog on this [1], but the main points about the new class are: 1) Generates bytestrings, not Ints 2) Generalized PRNG construction and reseeding 3) 'split' is in a different class. 4) Clean failure via Either (RandomGen forced you to use exceptions) And minor points - Providing additional entropy while requesting data is allowed and has a default instance so most users can ignore this all together. - a newtype wrapper and instance allows all RandomGenerator instances to be used as RandomGen when needed. Who cares about this? Anyone wanting to get random IVs for block cipher modes (without getIV_IO) and anyone wanting to generate asymmetric keys using the AsymCipher class. What can you do? Accept this API, help improve the API, or argue that we should stick with RandomGen (despite short-comings noted on the blog). Please pick one and get to it! Cheers, Thomas P.S. I would like to get crypto-api onto hackage by the end of the first week of September, but understand this is a fairly large change and will slide that date if there is an unusual strong objection. [1] http://tommd.wordpress.com/2010/09/02/a-better-foundation-for-random-values-...
Designing a random interface that provides something as high a level as monad random, is easy enough to make instances for (like RandomGen) and is feature rich enough to allow reseeding, additional entropy input, personalization, and failure is a non-trivial design task. Having ran into the dilemma of how to provide a reasonable high-level interface for DRBG, I agree with your statement but don't know how a solution would look.
FYI, BOS had a similar suggestion (on the blog) of moving away from RandomGen but I'm not clear on what I'd move toward.
Cheers, Thomas

Thomas DuBuisson wrote:
There is a blog on this [1], but the main points about the new class are:
1) Generates bytestrings, not Ints
I like this one because it's semantically truer (tm). ;-)
2) Generalized PRNG construction and reseeding
...which takes the great burden off it's users shoulders, nice!
3) 'split' is in a different class.
Is it necessary for crypto-use? I have never used it for that and I don't know if somebody other did, but I just ask myself the question.
4) Clean failure via Either (RandomGen forced you to use exceptions)
This is much better and fits nicely into the generateKeyPair of AsymCipher with a minimum of effort.
What can you do? Accept this API, help improve the API, or argue that we should stick with RandomGen (despite short-comings noted on the blog). Please pick one and get to it!
I plan to use this (genInteger looks just too convenient), but RandomGenerator looks nice enough to use it in other crypto-projects (just my RNG-output consumers view)! Marcel -- Marcel Fourné OpenPGP-Key-ID: 0x74545C72 A good library is preferable to a tool, except when you just need that one tool.

On Sun, Sep 5, 2010 at 1:30 AM, Marcel Fourné
3) 'split' is in a different class.
Is it necessary for crypto-use?
For now the Splittable class is necessary for the CryptoRandomGen --> RandomGen path allowing more users to use CryptoRandomGen instances: data AsRandomGen g = AsRG g instance (CryptoRandomGen, SplittableGen g) => RandomGen (AsRandomGen g) where ... ... but in general, no I don't see it being used and hope people avoid split like its ML. Eventually I see Crypto.Random becoming part of the 'random' package (at the same time as an overhaul of RandomGen). If that happens I envision an interface like: class Random a where someFuncs :: (RandomGen g) => ... class RandomGen g where next :: g -> (Int, g) class SplittableGen g where split :: g -> Either GenError (g,g) class CryptoRandomGen g where ... Not sure if we'd want to make split always succeed, if RandomGen should still return Int, etc, but this change is not going finish being discussed before crypto-api is out. Heck, I haven't even e-mailed in the proposal yet. Cheers, Thomas
participants (2)
-
Marcel Fourné
-
Thomas DuBuisson