After the wallet scrutiny drama and nvk's twitter response I decided to verify for myself whether I could reproduce several Coldcard builds, focusing on MK3 as I had seen most people complaining about these.
I started with a vanilla Ubuntu 22.04 VM running on QEMU/KVM (virt-manager)
I installed Docker using this guide and installed gcc etc. with
sudo apt install build-essential
I then followed the Coinkite guide and basically did the following operation several times:
git clone https://github.com/Coldcard/firmware.git
cd firmware/stm32
git tag
(<--- here I picked a build)
git checkout
<paste item from tag>
make repro
I did this for
MK4:
2023-04-07T1330-v5.1.2 (latest build)
MK3:
2023-06-19T1627-v4.1.8 (latest build)
2022-11-14T1854-v4.1.7
2022-10-05T1517-v4.1.6
2022-05-04T1258-v4.1.5
2022-04-25T1618-v4.1.4
2021-09-02T1752-v4.1.3
After each build, I recorded my results, then
rm -rf ./firmware
and started again from the beginning picking out a different build from git tag
For M4 5.1.2 I got
SUCCESS
from make repro
The binary on the webpage 893,237 bytes and the build file in ~/firmware/stm32/built/firmware-signed.dfu
was also 893,237 bytes.For M3 4.1.8 I got
SUCCESS
from make repro
The binary on the webpage is 753,981bytes, yet the build file in ~/firmware/stm32/built/firmware-signed.dfu
was 722944 bytesFor M3 4.1.7 I got
error 1
from make repro
The binary on the webpage is 760,637 bytes, yet the build file in ~/firmware/stm32/built/ was 729,600 bytesThis is the Diff: (the right hand side human readable stuff)
| to exit...R..Mi| |croPython v1.12-| |1092-gc087bbe8d-| |dirty on 2023-06| |-22; Coldcard wi| |dirty on 2022-11| |-14; Coldcard wi| |th STM32L4xxRG..| |.Type "help()" f| |or more informat| | with STM32L4xxR| |G.v1.12-1092-gc0| |87bbe8d-dirty on| | 2023-06-22.1.13| | 2022-11-14.1.13| |.0.pyboard...[..| |9....b..<...TS..| |........L.......|
For M3 4.1.6 I got
error 1
from make repro
The binary on the webpage is 760,125bytes, yet the build file in ~/firmware/stm32/built/ was 729,088 bytesThis is the Diff: (the right hand side human readable stuff)
| to exit...R..Mi| |croPython v1.12-| |1092-gc087bbe8d-| |dirty on 2023-06| |-22; Coldcard wi| |dirty on 2022-10| |-05; Coldcard wi| |th STM32L4xxRG..| |.Type "help()" f| |or more informat| | with STM32L4xxR| |G.v1.12-1092-gc0| |87bbe8d-dirty on| | 2023-06-22.1.13| | 2022-10-05.1.13| |.0.pyboard...[..| |9....b..<...TS..| |........L.......|
For M3 4.1.5 make repro failed with an error
=> ERROR [4/4] RUN ln -s /usr/bin/python3 /usr/bin/python 0.4s ------ > [4/4] RUN ln -s /usr/bin/python3 /usr/bin/python: #0 0.366 ln: /usr/bin/python: File exists ------ Dockerfile:23 -------------------- 21 | --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ 22 | 23 | >>> RUN ln -s /usr/bin/python3 /usr/bin/python 24 | 25 | -------------------- ERROR: failed to solve: process "/bin/sh -c ln -s /usr/bin/python3 /usr/bin/python" did not complete successfully: exit code: 1 make: *** [Makefile:248: repro] Error 1
Looking at the dockerfile.build file, it seems from 4.1.6 there is a change in the file:
<4.1.5 and previous>
FROM alpine:edge
<4.1.6 and subsequent builds>
FROM apline: 3.16.0
There is also the comment:
# PROBLEM: alpine has `gcc-arm-none-eabi` `but it's not in main repo, instead its part of "edge"? # # - for firmware v4.0.2, I used alphine:3.13.2 as base, but that doesn't work now for # some random reason, and I don't care to debug why. #
So this seems related to the issue of 4.1.5 not building for me. I got the same error for 4.1.4 and 4.1.3
These are my questions which I hope to get an answer for:
1: It seems that the 4.1.7 and 4.1.6 failing are just down to the build date being included in the build for some reason. This was also the finding of the original wallet scrutiny test if you scroll down to the bottom of the page. Whether Coldcard fixed 4.1.8 in the meantime or not I do not know. But, regardless, if the diff is nothing but a date, is it really a big deal?
2: For the MK4, not only do you get SUCCESS using Coinkite's docker build tool, but the build file is also the same size as the binary on their website. But for the MK3 even if you get SUCCESS the build file is a different number of bytes to the binary on Coinkit's website. Why would this be? If the files are supposed to be binary equivalent with only a minor (64 byte?) signing key difference why are the files such different sizes? Especially since the MK4 is the same size.
3: Anyone know how to fix the alpine.edge issue so I can complete my testing of 4.1.5 and below?
4: I was disappointed to find you cannot get the hash of the current firmware running on a Coldcard. You are able to do this on Foundation Passport. Am I missing something? Perhaps you can do it on newer firmware/ devices? I suppose the paranoid reflash the firmware from factory so the hash on the device is redundant, especially since it could tell you anything on the screen if it was compromised?
Finally, some comments, I am a big NVK and Coinkite fan and I really wanted to be reassured by the reproducible build process. I understand as a regular pleb I know just enough to be dangerous and maybe it's above my paygrade, but it does seem to me like, especially for the MK3, this is a bit of an afterthought for Coinkite. It seems like some text in their documentation pointing out the slight diff due to date in MK3 builds would be helpful, at the very least.
Also, I found NVK being a bit gaslightly in that Twitter thread. Of course some users can make videos showing SUCCESS of some builds. But there are other users with other builds who are not getting SUCCESS, especially for the MK3. I myself have found this.
Not wanting to FUD a great Bitcion only company like Coinkite but at the same time I'd love a bit of reassurance on my questions above.
error 1
, or else fail to build entirely.error 1
, or else fail to build entirely.make repro
to fail witherror 1