IPCrypt libsodium Implementation

High-performance implementation of IPCrypt in libsodium, supporting all four encryption modes.

IPCrypt libsodium Implementation

libsodium includes a high-performance, production-ready implementation of IPCrypt. It supports all four encryption modes and leverages hardware AES instructions (AES-NI / ARMv8 Crypto Extensions) when available.

Installation

libsodium is available on all major platforms:

# macOS
brew install libsodium

# Debian / Ubuntu
apt install libsodium-dev

# Fedora / RHEL
dnf install libsodium-devel

# From source
git clone https://github.com/jedisct1/libsodium.git
cd libsodium
./configure && make && make install

Requirements

  • libsodium 1.0.21 or higher
  • A C compiler (gcc, clang, MSVC)

Usage

The libsodium implementation provides a simple C API for all four encryption modes. IP addresses are represented as 16-byte arrays (IPv4-mapped IPv6 format).

Deterministic Encryption

#include <sodium.h>

unsigned char key[crypto_ipcrypt_KEYBYTES];
unsigned char ip[16], encrypted_ip[16], decrypted_ip[16];

crypto_ipcrypt_keygen(key);

crypto_ipcrypt_encrypt(encrypted_ip, ip, key);
crypto_ipcrypt_decrypt(decrypted_ip, encrypted_ip, key);

Prefix-Preserving Encryption (PFX)

#include <sodium.h>

unsigned char key[crypto_ipcrypt_pfx_KEYBYTES];  /* 32 bytes: two 16-byte keys */
unsigned char ip[16], encrypted_ip[16], decrypted_ip[16];

crypto_ipcrypt_pfx_keygen(key);

crypto_ipcrypt_pfx_encrypt(encrypted_ip, ip, key);
crypto_ipcrypt_pfx_decrypt(decrypted_ip, encrypted_ip, key);

Non-Deterministic Encryption (ND)

#include <sodium.h>

unsigned char key[crypto_ipcrypt_KEYBYTES];
unsigned char ip[16];
unsigned char encrypted[crypto_ipcrypt_nd_BYTES];  /* 24 bytes: 8-byte tweak + 16-byte ciphertext */
unsigned char decrypted_ip[16];

crypto_ipcrypt_keygen(key);

crypto_ipcrypt_nd_encrypt(encrypted, ip, key);
crypto_ipcrypt_nd_decrypt(decrypted_ip, encrypted, key);

Non-Deterministic Extended Encryption (NDX)

#include <sodium.h>

unsigned char key[crypto_ipcrypt_ndx_KEYBYTES];  /* 32 bytes */
unsigned char ip[16];
unsigned char encrypted[crypto_ipcrypt_ndx_BYTES];  /* 32 bytes: 16-byte tweak + 16-byte ciphertext */
unsigned char decrypted_ip[16];

crypto_ipcrypt_ndx_keygen(key);

crypto_ipcrypt_ndx_encrypt(encrypted, ip, key);
crypto_ipcrypt_ndx_decrypt(decrypted_ip, encrypted, key);

API Reference

Constants

Constant Value Description
crypto_ipcrypt_KEYBYTES 16 Key size for deterministic and ND modes
crypto_ipcrypt_INPUTBYTES 16 IP address size (IPv4-mapped IPv6)
crypto_ipcrypt_pfx_KEYBYTES 32 Key size for PFX mode (two 16-byte keys)
crypto_ipcrypt_nd_BYTES 24 ND ciphertext size (8-byte tweak + 16-byte ciphertext)
crypto_ipcrypt_ndx_KEYBYTES 32 Key size for NDX mode
crypto_ipcrypt_ndx_BYTES 32 NDX ciphertext size (16-byte tweak + 16-byte ciphertext)

Deterministic Encryption

void crypto_ipcrypt_keygen(unsigned char k[crypto_ipcrypt_KEYBYTES]);

int crypto_ipcrypt_encrypt(unsigned char out[16], const unsigned char in[16],
                           const unsigned char k[crypto_ipcrypt_KEYBYTES]);

int crypto_ipcrypt_decrypt(unsigned char out[16], const unsigned char in[16],
                           const unsigned char k[crypto_ipcrypt_KEYBYTES]);

Prefix-Preserving Encryption (PFX)

void crypto_ipcrypt_pfx_keygen(unsigned char k[crypto_ipcrypt_pfx_KEYBYTES]);

int crypto_ipcrypt_pfx_encrypt(unsigned char out[16], const unsigned char in[16],
                                const unsigned char k[crypto_ipcrypt_pfx_KEYBYTES]);

int crypto_ipcrypt_pfx_decrypt(unsigned char out[16], const unsigned char in[16],
                                const unsigned char k[crypto_ipcrypt_pfx_KEYBYTES]);

Non-Deterministic Encryption (ND)

int crypto_ipcrypt_nd_encrypt(unsigned char out[crypto_ipcrypt_nd_BYTES],
                              const unsigned char in[16],
                              const unsigned char k[crypto_ipcrypt_KEYBYTES]);

int crypto_ipcrypt_nd_decrypt(unsigned char out[16],
                              const unsigned char in[crypto_ipcrypt_nd_BYTES],
                              const unsigned char k[crypto_ipcrypt_KEYBYTES]);

Non-Deterministic Extended Encryption (NDX)

void crypto_ipcrypt_ndx_keygen(unsigned char k[crypto_ipcrypt_ndx_KEYBYTES]);

