The client could do 'signed' hashes using the local phone number and the friend number (sending the server both the local:friend pair and the friend:local pair).
That wouldn't really stop anybody from reversing the hashes, but it would make a global rainbow table useless.
It would make reversing the hashes substantially harder for any given hash function, though, right? Thanks very much for this idea. I'd thought about tracking social connections by sending hashes (on an explicit and opt-in basis) for my research app, Mappiness[1], but gave up the idea mainly because hashing seemed so hopelessly weak. But I think this + bcrypt might make it workable.
That's clever. You can then even improve the algorithm by only sending the hash of A:B for every phone number, where A < B (numerically). Then you don't have to worry about whether it's Friend:Local or Local:Friend.
That wouldn't really stop anybody from reversing the hashes, but it would make a global rainbow table useless.