How WhatsApp users authenticate themselves in end-to-end encryption? I read the WhatsApp Security Whitepaper and I want to know how a user A, which uses ECDH (Elliptic Curve Diffie-Hellman) to compute a master_secret, can be sure that the public keys for the recipient B used in the exchange belong to B and they have not been replaced by someone else.
A uses B (public) Identity Key, Signed Pre Key and One-Time Pre Key, all stored on the server at the moment of B's registration: how can A be sure that they are actually his recipient's keys?

(ECDH is an anonymous protocol, therefore authentication must be achieved someway else)
Basically the way WhatsApp and many other end-to-end encrypted messaging platforms work is that your device generates a public/private key pair. The public key is uploaded to the server and the private key is maintained. It is typically recommended that you do an "out-of-band" authentication of public keys with anyone you want to communicate with. This is often done by meeting in person. You can display your public key on your device, which they can see what public key they have for you (from the server) and compare. If you both see the same public key, all is well.

The reason and "out-of-band" mechanism is needed is that you cannot trust the WhatsApp channel for security yet, since security is being provided via the crypto. In theory, if you had some other trusted channel, you could use that. But if you already had a trusted channel, why use WhatsApp (or any other application)? This is why "in person" is typically the way this happens. You could do it over a phone call, or maybe even SMS, and feel sufficiently certain that correct public keys were exchanged. The beauty of how these apps work is that they allow you to decide that. That is also the disadvantage. If users don't fully understand the implications, they may be more risky than they would be otherwise.

This public/private key pair is used to sign partial ECDH key exchanges. You upload your half, signed by your private key to the server. The person who wants to communicate with you downloads one of the partial exchanges, verifies it with your public key. Completes the key exchange and uses the resulting key to encrypt the contents of the message. They then upload the other half of the key exchange, signed with their public key, and the encrypted message. Finally, you download all that info and are on your way.