How Bitchat Android Achieves 100% Protocol Compatibility with iOS

Bitchat Android guarantees full protocol compatibility with iOS by implementing an identical binary wire protocol, matching padding and compression algorithms byte-for-byte, aligning Noise-framework encryption tags, and enforcing cross-platform parity through an extensive interoperability test suite and release-gate validation.

Bitchat is an open-source peer-to-peer messenger from permissionlesstech, and seamless communication between Android and iOS requires strict wire-level consistency. The Bitchat Android codebase achieves protocol compatibility with iOS by mirroring every packet structure, cryptographic primitive, and encoding helper found in the iOS client. This ensures that payloads generated on either platform are indistinguishable at the byte level.

Unified Binary Packet Definition and Versioning

The core packet layout in app/src/main/java/com/bitchat/android/protocol/BinaryProtocol.kt duplicates the iOS structure exactly. Both platforms use the same versioning scheme (v1, v2) and fragment header format, so either client can parse the other’s packets without ambiguity.

Specifically, BinaryProtocol.encodeMessage() assembles frames using a 13-byte header layout that matches the iOS implementation. This guarantees that message IDs, timestamps, and payload boundaries are interpreted identically on both operating systems.

Byte-Level Payload Transformations

Before encryption, payloads pass through two deterministic layers—padding and compression—that must reproduce the iOS byte stream exactly.

iOS-Compatible PKCS#7 Padding

Privacy-preserving padding is handled in app/src/main/java/com/bitchat/android/protocol/MessagePadding.kt. The applyPadding() routine follows the iOS-side algorithm step-by-step, selecting the same block size and padding byte values, and performing strict validation on removal. Comments in the file explicitly mark the logic as "iOS compatible", ensuring that padded blocks decrypt identically on both platforms.

Cross-Platform Zlib Compression

Raw deflate behavior is implemented in app/src/main/java/com/bitchat/android/protocol/CompressionUtil.kt. The compressIfBeneficial() utility emits raw deflate data with no zlib header and applies the same entropy-threshold logic used by iOS CompressionUtil.swift. Because Android and iOS make the same compression decision and emit the same binary format, a payload compressed on Android decompresses correctly on iOS and vice-versa.

val payload = byteArrayOf(/* … data … */)
val padded = MessagePadding.applyPadding(payload, targetSize = 256)   // iOS-compatible
val compressed = CompressionUtil.compressIfBeneficial(padded)         // iOS-compatible
val packet = BinaryProtocol.encodeMessage(
    version = 2,
    messageId = 0x1234,
    payload = compressed
)

Noise-Protocol Encryption Alignment

The Noise-framework implementation follows identical handshake patterns and cipher suites on both platforms. Private-media payloads are encrypted with the same tags recognized by iOS—specifically 0x09 for prerelease iOS builds and 0x20 for the canonical version.

In app/src/test/kotlin/com/bitchat/android/mesh/PrivateMediaTransferPreparerTest.kt, unit tests verify that Android correctly handles both tag variants. When decrypting traffic from iOS, the Android client initializes a session via NoiseSession.fromHandshake(state) and calls decrypt(ciphertext), producing plaintext that is byte-for-byte identical to the iOS decrypted output.

val noiseSession = NoiseSession.fromHandshake(state)
val plaintext = noiseSession.decrypt(ciphertext)   // Handles both iOS tag variants

Binary Encoding Utilities for Endianness and Slicing

Low-level byte consistency is enforced by app/src/main/java/com/bitchat/android/util/BinaryEncodingUtils.kt. These extensions duplicate the helpers in iOS BinaryEncodingUtils.swift, including little-endian conversion, array concatenation, and slicing operations. By keeping these primitives identical, values such as cryptographic nonces, message IDs, and timestamps are encoded into the exact same byte sequences on both platforms.

Interoperability Validation and Release-Gate Enforcement

Protocol compatibility is not assumed; it is continuously proven through targeted tests and automated gates.

Regression Tests Against iOS Wire Contracts

The test suite contains multiple wire contracts that validate Android behavior against iOS expectations:

These tests catch any deviation in binary layout before it reaches production.

Physical Device Release-Gate Script

The repository includes tools/release_gate/release_gate.py, which enforces a hard requirement: every Android release must be validated against a physical iOS device. This release gate prevents regressions in cross-client compatibility by requiring successful end-to-end messaging between real Android and iOS hardware before merge.

Summary

Frequently Asked Questions

What versioning scheme does Bitchat Android use to stay compatible with iOS?

Bitchat Android and iOS share the same wire-protocol versions, currently v1 and v2, defined in BinaryProtocol.kt. Because both clients use identical version numbers and packet headers, they can parse each other’s frames without translation layers.

How does Bitchat Android ensure encrypted media can be read by iOS?

The Android Noise-framework implementation uses the same handshake patterns and cipher suites as iOS, and it recognizes both the prerelease tag (0x09) and the canonical tag (0x20). Tests in PrivateMediaTransferPreparerTest.kt explicitly validate decryption of iOS-encrypted private-media payloads.

Why is raw deflate used instead of standard zlib for compression?

CompressionUtil.kt emits raw deflate data with no zlib header to match the behavior of iOS CompressionUtil.swift. This choice eliminates header mismatches and ensures that Android-compressed payloads decompress identically on iOS.

How is cross-platform compatibility verified before each release?

Every Android release is blocked by tools/release_gate/release_gate.py until it passes validation against a physical iOS device. In addition, unit tests such as BinaryProtocolTest.kt and BLEPacketPaddingPolicyTest.kt continuously assert byte-level wire-protocol parity in CI.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →