review this for cryptographic safety. Anything ambigous should be assumed to follow industry standard protocol. When giving a review use the langauge and termenology used in the security document when the differ or conflict with industry standard terms.
- Mostly full post compormise security after a time in which the DH chain is updated. An attacker should not have access to more than one chain for each client.
- Full forward security, no messages from before the epoch should be decryptable.
- Chain (a group of messages sent by the same client one after another. Bookended by messages from the other client - The messages from the other client are not included- )
- DH chain (Diffe-Hellman Chain. The larger of the two rachetts. Cycles RK)
- CK chain (Chain Key Chain. The smaller of the two rachetts. Cycles CK)
- DM (Direct Message)
- Leader (The person who initiates a DM)
- Receiver (The other member of the DM that did not create it. It is NOT the person who receives an individual message)
- Epoch (moment in time in which an event happens)
- IK (Perminant Identity Keys)
- OPK (One time pre-key)
- SPK (Semi-Perminant signed pre key)
- EK (Ephemeral Key)
- RK_n (Root Key. n symbolizes the iternation that n is on)
- CK (Chain key, can be suffixed with: s(for send), r(for recieving), L(for Leader), R(for Receiver), n (an intiger for the iteration of that key))
- publicKey_n (The public key used for the n interation of the DH chain)
- privateKey_n (The private key used for the n interation of the DH chain)
- n (In most contexts it means the index of the recieved message in the CK chain. Only can be given directly from the header of a received message. Not called n when stored)
- pn (Reported number of messages sent in the CK chain prior. Reported by the header of a recievd message, and only can be given directly from that header. Not called pn when stored)
- nrs (The stored value of the projected index of the next message to be recieved. Should be equal to n in most cases when a new message is recieved)
- pnrs (The stored value of the pn as seen by the latest recived message)
- ns or nextN (same term) (The index of the message that is about to be sent. In most cases the next time a client sends a message the n in the header of that message will be equal to ns at time of creation)
- pns (The number of messages the client set in its last set of CK chain messages.)
Inintialization is created using the x3dh protocol using IK, EK , OPK generated by the receiver, and SPK
Generated is RK_0, CK_s, CK_r, all for the leader.
The Recipient then does the same x3dh protocol.
Generated is RK_0, CK_s, CK_r, all for the recipient.
When a DM is created a message is automatically send from the Leader. This is what starts the initialization & x3dh protocol. The messages header contains EK for the Leader in place of pubicKey_n
At the end ns = 1 most other metadata is undefined CK chain is updated to CK_1
The user may continue sending messages just like in any other CK chain.
When the first DM is received initalization and x3dh is run for the reciever.
The user than decrypts the welcome DM and CK_0 becomes CK_1.
Metadata: nrs = 1
There are eight destinct message events not including the welcome message or out of order messages
- Leader sends first message in chain
- Leader sends all other messages in a chain
- Receiver sends first message in chain
- Receiver sends all other messages in a chain
- Leader receives first message in the other user's chain
- Leader receives all other messages in the other user's chain
- Receiver receives first message in the other user's chain
- Receiver receives all other messages in the other user's chain
The easist of the decryptions is solved through a "simple decryption". Messages that can be solved by a simple decryption include
- Receiver receives all other messages in the other user's chain
- Leader receives all other messages in the other user's chain
The easiest of the encryptions is solved through a "simple encryption". Messages that can be solved by a simple encryption include.
- Leader sends first message in chain
- Leader sends all other messages in a chain
- Receiver sends all other messages in a chain
There is one special case where a DH chain cycle does not happen
- Receiver receives first message in the other user's chain
There are two special cases where a DH chain cycle happens
- Receiver sends first message in chain
- Leader receives first message in the other user's chain
Inputs CK_n, ciphertext Ouputs CK_n+1, rawtext
nrs is set to the n of the messsage header + 1 pnrs is set to the pn of the message header publicKey_n from the header is stored for later use
Inputs CK_n, rawtext Outputs CK_n+1, ciphertext
ns is incemented
pns is set to ns ns is set to 0
Proceeds with simple decryption
new privateKey_n and publicKey_n are generated and stored
A dh process happens
- RK_n+1, CK_s_n+1, CK_r_n+1 = KDF(RK_n, DH(privKey_n, publicKey_n_from_other))
- Inputs: other client's publicKey_n from storage, client's privateKey_n, RK_n
- Outputs: RK_n+1, CK_s_n+1, CK_r_n+1
CK_s_n+1 is then used in a simple encryption to encrypt the next message. The ouput from that along with RK_n+1, and CK_r_n+1 are all stored.
ns is then incrimented
new privateKey_n and publicKey_n are generated and stored A dh process happens
- RK_n+1, CK_s_n+1, CK_r_n+1 = KDF(RK_n, DH(privKey_n, publicKey_n_from_other))
- Inputs: other client's publicKey_n from the header, client's privateKey_n, RK_n
- Outputs: RK_n+1, CK_s_n+1, CK_r_n+1
ns is set to 0 pns is set to what ns was before it was set to 0 other client's publicKey_n is stored the ouputs from the dh proccess is stored
the proccess then proceeds with simple decryption to decrypt the message.
This proccess should create a secure double rachett encryption, assuming no messages arrive out of order.
While we recognise the importance of solving out of order messaging, it is also important to make sure the protocol is secuire first. That is why we need a comprehensive plan for the rest of the protocl before moving towards solving out of order messaging.
All keys after they have been used in their reasonable lifecycle. Excess chain keys and root keys are not stored after their use.
Instead up updating the rachett when a new publicKey_n is detected, it instead enforces strict rules opun both parties. When sending the first message after receiving a message the Receiver MUST cycle the DH rachett, additionally when receiving the first messages after sending a message the leader MUST cycle teh DH rachett.