int crypto_ipcrypt_ndx_encrypt(unsigned char out[crypto_ipcrypt_ndx_BYTES],
                               const unsigned char in[16],
                               const unsigned char k[crypto_ipcrypt_ndx_KEYBYTES]);

int crypto_ipcrypt_ndx_decrypt(unsigned char out[16],
                               const unsigned char in[crypto_ipcrypt_ndx_BYTES],
                               const unsigned char k[crypto_ipcrypt_ndx_KEYBYTES]);

Implementation Details

The libsodium implementation includes:

  1. Hardware Acceleration: Uses AES-NI on x86/x86_64 and Crypto Extensions on ARMv8 for maximum performance
  2. Constant-Time Operations: All operations are designed to run in constant time to prevent timing side-channel attacks
  3. Secure Memory: Keys can be stored in secure memory using sodium_malloc() and locked with sodium_mlock()
  4. Cross-Platform: Works on Linux, macOS, Windows, iOS, Android, and WebAssembly

Supported Features

  • IPv4 address encryption/decryption
  • IPv6 address encryption/decryption
  • Deterministic encryption (AES-128)
  • Prefix-preserving encryption (dual AES-128)
  • Non-deterministic encryption (KIASU-BC)
  • Extended non-deterministic encryption (AES-XTS)
  • Hardware-accelerated AES (AES-NI, ARMv8)
  • Constant-time implementation

Compilation

# Compile with pkg-config
cc -o example example.c $(pkg-config --cflags --libs libsodium)

# Or link directly
cc -o example example.c -lsodium

License

libsodium is licensed under the ISC License.

Examples

Deterministic Encryption

Encrypt an IP address using deterministic mode

#include 
#include 

int main(void) {
    unsigned char key[crypto_ipcrypt_KEYBYTES];
    unsigned char ip[16], encrypted_ip[16], decrypted_ip[16];

    if (sodium_init() < 0) return 1;

    /* Generate a random key */
    crypto_ipcrypt_keygen(key);

    /* Parse an IPv4 address into a 16-byte representation */
    /* 192.0.2.1 -> 0x00000000 0x00000000 0x0000FFFF 0xC0000201 */
    memset(ip, 0, 16);
    ip[10] = 0xff; ip[11] = 0xff;
    ip[12] = 192; ip[13] = 0; ip[14] = 2; ip[15] = 1;

    /* Encrypt */
    crypto_ipcrypt_encrypt(encrypted_ip, ip, key);

    /* Decrypt */
    crypto_ipcrypt_decrypt(decrypted_ip, encrypted_ip, key);
}

Prefix-Preserving Encryption (PFX)

Encrypt an IP address using prefix-preserving mode with dual AES-128

#include 

int main(void) {
    unsigned char key[crypto_ipcrypt_pfx_KEYBYTES]; /* 32 bytes */
    unsigned char ip[16], encrypted_ip[16], decrypted_ip[16];

    if (sodium_init() < 0) return 1;

    crypto_ipcrypt_pfx_keygen(key);

    memset(ip, 0, 16);
    ip[10] = 0xff; ip[11] = 0xff;
    ip[12] = 192; ip[13] = 0; ip[14] = 2; ip[15] = 1;

    /* Encrypt (output is same size as input) */
    crypto_ipcrypt_pfx_encrypt(encrypted_ip, ip, key);

    /* Decrypt */
    crypto_ipcrypt_pfx_decrypt(decrypted_ip, encrypted_ip, key);
}

Non-Deterministic Encryption (ND)

Encrypt an IP address using non-deterministic mode with KIASU-BC

#include 

int main(void) {
    unsigned char key[crypto_ipcrypt_KEYBYTES];
    unsigned char ip[16];
    unsigned char encrypted[crypto_ipcrypt_nd_BYTES]; /* 24 bytes */
    unsigned char decrypted_ip[16];

    if (sodium_init() < 0) return 1;

    crypto_ipcrypt_keygen(key);

    memset(ip, 0, 16);
    ip[10] = 0xff; ip[11] = 0xff;
    ip[12] = 192; ip[13] = 0; ip[14] = 2; ip[15] = 1;

    /* Encrypt (tweak is generated automatically) */
    crypto_ipcrypt_nd_encrypt(encrypted, ip, key);

    /* Decrypt */
    crypto_ipcrypt_nd_decrypt(decrypted_ip, encrypted, key);
}

Non-Deterministic Extended Encryption (NDX)

Encrypt an IP address using non-deterministic extended mode with AES-XTS

#include 

int main(void) {
    unsigned char key[crypto_ipcrypt_ndx_KEYBYTES]; /* 32 bytes */
    unsigned char ip[16];
    unsigned char encrypted[crypto_ipcrypt_ndx_BYTES]; /* 32 bytes */
    unsigned char decrypted_ip[16];

    if (sodium_init() < 0) return 1;

    crypto_ipcrypt_ndx_keygen(key);

    memset(ip, 0, 16);
    ip[10] = 0xff; ip[11] = 0xff;
    ip[12] = 192; ip[13] = 0; ip[14] = 2; ip[15] = 1;

    /* Encrypt (tweak is generated automatically) */
    crypto_ipcrypt_ndx_encrypt(encrypted, ip, key);

    /* Decrypt */
    crypto_ipcrypt_ndx_decrypt(decrypted_ip, encrypted, key);
}