Password4j/password4j

Support for Balloon Hashing

Closed this issue ยท 10 comments

Balloon hashing (Wikipedia), is similar to Argon2, which has proven memory-hardness properties. But it claims to match the performance of similar algorithms. It seems easy to implement. And it is recommended by NIST password guidelines.

There are Rust and Python implementations for references.

Balloon actually wraps existing hash functions, so we may need a generic type over MessageDigest for any standards non-space-hard cryptographic hash function.

firaja commented

Hi @Colerar,

thank you for your interest in the project!

I'm reviewing the paper and the implementations you provided and see if there is any industry standard.

@firaja any news? When will it get implemented?

firaja commented

Hi @BigPanda97 the implementation is in progress.
Unfortunately I can work on it only during free time ๐Ÿค•

Unfortunately I can work on it only during free time ๐Ÿค•

That's absolutely okay, but nice to hear that it will get implemented. ๐Ÿ˜Š

firaja commented

Hi @Colerar @BigPanda97,

in this branch you can find a preview version of Balloon Hashing: https://github.com/Password4j/password4j/tree/bal
This is the PR: #132

If you can test it along with the implementation you are using it would be great.

Here a quick usage guide for mono thread version (parallelism = 0)

// parameters:
// - algorithm name
// - space cost
// - time cost
// - parallelism
// - delta
BalloonHashingFunction balloonHashingFunction = BalloonHashingFunction.getInstance("SHA-256", 16, 20, 0, 4);
 
Hash hash = Password.hash("buildmeupbuttercup").addSalt("JqMcHqUcjinFhQKJ").with(balloonHashingFunction);

hash.getResult(); // 2ec8d833db5f88e584ab793950ecfb21657a3816edea8d9e73ea23c13ba2b740

and there the M-thread version (parallelism > 0)

BalloonHashingFunction balloonHashingFunction = BalloonHashingFunction.getInstance("SHA-256", 16, 20, 7, 4);
 
Hash hash = Password.hash("buildmeupbuttercup").addSalt("JqMcHqUcjinFhQKJ").with(balloonHashingFunction);

hash.getResult(); // 1c271e9069cb694ba5ae9d3da1f57be4614063e014410e7c484d7b47f8291bac

TODO:

  • cryptographic pepper
  • documentation
  • more tests
  • handling of borderline cases

It looks like a new thread pool is created every time a hash is calculated. So the multi-threaded version may be slower than the non-multi-threaded version. ๐Ÿค”

firaja commented

@Colerar do you suggest to make the thread pool shared among all the instances of BalloonHashingFunction (in most cases it will be a singleton) with a decent number of threads (e.g. parallelism * k, with k given by the end-user)?

@Colerar do you suggest to make the thread pool shared among all the instances of BalloonHashingFunction (in most cases it will be a singleton) with a decent number of threads (e.g. parallelism * k, with k given by the end-user)?

Yes, shared thread pool is reasonable.

firaja commented

Hi @Colerar I've updated the PR with a instance-shared forever-living thread pool.
The number of threads is related to the number of available cores and not to the parallelism parameter.

This feature is now present in 1.8.0