Skip to content
This repository was archived by the owner on May 1, 2026. It is now read-only.

semantic-reasoning/libksuid

Repository files navigation

libksuid

⚠ ARCHIVED. libksuid 1.0.0 is feature-complete and is preserved here as a read-only artifact. Active development continues under a broader scope in libchronoid — a C11 toolkit for time-ordered identifiers that includes both the original KSUID surface (renamed to chronoid_ksuid_*) and a new UUIDv7 (RFC 9562) implementation as sibling formats under one library.

Migration:

  • Header path: <libksuid/ksuid.h><chronoid/ksuid.h>
  • Library / SONAME: libksuid.so.1libchronoid.so.0 (0.9.x pre-release; SONAME advances when libchronoid cuts 1.0)
  • pkg-config: libksuid.pclibchronoid.pc
  • CLI: ksuid-genchronoid-gen
  • Public API: ksuid_* / KSUID_*chronoid_ksuid_* / CHRONOID_KSUID_* (semantics unchanged; wire format preserved bytewise)

No new commits, issues, or PRs will be accepted on this repository. Existing 1.0.0 consumers may continue to use libksuid.so.1 as shipped; libchronoid does not provide a libksuid.so.1-compatible binary.

A pure C11 port of segmentio/ksuid focused on small footprint, lock-free thread safety, and SIMD/NEON acceleration where the underlying algorithms admit it.

Status

1.0.0 — public API and ABI are stable, repository archived 2026-05-01. SONAME is libksuid.so.1; subsequent 1.x releases stay binary-compatible (semver) but no further releases will be cut from this repository.

Goals

  • Pure C11. No pthread; thread safety via _Thread_local storage and <stdatomic.h> only.
  • meson + ninja build. Both static and shared libraries plus a ksuid-gen CLI for round-trip generation and parsing.
  • Wire-compatible with upstream segmentio/ksuid — same 20-byte binary layout, same 27-character base62 string encoding, same epoch (1400000000 = 2014-05-13 16:53:20 UTC), same ordering invariants.
  • Honest SIMD: the base62 long-division core is sequential and is not vectorizable; SSE2/NEON paths accelerate input validation (16-byte packed range tests, sentinel-fill on miss).
  • Cross-platform RNG:
    • Linux: getrandom(2) with /dev/urandom fallback
    • macOS: getentropy(3) (10.12+) with /dev/urandom fallback
    • Windows: BCryptGenRandom (linked via bcrypt.lib)
    • Per-thread ChaCha20 CSPRNG keyed from the OS source, reseeded every 1 MiB / hour / fork / clock-skew event.
  • Small footprint: no heap allocations on the hot path; no third-party runtime dependencies. Stripped library is ~18 KB.

Licensing

libksuid is distributed under the GNU Lesser General Public License, version 3 or later (see LICENSE). It is a derivative work that ports algorithms and binary formats from segmentio/ksuid, which is distributed under the MIT License (see LICENSE.MIT for the upstream text). The combined attribution requirements are described in NOTICE.

Source files derived from upstream Go code carry the SPDX header

SPDX-License-Identifier: LGPL-3.0-or-later AND MIT

and a pointer back to the upstream source they were ported from.

Building

meson setup build
meson compile -C build
meson test    -C build

For a release build with NDEBUG and stripped binaries:

meson setup build-release --buildtype=release
meson compile -C build-release
strip --strip-unneeded build-release/libksuid.so.*

Footprint

A release build on x86_64 produces (post-strip --strip-unneeded):

Artifact Bytes
libksuid.so.1.0.0 26 752
libksuid.a 35 212
ksuid-gen (CLI) 22 920

The bulk-encode AVX2 kernel from libksuid/encode_avx2.c accounts for roughly 8 KB of the shared-library size; non-AVX2 hosts compile and link the kernel but never call into it, so the CPUID-gated dispatch adds no runtime cost to those targets.

The shared library has zero runtime dependencies beyond the C library and, on Windows, bcrypt.lib.

