permissionlesstech/bitchat · 언어 Swift 5.9(iOS 16+ / macOS 13+) · 소스 ~62,000줄·200+ 모듈 · 테스트 181개 파일 · 이중 전송 BLE 메시 + Nostr · 암호화 Noise XX/X · secp256k1 · Tor Arti(Rust) 내장 · ★ 27.1k · fork 3.3k · 라이선스 Unlicense(퍼블릭 도메인) · 백서 v2.0(2026-07-06) · shallow clone 소스 직접 분석)
우리가 쓰는 모든 메신저 — 카카오톡, 텔레그램, 시그널 — 는 공통점이 하나 있다. 중앙 서버를 반드시 거친다는 것. 내 메시지는 항상 어느 회사의 데이터센터를 통과해 상대에게 간다. 그래서 인터넷이 끊기면, 통신사가 막으면, 정부가 차단하면 — 대화도 멈춘다. bitchat은 이 전제를 통째로 뒤집는다: 메시지가 서버를 거치지 않고, 옆에 있는 기기들을 징검다리 삼아 흘러간다.
보통 메신저는 "우체국에 편지를 맡기는 것"이다 — 중앙(우체국)이 없으면 아무것도 못 보낸다. bitchat은 "손에서 손으로 쪽지를 넘기는 것"이다. 내 폰이 옆 폰에게, 그 폰이 또 다음 폰에게 — 참여한 기기들 자체가 배달망이 된다. 쪽지는 봉인(암호화)돼 있어 중간에서 전달해 준 사람들은 내용을 못 읽고, 받을 사람에게 닿으면 그 사람만 열 수 있다.
bitchat이 하는 일을 순서로 풀면 이렇다. ① 근처 기기를 블루투스로 자동 발견하고 → ② 서로 암호화 세션을 맺은 뒤 → ③ 메시지를 봉인해 controlled flood(통제된 확산)로 뿌리면 → ④ 중간 기기들이 내용을 못 본 채 릴레이하고 → ⑤ 인터넷이 있으면 멀리 있는 사람에겐 Nostr 릴레이로 다리를 놓아준다. 받을 사람이 지금 없으면? 누군가의 폰에 봉인된 채 실려 다니다가 나중에 만나면 전해진다.
이름의 유래도 성격을 드러낸다. permissionlesstech — "허가가 필요 없는 기술". 누구의 승인도, 가입도, 신원 확인도 없이 그냥 앱을 켜면 곧바로 통신망의 일원이 된다. README의 표현을 빌리면 "the side-groupchat" — 공식 채널 옆에서 조용히 도는 곁가지 단톡방이다.
bitchat은 2025년 7월 공개된 뒤 ★27,000+를 모았고, 2026년 7월 백서 v2.0이 나오며 다시 트렌딩에 올랐다. 인기의 뿌리는 단순한 기능이 아니라 "이런 게 정말 되는구나"라는 개념 자체의 힘이다. 대부분의 앱이 "더 편한 중앙화"를 향할 때, bitchat은 정반대로 "중앙이 아예 없는" 극단을 실제 동작하는 코드로 증명했다.
시그널·텔레그램도 종단간 암호화는 하지만, 인터넷이 있어야만 한다. bitchat의 BLE 메시는 인터넷이 완전히 없어도 동작한다. 통신망이 마비된 재난 지역, 신호가 끊긴 지하·산악, 통신이 차단된 시위 현장 — 이런 "인프라 공백" 시나리오가 정확히 bitchat의 무대다. README가 첫 문장부터 "with or without the internet"을 강조하는 이유다.
bitchat의 진짜 영리함은 이중 전송(dual transport)에 있다. 가까우면 블루투스(무료·오프라인), 멀면 Nostr(인터넷 릴레이) — 이 둘을 MessageRouter가 알아서 고른다. 라이브 메시 링크가 있으면 그걸 우선하고, 없으면 Nostr로 폴백하고, 둘 다 안 되면 택배원 시스템에 맡겨 나중을 기약한다. 사용자는 어느 길로 갔는지 신경 쓸 필요가 없다.
| 전송로 | 범위 | 인터넷 | 쓰임새 |
|---|---|---|---|
| BLE 메시 | 블루투스 도달거리 × 최대 7홉 | 불필요 | 오프라인·재난·시위·오지의 근거리 통신 |
| Nostr | 전 세계(290+ 릴레이) | 필요 | 멀리 있는 상호 즐겨찾기와의 사설 메시지, 지역 채널 |
| 택배원(courier) | 사람의 물리적 이동 | 불필요 | 지금 못 닿는 상대에게 "나중에" 전달(store-and-forward) |
계정이 없으니 수집할 개인정보 자체가 없다. 신원은 전화번호가 아니라 암호 키(cryptographic key)다. 평문 메시지는 디스크에 절대 기록되지 않고, 저장되는 건 봉인된 암호문이거나 이미 공개된 방송 트래픽뿐이며, 이마저도 패닉 와이프(3번 탭) 한 번에 전부 사라진다. Nostr 트래픽은 Tor로 흘려보낼 수도 있다.
재난·검열에 강한 회복탄력성(오프라인 메시), 중앙이 없다는 철학적 매력(계정·서버 zero), 그리고 뜯어볼수록 촘촘한 암호·네트워크 엔지니어링(Noise·Nostr·Tor·DTN) — 이 셋이 한 앱에 들어있다. 게다가 코드는 퍼블릭 도메인(Unlicense)이라 누구나 통째로 베껴 만들어도 된다. "쓸모"와 "낭만"과 "교재"를 동시에 갖춘 드문 프로젝트다.
bitchat은 웹앱이 아니라 iOS·macOS 네이티브 앱이다. 그래서 스택의 밑바닥이 자바스크립트가 아니라 Swift + Apple 프레임워크다. 화면(SwiftUI) 위에, 근거리무선(CoreBluetooth), 암호(Noise·secp256k1), 인터넷 분산 프로토콜(Nostr), 익명 라우팅(Tor)이 층층이 얹힌 구조다.
| 레이어 | 기술 | 역할 |
|---|---|---|
| 언어/런타임 | Swift 5.9 (iOS 16+ / macOS 13+) | 단일 코드베이스로 두 플랫폼 동시 지원(Universal App) |
| UI | SwiftUI + Combine | 선언형 화면 · ViewModels/의 30여 코디네이터가 상태 관리 |
| 근거리무선 | CoreBluetooth (BLE) | 각 기기가 동시에 GATT central+peripheral — 스캔·광고·릴레이 |
| 키 보관 | Keychain | Curve25519 정적키 · Ed25519 서명키를 안전 저장 |
| 패키징 | Swift Package Manager | Package.swift · 로컬 패키지 3개 + 외부 1개 |
| 구성 | 기술 | 역할 |
|---|---|---|
| 라이브 세션 | Noise XX | 연결된 두 피어 간 상호인증 + 순방향 비밀성(forward secrecy) |
| 암호 스위트 | Curve25519 / ChaCha20-Poly1305 / SHA-256 | 키 합의 · 대칭 암호 · 해시 (Noise 표준 조합) |
| 오프라인 봉인 | Noise X (일방향) | 택배 봉투를 수신자 정적키로 봉인(단, 순방향 비밀성 없음) |
| Nostr 키 | swift-secp256k1 (0.21.1) | Nostr 신원(secp256k1 키쌍) · NIP-17 암호화 |
XX, X 같은 패턴 이름이 "누가 먼저 키를 보여주고, 몇 번 주고받는지"를 정한다. XX는 양쪽이 서로를 인증하는 대화형 핸드셰이크(라이브 연결용), X는 상대가 없어도 상대의 공개키만으로 봉인하는 일방향(택배용)이다.| 구성 | 기술 | 역할 |
|---|---|---|
| 분산 릴레이 | Nostr (NIP-17 / NIP-59) | 290+ 공개 릴레이로 사설 메시지·지역 채널 전송 |
| 메시지 은닉 | Gift-wrap (kind 1059) | rumor→seal→gift-wrap 3중 포장 — 릴레이도 발신자·내용 모름 |
| 위치 채널 | Geohash | 지오해시 좌표로 "이 동네" 공개 채팅방을 구성 |
| 익명 라우팅 | Arti (Rust Tor) | Nostr 트래픽을 Tor로 흘려 메타데이터까지 은닉 · localPackages/Arti |
bitchat의 스택은 "교통수단 3종 세트"다. 블루투스 메시는 자전거(가깝고, 연료·인프라 필요 없음), Nostr는 국제선 비행기(멀리 가지만 공항=인터넷이 필요), Tor는 그 비행기의 차창 블라인드(누가 탔는지 안 보이게)다. 그리고 택배원 시스템은 "지나가는 사람 편에 부치는 소포" — 정기편이 없을 때 물리적 이동에 얹어 보낸다.
본체와 별도로 localPackages/에 재사용 모듈 3개를 분리해 뒀다. Arti(Rust로 짠 Tor 구현을 .xcframework로 감싼 것 — iOS/macOS 바이너리 포함), BitFoundation(공용 타입·유틸), BitLogger(로깅). 외부 의존성은 사실상 swift-secp256k1 하나뿐이라, 공급망 위험을 최소화한다.
bitchat 아키텍처의 모든 질문은 하나로 모인다: "중앙이 없는데 어떻게 배달이 보장되는가?" 답은 네 겹의 안전망이다. 근거리는 메시가 확산으로 잇고, 원거리는 Nostr가 잇고, 지금 못 닿으면 택배원이 나중에 나르고, 공개 대화는 가십 동기화로 뒤늦게 합류한 사람에게도 복원된다.
핵심은 Transport라는 공통 인터페이스다. BLE와 Nostr가 같은 프로토콜을 구현하고, MessageRouter는 구체적 전송로를 몰라도 "보내라"고만 지시한다. 덕분에 나중에 새 전송로(예: Wi-Fi Aware)를 추가해도 라우터는 안 바뀐다. 소스의 Services/Transport.swift가 이 추상 경계다.
근거리 배달의 심장이다. 메시지를 받은 노드는 무작정 다시 뿌리지 않는다. 그랬다간 브로드캐스트 폭풍(broadcast storm)으로 배터리와 대역폭이 순식간에 고갈된다. bitchat은 TTL·중복제거·지터·팬아웃 서브셋 네 장치로 확산을 정교하게 조인다.
이 설계의 묘미는 "모두가 다 뿌리면 낭비, 아무도 안 뿌리면 단절" 사이의 균형이다. 지터를 두면 근처 여러 노드 중 한 대만 먼저 릴레이하고 나머지는 "어, 벌써 갔네" 하고 자기 예약을 취소한다. 방송 메시지는 모든 링크가 아니라 메시지 ID로 결정되는 부분집합(~log₂)에만 보내, 밀집 구간에서 폭증을 막는다. 반면 핸드셰이크·사설 메시지 같은 지정 트래픽은 서브셋 없이 확실히 TTL−1로 전달한다.
연결된 두 피어는 Noise XX 핸드셰이크로 세션을 맺는다. 이후 모든 사설 페이로드(메시지·전달확인·읽음확인)는 이 세션 안에서 타입 있는 암호문(typed ciphertext)으로 흐른다. 중간 릴레이 노드가 보는 건 오직 noiseEncrypted라는 불투명한 봉투뿐 — 발신자·수신자·내용 어느 것도 알 수 없다. 게다가 패킷은 256/512/1024/2048바이트 블록으로 패딩되어, 길이만으로 내용을 추측하는 것도 막는다.
이 프로젝트에서 가장 독창적인 부분이다. 수신자가 지금 범위 안에 없을 때, bitchat은 포기하지 않고 네 가지 방법으로 "나중 배달"을 시도한다. 그중 압권이 택배원(courier) 시스템이다.
① 불투명 주소지정: 봉투에 적힌 유일한 정보는 16바이트 회전 태그 — "수신자 정적키 + 오늘 날짜(UTC)"의 HMAC이다. 그 키를 이미 아는 사람만 계산할 수 있어, 택배원은 발신자·수신자·내용을 전혀 모르고, 태그는 날마다 바뀌어 추적도 안 된다.
② 신뢰 등급: 상호 즐겨찾기는 5통씩, 서명 검증된 아무 피어는 2통씩 맡길 수 있되 즐겨찾기 몫을 침범 못 하도록 슬롯이 분리돼 있다(봉투 16KiB·24시간 상한).
③ Spray-and-Wait(분무 후 대기): 봉투엔 복사 예산(처음 4, 최대 8)이 있다. 택배원이 다른 적격 택배원을 만나면 남은 예산의 절반을 나눠준다. 그래서 편지가 한 사람이 아니라 움직이는 군중 속으로 확산된다. 앱을 껐다 켜도 예산·이력이 보존된다.
④ 핸드오버: 수신자의 서명된 직접 announce를 보면 즉시 라이브 링크로 배달·삭제하고, 중계된 announce면 사본만 흘려보낸다(봉투당 10분에 1회로 제한).
Spray-and-Wait는 "소문이 퍼지는 방식"과 같다. 한 사람이 100명에게 직접 말하는 대신(비효율·과부하), 몇 명에게만 말하고 그들이 또 절반씩 퍼뜨리면 — 결국 군중 전체에 닿는다. 편지가 특정 배달부 한 명에게 의존하지 않으니, 그 사람이 집에 가버려도 다른 복사본이 목적지로 향한다. "중복은 해롭지 않다"(수신 시 메시지 ID로 중복 제거)는 전제가 이 대담한 확산을 가능케 한다.
공개 채팅은 또 다른 문제가 있다: 방에 늦게 합류한 사람은 앞 대화를 못 본다. bitchat은 공개 방송 1000개를 캐시해두고, 약 15초마다 이웃과 GCS 필터(Golomb-Coded Set)로 "나는 이걸 갖고 있어 / 너는 이게 없네"를 압축 비교(set reconciliation)한 뒤 빠진 것만 주고받는다. 메시지는 6시간 동안 동기화 가능하고 캐시는 디스크에 남아, 두 무리 사이를 걸어서 오간 기기가 양쪽 대화를 실어 나르는 다리가 된다.
구조가 말해주는 이야기는 분명하다. 전송 계층, 그중에서도 Services/BLE/가 압도적으로 두껍다(45개 파일). 이는 이 프로젝트의 진짜 난이도가 "채팅 UI"가 아니라 "불안정한 블루투스 위에서 배달을 보장하는 것"에 있음을 보여준다. 파일 하나하나가 BLEFanoutSelector, BLEScanDutyPolicy, BLESourceRouteFailureCache처럼 단일 책임(single responsibility)으로 잘게 쪼개져 있어, 각 정책을 독립적으로 테스트할 수 있다.
이 코드베이스는 "항공 관제탑"을 닮았다. 승객이 보는 건 좌석과 안내방송(SwiftUI 화면)뿐이지만, 뒤에는 이착륙 순서·항로·연료·기상·충돌회피를 각각 담당하는 수십 개의 관제 규칙이 돌아간다. bitchat의 BLE/ 폴더가 바로 그 관제 규칙 뭉치다 — 언제 스캔하고(배터리), 누구에게 릴레이하고(팬아웃), 중복을 어떻게 거르고(dedup), 경로가 끊기면 어떻게 우회할지를 파일별로 나눠 맡는다.
"그냥 다 뿌리면 되지 않나?"라는 순진한 생각이 왜 안 되는지를 Services/BLE/가 실물로 가르쳐준다. TTL 클램프, LRU 중복제거, 지터 기반 억제, 팬아웃 서브셋, split horizon — 이건 사실 인터넷 라우팅 프로토콜(OSPF·BGP)이 쓰는 개념을 블루투스 스케일로 축소한 것이다. 분산 시스템의 고전 문제를 손에 잡히는 코드로 볼 수 있는 드문 기회다.
"종단간 암호화"를 말로만 듣다가, Noise/에서 XX 패턴 핸드셰이크가 실제로 몇 번 메시지를 주고받는지를 코드로 본다. 순방향 비밀성(forward secrecy)이 왜 라이브 세션엔 있고 오프라인 봉인(X 패턴)엔 없는지, 그 트레이드오프가 왜 생기는지까지 백서가 정직하게 설명한다. 시그널·와이어가드가 쓰는 바로 그 계열이다.
택배원 시스템은 DTN(Delay-Tolerant Networking)이라는 학문 분야의 실전 구현이다. Spray-and-Wait는 우주 통신·재난망 연구에서 나온 실제 알고리즘이고, bitchat은 여기에 "불투명 태그로 프라이버시 보장"이라는 현실적 장치를 더했다. "연결이 간헐적일 때 어떻게 배달을 보장하나"라는 질문의 모범 답안이다.
ViewModels/에 Chat*Coordinator가 20개 넘게 있는 걸 보고 놀랄 수 있다. 이건 거대해진 ChatViewModel을 기능별 코디네이터로 쪼개는 리팩터링의 흔적이다(docs/ARCHITECTURE_V2.md에 그 의도가 상세히 적혀 있다). "한 파일에 다 넣으면 안 되는 이유"와 "점진적으로 쪼개는 방법"을 실제 진행형 프로젝트에서 관찰할 수 있다.
bitchat은 강력하지만 만능이 아니다. 백서가 스스로 밝히듯, 택배 봉인(Noise X)엔 순방향 비밀성이 없어 수신자 정적키가 털리면 미배달 봉투가 노출된다. 또 블루투스 근접 자체는 관찰 가능하다 — 누가 근처에 있었는지의 메타데이터는 전파 특성상 완전히 숨길 수 없다. 실제 고위험 상황(내부고발·활동가)에서 생명을 걸 도구로 쓰기 전엔 이 한계와 위협 모델(docs/privacy-assessment.md)을 반드시 이해해야 한다.
WHITEPAPER.md를 읽고 "패닉 와이프가 지우는 것들" 목록을 정리해, 어떤 상태가 디스크에 남는지 역으로 파악해 보기Protocols/BitchatProtocol.swift의 NoisePayloadType enum을 보고, 왜 메시지·읽음확인·전달확인이 같은 봉투 타입 안에 숨겨졌는지(관찰자 방지) 설명해 보기just run 후 비행기 모드에서 메시지가 오가는지 확인 — "인터넷 0%"를 몸소 체감| 항목 | 요구사항 |
|---|---|
| 플랫폼 | iOS 16+ / macOS 13+ (Universal App · 하나의 코드베이스) |
| 빌드 도구 | Xcode (전체 설치 필요) · macOS는 just run으로 소스 실행 |
| 언어 | Swift 5.9 · Swift Package Manager(Package.swift) |
| 무선 | BLE(Bluetooth Low Energy) 지원 기기 — 메시는 실기기 권장(시뮬레이터는 BT 제한) |
| 설치(사용자) | iOS App Store("bitchat mesh") · 소스 빌드 시 개발자 Team ID 필요 |
| 서명 설정 | Configs/Local.xcconfig에 Team ID 기입 · Bundle ID chat.bitchat.<team_id> |
| 인터넷(선택) | Nostr·Tor·지역채널 사용 시에만 · BLE 메시만 쓰면 완전 오프라인 |
| 저장 | 평문 미저장 · 봉인 암호문·공개이력만 · Keychain에 키 보관 · 패닉 와이프로 전삭제 |
요구사항이 "평범한 iPhone/Mac"이라는 게 오히려 강점이다. 특수 무전기도, 유심도 필요 없이 이미 모두 주머니에 넣고 다니는 기기가 그대로 메시 노드가 된다. 재난 시 "기지국이 죽었는데 통신 장비가 따로 없다"는 상황을 정확히 겨냥한 설계다. 다만 배터리는 유한하므로, BLEScanDutyPolicy가 스캔을 듀티사이클로 조절해 소모를 억제한다.
WHITEPAPER.md의 6장(Store and Forward)을 읽고, 아웃박스 · 택배원 · 가십동기화 · Nostr 메일박스가 각각 "어떤 상황"을 커버하는지 한 장짜리 표로 정리한다. 코드 없이도 "왜 하나로는 부족하고 넷이 필요한지"가 보인다. 시스템 설계 감각을 기르는 최고의 워밍업.
macOS에서 just run, iOS는 시뮬레이터/실기기로 빌드해 실행한다. 그런 다음 Wi-Fi·셀룰러를 끄고 블루투스만 켠 채 메시지가 오가는지 확인한다. IRC 스타일 명령(/who, /msg, /slap)도 쳐본다. "서버 없는 채팅"을 처음으로 눈앞에서 목격하는 경험.
Services/BLE/에서 TTL 클램프·지터 범위·팬아웃 서브셋 크기가 정의된 정책 파일을 찾아, 값을 조금 바꿔본다(예: 지터를 없애면?). 중복 릴레이가 얼마나 늘어나는지를 로그로 관찰하며 "왜 원래 값이 그렇게 정해졌는지"를 역설계한다. 파라미터 하나가 전체 거동을 바꾸는 분산 시스템의 민감성을 체감.
Protocols/Packets.swift·BitchatProtocol.swift의 헤더 구조(버전·타입·TTL·타임스탬프·플래그 + 발신자ID + 페이로드 + 서명)를 읽고, 패킷 바이트를 사람이 읽는 표로 디코드하는 작은 파서를 Swift/Python으로 짠다. 네트워크 프로토콜이 "왜 텍스트 대신 촘촘한 바이너리를 쓰는지"(BLE MTU 제약)를 손으로 이해한다.
택배원의 복사 예산(4→8, 만날 때마다 절반 분배) 규칙만 떼어내, 랜덤 워크하는 N개 노드의 만남을 이산 이벤트로 시뮬레이션한다(Python + 간단한 이동 모델). "복사 예산을 늘리면 배달률·오버헤드가 어떻게 변하나"를 그래프로 그려, bitchat이 왜 상한 8을 뒀는지 정량적으로 검증한다. 논문 속 DTN 알고리즘을 내 손으로 실험하는 단계.
| 주차 | 주제 | 학습 내용 |
|---|---|---|
| 1주차 | BLE와 근거리무선 | Bluetooth LE의 GATT·central/peripheral 개념 / CoreBluetooth 기본 / 왜 MTU가 작아 분할이 필요한지 / RSSI·듀티사이클과 배터리. 대응 소스: Services/BLE/ |
| 2주차 | 메시 라우팅·확산 제어 | controlled flood / TTL·홉 / 중복제거(LRU) / split horizon / 소스 라우팅 / 집합 조정(GCS filter). 개념 뿌리: OSPF·에피데믹 라우팅. 대응: Sync/·docs/SOURCE_ROUTING.md |
| 3주차 | 실전 암호학 | Noise 프로토콜 프레임워크(XX vs X) / Curve25519·ChaCha20-Poly1305 / 순방향 비밀성 / 서명(Ed25519)과 신원. 대응: Noise/·Identity/·백서 5장 |
| 4주차 | 분산 소셜·익명 전송 | Nostr 프로토콜(이벤트·릴레이·NIP-17/59 gift-wrap) / geohash 위치 채널 / Tor·Arti 기초 / DTN·Spray-and-Wait. 대응: Nostr/·docs/TOR-INTEGRATION.md·백서 6장 |
이 순서를 밟으면 bitchat은 단순한 "신기한 앱"이 아니라 근거리무선·라우팅·암호·분산시스템을 잇는 살아있는 교과서가 된다. 각 주차 개념이 정확히 어느 소스 폴더·백서 절에 대응되므로, "이론 → 실제 코드 → 백서의 설계 근거"를 삼각 대조하며 왕복 학습할 수 있다.
| 용어 | 의미 |
|---|---|
| 메시 네트워크 | 중앙 장비 없이 참여 기기끼리 서로 중계하는 그물망. bitchat의 근간 |
| BLE (Bluetooth LE) | 저전력 블루투스. 각 폰이 central+peripheral로 동시 동작하며 릴레이 |
| controlled flood | 메시지를 통제된 방식으로 확산. TTL·dedup·지터·팬아웃으로 폭주 억제 |
| TTL / 홉(hop) | 패킷이 더 중계될 수 있는 횟수(7에서 시작, 릴레이마다 −1) / 중계 1회 |
| Noise XX / X | 종단간 암호 세션 패턴. XX=상호인증 라이브용, X=일방향 오프라인 봉인용 |
| 순방향 비밀성 | 과거 세션키가 나중에 털려도 옛 메시지는 못 여는 성질. 라이브엔 있고 봉인엔 없음 |
| 정적키 / 지문(fingerprint) | Curve25519 장기 키 / 그 SHA-256 해시가 피어의 안정적 신원 |
| Nostr | 계정 서버 없는 분산 소셜 프로토콜. 키가 곧 신원, 메시지를 릴레이에 뿌림 |
| gift-wrap (NIP-17/59) | Nostr 메시지를 rumor→seal→wrap 3중 포장. 릴레이가 발신자·내용 모름 |
| geohash | 위경도를 짧은 문자열로 인코딩. 정밀도에 따라 블록~국가 단위 위치 채널 구성 |
| Tor / Arti | 익명 라우팅망 / 그 Rust 구현. Nostr 트래픽의 메타데이터까지 은닉 |
| store-and-forward | 지금 못 닿는 상대에게 "보관했다 나중에" 전달하는 방식(4중 안전망) |
| courier(택배원) | 봉인된 봉투를 물리적으로 실어 나르는 중간 피어. 내용·상대 모름 |
| Spray-and-Wait | 복사 예산을 만날 때마다 절반씩 나눠 군중으로 확산하는 DTN 배달 알고리즘 |
| 회전 태그(rotating tag) | 수신자키+날짜의 HMAC(16바이트). 아는 사람만 계산, 날마다 바뀌어 추적 불가 |
| 가십 동기화 / GCS filter | 이웃과 "가진 것/없는 것"을 압축 비교해 빠진 메시지만 교환(집합 조정) |
| 패닉 와이프(panic wipe) | 3번 탭으로 키·즐겨찾기·봉투·이력·통계를 즉시 전삭제하는 비상 소거 |
WHITEPAPER.md(프로토콜 백서 v2.0 · 배달·암호·저장전달 전모) · README.md(개요·전송 아키텍처)docs/ARCHITECTURE_V2.md(리팩터링 방향) · docs/SOURCE_ROUTING.md · docs/TOR-INTEGRATION.md · docs/privacy-assessment.md(위협 모델)Services/Transport.swift(추상 경계) · Services/MessageRouter.swift(라우팅) · Services/BLE/(메시 45파일) · Noise/(암호) · Nostr/(인터넷) · Sync/(가십)