BitChat Trust Verification System and Vouch Attestations Explained
BitChat implements a layered trust model combining explicit user verification with transitive vouch attestations, where verified peers can cryptographically endorse others to establish trust without direct confirmation.
The permissionlesstech/bitchat repository implements a sophisticated decentralized identity system designed for mesh messaging. The trust verification system relies on SecureIdentityStateManager.swift as its central authority, managing both direct verification and the propagation of trust through vouch attestations. This architecture enables users to build transitive trust networks without requiring centralized identity providers.
How Explicit Verification Works in BitChat
Direct verification forms the foundation of BitChat's trust hierarchy. When a user manually confirms another peer's identity, the system records this decision cryptographically and durably.
Storing Verified Fingerprints
The SecureIdentityStateManager maintains verified state in cache.verifiedFingerprints, implemented as a Set<String> for O(1) lookups:
setVerified(_:verified:)(lines 71-99): Adds or removes a fingerprint from the verified setisVerified(_:): Returns boolean verification statusgetVerifiedFingerprints(): Enumerates all verified identities
Each verification event also records a timestamp in cache.verifiedAt. Upon verification, the associated social identity's trustLevel upgrades to .verified (lines 86-90).
let manager = SecureIdentityStateManager(keychain)
manager.setVerified(fingerprint: "a1b2c3…", verified: true)
Vouch Attestations: Transitive Trust in BitChat
Vouch attestations enable trust delegation—allowing a verified user to endorse another peer without requiring the recipient to verify that peer directly. This creates a web of trust that scales beyond pairwise connections.
Recording a Vouch Attestation
The recordVouch(voucheeFingerprint:voucherFingerprint:timestamp:) method (lines 124-166) enforces strict validation rules:
- Reject self-vouches: A peer cannot vouch for itself
- Prevent redundant vouches: Already-verified peers cannot be vouched for
- Voucher authority check: The voucher fingerprint must exist in
verifiedFingerprints - Temporal validation: Timestamp must satisfy
VouchAttestation.maxAgeandmaxClockSkewconstraints
let voucher = "deadbeef…" // must be pre-verified
let vouchee = "feedface…"
let ok = manager.recordVouch(
voucheeFingerprint: vouchee,
voucherFingerprint: voucher,
timestamp: Date()
)
Storage and Capping of Vouch Records
Vouches are stored in cache.vouchesByVouchee as a per-peer array of VouchRecord(voucherFingerprint:timestamp:) structures. The implementation applies two critical limits (lines 111-112):
- Maximum 8 vouchers per vouchee (
maxVouchersPerVouchee = 8) - Sorted by timestamp, ensuring recent attestations displace older ones
This bounded storage prevents memory exhaustion attacks and ensures relevance of retained attestations.
Validating and Querying Vouch Status
BitChat distinguishes between stored and valid vouches through dedicated methods:
| Method | Location | Purpose |
|---|---|---|
validVouchers(for:now:) |
lines 170-178 | Filters to vouchers still verified and temporally valid |
isVouched(fingerprint:now:) |
lines 184-191 | Returns true if ≥1 valid vouch exists and peer is not explicitly verified |
if manager.isVouched(fingerprint: targetPeer) {
// Grant access to vouch-dependent features
}
Trust Level Calculation and Hierarchy
The effectiveTrustLevel(for:now:) method (lines 200-227) resolves all verification sources into a single authoritative level. Resolution occurs in priority order:
.verified— fingerprint exists inverifiedFingerprints(explicit verification).vouched— valid vouch exists and no explicit verification (transitive trust)- Stored social identity level —
.trusted,.casual, or.unknown
The .vouched level sits between .casual and .trusted in the trust hierarchy, granting elevated but not full privileges.
let level = manager.effectiveTrustLevel(for: peerFingerprint)
// Possible values: .verified, .vouched, .trusted, .casual, .unknown
Vouch Protocol Capabilities and Batch Distribution
BitChat peers advertise protocol support through a capability bitfield defined in PeerCapabilities.swift (lines 16-22). The vouch capability (1 << 5) indicates a peer can receive and process vouch attestations.
Batching and Rate Limiting
The state manager supports efficient vouch propagation through:
mostRecentlyVerifiedFingerprints(limit:excluding:)(lines 236-245): Returns ordered list for outbound vouch batcheslastVouchBatchSent(to:)/markVouchBatchSent(to:at:)(lines 232-239): Tracks batch timing to prevent flooding
Security Guarantees in BitChat's Trust System
The implementation provides four key security properties:
- Voucher authority binding: Only fingerprints in
verifiedFingerprintsmay issue valid vouches, preventing arbitrary trust injection - Temporal bounds:
VouchAttestation.maxAgeandmaxClockSkewprevent replay attacks using stale or future-dated attestations - Storage exhaustion protection: The 8-voucher cap per vouchee bounds memory consumption
- Encrypted persistence: All state—including vouches, verification flags, and timestamps—serializes to
IdentityCachevia keychain encryption, ensuring confidentiality at rest and durability across restarts
Complete Vouch Attestation Workflow
// 1. Establish verified identity
let manager = SecureIdentityStateManager(keychain)
manager.setVerified(fingerprint: myTrustedContact, verified: true)
// 2. Receive and record vouch for unknown peer
let unknownPeer = "newcomer…"
let recorded = manager.recordVouch(
voucheeFingerprint: unknownPeer,
voucherFingerprint: myTrustedContact,
timestamp: Date()
)
// 3. Query effective trust
if recorded {
let trust = manager.effectiveTrustLevel(for: unknownPeer)
print(trust) // .vouched — elevated from .unknown
}
// 4. Check vouch status specifically
let isVouched = manager.isVouched(fingerprint: unknownPeer)
Summary
- Explicit verification stores user-confirmed fingerprints in
cache.verifiedFingerprintswith associated timestamps - Vouch attestations allow verified peers to transitive-trust others through cryptographically signed endorsements
recordVouch()enforces strict validation: no self-vouches, verified-voucher requirement, and temporal bounds- Storage is capped at 8 vouchers per peer, sorted by recency
effectiveTrustLevel()resolves.verified>.vouched> stored level, giving the UI and routing layers a single trust signalPeerCapabilities.swiftdefines thevouchbit (1 << 5) for protocol negotiation- All state persists encrypted via keychain-backed
IdentityCache
Frequently Asked Questions
How does BitChat prevent fake vouch attestations?
BitChat's recordVouch() method validates that the voucher fingerprint exists in cache.verifiedFingerprints before accepting any attestation. This binding ensures only identities the user has explicitly verified can delegate trust. Additionally, temporal checks using VouchAttestation.maxAge and maxClockSkew reject replayed or timestamp-manipulated vouches.
What happens when a peer has multiple vouch attestations?
The validVouchers(for:now:) method returns all temporally valid vouches from currently verified peers. However, isVouched() and effectiveTrustLevel() require only one valid vouch to confer .vouched status. The maxVouchersPerVouchee = 8 limit ensures storage remains bounded, with newer vouches displacing older ones.
Can a vouch attestation expire in BitChat?
Yes. Vouches are validated against VouchAttestation.maxAge at query time through validVouchers(for:now:). A vouch older than this threshold becomes invalid even if stored, causing isVouched() to return false and effectiveTrustLevel() to fall back to the stored social identity level. The original record remains in cache but is filtered during validation.
How does BitChat advertise vouch protocol support?
Peers declare capabilities through a bitfield in PeerCapabilities.swift. The vouch capability (1 << 5) signals that a peer can receive and process vouch attestations. This allows negotiation before attempting vouch transmission, preventing protocol errors on incompatible peers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →