
P2P, 종단 간 암호화 채팅. 받은편지함 없음. 복구할 계정 없음. 아무도 듣지 않습니다 — 우리조차도요.
메시지는 libp2p를 통해 피어 간에 직접 전송되며, 기기를 떠나기 전에 Signal 스타일의 Olm/Megolm 프로토콜(vodozemac을 통해)로 암호화됩니다. 관여하는 유일한 서버는 피어가 서로의 현재 주소를 찾도록 도와주는 작은 디렉터리입니다. 이 서버는 메시지 내용을 절대 볼 수 없으며, 한 번의 명령으로 제거할 수 있습니다.
실제로 무엇으로부터 보호되는지와 그 방법은 docs/THREAT_MODEL.md 및 docs/SECURITY.md를 참조하세요.
첫 실행 — 이름을 정하세요. 설정할 것은 그것뿐입니다.
대화 — 그룹 레일, 연락처 목록, 종단 간 암호화된 채팅 창.
설정 — 마이크 감도, 푸시 투 토크, 로그인 시 실행, 네트워크 연결 가능 여부.
crates/directory-server)는 사용자 ID를 현재 네트워크 주소에 매핑할 뿐 그 이상은 하지 않습니다. 구조적으로 메시지 내용을 읽을 수 없습니다. Cargo.toml은 그 방법을 아는 크레이트조차 의존하지 않습니다.이 앱에는 두 종류의 신원이 있으며, 의도적으로 분리되어 있습니다:
identity::Identity). 공개 "사용자 ID"는 그 키의 지문일 뿐입니다(wire_proto::user_id_from_ed25519). 생성에 서버가 관여하지 않기 때문에 어떤 서버도 이를 발급하거나 취소할 수 없습니다.PeerId)입니다. 재시작 후에도 변경될 수 있으며 채팅 신원에는 전혀 영향을 주지 않습니다. 둘은 사용자가 직접 서명한 프레즌스 레코드로만 묶여 있습니다.누군가를 찾는 것과 실제로 대화하는 것은 서로 다른 두 단계입니다:``` ┌────────────────────────┐ │ directory server │ │ (axum + one SQLite │ │ file: users, │ │ presence, group │ │ rosters. Never │ │ message content.) │ └─────────┬───────────────┘ 1. "where is bob │ 2. "here's my current right now?" │ address" (signed, │ expires in minutes) ┌─────────┴───────────────┐ ▼ ▼ ┌───────┐ 3. direct libp2p ┌───────┐ │ alice │◄──── connection ────►│ bob │ └───────┘ (Noise + Olm/ └───────┘ Megolm encrypted)
1. Alice는 디렉터리에서 Bob의 사용자 ID로 그를 찾는다. 그러면 Bob의
공개 키와 마지막으로 알린 네트워크 주소가 반환된다. 디렉터리가
보관하는 것은 그것이 전부다: 공개 키, 표시 이름, 그룹
멤버십 목록, 그리고 수명이 짧은 주소 알림
(`crates/directory-server`).
2. Alice는 libp2p(QUIC 또는 TCP+Noise, NAT 뒤에 있는 피어를 위한 릴레이 +
홀 펀칭 지원; `crates/net` 참조)를 통해 Bob에게 직접 연결한다.
디렉터리는 이 시점부터 완전히 관여하지 않는다.
3. 실제 메시지는 libp2p 연결에 올려지기 전에 1:1 채팅용 **Olm** 또는
그룹용 **Megolm**(`crates/crypto-session`)으로 암호화된다. 이는
모든 메시지가 고유한 키를 갖는 Double-Ratchet 방식의 기법이다.
서버 측 받은편지함은 없다: Bob이 오프라인이면 메시지는 로컬에서
대기하고 재시도되며, 다른 누군가의 인프라에 저장되지 않는다.
위의 모든 것은 Tauri 앱의 Rust 백엔드(`apps/desktop/src-tauri`)가 실제로
호출하는 `crates/core`의 `AppService`에 의해 조율된다. UI는
네트워크와 직접 통신하지 않는다.