thoughtpolice / salt

Fast cryptographic networking for Haskell
http://thoughtpolice.github.com/salt
MIT License
24 stars 1 forks source link

Different types for different kinds of keys #16

Closed andres-erbsen closed 11 years ago

andres-erbsen commented 12 years ago

Having key type indicate its length would make serialization (and probably some other instances too) easier. It would also make it clear that signing and encryption keys are different (already in docs though, I think).

thoughtpolice commented 12 years ago

Hi Andreas,

I already did something somewhat similar to this for nonces. I'll take a look sometime in the next few days at attacking this for key types (I'm a bit busy writing proposals/papers at the moment.)

tel commented 11 years ago

How far along are you on this? I'd really like to help push this ahead to a 1.0 release. This could be solved by type classing or GADTs. Are you interested in keeping this library Haskell98 compatible?

thoughtpolice commented 11 years ago

I've already got a solution for this in my working tree at home but I haven't pushed it (because I haven't fixed the tests.) I did it last night. I'm trying to refactor everything to move away from type classes (Nonce is an egregiously bad design story, here.)

It essentially parametrizes a single Key type by two parameters: it's "secrecy" and it's "index." The definition is thus:

data Secret -- :: *
data Public -- :: *
data Key s i = Key { unKey :: ByteString }

The secrecy refers to whether a key is public or private. That's the s parameter. Individual modules parametrize the i parameter with their own empty data type, and use this to enforce you're using the right kind of key. So for example, signing now looks like this:

createKeypair :: IO (KeyPair SigningKey) -- type KeyPair i = (Key Public i, Key Secret i)
sign :: Key Secret SigningKey -> ...
verify :: Key Public SigningKey -> ...

The encryption module also defines its own PublicEncryptionKey type etc. So this ensures you can never confuse the use-case or secrecy of a key.

FWIW, I don't want to break Haskell 2010 compatibility if possible. The FFI is a vouched amendment there, as well as empty data types, and generally the API is small enough to where more featureful APIs should really be in their own package, I think. Once I refactor Nonce I believe I'll get rid of most of the complexity.

This patch will also fix #17 and #22 along the way. I expect to commit it later tonight after work.

thoughtpolice commented 11 years ago

Oh, and the safety of this could be improved in a backwards compatible way if you have recent GHC: by using DataKinds it would be possible to have Secret and Public be types of a particular kind (data Secrecy = Secret | Public), in place of having empty data declarations. Then the s parameter can be enforced of that particular kind. You can do this with CPP. I believe this should be fully backwards compatible (although I don't know if it's possible to export promoted type constructors and not the constructors themselves...)

tel commented 11 years ago

Oh, that's a good method (the repa3 method?) to get indexed key types. I don't know how to evaluate DataKinds yet. It seems favorable and simple to my Agda-infected mind, but edge cases around greater type calculi in Haskell get confusing.

If you're able to push this change tonight do you have an expected timeline for a 1.0/hackage release?

thoughtpolice commented 11 years ago

I've gone ahead and triaged the current issues in the bug tracker to reflect reality better. Basically, once the outstanding issues in the 0.1.0.0 milestone are fixed, I'm open to a release. I expect if you are willing to work on them (which will motivate me :) then this could be done in just a week or two with consistent work.

The 1.0.0.0 milestone is obviously much farther off, and includes some 'pie in the sky stuff' but that can be realistically punted or closed if they're infeasible. It also includes some notion of extra libraries surrounding this primitive library, so it'll probably involve a bit of reorganization.

thoughtpolice commented 11 years ago

Also, I know @brinchj is using salt in a project of his own, but I don't know its status, so hopefully he'll be happy about a release too :)

tel commented 11 years ago

Very cool. I'll take a look at what you have and make a plan of attack myself. I think a good, hands-off crypto library like salt is very needed in the Haskell community since most of the existing work is complex and leaves a lot of crypto design up to the user.

thoughtpolice commented 11 years ago

Ugh, the tests are such a mess from history that rewriting them for my change will take some work and I just don't want to pile on more crap. I will try to stop-gap or comment the broken ones (so some still run) and begin converting them to be cleanlier. I probably will not get all of this done tonight but it should make the changes needed to Key available so you can use it.

tel commented 11 years ago

Very cool—thanks!

Doctest is getting up and running now, too. It's acting somewhat finicky around the hsc conversion (I think). If I can get it working well enough to make for a meaningful workflow I'll send you that patch so you can try using doctests during the test rewrite as well.