package argon2 import ( // Standard "crypto/subtle" "encoding/base64" "errors" "fmt" "strings" // Standard Extended "golang.org/x/crypto/argon2" ) // Check Hash func (algorithm Algorithm) CheckHash(data []byte, hashToCheck string) (bool, error) { // Hash Information var version int var memory uint32 var threads uint8 var time uint32 // Hash Parts hashParts := strings.Split(hashToCheck, "$") // Validate Hash Parts if len(hashParts) != 6 { return false, errors.New("the hash is invalid") } // Get Version _, err := fmt.Sscanf(hashParts[2], "v=%d", &version) // Handle Error if err != nil { return false, err } // Validate Version if version != argon2.Version { return false, errors.New("incompatible version") } // Get Other Hash Information _, err = fmt.Sscanf(hashParts[3], "m=%d,t=%d,p=%d", &memory, &time, &threads) // Handle Error if err != nil { return false, err } // Salt salt, err := base64.RawStdEncoding.Strict().DecodeString(hashParts[4]) // Handle Error if err != nil { return false, err } // Hash hash, err := base64.RawStdEncoding.Strict().DecodeString(hashParts[5]) // Handle Error if err != nil { return false, err } // Return Match return subtle.ConstantTimeCompare(argon2.IDKey(data, salt, time, memory, threads, uint32(len(hash))), hash) == 1, err }