
On 11/21/05, Dominic Steinitz
David,
The Haskell Cryptographic Library consists of contributions from different authors which I have wrapped to give a uniform API, written a test suite and darcsized and cabalized. But caveat emptor! I am happy to incorporate new contributions.
Oh that is excellent! I'll go look that up and make sure my toplevel interfaces conform to that. Right now they follow that in Peter Simons' Digest.hs; it that is different I'll change to your standard, as I haven't finished the padding code that interfaces to the outside world yet either, so it's no skin off of my nose!
A different approach would be to provide an interface to openssl and Peter Simons has already done something along these lines, see http://cryp.to/hopenssl/. The latest version of openssl supports SHA-256 for example. From an industrial strength point of view, this is probably the way to go.
This project was begun (last week!) as an alternative to my updating the openssl wrappers that I found that already supported sha1, and needed to be extended to use the sha2 family of message digests, which of course have been in openssl for a long while (I'm acquainted with Ben Laurie from a number of mailing lists and online fora for years running now). I have found the C and C++ implementations of the FIPS 180-2 spec to be, while certainly fast, very hard to read and correlate with that spec. Wrappers in other languages, which is how almost all obtain their crypto functions, are little better. None of them can ever (feasibly) have any runtime or termination properties formally proved. Finding this state of affairs deeply unsatisfying on aesthetic grounds (which I have for years, just not specifically in regard to Haskell), I began the instant project.
Peter had a view that all "crypto" algorithms (I include hashes here) should have monadic versions- see below - even though they are all pure. Neither he nor I got round to doing anything about this.
I am intending to do all of the stateful bits are both pure and monadic versions. The monadic version with an unboxed mutable array for the inner loop's hash state will hopefully be tunable under ghc 6 to run within a binary order of magnitude of the performance of C++ implementations of the spec.
I'm not a lawyer but do hash functions count as encryption? There are no keys and you can't recover the data. And haven't the regulations been relaxed recently? Lots of publicly available packages offer SHA-256.
Unfortunately they do, they just relaxed it to a notification requirement. Which means I had to email the NSA and Commerce Dept. at a predefined email address before posting to the web, and have to put a disclaimer somewhere stating basically that persons from 'naughty' places can't download, persons from the 'good' places can, and bugger all if I know for folks in the middle. The paranoid will of course (rightly?) presume that the NSA now just merely want to packet sniff somewhere and watch who downloads from crypto sites, and see who might be naughty. But you're in the uk, which is good! :-) Long and short of it is that I personally just can't directly email a source file to a 'bad person'. This all of course is the rules for open source, closed source is still stricter. See the documents referenced in my disclaimer if you want to hurt your brain with Federal legalese: http://davidmercer.cust.nearlyfreespeech.net/projects/shaskell/export.txt Those are the pertinent sections when you read everything recursively referenced starting from the Export section on page ii of FIPS 180-2, which is where SHA2 is defined (spec is public domain and non-export controlled, my local mirror is at): http://davidmercer.cust.nearlyfreespeech.net/projects/shaskell/fips180-2with... And I did indeed send the requisite email to Big Brother last night before seting the read bit on my posted files. The bits in the email exchange you quote below are indeed pertinent to a number of issues I've been grappling with this past week, as the folks on #haskell can attest! I'll have to do more reading on them and any follow ups that might be in the archive, thanks indeed for that reference! I just want to emphasize again how awesome I've come to see Haskell as during this project. Nearly all of the formulas and definitions in the specification for sha2 translate one to one into pure, stateless, lazy haskell. And are pretty much just a rendering of those typeset formulas into a representation with ascii identifiers instead of sigmas and such. My goal for the stateful version is to as closely as possible follow the pseudocode for the inner loops in the spec as well. And once we're done, then we start attacking it with Agda to see what is provable about it! However much that ends up being, it'll be more than one can prove about anything on the FIPS 180-2 validated implementations list. Cheers, David Mercer Univ. of Arizona Tucson, AZ
Dominic.
On Monday 07 Feb 2005 8:27 pm, you wrote: Dominic Steinitz writes:
I'd suggest not touching anything to do with ASN.1 as I have now got a prototype of the re-write which will parse an X.509 certificate and extract the public key.
Sounds great. I'll update the repository every now and then so that I can see what's going on. I was wondering about OpenSSL ... Have you made FFI bindings to the library? Are you aware that I've made some for EVP digests too? Maybe we could throw together?
My main interest in Codec is in unifying the API; hiding the symmetric ciphers and digests behind one simple type class or monad or whatever it will be. I want to use those functions without knowing which one I am using.
I'm not sure how asymmetric ciphers fit into that; they're typically used differently, not for octet streams.
It seems that the latest ghc from CVS comes with several changes that break compilation of the code. I'll try to get that fixed without becoming incompatible with the 6.2.2 release in turn.
I'm surprised as I am running 6.2.2 [dom@tility dom]$ ghc --version The Glorious Glasgow Haskell Compilation System, version 6.2.2
Well, GHC is at 6.5 by now, if you use the CVS version. ;-)
I think you need both the pure and monadic versions. They really are pure functions but sometimes you don't have all the data you want to encrypt available in one go.
A State monad is a pure function. If you have
aesM :: [Word8] -> State AES [Word] initAES :: AES
then you have
aes :: [Word8] -> [Word8] aes x = evalStateState (aesM x) initAES
just as well. But the reverse is impossible. I think _all_ ciphers and digests should be State monads. It means that an awfully lot of combinators can be written as monad transformers:
asciiArmor :: ([Word8] -> State st [Word8]) -> [Word8] -> State st [Word8]
Block chaining, encoding, layering of ciphers, permutations and all that can be written independently of what the actual cipher is. A cipher is just a transformer with state: we can run it with runState, we can compose it, and we can fool around with the input/output stream.
That's the way to go, IMHO. I've used this exact same design in Postmaster to build the ESMTP state machine, and the flexibility is staggering. I've come to love monads by now. ;-)
Anyway, that's all just speculation. We'll see whether I can whip up a nice module which shows what it would look like. Unfortunately, my time is very limited too. It's a shame, really.
Oh well, I you'll find some spare time and get your ASN.1 parser done. I'm looking forward to having SSL/TLS support in Postmaster soon then. ;-)
Take care,
Peter
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries