I'm using Virgil E3Kit SDK to implement end-to-end encryption in my App. Their E3Kit SDK is very effective and not too hard to understand, but I still don't understand how does the key agreement process take pace in Virgil E3Kit SDK. The workflow they describe in SDK document is:
If A want to send messages with end-to-end encryption protection to B, so the steps are:
- A generate her key pairs (one Public Key is published on Virgil Card Services and one Private Key is saved securely on her own device).
- B generate his key pairs.
- A looks up for B's Public Key on Virgil Card Services and uses B's Public Key to encrypt the messageA-B.
- When B is received the messageA-B, he use A's Public Key to verify the messageA-B's integrity and he uses his Private Key saved on his device to decrypt the messageA-B.
In the document page, Virgil shows algorithms that are used in Virgil E3Kit, in which:
- They uses PRNG for key generation
- They uses KDF2 for key derivation
- They uses X25519 or ECDH for key exchange
I think both X25519 and ECDH need a new random shared secret for each secure communication session. How does Virgil E3Kit do that while both parties of communication just only need to generate their key pairs when they first register account, then they can start using end to end encryption with these key pairs forever? Virgil E3Kit uses asymmetric key exchange with X25519 or ECDH, but after that they use symmetric encryption with AES GCM to encrypt messages in endpoints.
So my questions are:
How can Virgil E3Kit SDK use symmetric key for symmetric encryption in endpoints, while they use asymmetric key exchange? And could you please illustrate and explain for me about this process?
And, what role PRNG, KDF2 (key derivation function) and X25519 or Ed25519 (Elliptic Curves) play in this key agreement process?