openmelib — C Library

Keywords

openme C library, openmelib, Arduino SPA, ESP32 knock protocol, single packet authentication C, embedded openme, POSIX openme C99

openmelib is the official C99 implementation of the openme Single Packet Authentication protocol.

Note

The standalone merlos/openmelib repository is an automatically maintained mirror of the c/openmelib/ subtree. It is updated by the release CI workflow on every lib/c/vX.Y.Z tag. Development, issue tracking, and contributions happen in the openme monorepo.

Features

Capability Details
SPA packet builder openme_build_packet() — fully deterministic, no OS calls
Entropy abstraction Caller supplies all random bytes — portable across targets
Crypto Monocypher 4 (bundled) — Curve25519, ChaCha20-Poly1305, Ed25519
HKDF-SHA256 Bundled openme_sha256.h/c — no external crypto dep
Build systems CMake (desktop/cross-compile), Arduino Library Manager, ESP-IDF component

Installation

CMake (desktop / cross-compile)

From the monorepo (development):

cmake -S c/openmelib -B build \
    -DOPENME_FETCH_MONOCYPHER=ON \
    -DOPENME_BUILD_EXAMPLES=ON \
    -DCMAKE_BUILD_TYPE=Release
cmake --build build

Standalone (external projects using CMake FetchContent):

include(FetchContent)
FetchContent_Declare(
    openmelib
    GIT_REPOSITORY https://github.com/merlos/openmelib.git
    GIT_TAG        v1.0.0
)
FetchContent_MakeAvailable(openmelib)
target_link_libraries(my_target PRIVATE openmelib)

Arduino

Install via the Arduino Library Manager — search for openmelib. The Library Manager fetches releases from the merlos/openmelib repository, where each vX.Y.Z tag corresponds to a versioned release.

Alternatively, download a pre-built source tarball and use Sketch → Include Library → Add .ZIP Library….

#include <openmelib.h>

uint8_t packet[OPENME_PACKET_SIZE];
openme_build_packet(
    packet,
    server_pubkey,  // 32-byte X25519
    client_seed,    // 32-byte Ed25519 seed
    timestamp_ns,
    ephem_secret,   // 32-byte CSPRNG
    aead_nonce,     // 12-byte CSPRNG
    random_nonce,   // 16-byte CSPRNG
    NULL            // target IP — NULL = use source IP
);

ESP-IDF (ESP32)

Add the component to your project’s idf_component.yml using the standalone merlos/openmelib repository:

dependencies:
  openmelib:
    git: https://github.com/merlos/openmelib.git
    version: ">=1.0.0"

Or clone it directly into your project’s components/ directory:

cd components
git clone --depth 1 --branch v1.0.0 \
    https://github.com/merlos/openmelib.git openmelib

See c/openmelib/examples/esp32_idf/ in the monorepo for a complete project.

API Reference

The full Doxygen API reference is generated from source and published with each release of the documentation site:

→ openmelib Doxygen Reference

The public API header is also available on GitHub: include/openmelib.h.

Core function signature

int openme_build_packet(
    uint8_t        out[OPENME_PACKET_SIZE],
    const uint8_t  server_pubkey[32],   /* X25519 server public key */
    const uint8_t  client_seed[32],     /* Ed25519 private key seed */
    int64_t        timestamp_ns,        /* Unix time in nanoseconds */
    const uint8_t  ephem_secret[32],    /* 32 random bytes per knock */
    const uint8_t  aead_nonce[12],      /* 12 random bytes per knock */
    const uint8_t  random_nonce[16],    /* 16 random bytes per knock */
    const uint8_t *target_ip            /* 16-byte IPv6, or NULL = source IP */
);
/* Returns: OPENME_OK (0) on success, negative error code on failure. */

Protocol constants

Constant Value Description
OPENME_PACKET_SIZE 165 Total UDP datagram size
OPENME_SIGNED_SIZE 101 Bytes covered by Ed25519 signature
OPENME_VERSION 1 Protocol version byte
OPENME_DEFAULT_PORT 54154 Default UDP port

Running Tests

cmake --build build --target test
# or
ctest --test-dir build -V

Examples

Example Path
POSIX CLI c/openmelib/examples/desktop/
Arduino sketch c/openmelib/examples/arduino/
ESP32 ESP-IDF c/openmelib/examples/esp32_idf/

See Also