lime
Lime is a C++ library implementing Open Whisper System Signal protocol
Classes | Enumerations | Functions | Variables
lime::double_ratchet_protocol Namespace Reference

Group in this namespace all the functions related to building or parsing double ratchet packets. More...

Classes

class  DRHeader
 helper class and functions to parse Double Ratchet message header and access its components More...
 

Enumerations

enum  DR_message_type : uint8_t { DR_message_type::X3DH_init_flag =0x01, DR_message_type::payload_direct_encryption_flag =0x02 }
 DR message type byte bit mapping. More...
 
enum  DR_X3DH_OPk_flag : uint8_t { DR_X3DH_OPk_flag::withoutOPk =0x00, DR_X3DH_OPk_flag::withOPk =0x01 }
 haveOPk byte from X3DH init message mapping More...
 

Functions

template<typename Curve >
void buildMessage_X3DHinit (std::vector< uint8_t > &message, const DSA< Curve, lime::DSAtype::publicKey > &Ik, const X< Curve, lime::Xtype::publicKey > &Ek, const uint32_t SPk_id, const uint32_t OPk_id, const bool OPk_flag) noexcept
 build an X3DH init message to insert in DR header More...
 
template<typename Curve >
void parseMessage_X3DHinit (const std::vector< uint8_t >message, DSA< Curve, lime::DSAtype::publicKey > &Ik, X< Curve, lime::Xtype::publicKey > &Ek, uint32_t &SPk_id, uint32_t &OPk_id, bool &OPk_flag) noexcept
 Parse the X3DH init message and extract peer Ik, peer Ek, self SPk id and seld OPk id if present. More...
 
template<typename Curve >
bool parseMessage_get_X3DHinit (const std::vector< uint8_t > &message, std::vector< uint8_t > &X3DH_initMessage) noexcept
 check the message for presence of X3DH init in the header, extract it if there is one More...
 
template<typename Curve >
void buildMessage_header (std::vector< uint8_t > &header, const uint16_t Ns, const uint16_t PN, const X< Curve, lime::Xtype::publicKey > &DHs, const std::vector< uint8_t > X3DH_initMessage, const bool payloadDirectEncryption) noexcept
 Build a header string from needed info. More...
 
template<typename Curve >
constexpr size_t headerSize () noexcept
 return the size of the double ratchet packet header More...
 
template<typename Curve >
constexpr size_t X3DHinitSize (bool haveOPk) noexcept
 return the size of the X3DH init packet included in the double ratchet packet header More...
 

Variables

constexpr std::uint8_t DR_v01 =0x01
 

Detailed Description

Group in this namespace all the functions related to building or parsing double ratchet packets.

Implemented version of the DR session protocol (provide a way to handle future/alternative packets formats/crypto algorithm) Supported version description :

Version 0x01:

DRHeader is: Protocol Version Number<1 byte> || Message Type <1 byte> || curveId <1 byte> || [X3DH Init message < variable >] || Ns<2 bytes> || PN<2 bytes> || DHs<...>

Message is : DRheader<...> || cipherMessageKeyK<32 bytes> || Key auth tag<16 bytes> || cipherText<...> || Message auth tag<16 bytes>

Associated Data are transmitted separately: ADk for the Key auth tag, and ADm for the Message auth tag

Message AEAD on : (ADm, message plain text) keyed by message Key(include IV)

Key AEAD on : (ADk || Message auth tag || header, Message Key) keyed by Double Ratchet generated key/IV

ADm is : source GRUU<...> || recipient sip-uri(can be a group uri)<...>

ADk is : source GRUU<...> || recipient GRUU<...>

Note
: ADk is used with session stored AD provided by X3DH at session creation which is HKDF(initiator Ik || receiver Ik || initiator device Id || receiver device Id)

Diffie-Hellman support: X25519 or X448 (not mixed, specified by X3DH server and client setting which must match)

Packets types are : regular or x3dhinit

Enumeration Type Documentation

◆ DR_message_type

DR message type byte bit mapping.

| 7 6 5 4 3 2 1 0 |
| < Unused > Payload_Direct_Encryption_Flag X3DH_Init_Flag |

Payload_Direct_Encryptiun Flag (bit 1):

  • set : the Double Ratchet packet encrypts the user plaintext
  • unset: the Double Ratchet packet encrypts a random seed used to encrypt the user plaintext

X3DH_Init_Flag (bit 0):

  • set : the Double Ratchet Packet header contains a X3DH Init message
  • unset: the Double Ratcher Packet header does not contain a X3DH Init message
Enumerator
X3DH_init_flag 

bit 0

payload_direct_encryption_flag 

bit 1

◆ DR_X3DH_OPk_flag

haveOPk byte from X3DH init message mapping

Enumerator
withoutOPk 

0x00

withOPk 

0x01

Function Documentation

◆ buildMessage_header()

