- C 95.5%
- CMake 4.4%
- Zig 0.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .github | ||
| benchmark | ||
| docs | ||
| examples | ||
| include | ||
| src | ||
| test/esp-idf | ||
| tests | ||
| zig-include | ||
| .gitignore | ||
| .valgrind-suppressions | ||
| build.zig | ||
| build.zig.zon | ||
| CHANGELOG.md | ||
| CMakeLists.txt | ||
| CMakePresets.json | ||
| CONFIG.md | ||
| CONTRIBUTING.md | ||
| Doxyfile | ||
| idf_component.yml | ||
| libnostr-c-config.cmake.in | ||
| libnostr-c.pc.in | ||
| LICENSE | ||
| README.md | ||
| SECURITY.md | ||
| Taskfile.yaml | ||
libnostr-c
A lightweight, portable C library for the Nostr protocol with native Lightning Network integration
What is libnostr-c?
A high-performance C implementation of the Nostr protocol built for efficiency and minimal dependencies. libnostr-c provides core event management, modern NIP-44 encryption powered by noscrypt, Lightning zaps, WebSocket relay communication, and complete relay-side protocol support. Designed for both client applications and relay implementations, with a focus on security, portability, and embedded systems.
API Example
// Client-side
nostr_init();
nostr_keypair_generate();
nostr_event_create();
nostr_event_sign();
nostr_nip44_encrypt();
nostr_relay_connect();
// Relay-side (for relay implementations)
nostr_client_msg_parse();
nostr_filter_matches();
nostr_event_validate_full();
nostr_deletion_authorized();
nostr_relay_msg_serialize();
nostr_relay_info_serialize();
Motivation
Building nostr applications in C requires reliable, efficient cryptographic operations and protocol handling. libnostr-c provides a complete implementation with modern NIP-44 encryption, Lightning integration, and minimal resource requirements. Built with security-first design principles and optimized for both desktop and embedded systems.
Platform Support
The following table lists supported platforms and cryptographic backends:
| Platform | Crypto Backend | Notes | CI Status |
|---|---|---|---|
| Linux | noscrypt, secp256k1 | GCC/Clang | ✅ Tested |
| macOS | noscrypt, secp256k1 | Clang | ✅ Tested |
| Windows | noscrypt, secp256k1 | MSVC | ✅ Tested |
| ESP-IDF | noscrypt, mbedtls | ESP32/S2/S3/C3/C6, v5.0+ | ✅ Tested, run under QEMU |
ESP-IDF stack requirement
On ESP targets the RNG goes through a cached mbedTLS CTR-DRBG rather than
esp_fill_random(), so that a failed draw can be reported instead of silently
returning zeros. That costs stack in the task that happens to seed it.
Call nostr_random_bytes(), nostr_key_generate(), nostr_keypair_generate()
or any signing entry point from a task with at least 4 KB of stack.
(nostr_keypair_generate() delegates to nostr_key_generate(), so either
reaches the same draw.) The first call in the process seeds
the DRBG, and ctr_drbg_reseed_internal() puts a 384-byte
MBEDTLS_CTR_DRBG_MAX_SEED_INPUT buffer on the caller's stack
(mbedtls/library/ctr_drbg.c:452), plus the entropy gather. Roughly 500 bytes
transient that esp_fill_random() never needed. It is re-paid every
MBEDTLS_CTR_DRBG_RESEED_INTERVAL draws, which is 10000 by default, so a task
that seeds successfully once can still overflow much later.
Seeding lazily from whichever task draws first means the cost lands wherever
that happens to be. Calling nostr_init() early, from a task you control the
depth of, makes it predictable.
Fixed cost is small: 500 bytes of .bss for the two contexts, measured from a
built ESP32-S3 image (rng_entropy 420 B, rng_ctr_drbg 76 B,
rng_initialized 4 B). The entropy accumulator also mallocs its message-digest
context on first use and never frees it, which is one-time rather than a growing
leak.
This is measured, not estimated. Under QEMU on ESP32-S3:
| first caller | result |
|---|---|
| 2 KB task drawing from an already-seeded DRBG | passes |
| 2 KB task that seeds the DRBG itself | crashes, Guru Meditation Error: Core 1 panic'ed (LoadProhibited) |
| 3 KB task that seeds | passes |
| 4 KB task that seeds | passes |
8 KB task (app_main) seeding, then 2 KB tasks drawing |
passes |
The threshold is between 2 KB and 3 KB on this build. 4 KB is the recommendation because it leaves margin for your own frames on top of the seed, not because 3 KB was observed to fail.
So the hazard is specifically the first caller, which is why seeding from a task whose depth you control is worth doing deliberately.
test/esp-idf sets CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192, so CI seeds from
app_main with headroom and will not catch a consumer that seeds from a smaller
task.
Getting started
Please use the following links to obtain packages and extended documentation.
Documentation
Examples
Performance Analysis
Super quick start
Prerequisites:
- CMake 3.16+, C99 compiler, OpenSSL
- secp256k1, libcjson, libwebsockets (see BUILDING.md)
git clone https://github.com/privkeyio/libnostr-c.git
cd libnostr-c
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
For detailed installation instructions, dependency management, and platform-specific setup, see docs/BUILDING.md.
Notes
Builds
Automated builds and releases are available through GitHub Actions CI/CD.
Features
libnostr-c supports modular compilation - build only what you need:
- Core NIPs (01, 02, 05, 06, 10, 13, 18, 19, 21, 25, 57, 65) enabled by default
- Optional NIPs (04, 09, 11, 17, 26, 40, 44, 45, 46, 47, 49, 50, 51, 59) via feature flags
- NIP-11 relay information document for serving relay metadata
- Relay protocol support for building relay implementations
- Modern noscrypt backend provides NIP-44 encryption
- Fallback to secp256k1 for basic operations
Projects Using libnostr-c
- keep-esp32 - Air-gapped ESP32-S3 FROST threshold signing device with Nostr DKG coordination
- wisp-esp32 - Minimal ESP32-S3 Nostr relay with 21-day ephemeral storage
- whisper - Encrypted DM pipe for Nostr using NIP-17 + NIP-44, Unix-style CLI
- vain - High-performance vanity Nostr public key miner
License
The software in this repository is licensed under MIT. See the LICENSE file for details.
Acknowledgments
This project is powered by noscrypt for high-performance cryptographic operations and NIP-44 encryption.