Loading...
Searching...
No Matches
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 class | DR_message_type : uint8_t { X3DH_init_flag =0x01 , payload_direct_encryption_flag =0x02 }
| DR message type byte bit mapping. More...
enum class | DR_X3DH_OPk_flag : uint8_t { withoutOPk =0x00 , 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
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.
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
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.
template<typename Curve>
constexpr size_t | headerSize () noexcept
| return the size of the double ratchet packet header
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

## Variables

constexpr 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

- regular packet does not contain x3dh init message
- x3dh init packet includes x3dh init message in the header as follow:
  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>]

## Enumeration Type Documentation

## DR_message_type

enum class lime::double_ratchet_protocol::DR_message_type : uint8_t

strong

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

enum class lime::double_ratchet_protocol::DR_X3DH_OPk_flag : uint8_t

strong

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] | header | the buffer containing header to be sent to recipient
  [in] | Ns | Index of sending chain
  [in] | PN | Index of previous sending chain
  [in] | DHs | Current DH public key
  [in] | X3DH_initMessage | A buffer holding an X3DH init message to be inserted in header. If empty message type X3DH init flag is not set
  [in] | payloadDirectEncryption | Set 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] | message | the X3DH init message
  [in] | Ik | self public identity key
  [in] | Ek | self public ephemeral key
  [in] | SPk_id | id of peer signed prekey used
  [in] | OPk_id | id of peer OneTime prekey used(if any)
  [in] | OPk_flag | do we used an OPk?

## headerSize()

template<typename Curve>

size_t lime::double_ratchet_protocol::headerSize | ( |  | ) |

constexpr 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] | message | A 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_initMessage | A 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 > ||\n
    peer Ik ||\n
    peer Ek ||\n
    self SPk id ||\n
    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] | message | the message to parse
  [out] | Ik | peer public Identity key
  [out] | Ek | peer public Ephemeral key
  [out] | SPk_id | self Signed prekey id
  [out] | OPk_id | self One Time prekey id(if used, 0 otherwise)
  [out] | OPk_flag | true if an OPk flag was present in the message

## X3DHinitSize()

template<typename Curve>

size_t lime::double_ratchet_protocol::X3DHinitSize | ( | bool | haveOPk | ) |

constexpr 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

uint8_t lime::double_ratchet_protocol::DR_v01 =0x01

constexpr

Double ratchet protocol version number