Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
6aae1d7
Fix unpleasant string chopping
jagerman Feb 13, 2026
3831d05
Refactor internal dependencies to use session-deps
jagerman Mar 10, 2026
9474dad
Drop libsodium-internal; add tweetnacl implementation for X->Ed
jagerman Mar 10, 2026
49608f5
API improvements for hashing, arrays, clearing, spans
jagerman Mar 10, 2026
3f6244c
WIP - session db, PFS, device linking, etc.
jagerman Mar 10, 2026
61d3a40
Add simdutf to session-deps
jagerman Mar 10, 2026
9b5418a
Various build fixes
jagerman Mar 11, 2026
7d744e5
session-deps: session-router, libquic, and fix
jagerman Mar 11, 2026
4485a01
Add devices message parsing
jagerman Mar 11, 2026
eee237c
Expose callbacks to components
jagerman Mar 11, 2026
f6ea190
WIP: device linking
jagerman Mar 11, 2026
49c9f0f
Add generic core message consumer
jagerman Mar 11, 2026
aa6fff8
formatting
jagerman Mar 11, 2026
d8db5b4
Hash & type unification
jagerman Mar 12, 2026
a46b400
Make hashing endian-safe; more blake2b_pers conversion
jagerman Mar 12, 2026
7463d47
Use std::byte to avoid oxenc buggy overload
jagerman Mar 12, 2026
ec673dd
array_ucNN -> ucNN, for test suite
jagerman Mar 12, 2026
fae949c
Bake int_for_hashing into the hash helpers
jagerman Mar 12, 2026
04cbc9c
Add emoji SAS support for link requests
jagerman Mar 12, 2026
edf9cbb
link request handling WIP
jagerman Mar 12, 2026
b2d37e2
Merge link requests and devices into same namespace
jagerman Mar 13, 2026
b96b207
Move device list to subkey of device group message
jagerman Mar 13, 2026
b1e9bab
WIP on device and account messages
jagerman Mar 16, 2026
4f4b59a
Account key rotation tie-breaking
jagerman Mar 16, 2026
8865051
bump session-deps for sqlite3mc namespacing patch
jagerman Mar 17, 2026
78210a4
Add network to core + fixes
jagerman Mar 18, 2026
91b448d
devices: publish & distributed tracking
jagerman Mar 17, 2026
39f20b5
Implement update_info
jagerman Mar 18, 2026
1afcc89
Add a global adjustable system clock
jagerman Mar 18, 2026
5aabcb5
Add test helper friend class
jagerman Mar 19, 2026
d7a519d
Add optional Core polling of device & account namespaces
jagerman Mar 19, 2026
b9f3f21
update session-deps
jagerman Mar 19, 2026
3a38ca1
formatting & small code simplifications
jagerman Mar 19, 2026
04f1e62
add missing clock header
jagerman Mar 19, 2026
f799b2a
Devices tests; various fixes
jagerman Mar 19, 2026
d20ade5
add missing files
jagerman Mar 19, 2026
5cda501
fix merge conflict
jagerman Mar 19, 2026
473812f
Update session-deps
jagerman Mar 19, 2026
7133598
Add Electrum word lists
jagerman Mar 20, 2026
c2af9f0
Add ability to use a predefined seed
jagerman Mar 20, 2026
de91f75
Seed word handling fixes and improvements
jagerman Mar 20, 2026
fd980f8
Add checksum support to seed words
jagerman Mar 20, 2026
8e28520
Mnemonics secure mem & integration with predefined_seed
jagerman Mar 21, 2026
e3220f9
Make last_hash cache node-dependent
jagerman Mar 20, 2026
934704b
Add PFS+PQ remote session id cache & prefetching
jagerman Mar 21, 2026
5c1f640
Add negative-ack caching to PFS+PQ pubkey prefetching
jagerman Mar 21, 2026
8f0b224
improve ScopedClockOffset variable names
jagerman Mar 21, 2026
94a124d
Add callback + status returns for remote PFS key prefetch
jagerman Mar 23, 2026
d597712
Switch to SHAKE256; improve SHAKE256 API
jagerman Mar 24, 2026
551a7b5
Add SHA3-256 hasher
jagerman Mar 24, 2026
f939173
Abstract 32-or-64 seed input
jagerman Mar 24, 2026
6f6233b
bump session-router
jagerman Mar 24, 2026
7ca2b47
Refactor: compile-time safe Ed25519 privkey args
jagerman Mar 24, 2026
7a8f106
Add live (testnet) network test script
jagerman Mar 25, 2026
5048553
Add PFS + PQ encryption and decryption implementations
jagerman Mar 24, 2026
d0321f6
Improve test db naming to avoid parallel invocation overlap
jagerman Mar 25, 2026
7c24552
Cache long-term x25519 private scalar alongside the seed
jagerman Mar 25, 2026
1a6583c
Fix test suite
jagerman Mar 25, 2026
551379f
Refactor to use fixed-extent spans for fixed-size quantities
jagerman Mar 26, 2026
24ac035
uint8_t -> unsigned char for byte values
jagerman Mar 26, 2026
1a325b9
Add DM v1+v2 parsing and polling support
jagerman Mar 26, 2026
01f1c67
formatting
jagerman Mar 26, 2026
89d779a
Split up big nested functions
jagerman Mar 26, 2026
d4fb0a4
session_protocol: Replace destination-dispatch pattern with typed enc…
jagerman Mar 26, 2026
2dfa9a2
Use hash::blake2b in more places
jagerman Mar 27, 2026
cda7c98
unsigned char -> std::byte refactor, part 1
jagerman Mar 27, 2026
f0054a9
Add fallback "no-PFS" support
jagerman Mar 27, 2026
14956c7
Replace snprintf_clamped with fmt-based helpers
jagerman Mar 28, 2026
55cc134
Add "v2" DM construction via Core
jagerman Apr 1, 2026
5f51bf0
QUIC file server over session-router support
jagerman Mar 31, 2026
beb6932
Add a streaming decryptor; tweak encrypt keygen
jagerman Mar 31, 2026
02663c0
Make quic file uploader use streaming encryption
jagerman Apr 1, 2026
211be88
update session-router/libquic to fix send_fin bug
jagerman Apr 1, 2026
25f2991
Add -Werror=missing-declarations; fix issues it caught.
jagerman Apr 8, 2026
b46b88f
QUIC file transfer improvements: progress, ready-gating; MTU config
jagerman Apr 8, 2026
ba90d7c
unsigned char -> std::byte refactor, part 2: b32
jagerman Mar 27, 2026
7662405
unsigned char -> std::byte refactor, part 3: crypto API reorganization
jagerman Apr 8, 2026
c9b2394
Merge conflicts
jagerman Apr 9, 2026
6e6ddbd
Add generic fmt::formatter for std::byte spans
jagerman Apr 9, 2026
414b5ff
std::byte refactor: cleanup, formatting, and API improvements
jagerman Apr 10, 2026
6559d36
std::byte refactor: final reformatting
jagerman Apr 10, 2026
8ed0b89
Bump session-sqlite submodule to avoid undeclared oxenc dep
jagerman Jul 6, 2026
c3e294f
formatting
jagerman Jul 6, 2026
911d474
Bump session-sqlite
jagerman Jul 8, 2026
2bcd8e9
Bump session-deps
jagerman Jul 8, 2026
4347851
Bump session-router
jagerman Jul 8, 2026
ab36475
Parse JSON from a char view rather than a byte range
jagerman Jul 8, 2026
a66aed3
Link simdutf, nlohmann_json and network into their targets
jagerman Jul 8, 2026
707c3f3
Drive all LTO from USE_LTO; use bundled fmt/spdlog for static builds
jagerman Jul 8, 2026
4955a49
Miscellaneous build and compatibility fixes
jagerman Jul 8, 2026
2c1c46e
Fix endian byte-swap in hash::detail::make_hashable big-endian path
jagerman Jul 16, 2026
f184204
formatting
jagerman Jul 17, 2026
5ddcc1c
Fix quic linking
jagerman Jul 17, 2026
e80c69c
Fix compilation with session-router is disabled
jagerman Jul 17, 2026
fadbd49
Build fixes: fmt/spdlog linking, oxen-logging/oxen::quic resolution, …
jagerman Jul 18, 2026
8fd230d
Add clarifying comment that swarm is preshuffled
jagerman Jul 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Cpp11BracedListStyle: 'true'
KeepEmptyLinesAtTheStartOfBlocks: 'true'
NamespaceIndentation: Inner
CompactNamespaces: 'true'
PenaltyBreakString: '3'
PenaltyBreakString: '1000'
SpaceBeforeParens: ControlStatements
SpacesInAngles: 'false'
SpacesInContainerLiterals: 'false'
Expand Down
31 changes: 30 additions & 1 deletion .drone.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,21 @@ local windows_cross_pipeline(name,
}] else [])
);

local live_test_step(image, mode) = {
name: 'live tests (' + mode + ')',
image: image,
pull: 'always',
commands:
[apt_get_quiet + ' install -y eatmydata'] +
add_stf_repo(image) + [
'eatmydata ' + apt_get_quiet + ' update',
'eatmydata ' + apt_get_quiet + ' dist-upgrade -y',
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y ' + std.join(' ', default_test_deps),
'cd build',
'./tests/testLive --' + mode + ' --log-level warning --colour-mode ansi -d yes "[file]"',
],
};

local clang(version) = debian_build(
'Debian sid/clang-' + version,
docker_base + 'debian-sid-clang',
Expand Down Expand Up @@ -351,6 +366,20 @@ local static_build(name,

// Various debian builds
debian_build('Debian sid', docker_base + 'debian-sid'),

// Debian sid with session-router + live file transfer tests
local live_image = docker_base + 'debian-sid';
debian_build(
'Debian sid (live tests)',
live_image,
cmake_extra='-DENABLE_NETWORKING=ON -DENABLE_NETWORKING_SROUTER=ON -DBUILD_LIVE_TESTS=ON',
) + {
steps: super.steps + [
live_test_step(live_image, 'onionreq'),
live_test_step(live_image, 'srouter'),
live_test_step(live_image, 'direct'),
],
},
debian_build('Debian sid/Debug', docker_base + 'debian-sid', build_type='Debug'),
debian_build('Debian testing', docker_base + 'debian-testing'),
clang(19),
Expand All @@ -365,7 +394,7 @@ local static_build(name,
debian_build('Debian stable (armhf)', docker_base + 'debian-stable/arm32v7', arch='arm64', jobs=4),

// Macos builds:
mac_builder('macOS Intel (Release)', allow_test_fail=true/*the current intel mac has issues*/),
//mac_builder('macOS Intel (Release)', allow_test_fail=true/*the current intel mac has issues*/),
mac_builder('macOS Arm64 (Release)', arch='arm64'),
mac_builder('macOS Arm64 (Debug)', arch='arm64', build_type='Debug'),

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/build*/
/compile_commands.json
/.cache/
/.claude/
/.vscode/
.DS_STORE
15 changes: 6 additions & 9 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
[submodule "external/libsodium-internal"]
path = external/libsodium-internal
url = https://github.com/session-foundation/libsodium-internal.git
[submodule "tests/Catch2"]
path = tests/Catch2
url = https://github.com/catchorg/Catch2
[submodule "external/ios-cmake"]
path = external/ios-cmake
url = https://github.com/leetal/ios-cmake
[submodule "external/zstd"]
path = external/zstd
url = https://github.com/facebook/zstd.git
[submodule "external/protobuf"]
path = external/protobuf
url = https://github.com/protocolbuffers/protobuf.git
[submodule "external/session-router"]
path = external/session-router
url = https://github.com/session-foundation/session-router.git
[submodule "external/simdutf"]
path = external/simdutf
url = https://github.com/simdutf/simdutf.git
[submodule "external/session-sqlite"]
path = external/session-sqlite
url = https://github.com/session-foundation/session-sqlite.git
[submodule "external/date"]
path = external/date
url = https://github.com/HowardHinnant/date.git
[submodule "cmake/session-deps"]
path = cmake/session-deps
url = https://github.com/session-foundation/session-deps.git
79 changes: 79 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Build Commands

```bash
# Configure (out-of-source build required)
cmake -G Ninja -S . -B build-claude

# Build
cmake --build build-claude --parallel --verbose

# Run tests
./build-claude/tests/testAll [test-tag-or-name]

# Regenerate protobuf files
cmake --build build-claude --target regen-protobuf --parallel
```

### Notable CMake Options

- `-DBUILD_STATIC_DEPS=ON` — force all deps to build statically (no system libs)
- `-DENABLE_ONIONREQ=ON/OFF` — include onion request / network functionality (default ON)
- `-DWARNINGS_AS_ERRORS=ON` — treat warnings as errors
- `-DSUBMODULE_CHECK=OFF` — skip submodule freshness checks (useful during dev)

## Architecture Overview

This is **libsession-util**, the C++20 utility library for Session clients. It provides:

1. **Cryptographic primitives** (`libsession::crypto`) — Ed25519/X25519 keys, blinding, hashing, encryption (session protocol, multi-encrypt, attachments), XEd25519 signatures.

2. **Config sync system** (`libsession::config`) — CRDT-style distributed config that syncs across Session devices via swarm storage. Each config type has a namespace:
- `UserProfile`, `Contacts`, `ConvoInfoVolatile`, `UserGroups` — per-user configs
- `GroupKeys`, `GroupInfo`, `GroupMembers` — shared group configs (closed groups)
- `Local` — device-local config (never pushed to swarm)
- Config messages use bt-encoding (bencode), seqno-based CRDT merge with deterministic tie-breaking. See `docs/api/docs/config_merge_logic.md` for protocol details.

3. **Core** (`libsession::core`) — Persistent client state backed by SQLite. The `Core` class owns `CoreComponent`-derived members (`Globals`, `Devices`, `Pro`) that share a connection pool. Migrations live in `src/core/schema/` as `NNN_name.sql` or `NNN_name.cpp` files.

4. **Onion requests** (`libsession::onionreq`, optional) — Builder/parser for onion-routed requests to the Session network.

### Library Targets and Dependencies

```
util ← file, logging, util (uses zstd, simdutf)
crypto ← util + libsodium (blinding, ed25519, session_encrypt, etc.)
config ← crypto + libsodium + protos (all config types)
core ← crypto + SQLite + mlkem768 (PQC key encapsulation)
onionreq ← crypto + quic + nettle (optional)
```

All targets are aliased as `libsession::util`, `libsession::crypto`, etc.

### Header Layout

Public headers are in `include/session/`:
- `include/session/config/` — config type headers (`.h` = C API, `.hpp` = C++ API)
- `include/session/config/groups/` — closed group configs (keys, info, members)
- `include/session/core/` — Core persistent state components
- `include/session/onionreq/` — onion request types

### Dependency System

Dependencies are managed via `cmake/session-deps/` which provides `session_dep()` and `session_dep_or_submodule()` macros. These first try system libraries; if not found they fall back to static builds. External submodules live in `external/` (oxen-logging, nlohmann-json, ios-cmake, protobuf, oxen-libquic).

### Tests

Tests use Catch2. Most tests are compiled into `testAll`; logging tests are isolated in `testLogging` because they modify global sink/level state. Filter tests with Catch2 tag syntax, e.g. `./Build/tests/testAll "[config]"`.

### Dual C/C++ API

Many headers come in pairs: `foo.h` (C API for FFI use) and `foo.hpp` (C++ API). The C API generally is a wrapper around the primary C++ API. When adding new public functionality, consider whether a C API is needed.

## Code Style

- **Prefer DRY code**: when logic is duplicated across two or more call sites, extract a shared helper. Do this proactively when writing new code, not only when asked.
- **Specify the shape upfront**: when asked to implement something that overlaps with existing code, identify and extract the shared piece before writing the new code, so duplication never appears in the first place.
55 changes: 33 additions & 22 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,17 @@ else()
set(static_default ON)
endif()

option(BUILD_STATIC_DEPS "Build all dependencies statically rather than trying to link to them on the system" ${static_default})
option(STATIC_BUNDLE "Build a single static .a containing everything (both code and dependencies)" ${static_default})
# Override the default OFF value set in cmake/session-deps/Deps.cmake so that BUILD_STATIC_DEPS
# defaults to the same value as BUILD_SHARED_LIBS (i.e. static by default).
set(BUILD_STATIC_DEPS ${static_default} CACHE BOOL "Build all dependencies statically rather than trying to link to them on the system")

include(cmake/session-deps/Deps.cmake)

option(STATIC_BUNDLE "Build a single static .a containing everything (both code and dependencies)" ${BUILD_STATIC_DEPS})

if(STATIC_BUNDLE AND NOT BUILD_STATIC_DEPS)
message(FATAL_ERROR "STATIC_BUNDLE requires BUILD_STATIC_DEPS to be enabled")
endif()

if(BUILD_SHARED_LIBS OR libsession_IS_TOPLEVEL_PROJECT)
set(install_default ON)
Expand All @@ -76,14 +85,13 @@ else()
endif()

option(WARNINGS_AS_ERRORS "Treat all compiler warnings as errors" OFF)
option(FATAL_MISSING_DECLARATIONS "Developer/CI option: fatal error on non-static definitions without prior declarations (-Werror=missing-declarations)" OFF)

option(STATIC_LIBSTD "Statically link libstdc++/libgcc" ${default_static_libstd})

option(USE_LTO "Use Link-Time Optimization" ${use_lto_default})

# Provide this as an option for now because GMP and Desktop are sometimes unhappy with each other.
option(ENABLE_NETWORKING "Build with networking functionality" ON)
option(ENABLE_NETWORKING_SROUTER "Build with session-router networking support (requires ENABLE_NETWORKING)" ON)
option(ENABLE_NETWORKING_SROUTER "Build with session-router networking support" ON)

if(USE_LTO)
include(CheckIPOSupported)
Expand All @@ -102,6 +110,17 @@ if(IPO_ENABLED AND NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()

# USE_LTO is the single LTO knob. Two submodule-provided options default ON independently of it:
# SESSIONDEPS_LTO (session-deps, several copies sharing one cache variable) controls LTO for static
# dependency builds, and WITH_LTO (session-router's enable_lto.cmake) controls LTO for session-router's
# own targets. Leaving either ON in a non-LTO build breaks the link: LTO'd static archives can't be
# consumed by a non-LTO link -- clang in particular emits pure bitcode archives that a plain bfd link
# reports as "file format not recognized", or silently drops the members (undefined references). Force
# both to follow USE_LTO, seeding these shared cache variables before any submodule evaluates its own
# option() so there is exactly one LTO switch.
set(SESSIONDEPS_LTO ${USE_LTO} CACHE BOOL "Use LTO for static dependency builds, where supported" FORCE)
set(WITH_LTO ${USE_LTO} CACHE BOOL "enable lto on compile time" FORCE)

if(STATIC_LIBSTD)
add_link_options(-static-libstdc++)
if(NOT CMAKE_CXX_COMPILER_ID MATCHES Clang)
Expand All @@ -117,30 +136,22 @@ include(AddStaticBundleLib)
# Always build PIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# For a static-deps build we build everything from source; don't let oxen-logging pick up system
# fmt/spdlog via find_package. Beyond the usual reasons to prefer our own versions, a system
# fmt/spdlog is built against libstdc++ and cannot be linked into a libc++ build (undefined
# std::__1 symbols), so force the bundled submodules which build with our toolchain.
if(BUILD_STATIC_DEPS)
set(OXEN_LOGGING_FORCE_SUBMODULES ON CACHE INTERNAL "")
endif()


add_subdirectory(external)

if(ENABLE_NETWORKING)
if(NOT TARGET nettle::nettle)
if(BUILD_STATIC_DEPS)
message(FATAL_ERROR "Internal error: nettle::nettle target (expected via libquic BUILD_STATIC_DEPS) not found")
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(NETTLE REQUIRED IMPORTED_TARGET nettle)
add_library(nettle INTERFACE)
target_link_libraries(nettle INTERFACE PkgConfig::NETTLE)
add_library(nettle::nettle ALIAS nettle)
endif()
endif()
endif()
session_dep(nettle 3)

add_subdirectory(src)
add_subdirectory(proto)

if (BUILD_STATIC_DEPS)
include(StaticBuild)
endif()

if(STATIC_BUNDLE)

include(combine_archives)
Expand Down
Loading