No description
Find a file
Niko Marmeladkov 48143cdbf5 Allocate: deduplicate by pubkey, GetByPubKey: return latest
Allocate now checks if pubkey already has an identity and returns it. Prevents duplicate identities for same pubkey (was causing random number assignment on cert auth). GetByPubKey returns identity with highest CreatedAt for deterministic behavior.
2026-07-01 15:41:00 +03:00
cmd/qccd Initial commit: QuiC Call server 2026-06-30 12:52:09 +03:00
internal Allocate: deduplicate by pubkey, GetByPubKey: return latest 2026-07-01 15:41:00 +03:00
mobile Fix missing ALPN NextProtos for QUIC handshake 2026-06-30 13:43:54 +03:00
pkg/types Add debug log to HandleDial, remove OpRegister 2026-07-01 15:08:23 +03:00
.gitignore Initial commit: QuiC Call server 2026-06-30 12:52:09 +03:00
config.yaml.example Initial commit: QuiC Call server 2026-06-30 12:52:09 +03:00
go.mod Fix missing ALPN NextProtos for QUIC handshake 2026-06-30 13:43:54 +03:00
go.sum Fix missing ALPN NextProtos for QUIC handshake 2026-06-30 13:43:54 +03:00
LICENSE Initial commit: QuiC Call server 2026-06-30 12:52:09 +03:00
main.go Initial commit: QuiC Call server 2026-06-30 12:52:09 +03:00
README.md Initial commit: QuiC Call server 2026-06-30 12:52:09 +03:00

QuiC Call

A server for audio/video calls between people. A family phone system replacement.

No WebRTC. No STUN/TURN. Everything goes through the server.

How it works

  1. Client connects via QUIC (TLS + ACME Let's Encrypt)
  2. Server sends a PoW (Hashcash) challenge
  3. Client solves it, sends solution with their Ed25519 public key
  4. Server allocates a phone number (+0 XXX YYY ZZZ), issues an X.509 certificate proving ownership
  5. Client can re-roll the number once per 24h
  6. To call someone, dial their number — server relays media blindly (E2EE)

Architecture

  • Transport: QUIC (hysteria fork of quic-go) over UDP
  • TLS: Automatic via certmagic + Cloudflare DNS-01 (ACME)
  • Auth: Proof-of-Work (Hashcash SHA-256), no passwords
  • PKI: Ed25519 CA, X.509 client certs with phone number as CN
  • DB: Custom append-only frame-based engine with AES-256-GCM at-rest encryption (hash-chain integrity)
  • Signaling: Binary varint frames over QUIC streams
  • Media relay: Unreliable QUIC datagrams, server forwards blindly
  • Congestion control: Brutal (CBR) from Hysteria
  • E2EE: X25519 + HKDF + ChaCha20-Poly1305 (key exchange during signaling)

Status

Pre-alpha. Server compiles and passes vet. No client application exists yet.

Quick start

# Build
go build -o qccd ./cmd/qccd

# Configure
cp config.yaml.example config.yaml
# edit config.yaml — set ACME domains, email, Cloudflare API token

# Run
./qccd server

Configuration

See config.yaml.example.

Key options:

Field Default Description
server.listen :1963 UDP listen address
pow.difficulty 22 PoW leading zero bits
identity.cooldown 24h Minimum time between number re-rolls
identity.prefix +0 Phone number prefix
ca.key_type ed25519 CA key type
relay.bandwidth_up 100 mbps Media relay upstream bandwidth

Dependencies

  • github.com/apernet/quic-go — QUIC transport (Hysteria fork)
  • github.com/caddyserver/certmagic + github.com/libdns/cloudflare — ACME TLS
  • golang.org/x/crypto — X25519, ChaCha20-Poly1305, HKDF

License

AGPL-3.0-only