This is a question sparked purely by curiosity, wanting to understand a little more about cryptography and authentication. Thanks in advance to anybody taking their time to answer.
Instead of salting and hashing a password, sending it to the server to authenticate yourself, could something like this work? A client generates a private/public key pair from a password and random salt. The public key and salt is stored by the server. For each login the server sends the salt, and a randomly generated value for the client to sign. The client regenerates the private key from the password and salt, then signs the randomly generated value and sends that to the server. The server verifies the signature with the corresponding public key.
To slow down a brute force attack, a key must be derived from the password and salt using a slow KDF, before generating the private/public keys.
Alternatively the server can require the client to derive a key from the randomly generated value, using some slow KDF, before it is signed – although this, to me, seems less ideal than just slowing down the key derivation. To save on server resources when verifying the signature, one can use a Proof of Work style mechanism instead of a slow KDF where the client must find a nonce such that hash(randomly_generated_value + nonce) > some_set_difficulty, then the nonce is signed and sent to the server to be verified. The server may even vary the difficulty, say increasing the difficulty for each unsuccessful login attempt.
What would be some advantages and disadvantages of such a scheme? I suspect exposing the salt on every login attempt would be an issue.