I am trying to understand the signal protocol better. I spend some time trying to understand their codebase (the backend is written in java).

The signal protocol indicates that the user has to upload one prekey at the time of registration (signed using their identity key) and about a 100 unsigned prekeys.

Then when someone tries to initiate contact, they are given one of the prekeys, the signed prekey and the identity.

However, somewhere else it states that the signed prekey is used as a last resort. In the signal codebase, I saw a store for both signed as well as unsigned prekeys.

Which keys are to be stored? Which keys are sent to the party that tries to initiate a conversation?

Is it the identity key, last resort signed prekey and bunch of prekeys (not signed)? Do we also need to upload some signature?


1 Answer 1


Which keys are to be stored? Which keys are sent to the party that tries to initiate a conversation?

It depends on the entity under consideration (initiator, responder or server), but I assume this is mostly server-related. Let's review the X3DH protocol to get a better sense of how to answer the questions (the new PQ-X3DH has similar features but uses KEMs for post-quantum security).

In signal, each device uploads bundles of keys upon registration, as the question already mentions. To establish a session, the initiator retrieves the bundle of keys from the intended recipient and does a few Diffie-Hellman operations to derive a shared key that will be the basis of the secure channel. This is shown in the figure below.

One of the keys involved in the process is a one-time key (another commonly used name to differentiate with signed keys). These are to be used only once and are refurbished as needed. What happens, however, when there are no more one-time keys? Then, the server will send an especially designated last-resort key.

The original specification doesn't mention them, but I believe the last-resort keys are also signed in the implementation. Furthermore, in PQ-X3DH signs all keys as well.

Do we also need to upload some signature?

So yes, each signed key is uploaded along with its signature so the signature can be checked.

So overall, the server will track each user's identity key, the signed prekey and the one-time key (including the last-resort key). For a new key bundle request, the server responds with the identity key, the signed prekey and a one-time key that is then deleted. If not available, the last-resort key is sent instead.

The X3DH key establishement

  • IK: identity keys
  • EK: ephemeral keys (generated at the time of running X3DH)
  • SPK: signed prekeys
  • OPK: one-time prekeys
  • $\begingroup$ Just to be clear. One time keys are not signed. 2> The signed prekey is used multiple times. And the last resort key is signed. $\endgroup$ Jan 5 at 6:23
  • $\begingroup$ @FarhanSyedain 1) The original spec is not explicit about signing OT keys. They might be doing something different in the implementation, though. In contrast, the PQX3DH indicates they are all signed. 2) The signed prekey is used every time a new session is established. That key and the last resort keys are semi-static and rotated over time. So after some time another pair of signed prekey and last resort key will be used and so on. $\endgroup$ Jan 5 at 9:14
  • $\begingroup$ I'm actually making a chat application. That is why. Can you please try to confirm if the OT keys are signed or not. $\endgroup$ Jan 5 at 17:33
  • $\begingroup$ @FarhanSyedain, AFAIK client implementation are also available so why not use the implementation directly instead of re-writing? Also you probably spent more time in the codebase than me, so I assume you can find this information more easily there. $\endgroup$ Jan 5 at 22:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.