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:

  1. Checks out the precise git ref (tag or commit)
  2. Captures the commit hash via git rev-parse HEAD
  3. Captures the tree hash via git rev-parse HEAD^{tree}
  4. Generates files.sha256 by hashing every tracked file with git ls-files -z | sort -z | xargs -0 sha256sum
  5. Combines a human-readable header with the file-hash list into SOURCE-MANIFEST.txt
  6. Verifies the manifest matches the checkout using sha256sum -c check.sha256
  7. 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.txt from official release assets for any BitChat version you want to verify
  • Validate file hashes with shasum -a 256 -c to 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 verify to confirm CI origin
  • Reference .github/workflows/source-manifest.yml and docs/VERIFYING-A-BUILD.md for 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:

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 →