openmelib — C Library
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.
- Source (monorepo):
c/openmelib/in the openme repository - Standalone repo: github.com/merlos/openmelib — used by the Arduino Library Manager and ESP-IDF Component Manager
- Standard: C99 (no VLAs, no dynamic allocation in the core path)
- Targets: POSIX desktop, Arduino, ESP32/ESP-IDF, any bare-metal MCU with a CSPRNG
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 buildStandalone (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 openmelibSee 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:
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 -VExamples
| Example | Path |
|---|---|
| POSIX CLI | c/openmelib/examples/desktop/ |
| Arduino sketch | c/openmelib/examples/arduino/ |
| ESP32 ESP-IDF | c/openmelib/examples/esp32_idf/ |