Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rust Peergos client

A native Rust implementation of the Peergos client — a port of the Java reference client that speaks the same wire protocol and is validated end-to-end against a live Peergos server and against the Java client for interop.

Peergos is a peer-to-peer, end-to-end encrypted file storage and social platform. Its security model is a cryptree: every file and directory is a tree of symmetric-key–encrypted nodes, addressed and shared by capability rather than by ACL, so the server stores only opaque encrypted blocks and never sees plaintext, filenames, or the directory structure. This crate reimplements that client stack in Rust with no plaintext or key material ever leaving the process unencrypted.

Status: functional and exercised against a real server, but pre-1.0. The public API is still evolving.

Architecture

Crate Responsibility
peergos-crypto Cryptographic primitives: NaCl (Ed25519 signing, box/secretbox) and the hybrid post-quantum key exchange (X25519 + ML-KEM).
peergos-cbor A byte-exact CBOR codec whose map ordering and integer encoding match the Java client bit-for-bit (required for content-addressing and signatures).
peergos-multiformats CIDv1 / multihash / multibase encoding and the base58/base32 alphabets Peergos uses.
peergos-core The network layer: the content-addressed block store client, mutable pointers (signed CAS), the CHAMP hash-array-mapped-trie, the buffered-write network decorator, and direct-to-S3 block access.
peergos-fs The cryptree filesystem: files and directories, capabilities, sharing and revocation, social features, email, publishing, upload transactions, and the ergonomic FileWrapper / UserContext handles.
peergos-sync Bidirectional local ↔ remote directory sync, mirroring the Java DirectorySync: content-hashed state diffing, batched transfers, and optional deletion propagation.
peergos-cli The interactive peergos-shell — a login (or secret-link) session with remote and local working directories and the same command set as the Java shell.
peergos-mock-server An in-process Peergos server used to drive the end-to-end tests without a live backend.

What it does

  • Accounts — post-quantum sign-up, sign-in, and MFA/TOTP second factors.
  • Files & directories — create, read, write, delete, move, rename; multi-chunk files streamed with bounded memory; directory listing with chunked children.
  • Capabilities & sharing — read and write sharing of files and directories with other users, capability caches, nested sharing, and access revocation via key rotation.
  • Secret links — create and resolve password-protected shareable links.
  • Social — follow requests, friends/followers groups, a social feed with posts, comments and media, and per-user profiles.
  • Email — an end-to-end encrypted email bridge: encrypt, outbox, inbox and sent folders over the Peergos email protocol.
  • Sync — bidirectional local ↔ remote directory sync with content-hashed change detection, batched transfers, and optional deletion propagation.
  • Interactive shellpeergos-shell, a login or secret-link session with paired remote/local working directories and the same commands as the Java CLI.
  • Publishing — make files public and serve a website through the Peergos gateway.
  • Efficient reads — the server-side champ/get lookup returns a whole tree path in one round-trip, and every returned block is re-hashed and re-resolved locally so a malicious or faulty server cannot forge results.
  • Caching — a block cache plus a decrypted-cryptree-node cache keyed by the content-addressed tree root (so entries can never go stale).
  • Random access — read or overwrite an arbitrary byte range of a file, touching only the chunks that overlap the range rather than the whole file.
  • Crash-safe/resumable uploads — large uploads commit chunk-by-chunk through a transaction record, and re-uploading the same content automatically resumes an interrupted upload from the first missing chunk.

Getting started

Toolchain

A recent stable Rust via rustup is required (some dependencies declare edition2024, which older distro rustc cannot parse). Ensure ~/.cargo/bin is on your PATH so rust-toolchain.toml is honoured:

export PATH="$HOME/.cargo/bin:$PATH"

Build & test

cargo build --workspace
cargo test  --workspace

Running against a server

The examples talk to a Peergos server (default http://localhost:7777/). Point one up locally, then run any example under crates/peergos-fs/examples/:

# sign in / up, create a home dir, upload and read back a file
cargo run -p peergos-fs --example context -- http://localhost:7777/

# ranged read + in-place ranged overwrite of a multi-chunk file
cargo run -p peergos-fs --example file_section -- http://localhost:7777/

# interrupt a large upload, then auto-resume it by re-uploading the same bytes
cargo run -p peergos-fs --example resume_upload -- http://localhost:7777/

There are runnable examples for most features — sharing, revocation, secret links, social/feed, publishing, the buffered network, upload transactions, and more.

Interactive shell

peergos-shell mirrors the Java peergos.server.cli: a login (or secret-link) session with a remote and a local working directory, and commands such as ls/lls, get/put, mkdir, rm, cd/lcd, pwd/lpwd, space, follow, share_read, share_write, link, and passwd, with command history and line editing.

# log in and drop into the shell
cargo run -p peergos-cli -- --server http://localhost:7777/ --username alice

# cache the session to ~/.peergos-shell/session.cbor so later runs skip login
cargo run -p peergos-cli -- --username alice --stay-logged-in

# open the shell over a set of secret links, each mounted at its true path
cargo run -p peergos-cli -- --links LINK1,LINK2

Using it as a library

UserContext is the top-level handle; FileWrapper is an ergonomic file/directory handle in the spirit of the Java client:

let ctx  = UserContext::sign_in("alice", "password", None, poster, store, mutable).await?;
let home = ctx.get_home().await?;

let dir  = home.mkdir("documents").await?;
let file = dir.upload("notes.txt", b"hello peergos").await?;
assert_eq!(file.read().await?, b"hello peergos");

// read/overwrite a byte range without fetching the whole file
let head = file.read_section(0, 5).await?;
file.overwrite_section(6, b"world").await?;

Design notes

A few places where the port mirrors specific behaviours of the reference client:

  • Verified reads. Directory and file reads use the server's champ/get/champ/get/bulk API for one-round-trip lookups, but the returned blocks are loaded into a local store under their recomputed CIDs and the lookup is re-run locally — so every hash is verified client-side and the server is never trusted.
  • Buffered network. A decorator buffers block writes and pointer updates, flushes them in bulk (grouped into cbor / small-raw / large-raw batches with bounded concurrency), and resolves concurrent-modification conflicts with a node-level three-way CHAMP merge that touches only the changed path.
  • Cryptree cache. Decrypted nodes are cached by (tree root, map key); because the key includes the content-addressed root, a write produces a new root and stale entries simply miss. After a write the cache migrates unchanged siblings forward.
  • Content-addressed resume. Uploads are keyed by their content hash tree, so an interrupted upload resumes from the first absent chunk when the same bytes are uploaded again.

Licence

AGPL-3.0-or-later. See Licence.txt.

About

A rust implementation of the Peergos client

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages