package passwords import ( "golang.org/x/crypto/argon2" "crypto/subtle" "crypto/rand" "bytes" "log" ) const version = 0 func doHash(ver int, password string, salt []byte) []byte { return argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32) } func Hash(password string) []byte { var buf bytes.Buffer buf.WriteByte(version) salt := make([]byte, 32) _, err := rand.Read(salt) if err != nil { log.Fatal("error generating password hash:", err) } buf.Write(doHash(version, password, salt)) buf.Write(salt) return buf.Bytes() } func Check(password string, hash []byte) bool { ver := int(hash[0]) hashData := hash[1:33] salt := hash[33:] check := doHash(ver, password, salt) return subtle.ConstantTimeCompare(hashData, check) == 1 }