
The password hash Argon2, winner of PHC - kevindeasis
https://github.com/P-H-C/phc-winner-argon2
======
jph
Argon2 is an improvement over bcrypt, scrypt, etc.

For typical needs, such as passwords and keys, you'll want to use the Argon2i
variant, which is slower and provides more protections.

For atypical needs, when you're certain there are no side-channel risks, you
may want to use the Argon2d variant, which is faster.

Argon2 has introduction slides here:
[https://www.cryptolux.org/images/c/c5/Rwc-
slides.pdf](https://www.cryptolux.org/images/c/c5/Rwc-slides.pdf)

~~~
tryp
Toward the end of that slide deck, in the "Slowing Brute Force" section, there
the following slide:

> Argon2 ensures that both defenders and attackers hash passwords on the same
> platform (x86)

Do they simply mean that currently the most cost effective platform to deliver
the necessary computation and memory is x86?

I'm having trouble believing that it is either achievable or desirable to
design a password hash that's only efficient on one architecture.

~~~
sbierwagen

      I'm having trouble believing that it is [...] desirable
    

To make it less useful to build a NSA-style ASIC hash cracking cluster, like
[https://en.wikipedia.org/wiki/EFF_DES_cracker](https://en.wikipedia.org/wiki/EFF_DES_cracker)

    
    
      I'm having trouble believing that it is [...] achievable
    

The point is not to write an algorithm that is only fast on x86, rather than
ARM, POWER, whatever; it's to write an algorithm that uses so much memory that
it's not orders-of-magnitude faster to use an ASIC that's just a bunch of
compute cores connected to fast buses, rather than a general-purpose processor
with megabytes of on-chip cache.

------
mintplant
> There are two main versions of Argon2, Argon2i and Argon2d. Argon2i is the
> safest against side-channel attacks, while Argon2d provides the highest
> resistance against GPU cracking attacks.

Does this mean that one has to choose between protection against side-channel
attacks and protection against GPU cracking? While not the "safest", how safe
is Argon2d against side-channel attacks, and vice-versa? Any advice on making
this choice?

(It's late here so I haven't read the paper yet. Apologies if this is all
covered in there.)

~~~
fryguy
Basically, use Argon2d for proof-of-work, and Argon2i for everything else.

~~~
tromp
A memory intensive proof-of-work should be much faster to verify than to
attempt a proof.

------
jedisct1
Argon2i was recently merged into libsodium, and will be part of the next
release, as the default password hashing function.

~~~
onlydnaq
Awesome, good work. I was just going to ask you if you had any roadmap for
adding Argon2i.

------
abhv
I just saw the talk by Dmitry today on Argon2 at RealWorldCrypto. I was
impressed by the ideas there; in particular, the ideas in Argon2 can be
extended to transform any protocol into one that includes memory-hard steps.
This re-balances the potential adversary advantage. Very neat concept.

------
ocharles
Haskell bindings are here:
[https://hackage.haskell.org/package/argon2-1.0.0/docs/Crypto...](https://hackage.haskell.org/package/argon2-1.0.0/docs/Crypto-
Argon2.html)

------
wereHamster
Why was scrypt/bcrypt not part of the competition?

~~~
creshal
bcrypt is just obsolete – this was to find a _successor_ to it.

yescrypt, one of the recommended finalists, is an improved/fixed version of
scrypt.

~~~
themartorana
What's the best way to move a huge database from one scheme to the next? It's
hard to keep up...

~~~
JackC
My favorite way would be to store password information as a hash chain, so old
users can be immediately upgraded to the latest method while new users just
use the latest.

For example, Django currently stores its passwords in a single database column
as

    
    
      <algorithm>$<iterations>$<salt>$<hash>
    

So suppose we generalize that to a chain of one or more hash algorithms, with
each output fed in as the password to the next, resulting in a final hash:

    
    
      <algorithm>$<iterations>$<salt>|<algorithm>$<iterations>$<salt>|$<hash>
    

For example if you had a user who logged in way back in unsalted md5 days and
never logged in again, you might end up with a chain like this:

    
    
      md5|sha256$<salt>|bcrypt$<iterations>$<salt>|$<hash>
    

... and then to upgrade to argon you would grab that string, shove the final
hash through argon(), and write back:

    
    
      md5|sha256$<salt>|bcrypt$<iterations>$<salt>|argon$<iterations>$<salt>|$<hash>
    

For new users, or if the old user finally came back and logged in with their
correct password, you could then take the opportunity to write back a
simplified version:

    
    
      argon$<iterations>$<salt>|$<hash>
    

Iterations could be calibrated differently depending on the chain, if the
earlier steps take enough time to matter.

As far as I can tell this is the best possible service you can offer to the
users whose long-ago passwords you're storing, short of deleting their
passwords entirely. Throwing away the earlier version and replacing it with
the argon-wrapped version can't hurt them, and will almost certainly help.

(Usual caveats apply about not doing things that add complexity if you don't
need it.)

~~~
ocharles
> hrowing away the earlier version and replacing it with the argon-wrapped
> version can't hurt them

Are you sure? And if so, can you convince me as to why you are so sure?

~~~
JackC
To be specific about my claim: throwing away the earlier version and replacing
it with the argon-wrapped version cannot make the user's original password
_easier_ to recover, because it adds no new information about the password. To
convince yourself of that, imagine that there was some function `argon(hash)`
that made the password easier to recover. Why wouldn't an attacker run that
function themselves? In the very worst case a bad hash function that takes one
second to run could only speed up the attacker's job by one second.

Wrapped hashes _could_ have other side effects for probing non-hacked sites --
for example, attackers could probably figure out which chain a user has based
on timing, which would let them narrow down a bit when the user last logged
in. Hash chains could also theoretically reduce the total output space for the
final hash, making it easier to brute force a password through the login form
of a non-hacked site. I don't consider either of those likely to matter, but
you might.

------
lelf
Some discussion here:
[https://news.ycombinator.com/item?id=10857771](https://news.ycombinator.com/item?id=10857771)
(less than a day ago)

------
jnoland
Is there a pure Python version of Argon2?

~~~
bwesterb
I am writing one. You should use the C one, if you can.

[https://github.com/bwesterb/argon2pure](https://github.com/bwesterb/argon2pure)

------
jbb555
I thought this looked interesting until I read the page :-

"A memory cost, which defines the memory usage, given in kibibytes "

Kibibytes? Really?

Can't read any more. I'll find something else.

~~~
ybx
You're angry because they properly measure base 2 data?

Even if you disagree on how proper it is, that seems like an extremely small
and unimportant qualm.

~~~
zeveb
> Even if you disagree on how proper it is, that seems like an extremely small
> and unimportant qualm.

Use of 'kibibytes' and 'KiB' reflects a fundamentally wrongheaded view of the
world, either unserious or too-serious, which shouldn't be taken seriously.

~~~
recursive
Wrongheaded view of the world?

When doing science, is it inappropriate to distinguish between the numbers
1000 and 1024?

~~~
zeveb
> When doing science, is it inappropriate to distinguish between the numbers
> 1000 and 1024?

Of course not! In computers, 'kilo-' means 1,024; everywhere else it means
1,000. This is a simple rule; network-device and hard-drive manufacturers are
just wrong when they violate it.

~~~
ybx
This is actually incorrect. "kilo-" always means 1000, and computers are not
given some exception. 1024 is a KiB, 1000 is a KB.

