You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The discussion on #15270 led to an interesting argument: we don't need the Crypto::BCrypt nor the Crypto::BCrypt::Password classes. We only need a couple methods:
Crypto::BCrypt.hash(password : String, *, cost = DEFAULT_COST) : String to generate the bcrypt hash for password, using the provided cost and a randomly generated salt (RNG must be of cryptography quality).
Crypto::BCrypt.verify(hash : String, password : String) : Bool to encode password using the hash salt then safely compare it (in constant time) against the provided hash digest.
The only useful case for the classes is to compare the same bcrypt hash against multiple passwords... but what's the use-case outside of rainbow tables?
Bonus: we allocate multiple intermediate objects (Array(String), Bytes, Crypto::BCrypt or Crypt::BCrypt::Password) and we could avoid all of them but the final, fixed size, String for the .hash method 🤔
The text was updated successfully, but these errors were encountered:
I agree that Bcrypt::Password seems unnecessary for its primary function of verifying a password.
However, there are other use cases: It exposes an API to make properties of the hash available. version and cost are relevant diagnostic information. You might want to know whether a hash was created with an obsolete version or obsolete cost policy, for example. salt and digest are maybe less generally useful.
So I believe we need more than just a hash and verify methods for a comprehensive API.
But two relatively simple methods for quering the version and cost of a hash could be enought for this.
Bonus: we allocate multiple intermediate objects (Array(String), Bytes, Crypto::BCrypt or Crypt::BCrypt::Password) and we could avoid all of them but the final, fixed size, String for the .hash method 🤔
I believe it should be possible to do most of the optimizations within the Bcrypt::Password class. For example, the getters could allocate lazily. And the bcrypt algorithm could be fed allocation-free subslices.
So I feel the optimization story is not directly related to the API (although having a smaller/simpler API would probably make optimizing easier).
The discussion on #15270 led to an interesting argument: we don't need the
Crypto::BCrypt
nor theCrypto::BCrypt::Password
classes. We only need a couple methods:Crypto::BCrypt.hash(password : String, *, cost = DEFAULT_COST) : String
to generate the bcrypt hash forpassword
, using the providedcost
and a randomly generated salt (RNG must be of cryptography quality).Crypto::BCrypt.verify(hash : String, password : String) : Bool
to encodepassword
using thehash
salt then safely compare it (in constant time) against the providedhash
digest.The only useful case for the classes is to compare the same bcrypt hash against multiple passwords... but what's the use-case outside of rainbow tables?
Bonus: we allocate multiple intermediate objects (
Array(String)
,Bytes
,Crypto::BCrypt
orCrypt::BCrypt::Password
) and we could avoid all of them but the final, fixed size, String for the.hash
method 🤔The text was updated successfully, but these errors were encountered: