password4j icon indicating copy to clipboard operation
password4j copied to clipboard

Support for Balloon Hashing

Open Colerar opened this issue 9 months ago • 9 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.

Colerar avatar Sep 21 '23 06:09 Colerar

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 avatar Sep 21 '23 15:09 firaja

@firaja any news? When will it get implemented?

BigPanda97 avatar Oct 04 '23 09:10 BigPanda97

Hi @BigPanda97 the implementation is in progress. Unfortunately I can work on it only during free time 🤕

firaja avatar Oct 04 '23 12:10 firaja

Unfortunately I can work on it only during free time 🤕

That's absolutely okay, but nice to hear that it will get implemented. 😊

BigPanda97 avatar Oct 04 '23 12:10 BigPanda97

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: https://github.com/Password4j/password4j/pull/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

firaja avatar Oct 09 '23 07:10 firaja

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. 🤔

Colerar avatar Oct 09 '23 10:10 Colerar

@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)?

firaja avatar Oct 09 '23 10:10 firaja

@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.

Colerar avatar Oct 09 '23 10:10 Colerar

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.

firaja avatar Oct 10 '23 11:10 firaja

This feature is now present in 1.8.0

firaja avatar Mar 04 '24 09:03 firaja