template<typename Curve >
void lime::double_ratchet_protocol::buildMessage_header ( std::vector< uint8_t > &  header,
const uint16_t  Ns,
const uint16_t  PN,
const X< Curve, lime::Xtype::publicKey > &  DHs,
const std::vector< uint8_t >  X3DH_initMessage,
const bool  payloadDirectEncryption 
)
noexcept

Build a header string from needed info.

header is:

Protocol Version Number<1 byte> ||
Message Type <1 byte> ||
curveId <1 byte> ||
[X3DH Init message < variable >] ||
Ns<2 bytes> ||
PN<2 bytes> ||
DHs<...>

Parameters
[out]headerthe buffer containing header to be sent to recipient
[in]NsIndex of sending chain
[in]PNIndex of previous sending chain
[in]DHsCurrent DH public key
[in]X3DH_initMessageA buffer holding an X3DH init message to be inserted in header. If empty message type X3DH init flag is not set
[in]payloadDirectEncryptionSet the Payload Direct Encryption flag in header

◆ buildMessage_X3DHinit()

template<typename Curve >
void lime::double_ratchet_protocol::buildMessage_X3DHinit ( std::vector< uint8_t > &  message,
const DSA< Curve, lime::DSAtype::publicKey > &  Ik,
const X< Curve, lime::Xtype::publicKey > &  Ek,
const uint32_t  SPk_id,
const uint32_t  OPk_id,
const bool  OPk_flag 
)
noexcept

build an X3DH init message to insert in DR header

haveOPk <flag 1 byte> ||
self Ik < DSA<Curve, lime::DSAtype::publicKey>::ssize() bytes > ||
Ek < X<Curve, lime::Xtype::publicKey>::keyLenght() bytes> ||
peer SPk id < 4 bytes > ||
[peer OPk id(if flag is set)<4bytes>]

Parameters
[out]messagethe X3DH init message
[in]Ikself public identity key
[in]Ekself public ephemeral key
[in]SPk_idid of peer signed prekey used
[in]OPk_idid of peer OneTime prekey used(if any)
[in]OPk_flagdo we used an OPk?

◆ headerSize()

template<typename Curve >
constexpr size_t lime::double_ratchet_protocol::headerSize ( )
noexcept

return the size of the double ratchet packet header

header is: Protocol Version Number<1 byte> || Message Type <1 byte> || curveId <1 byte> || [X3DH Init message < variable >] || Ns<2 bytes> || PN<2 bytes> || DHs< DH public key size >

Returns
the header size without optionnal X3DH init packet

◆ parseMessage_get_X3DHinit()

template<typename Curve >
bool lime::double_ratchet_protocol::parseMessage_get_X3DHinit ( const std::vector< uint8_t > &  message,
std::vector< uint8_t > &  X3DH_initMessage 
)
noexcept

check the message for presence of X3DH init in the header, extract it if there is one

Parameters
[in]messageA buffer holding the message, it shall be DR header || DR message. If there is a X3DH init message it is in the DR header
[out]X3DH_initMessageA buffer holding the X3DH input message
Returns
true if a X3DH init message was found, false otherwise (also in case of invalid packet)

◆ parseMessage_X3DHinit()

template<typename Curve >
void lime::double_ratchet_protocol::parseMessage_X3DHinit ( const std::vector< uint8_t >  message,
DSA< Curve, lime::DSAtype::publicKey > &  Ik,
X< Curve, lime::Xtype::publicKey > &  Ek,
uint32_t &  SPk_id,
uint32_t &  OPk_id,
bool &  OPk_flag 
)
noexcept

Parse the X3DH init message and extract peer Ik, peer Ek, self SPk id and seld OPk id if present.

usedOPk < flag on one byte > ||
peer Ik ||
peer Ek ||
self SPk id ||
self OPk id(if flag is set)

When this function is called, we already parsed the DR message to extract the X3DH_initMessage all checks were already performed by the Double Ratchet packet parser, just grab the data

Parameters
[in]messagethe message to parse
[out]Ikpeer public Identity key
[out]Ekpeer public Ephemeral key
[out]SPk_idself Signed prekey id
[out]OPk_idself One Time prekey id(if used, 0 otherwise)
[out]OPk_flagtrue if an OPk flag was present in the message

◆ X3DHinitSize()

template<typename Curve >
constexpr size_t lime::double_ratchet_protocol::X3DHinitSize ( bool  haveOPk)
noexcept

return the size of the X3DH init packet included in the double ratchet packet header

X3DH init packet is : OPk flag<1 byte> || Ik < DSA public key size > || Ek < DH public key size > || SPk Id <4 bytes> || [OPk Id <4 bytes>]

Returns
the header size without optionnal X3DH init packet

Variable Documentation

◆ DR_v01

constexpr std::uint8_t lime::double_ratchet_protocol::DR_v01 =0x01

Double ratchet protocol version number