Argon2 will produce an encoded hash that contains everything you need to know about how it was produced
$argon2id$v=19$m=19456,t=2,p=3$SqUV+y5EZ9KagOg52BqQ8A$JRA/a2kS/8Hypl9diDnHqg
Argon2 also provides 'verify' routines that take (a) an encoded hash and (b) a 'candidate' password that is to be verified.
ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen);
ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen);
ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen);
ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, argon2_type type);
Apparently these 'verify' routines will hash the 'candidate' passwords using the parms as extracted from the encoded hash. Brilliant - I don't have to remember what parms I used when creating the original hash being verified against.
But what I don't get is why all of these 'verify' routines have to be told what Argon2 algorithm (i, d, or id) to use. That info is right there as the first item in the encoded hash
I tried calling argon2_verify(...) using (a) a hash created from known password 'X' (b) cleartext password 'X' and (c) a specific Argon2 algorithm ID. I did this for for each of the algorithms (i, d, id)
I was hoping that perhaps the algorithm I specified would be used only if the API couldn't figure out what algorithm to use from the encoded hash. But what I found is that if the algorithm I passed to the API didn't match the algorithm indicated in the encoded hash, then argon2_verify(...) returns ARGON2_DECODING_FAIL (-32). If the algorithm I pass to the API matches what's in the encoded hash, then the API returns ARGON2_SUCCESS (0) if the passwords match or ARGON2_VERIFY_MISMATCH (-35) if the passwords don't match.