|
| 1 | +<!-- |
| 2 | +SPDX-FileCopyrightText: 2025 Foundation Devices, Inc. <hello@foundation.xyz> |
| 3 | +SPDX-License-Identifier: GPL-3.0-or-later |
| 4 | +--> |
| 5 | + |
| 6 | +# Reproducibility Guide |
| 7 | + |
| 8 | +The instructions below describe how to easily build and verify Prime BLE firmware in a reproducible way. |
| 9 | + |
| 10 | +Please note that this guide has been designed for Linux, so if you're running a different operating system the exact steps here may differ slightly. However, we've done our best to make them as portable as possible for other popular operating systems. |
| 11 | + |
| 12 | +## What to Expect |
| 13 | + |
| 14 | +In this guide we will outline the exact steps necessary to get set up, build firmware directly from the source code, and verify that it properly matches the published build hash and release binaries for any given version of Prime BLE's firmware. Once you've completed the steps outlined here, you'll have verified fully that the source code for a given version does indeed match the binaries we release to you. This ensures that nothing outside of the open-source code has been included in any given release, and that the released binaries are indeed built directly from the publicly available source code. |
| 15 | + |
| 16 | +Security through transparency is the goal here, and firmware reproducibility is a key aspect of that! |
| 17 | + |
| 18 | +## Setup |
| 19 | + |
| 20 | +In order to build and verify the reproducibility of Prime BLE firmware, you will need to: |
| 21 | + |
| 22 | +- Get the source code and checkout the correct tag |
| 23 | +- Install Nix package manager with flakes enabled |
| 24 | +- Set up the development environment using the flake |
| 25 | +- Build the reproducible binaries |
| 26 | +- Verify the binaries match the published build hash |
| 27 | + |
| 28 | +We'll walk through every step above in this guide to ensure you can build and verify any version of Prime BLE's firmware easily. |
| 29 | + |
| 30 | +### **Get the Source Code** |
| 31 | + |
| 32 | +The instructions below assume you are installing into your home folder at `~/prime-ble-firmware`. You can choose to install to a different folder, and just update command paths appropriately. |
| 33 | + |
| 34 | +**Important**: Before building, you must checkout the specific git tag you want to reproduce. This ensures you're building the exact same code as the published release. |
| 35 | + |
| 36 | +```bash |
| 37 | +cd ~/ |
| 38 | +git clone https://github.com/Foundation-Devices/prime-ble-firmware.git |
| 39 | +cd prime-ble-firmware |
| 40 | +git checkout app_v3.2.0 # Replace with the tag you want to reproduce |
| 41 | +``` |
| 42 | + |
| 43 | +### **Install Nix Package Manager** |
| 44 | + |
| 45 | +Nix is a powerful package manager that provides reproducible builds and development environments. The reproducibility of Prime BLE firmware is guaranteed through the use of our Nix flake, which pins exact versions of all tools and dependencies. |
| 46 | + |
| 47 | +#### Install Nix |
| 48 | + |
| 49 | +Follow the official Nix installation guide for your operating system: |
| 50 | + |
| 51 | +- [Official Nix Installation Guide](https://nixos.org/download.html) |
| 52 | + |
| 53 | +For Linux and macOS, the recommended installer is: |
| 54 | + |
| 55 | +```bash |
| 56 | +curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install |
| 57 | +``` |
| 58 | + |
| 59 | +#### Enable Flakes |
| 60 | + |
| 61 | +After installing Nix, you need to enable experimental flakes features. Create or edit `~/.config/nix/nix.conf`: |
| 62 | + |
| 63 | +```bash |
| 64 | +mkdir -p ~/.config/nix |
| 65 | +echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf |
| 66 | +``` |
| 67 | + |
| 68 | +Or, you can enable flakes temporarily by setting an environment variable: |
| 69 | + |
| 70 | +```bash |
| 71 | +export NIX_CONFIG="experimental-features = nix-command flakes" |
| 72 | +``` |
| 73 | + |
| 74 | +### **Set Up Development Environment** |
| 75 | + |
| 76 | +Once Nix is installed with flakes enabled, use the flake in this repository to set up the reproducible development environment: |
| 77 | + |
| 78 | +```bash |
| 79 | +nix develop |
| 80 | +``` |
| 81 | + |
| 82 | +This command: |
| 83 | +- Downloads the exact toolchain versions specified in `flake.nix` |
| 84 | +- Sets up the development environment with all required tools |
| 85 | +- Ensures you're using the same toolchain as our official builds |
| 86 | + |
| 87 | +The environment includes: |
| 88 | +- Rust toolchain with the exact version from `rust-toolchain.toml` |
| 89 | +- Build tools (cargo-binutils, gcc-arm-embedded, etc.) |
| 90 | +- Signing tools (cosign2) |
| 91 | +- Development utilities (just, git) |
| 92 | + |
| 93 | +## **Building Prime BLE Firmware** |
| 94 | + |
| 95 | +### Architecture and Toolchain Verification |
| 96 | + |
| 97 | +Our build system includes automatic checks to ensure reproducibility: |
| 98 | + |
| 99 | +1. **Architecture Check**: Verifies you're building on `x86_64` - this is required for official reproducible builds |
| 100 | +2. **Toolchain Check**: Verifies you're using the Nix-provided toolchain from the nix store |
| 101 | + |
| 102 | +These checks are built into the `build-unsigned` command and will warn you if you're not using the correct environment. |
| 103 | + |
| 104 | +### Build the Firmware |
| 105 | + |
| 106 | +Now that we have everything in place, we can build the firmware binaries for Prime BLE with a simple command: |
| 107 | + |
| 108 | +```bash |
| 109 | +just build-unsigned |
| 110 | +``` |
| 111 | + |
| 112 | +This command: |
| 113 | +1. Runs the architecture and toolchain verification checks |
| 114 | +2. Builds the bootloader and firmware in release mode |
| 115 | +3. Outputs the binaries to `BtPackage/` directory |
| 116 | +4. Displays binary sizes and flash usage information |
| 117 | +5. Shows the SHA256 hash of the built files for verification |
| 118 | + |
| 119 | +The build process will take a few minutes as it compiles the bootloader and application from source. Once complete, you'll have: |
| 120 | +- `BtPackage/bootloader.bin` - The compiled bootloader |
| 121 | +- `BtPackage/BT_application.bin` - The compiled application |
| 122 | + |
| 123 | +**Note**: This builds unsigned firmware. If you want to create a fully flashable package, you would need to sign the firmware using our cosign2 process, but for reproducibility verification, the unsigned binaries are sufficient. |
| 124 | + |
| 125 | +## Verifying Prime BLE Firmware |
| 126 | + |
| 127 | +### Verify Build Hash |
| 128 | + |
| 129 | +To verify that the binary produced matches what you should see, you can calculate the SHA256 hash of the built files and compare it to the published hash in the GitHub release notes. |
| 130 | + |
| 131 | +```bash |
| 132 | +# Calculate SHA256 hash of the built binaries |
| 133 | +sha256sum BtPackage/bootloader.bin BtPackage/BT_application.bin |
| 134 | +``` |
| 135 | + |
| 136 | +Example output: |
| 137 | +``` |
| 138 | +a1b2c3d4e5f6... BtPackage/bootloader.bin |
| 139 | +f6e5d4c3b2a1... BtPackage/BT_application.bin |
| 140 | +``` |
| 141 | + |
| 142 | +Compare these hashes with the ones published in the GitHub release notes for the tag you checked out. If the hashes match, congratulations! You've successfully verified that the firmware you built exactly matches the source code published on GitHub. |
| 143 | + |
| 144 | +If your hashes do not match for any reason, stop immediately and contact us at [hello@foundation.xyz](mailto:hello@foundation.xyz)! We'll help you investigate the cause of this discrepancy and get to the bottom of the issue. |
| 145 | + |
| 146 | +## Reproducibility Guarantee |
| 147 | + |
| 148 | +The reproducibility of Prime BLE firmware is guaranteed by: |
| 149 | + |
| 150 | +1. **Nix Flakes**: The `flake.nix` file pins exact versions of all dependencies, ensuring the same tools are used every time |
| 151 | +2. **Architecture Verification**: Only `amd64` builds are considered official reproducible builds |
| 152 | +3. **Toolchain Verification**: The build system checks that the toolchain comes from the Nix store |
| 153 | +4. **Deterministic Builds**: The build process avoids timestamps and other non-deterministic factors |
| 154 | + |
| 155 | +When you follow these steps exactly: |
| 156 | +- Using the same git tag |
| 157 | +- Using the Nix development environment |
| 158 | +- Building on amd64 architecture |
| 159 | +- Using the provided build commands |
| 160 | + |
| 161 | +You will get bit-for-bit identical binaries every time, and identical to our official builds. |
| 162 | + |
| 163 | +## Installing Firmware |
| 164 | + |
| 165 | +For installing firmware on your device, please use the official signed binaries from the GitHub releases. The unsigned binaries you built are for verification purposes only. |
| 166 | + |
| 167 | +## Conclusion |
| 168 | + |
| 169 | +We want to close out this guide by thanking our fantastic community. Open source and the verifiability and transparency it brings are core to our ethos at Foundation, and the ability to reproducibly build firmware for Prime BLE is a core outpouring of that. |
| 170 | + |
| 171 | +We can't wait to see more of our community take this additional step and remove a little more trust from the process by verifying that each build is reproducible. |
0 commit comments