How to Verify the BitChat Build Using Source-to-Binary Hash Manifests
BitChat publishes a signed source manifest with every release containing commit hashes, tree hashes, and per-file SHA-256 checksums that you can verify to confirm your source code matches the authentic release.
BitChat protects users against supply-chain attacks through a verifiable build system based on hash manifests. Since the repository has faced takedown requests leading to untrusted mirrors, the source-to-binary verification process ensures that any code you compile is exactly what the maintainers released. This guide explains how the manifests work, how they're generated, and how you can verify them step by step.
How the Source Manifest Works
Every tagged release includes a SOURCE-MANIFEST.txt file that cryptographically binds the release to a specific state of the repository. The manifest contains three critical components that work together to prevent tampering:
- Commit and tree hashes – a single SHA-256 value that uniquely identifies the exact snapshot of tracked source files
- SHA-256 hashes of every tracked file – listed in a stable, NUL-separated order so any alteration is immediately detectable
- Provenance attestation – signed by the GitHub Actions workflow that generated it, making the manifest tamper-evident
Because Xcode compiles any file present in the checkout, verifying against the manifest ensures no extra malicious files have been injected into your source tree.
How the Manifest Is Generated
The manifest production is fully automated through .github/workflows/source-manifest.yml, which triggers on every tag push. The workflow performs these exact steps:
- Checks out the precise git ref (tag or commit)
- Captures the commit hash via
git rev-parse HEAD - Captures the tree hash via
git rev-parse HEAD^{tree} - Generates
files.sha256by hashing every tracked file withgit ls-files -z | sort -z | xargs -0 sha256sum - Combines a human-readable header with the file-hash list into
SOURCE-MANIFEST.txt - Verifies the manifest matches the checkout using
sha256sum -c check.sha256 - Attests the manifest with
actions/attest-build-provenance@v1
This automated process eliminates human error and creates an auditable chain of trust from source code to published manifest.
Step-by-Step Verification Process
Follow these five steps to verify any BitChat source checkout against the official release manifest.
Step 1: Download the Manifest
Obtain the manifest from the official release assets and store it outside your source tree:
curl -L -o /tmp/SOURCE-MANIFEST.txt \
https://github.com/permissionlesstech/bitchat/releases/download/v1.2.3/SOURCE-MANIFEST.txt
Step 2: Verify File Hashes
Check that every tracked file matches its recorded hash. Any FAILED line indicates tampering:
grep -v '^#' /tmp/SOURCE-MANIFEST.txt > /tmp/files.sha256
shasum -a 256 -c /tmp/files.sha256
Step 3: Check for Unexpected Files
A malicious mirror could add new files while keeping original hashes unchanged. Verify the path lists match exactly:
grep -v '^#' /tmp/SOURCE-MANIFEST.txt | sed 's/^[0-9a-f]* //' | LC_ALL=C sort > /tmp/manifest-paths
find . -type f ! -path './.git/*' | sed 's|^\./||' | LC_ALL=C sort > /tmp/actual-paths
diff /tmp/manifest-paths /tmp/actual-paths
If using a clean Git checkout, you can simplify this to:
git status --porcelain --ignored
This must produce no output—any result indicates extra or modified files.
Step 4: Validate the Tree Hash
The tree hash provides a concise single-value proof of the entire source tree. Compare the manifest header against your checkout:
git rev-parse HEAD^{tree}
Match this output against the tree: line in /tmp/SOURCE-MANIFEST.txt.
Step 5: Verify Provenance Attestation
Finally, confirm the manifest was produced by the trusted CI workflow:
gh attestation verify /tmp/SOURCE-MANIFEST.txt --repo permissionlesstech/bitchat
This cryptographically binds the manifest to a specific GitHub Actions run, protecting against replay attacks where an older manifest is presented as current.
Complete Verification Script
Combine all steps into a single verification workflow:
# 1. Obtain manifest
curl -L -o /tmp/SOURCE-MANIFEST.txt \
https://github.com/permissionlesstech/bitchat/releases/download/v1.2.3/SOURCE-MANIFEST.txt
# 2. Verify file hashes
grep -v '^#' /tmp/SOURCE-MANIFEST.txt > /tmp/files.sha256
shasum -a 256 -c /tmp/files.sha256
# 3. Check for unexpected files
grep -v '^#' /tmp/SOURCE-MANIFEST.txt | sed 's/^[0-9a-f]* //' | LC_ALL=C sort > /tmp/manifest-paths
find . -type f ! -path './.git/*' | sed 's|^\./||' | LC_ALL=C sort > /tmp/actual-paths
diff /tmp/manifest-paths /tmp/actual-paths
# 4. Confirm tree hash
git rev-parse HEAD^{tree}
# 5. Verify provenance
gh attestation verify /tmp/SOURCE-MANIFEST.txt --repo permissionlesstech/bitchat
Key Files in the Verification System
| File | Purpose | Location |
|---|---|---|
.github/workflows/source-manifest.yml |
CI workflow that builds and attests manifests | source-manifest.yml |
docs/VERIFYING-A-BUILD.md |
Official user guide for build verification | VERIFYING-A-BUILD.md |
SOURCE-MANIFEST.txt |
Generated manifest with hashes and attestation | Release assets for each tag |
README.md |
Project overview with verification pointers | Repository root |
Why Source-to-Binary Verification Matters
BitChat's verification system addresses specific supply-chain risks:
- Mirror compromise: Untrusted mirrors can host modified code; hash verification detects any deviation
- File injection attacks: The extra-file check prevents scenarios where malicious files are added to an otherwise legitimate source tree
- Manifest replay: Provenance attestation ensures you're not validating against an outdated manifest from a previous release
- Build reproducibility: Since Xcode's compilation is deterministic based on source contents, source verification indirectly verifies the resulting binary
The tree hash serves as the ultimate compact proof—any change anywhere in the tracked tree produces a completely different hash, making verification efficient even for large codebases.
Summary
- Download the
SOURCE-MANIFEST.txtfrom official release assets for any BitChat version you want to verify - Validate file hashes with
shasum -a 256 -cto detect modified content - Confirm no extra files exist by comparing manifest paths against actual paths
- Check the tree hash against
git rev-parse HEAD^{tree}for a single-value integrity proof - Verify provenance attestation with
gh attestation verifyto confirm CI origin - Reference
.github/workflows/source-manifest.ymlanddocs/VERIFYING-A-BUILD.mdfor implementation details and additional guidance
Frequently Asked Questions
What is a source-to-binary hash manifest in BitChat?
A source-to-binary hash manifest is a cryptographically signed file that records the exact state of BitChat's source code at release time. Published as SOURCE-MANIFEST.txt with every tag, it contains the commit hash, tree hash, and SHA-256 checksums of every tracked file. This enables anyone to verify that their source code matches the authentic release before compiling, protecting against supply-chain attacks from compromised mirrors.
How does BitChat prevent malicious files from being injected into the source?
BitChat's verification includes an extra-file check that compares the list of paths in the manifest against the actual files present in your checkout. Because Xcode automatically compiles any file in the source tree, an attacker could inject malicious code by adding new files while leaving originals untouched. The path comparison step (diff /tmp/manifest-paths /tmp/actual-paths) detects this attack by requiring exact correspondence between manifest and filesystem.
Can I trust a BitChat mirror if it provides the same manifest?
No—mirrors should not be trusted based on manifest presence alone. An attacker could copy an older legitimate manifest alongside modified source code. Always verify the provenance attestation using gh attestation verify, which cryptographically binds the manifest to a specific GitHub Actions run from the official permissionlesstech/bitchat repository. The attestation proves the manifest was generated by trusted infrastructure, not merely copied by a third party.
What should I do if the tree hash doesn't match?
If git rev-parse HEAD^{tree} produces a different value than the tree: line in the manifest, your source code differs from the release. Do not build or run BitChat from this checkout. Possible causes include: an incomplete or partial checkout, local modifications, or a compromised mirror. Obtain the source from a different trusted source and repeat the verification process.
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 →