End-to-End Encryption: Math & Logic

Murtuza
7 min readMar 20, 2021

Encryption is one of the things which are essential for securing a system. End to end encryption is a pretty good way to secure the channel of communication between two communicators. Let’s take a look at what encryption is and how end-to-end encryption actually works.

What is encryption?

Encryption is a way to encode a message in a format which is uncommon for people to understand. It can be done using different encryption algorithms. Encryption is succeeded by decryption, in which a key is required to decrypt a particular message with the help of the format used to encrypt it in the first place.

Now, the most basic form of encryption is to encrypt a message using a format or an algorithm, generating a key and sending that key to the receiver in order to decrypt the message you sent. Simple, right? But there are some drawbacks.

If the key is compromised, then the message is no longer secure and it can be decrypted by anyone with access to the key. Also, if anyone gets access to the algorithm or the format which you used to encrypt the message, then it will be easy for an attacker to decrypt your message or even modify the message even before it reaches the receiver.

So, how do we make encryption more secure to make sure that the message will not be compromised? That’s where end-to-end encryption comes into action.

End-to-End encryption

The term ‘end-to-end encryption’ is self-explanatory. It means, no one except you and the receiver will be able to modify or read the message sent through a channel of communication. Let’s take a closer look at how this actually works.

To make sure that the message must not be compromised, there a couple of things to remember :-

  • The KEY used for decryption should stay secure.
  • The message should remain encrypted even through a communication medium (for example, a server). This means, the message should not be read even by the owners who are providing the service.
  • The algorithm should be irreversible (more on that in a minute).
  • The authenticity of a particular user should be known.

In order to satisfy all these points, we are going to take a deep dive in the world of end-to-end encryption (E2EE).

The Math

Now, if you are not quite interested in the actual math behind E2EE, you can read the summary of all the messy stuff that we are going to discuss for a couple of seconds. With that being said, let’s explore some math.

It all starts with something known as ‘Diffie-Hellman Key Exchange’. For example, there are two users, USER-1 and USER-2 trying to contact each other over a channel of communication. Three entities are involved in this process, USER-1, USER-2 and a SERVER which is providing the service.

First Step:- In order to establish communication between USER-1 and USER-2, the server will generate two numbers, let’s say, P and Q. We will not go into the specifics of how these numbers are generated because its something beyond the scope of this blog post. These two numbers, P and Q, are visible to everyone on the internet as they are generated and stored in the server. Both the users will get these numbers from the server. Let’s say, P = 679 and Q = 13.

Second Step:- Both the users on each end will generate a unique number for themselves and store them privately on their local machine. Let’s say, USER-1 generated number ‘a = 283‘ and USER-2 generated number ‘b = 411‘. These numbers are private keys and not visible to anyone except to the user itself.

Third Step:- At this stage USER-1 has P, Q and ‘a’ & USER-2 has P, Q and ‘b’. Now, USER-1 will take ‘a’ and raise it to the power of Q and then divide it by P to get a remainder as an output. Mathematically speaking, it will be (Q)^a % P (here ‘%’ refers to modulus). This remainder is equal to the number 447. Let’s call it x, such that x = 447. This number will act as a public key for USER-1.

x = (Q ^ a) % P

Similarly, USER-2 will take ‘b’ and raise it to the power of Q and then divide it by P to get a remainder as an output, i.e. (Q)^b % P. This remainder happens to be 125. Let’s call it y, such that y = 125. This number will act as a public key for USER-2.

y = (Q ^ b) % P

Fourth Step:- Both the users exchange their public keys. This means that USER-1 will get ‘y’ and USER-2 will get ‘x’.

Fifth Step:- USER-1 will now take his private key ‘a’ and raise it to the power of ‘y’ and then divide it by P to get a remainder as an output, i.e. (y)^a % P. The output happens to be 601.

Shared Secret Key 1 = (y ^ a) % P

In the same way, USER-2 will take his private key ‘b’ and raise it to the power of ‘x’ and then divide it by P to get a remainder as an output, i.e. (x)^b % P. The output happens to be 601.

Shared Secret Key 2 = (x ^ b) % P

Yes, you read it right. The final output(shared secret key) for both users happens to be the number 601. This number acts as a shared secret key in Diffie-Hellman key exchange. Using this key the encryption / decryption is carried out of the respective message.

Shared Secret Key 1 = Shared Secret Key 2
Output of Diffie-Hellman Key Exchange using Python Programming Language

Did you notice how the key exchange was made? The key was not transferred literally from USER-1 to USER-2 or vice-versa, instead it was transferred without actually being transferred. That’s what makes Diffie-Hellman algorithm secure because key exchange is done seamlessly without the transfer actually being done. Only the public key is being transferred from one user to another. Even if anyone gets the public key, they cannot reverse the whole process because of the involvement of modulus. You can easily find remainder of two given numbers, but you cannot find the numbers just by looking at their remainder because there can be many other combinations resulting into the same remainder. And usually, the numbers involved in this process are pretty large so it can take a huge amount of time to make a brute-force attack. Also, Diffie-Hellman key exchange is an asymmetric algorithm which produces a symmetric key for symmetric key algorithms like AES.

Three of the four essential point are satisfied by using Diffie-Hellman key exchange. Firstly, the key used for encryption and decryption is secure. Secondly, no one can read messages except the sender and the receiver because of the involvement of a private key. And third, the algorithm is one way because the only way to break it is to brute force every single combination which is quite cumbersome. But what about the fourth one? How will we make sure that the message is sent by USER-1 only and not by some other random person? That’s an interesting question to ask.

To overcome this difficulty, we have another algorithm known as RSA. In this algorithm also, two keys are generated by users, a private key and a public key. USER-1 will encrypt the message using the public key of USER-2 and the algorithm is such that USER-2 will be able to decrypt the message using its own private key. Isn’t that interesting? But wait a minute, how do you verify that the message is coming from USER-1 only? To do that, USER-1 will encrypt the message with his private key. It’s a rule that if a user encrypts a message using their private key, anyone will be able to decrypt the message using the user’s public key. And the fact that the message can be decrypted using public key of a user, proves that the user must have encrypted the message using its private key. This is the principle behind digital signatures.

Seems messy? Well, we have a summary for you.

Summary

Algorithms like ‘Diffie-Hellman Key Exchange’ and ‘RSA’ are frequently used in implementing end-to-end encryption. Both DH and RSA generate public and private keys and both the algorithms are asymmetric. DH algorithm produces a shared secret key between two communicators while keeping it secure. This shared secret key is used for encrypting/decrypting messages using symmetric algorithms. DH did not solve the problem of authentication. Fortunately it can be solved by using RSA algorithm.

In RSA, the sender encrypts the message using the public key of the receiver and on the other hand, the receiver decrypts the message using its own private key. Also, if the sender encrypts the message using its private key then the message can be decrypted using its public key. The fact that the message can be decrypted using the public key of that user establishes the fact that the message has been encrypted by that user only.

Conclusion

Now, I have just touched the surface level of what happens during End-to-End Encryption process. There’s a lot more that comes into action such as performing Diffie-Hellman three to four times, adding more security measures, performing different operations and using different techniques for group messaging.

So, end-to-end encryption is just a way of randomizing things over the communication channel and doing the real work at both the communication ends.

It is mostly secure until and unless someone reads the messages by actually opening that application on your device because the messages no longer remain encrypted at both the ends. LOL.

This post was originally published at my blog techthatthrills.

--

--

Murtuza

Full Stack Developer | Content Creator | Technical Writer