Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

libsaxolotl v0.1

libsaxolotl implements the Axoltol protocol using curve25519 from libsodium in a LGPLv3+ library.

this library implements a variation, where the skipped header keys are not retained and hence not used when trying to decrypt out-of-band messages.

The axolotl context is 769 bytes, with 16 slots for the latest missed message keys. The initial handshake message (which can be produced in bulk and used for setting up channels asynchronously) is 96 bytes. Encrypted messages have an overhead of 128 bytes.


void axolotl_genid(Axolotl_KeyPair * keys);

Initializes a long-term identity key. This long-term key is the authenticating the persona to all peers.

void axolotl_prekey(Axolotl_PreKey *prekey, Axolotl_ctx *ctx, const Axolotl_KeyPair *keypair);

Creates the initial handshake to be exchanged for setting up an Axolotl channel. The pointer to the prekey is the initial packet that needs to be shared with 1 peer, reuse of these prekeys is not recommended. ctx is a pointer to a new Axolotl_ctx object, which needs to be preserved across the life-time of the connection. keypair is the long-term identity key for the persona generating the handshake message.

It is important to note that each prekey is coupled with a context, for correct setup the context according to the prekey must be used.

Generating and serving many of these prekeys centrally allows for asynchronous messaging. but this is not necessary.

int axolotl_handshake(Axolotl_ctx* ctx, const Axolotl_PreKey *prekey);

Receives an initial handshake and derives the initial context. ctx is the persistent context of the Axolotl channel. prekey is one of the communicating peers prekeys, this should be discarded, and never used again after using once. Both peers must execute this with each others prekeys before they can exchange messages.

The ctx must be the one coupled with the prekeys sent to the peer. The prekeys similarly must be the one associated with the ctx of the peer.

void axolotl_box(Axolotl_ctx *ctx, uint8_t *out, int *out_len, const uint8_t *in, const int in_len);

Encrypts a message in using the axolotl context ctx into out;

int axolotl_box_open(Axolotl_ctx *ctx, uint8_t *out, int *out_len, const uint8_t *in, const int in_len);

decrypts a message in using the axolotl context ctx into out;

a quick example for exchange between alice and bob:

#include "axolotl.h"

void main(void) {
  Axolotl_ctx alice_ctx, bob_ctx;
  Axolotl_KeyPair alice_id, bob_id;
  Axolotl_PreKey alice_prekey, bob_prekey;

  // init long-term identity keys

  axolotl_prekey(&alice_prekey, &alice_ctx, &alice_id);
  axolotl_prekey(&bob_prekey, &bob_ctx, &bob_id);

  // both derive the ctx from their exchanged prekey msg
  axolotl_handshake(&alice_ctx, &bob_prekey);
  axolotl_handshake(&bob_ctx, &alice_prekey);

  uint8_t out[4096], out2[4096];
  int outlen,outlen2;
  axolotl_box(&alice_ctx, out, &outlen, (const uint8_t *) "howdy", 6);
  if(axolotl_box_open(&bob_ctx, out2, &outlen2, out, outlen)!=0) {
    // fail
    printf("fail :/\n");
  printf("%d %s\n", outlen2, out2);


axolotl based on libsodium






No releases published


No packages published