Hacker News new | comments | show | ask | jobs | submit login
Hulk: A Haskell IRC server (chrisdone.com)
94 points by profquail 1613 days ago | hide | past | web | 36 comments | favorite


No seriously, before you get like a million users you should switch to a much slower hashing alg that's designed for passwords, not for checksums. Scrypt is good, bcrypt is good, and there are a few others. But here's a(n?) scrypt package on Haskell that will do it for you and has a really nicely designed API: http://hackage.haskell.org/packages/archive/scrypt/0.3.1/doc...

Yes, the scrypt package's PasswordHash API is great, akin to bcrypt (http://hackage.haskell.org/packages/archive/bcrypt/0.0.4/doc...). Just ignore the terminology used ("encryptPassword", "password encryption", etc.)

Why: http://throwingfire.com/storing-passwords-securely/#notpassw...

Could you explain a little more about why you need a slower algorithm? How is anyone going to crack a well-salted SHA1 password?

It is increasingly trivial to try millions or billions of hashes per second. Using scrypt forces the computer to use more resources (in this case, memory in particular) which means that scaling the guess rate is orders of magnitude slower and cannot be significantly increased by building faster computers (because it's limited by memory not process speed).


It comes down to this: Why use something which is designed for speed like hashes to do something that can be broken by highspeed guessing?

>Why use something which is designed for speed like hashes to do something that can be broken by highspeed guessing?

Perhaps you have hundreds of millions of users? The slower your hash algorithm the more resources it takes to run it.

At hundreds of millions of users, I rather suspect resources spent on password hashing are going to be low on the list of concerns.


2800M/s SHA1 hashes on a ATI HD 7970.



PBKDF2 is still very much harder to crack then SHA1 with any reasonable length of salt.

By brute-forcing it using GPUs. With a consumer-quality graphics card, anyone can try thousands of variations on every word in the dictionary in a few seconds. Common passwords that are not related to dictionary words (such as numbers and dates) take an ignorable amount of time longer.

While you may use better passwords than this, it's certain that some of your users do not.

The key is that you want an alg designed for passwords, not for checksums. The design goals of each are very different.

> It’s also common to put all your types into one module named Types, as you tend to use types from every module

Is that true? Wouldn't that mean that typical Haskell applications aren't very modular, if every module needs access to all types? How can this be a good thing?

[I'm not good with Haskell; I sort of like it, but it makes me feel rather unintelligent.]

I wouldn't confuse modules with modularity. Think of it like this: types are the primary API for the program. In fact, I tend to call the modules that perform this function in my code something like 'Core'. Since they're a shared language that allow different parts of the code to communicate without knowing any implementation details, these types actually make it possible to write code that is more modular, not less. Different parts of the program can go about their business and perform specialised tasks, while still being interoperable (and composable) with other parts of the program (and, hopefully, code not yet written—although this very much depends on how well your types model your problem domain).

I'm not sure the author's explained this point quite as clearly as it could have been. One doesn't want to expose every type used in the program across all modules: there are many that are just used in internal representations within particular modules.

Here's an example from a project of mine, which is a command line program to produce truth tables. There's a Core module which contains the types shared across the whole program, and the most fundamental operations on them.


Then there are other modules like Parser which just exposes a single function, but of course makes use of the core types.


The command line program itself is defined as a Main module, which imports the pure library modules and does all the I/O. It has a few types of its own but these aren't shared across the program, because the library doesn't need to know about all this stuff.


Ah, thanks!

I don't mean to criticize the blog post, since it's probably valuable to some people. But if you're sick of Skype for Linux and you realize that something like IRC would be good replacement, then what's the point of writing an IRC server in Haskell (except for fun/education/pleasure) when you could use existing software (open source or not) like Apache Wave, Mumble, one of the many XMPP servers, IRC servers etc.?


Isn't this enough? You learn something and you'll probably get something useful out of it in the end, as well.

>But if you're sick of Skype for Linux and you realize that something like IRC would be good replacement

Huh? How do those even compare?

I know at least one organization that mainly used the group chat bit of Skype. In that case, one might think it possible to replace it with XMPP or IRC.

Read the first paragraph of the OP.

So as to have a pure wheel...

Instead of writing about purity and impurity all day he could have spent that time improving the IRC server to the point where the authentication can not be trivially replayed in what is a clear text protocol and implemented IRC over SSL/TLS.

That sounds a bit snarky; it just seems like purity/impurity is the favorite bikeshed for haskell programmers.

> I will also add OpenSSL support using the HsOpenSSL package which seemingly makes the whole process trivial.

Sometimes people like to write about their pleasant experience before the project is completely finished. I'm bookmarking the project as a good example of Cabal Project structuring and use of some network libraries. Good examples like these aren't very well curated from the universal Haskell repertoire.

He only used part of the blog post to talk about purity; when explaining how the code is designed and organized, it's not like he could reasonably skip that part. Besides, Haskell makes the distinction sufficiently natural that it does but take much effort when actually coding, so the main "cost" in terms of time was probably in writing the blog post :P.

Since it's an internal effort, simplicity trumps security and features. I doubt making the IRC server more complete would be worth the effort and maintenance cost. It's much better to add features only of they are obviously missing when they actually use the server.

Well yes, and then he went on to completely rewrite it, for puritys sake:


God forbid someone learns while using a new language and may not implement it the most optimal way the first time. What a waste!

Chris Done is a haskell veteran though...

I'm not seeing the problem here.

It's his project, he calls the shots. If you want a feature, get in and write it. Being Right On The Internet doesn't mean shit.

But lots of IRC servers let you connect in the clear and it's not a real problem. It's IRC, you see.

Neat trick with the generalized derived classes! You don't actually need to make IRC a monad transformer if you don't need it. Just drop the `m` from the `newtype` declaration, and you have a nice simple `IRC a` monad.

It's a common trick from the 'transformers' lib to define type SomeMonad = SomeMonadT Identity

Ooooooooo neat!

We agreed something like IRC would be good, so I thought it would be easy in Haskell to make such a thing.

Or you can use any of the thousand services running IRC servers ;-)

Why pass up the opportunity for a valuable learning experience? Even if it doesn't pan out, chances are that you'll learn something, no?

Language advocacy, I suppose.

that blog post is from 2011. just so you know...

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact