Rather than providing the service a password hash for it to look up in its database, you download k password hashes that have the same prefix and do the matching locally. That way, the user’s real password hash is never sent over.
I was super skeptical of "send Troy your whole SHA1 hash", because many many SHA1 hashes have been reversed. Then when I was looking at V2, I was considering the fact that in a given set of 381 passwords, there were probably only a couple you might be meaning to check (if you look at a range set, each one generally has a couple of repeatedly used password hashes).
But if my passwords fall outside of that set, someone might think I am maybe checking against one of the more commonly leaked passwords, when mine isn't even in that range set at all.
Partially for my own comfort, and for fun, I ended up writing my own short checker in a .NET console app: https://github.com/ocdtrekkie/PwnPsswords