CLI

$ ksuid-gen
3D3tYHbvwtnqJnHlVV0SnfLhsIl

$ ksuid-gen -n 3
3D3tYDod37FCb5o2znp85EOqeO3
3D3tYG2kSSEmqfHFkSFXeSYyLAa
3D3tYGRMmQOon3PeymhLvYc1yu5

$ ksuid-gen -f inspect 0ujtsYcgvSTl8PAuAdqWYSMnLOv

REPRESENTATION:

  String: 0ujtsYcgvSTl8PAuAdqWYSMnLOv
     Raw: 0669F7EFB5A1CD34B5F99D1154FB6853345C9735

COMPONENTS:

       Time: 2017-10-10 04:00:47 +0000 UTC
  Timestamp: 107608047
    Payload: B5A1CD34B5F99D1154FB6853345C9735

The full flag set is -n N, -f {string,inspect,time,timestamp,payload,raw}, -v, -h. See ksuid-gen -h for details.

The Go upstream's -f template is intentionally not supported -- a faithful re-implementation of Go's text/template grammar in C is out of scope, and a "mostly compatible" template engine is worse than no engine at all.

Bulk encode

When formatting many KSUIDs at once (database snapshots, log batches, network bulk responses), use the bulk variant rather than calling ksuid_format in a loop:

ksuid_t ids[1024];
char    out[1024 * KSUID_STRING_LEN];   /* no NUL terminators */

ksuid_string_batch (ids, out, 1024);
/* ids[i] is now at out[i * KSUID_STRING_LEN .. (i + 1) * KSUID_STRING_LEN - 1] */

The function is thread-safe for disjoint output buffers and n == 0 is a no-op. Output is byte-identical to a ksuid_format loop -- only the throughput differs.

The implementation dispatches at first call to a kernel selected from CPU features via an atomic function pointer (libsodium-style trampoline; race-free without locks or allocation):

  • x86_64 + AVX2: an 8-wide AVX2 kernel that processes eight KSUIDs per outer iteration via a Granlund-Möller floor-reciprocal multiply divide-by-62 (#13). The magic constant is auto-generated by tools/derive-magic.py, pinned in libksuid/divisor_magic.h, and verified against __uint128_t integer division on every CI run.
  • Other hosts (non-AVX2 x86_64, aarch64, arm, ...): a per-ID scalar loop equivalent to calling ksuid_format N times.

Output is byte-identical across kernels; the differential parity test in tests/test_string_batch.c cross-checks the AVX2 kernel against the scalar reference over ≥ 2²⁰ pseudo-random KSUIDs and a lane-swap detection corpus.

Setting the environment variable KSUID_FORCE_SCALAR=1 pins the dispatcher to the scalar path at first call (runtime kill switch without rebuilding the library).

Layout

The repository follows the libsoup-style single-source-directory convention. All public and private library code lives under libksuid/, and every C file -- inside the library, in tests, and in examples -- includes its dependencies with the prefixed form

#include <libksuid/ksuid.h>          /* the public umbrella */
#include <libksuid/base62.h>         /* internal helper */

After install the public header lands at ${prefix}/include/libksuid/ksuid.h, so downstream consumers use the exact same include line that the in-tree sources do.

libksuid/        library source + headers (public ksuid.h here too)
examples/        example consumers; ksuid-gen CLI
tests/           unit + integration tests
tools/           build tooling (gst-indent)
hooks/           git hooks (pre-commit code-style check)

Acknowledgements

The KSUID specification, base62 alphabet, encoding scheme, and reference test vectors all originate from segmentio/ksuid (MIT License, Copyright (c) 2017 Segment.io). This project would not exist without that prior art.

About

KSUID library in C11

Resources

License

LGPL-3.0, MIT licenses found

Licenses found

LGPL-3.0
LICENSE
MIT
LICENSE.MIT

Stars

Watchers

Forks

Packages

 
 
 

Contributors