Vérifier un téléchargement
Un build reproductible affirme ceci provient de ce code source, et n'importe qui peut le vérifier — ce qui est l'assurance qu'un projet publié anonymement peut offrir à la place d'un certificat de signature de code. Voici comment l'encaisser.
Trois vérifications, et elles répondent à des questions différentes. Effectuez-les dans cet ordre ; chacune vaut moins sans celle qui la précède.
| Vérification | Ce qu'elle prouve | Ce qu'elle ne prouve pas |
|---|---|---|
| Somme de contrôle | Le fichier n'a pas été altéré en transit. | Quoi que ce soit sur qui l'a produit, ou sur ce qu'il contient. |
| Signature | La liste des sommes de contrôle provient du détenteur de la clé du projet. | Que cette clé appartienne à quelqu'un à qui vous ayez des raisons de faire confiance. |
| Reconstruction | Le binaire contient ce code source et rien d'autre. | Que le code source soit honnête — lisez-le, ou lisez les revues. |
La somme de contrôle#
curl -fsSLO https://zycord.com/releases//download/v<version>/SHA256SUMS.randomx
sha256sum --check --ignore-missing SHA256SUMS.randomx
# on macOS:
shasum -a 256 --check --ignore-missing SHA256SUMS.randomx
--ignore-missing n'est pas facultatif, et ce n'est pas de la complaisanceLes versions livrent désormais uniquement les archives -randomx ;
SHA256SUMS.randomx est donc la liste qui couvre ce que vous avez téléchargé ;
SHA256SUMS.deb et SHA256SUMS.desktop couvrent les paquets Debian et le
portefeuille de bureau. Chacune couvre plusieurs fichiers et vous n'en avez téléchargé qu'un. Sans ce drapeau, les cinq que vous n'avez pas sont signalés comme
FAILED open or read et la commande sort avec un code non nul pour un téléchargement parfaitement bon, sur
la page même qui vous dit qu'une non-concordance signifie un binaire compromis. Une vérification dont le résultat normal est
un échec est une vérification que les gens apprennent à ignorer.
La signature#
Les versions livrent actuellement zycord-release-key.asc — la clé publique — mais
rien qui soit signé avec elle au-delà du manifeste de l'updater : aucun des fichiers de sommes de contrôle n'a de
signature détachée, et aucun n'est signé en clair. Le gpg --verify ci-dessous échoue donc
aujourd'hui sur un fichier manquant, et c'est là une lacune de la version plutôt qu'une erreur de votre part. Tant qu'elle n'est pas comblée, la
vérification qui porte réellement l'argument de confiance est la
reconstruction : elle n'a besoin d'aucune signature, puisque vous produisez les octets vous-même et comparez.
Lorsqu'une signature de somme de contrôle est publiée, elle est faite avec la clé du projet. L'empreinte complète est :
E724 39CE DD85 11F9 D607 550B 87FD 60D5 EB4A 0B29
Elle est publiée dans l'en-tête du livre blanc, dans le dépôt archivé, et dans l'annonce de la genèse. Elle ne tourne jamais silencieusement : une clé qui change sans déclaration signée par l'ancienne est indiscernable d'une compromission, et doit être traitée comme telle.
Récupérez la clé où bon vous semble, puis vérifiez ce que vous avez obtenu contre la ligne ci-dessus. Un fichier de clé dont l'empreinte est celle-là est la clé du projet quel que soit l'hôte qui vous l'a remise, et un fichier dont l'empreinte est autre chose ne vaut rien, si digne de confiance que l'hôte ait pu paraître.
Trois endroits la portent. N'importe lequel fera l'affaire :
# 1. The repository, if you have a clone. No network, no keyserver.
gpg --import packaging/zycord-release-key.asc
# 2. The release page, as an asset beside the archives.
curl -fsSLO https://zycord.com/releases//download/v<version>/zycord-release-key.asc
gpg --import zycord-release-key.asc
# 3. A keyserver. Use this one.
gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys E72439CEDD8511F9D607550B87FD60D5EB4A0B29
Confirmez ensuite ce qui est entré dans votre trousseau, avant de vous y fier :
gpg --fingerprint E72439CEDD8511F9D607550B87FD60D5EB4A0B29
keys.openpgp.org pour cette cléC'est le serveur de clés par défaut dans plusieurs versions de GnuPG, et il sert une copie amputée : le simple
paquet de clé publique, sans identifiant d'utilisateur et sans auto-signature. GnuPG refuse cette copie —
gpg: key 87FD60D5EB4A0B29: new key but contains no user ID - skipped — et la
clé n'entre jamais dans le trousseau, si bien que la vérification ci-dessous échoue sur ce qui ressemble à une mauvaise signature et
est en réalité une clé manquante. Ce serveur retire les identifiants d'utilisateur par politique jusqu'à ce qu'une adresse soit confirmée
par son intermédiaire, ce qu'un projet pseudonyme ne peut pas faire.
gpg --verify SHA256SUMS.randomx.asc SHA256SUMS.randomx
Aujourd'hui, cela signale No such file or directory,
parce qu'aucune version n'a encore publié ce fichier. Voyez la note en tête de cette section.
gpg ajoutera que la clé n'est pas certifiée par une signature de confiance. C'est
attendu et ce n'est pas un échec. Cela signifie que vous n'avez pas dit à votre trousseau que vous vous
portez personnellement garant de cette clé, ce que l'empreinte est précisément là pour trancher. Ce qui
compte, c'est que la signature se vérifie, et que la clé contre laquelle elle s'est vérifiée soit l'empreinte
imprimée ci-dessus.
Le livre blanc est signé lui aussi#
Le PDF servi depuis ce site a une signature détachée à côté de lui, faite par la même clé :
curl -fsSLO https://zycord.com/assets/zycord-whitepaper.pdf
curl -fsSLO https://zycord.com/assets/zycord-whitepaper.pdf.asc
gpg --verify zycord-whitepaper.pdf.asc zycord-whitepaper.pdf
La reconstruction — la vérification qui remplace véritablement un certificat#
Un hachage vous dit que le fichier n'a pas été altéré en transit. Il ne dit rien de ce que l'éditeur y a mis. Ceci le dit :
git clone https://gitlab.com/zycord-group/zycord-node.git
cd zycord-node
git checkout v<version>
make build
sha256sum bin/zcd bin/zycordd
Comparez avec SHA256SUMS.binaries issu de la version. Ils doivent correspondre
exactement. Si c'est le cas, le binaire que vous avez téléchargé contient ce code source et rien d'autre
— une affirmation qu'aucun certificat n'a jamais faite sur quoi que ce soit.
La chaîne d'outils Go fait partie de ce que vous reproduisez#
C'est go1.26.2. Le même code source compilé par deux versions de Go différentes donne deux
binaires différents ; ce n'est pas une subtilité, c'est mesurable — le workflow de publication de ce dépôt
a un jour enregistré trois valeurs SHA-256 distinctes pour un seul commit et un seul jeu de drapeaux, une par
version de Go. Aussi make build fixe-t-il GOTOOLCHAIN=go1.26.2 et s'arrête-t-il avec une
explication s'il ne peut pas utiliser cette chaîne d'outils, plutôt que de produire une divergence qui ressemble à la
falsification que toute cette page est là pour détecter.
Deux conséquences qu'il vaut la peine d'avoir :
- Vous n'avez pas à faire confiance à la version écrite ci-dessus. Le binaire publié la
déclare :
go version -m zcdaffiche la chaîne d'outils qui l'a construit, à côté du module et des drapeaux de build. Si cette ligne et la valeur fixée dans leMakefilevenaient à diverger, le binaire n'a pas été construit de la manière que décrit cette page. - Extraire un tag plus ancien extrait aussi sa version fixée en même temps que son code source ; reconstruire une ancienne version continue donc de fonctionner après que le projet est passé à un Go plus récent.
Les fins de ligne font ici partie du code source#
wallet/webui embarque le frontend du portefeuille avec //go:embed, si bien que les fins de ligne
de ces fichiers sont des octets dans le binaire : une copie de travail convertie en CRLF construit un
zcd différent à partir du même commit — une divergence à la cause innocente et à
l'apparence effrayante. Un .gitattributes portant * text=auto eol=lf donne des LF dans la
copie de travail sur toute plateforme et toute configuration git, si bien qu'un clone frais
donne partout la même réponse.
Deux cas qu'il ne couvre pas : reconstruire un tag antérieur à ce fichier (posez
core.autocrlf=input avant de faire le checkout), et un clone existant fait avec
core.autocrlf=true, qui ne se répare pas sur un pull.
-randomx ne sont pas reproductibles, par constructionRandomX est du C++, si bien qu'une compilation cgo emporte une chaîne d'outils C du système dans le résultat et que personne ne peut
le reconstruire octet pour octet. Ces archives sont couvertes par SHA256SUMS.randomx et
sont délibérément absentes de SHA256SUMS.binaries, qui liste ce à quoi doit correspondre le hachage d'une compilation que vous
faites depuis les sources. C'est le seul endroit où le
niveau qui rejoint un réseau et le niveau qui est attesté ne se recouvrent pas — voyez la table des deux niveaux
sous Installation.
L'énoncer est tout l'enjeu : c'est votre décision plutôt qu'une hypothèse prise pour vous.
Vérifier l'implémentation contre le protocole#
Indépendamment de la vérification de la provenance d'un binaire, vous pouvez vérifier qu'il implémente le protocole. Les vecteurs de référence sont le protocole ; une implémentation indépendante qui les passe est un pair, pas un fork.
zcd vectors # check this build against spec/vectors
zcd genesis --testnet # rebuild block 0 and print its id
zcd params --testnet # print the frozen parameters
zcd genesis est la commande qui compte le plus : une annonce de lancement s'engage, des semaines
à l'avance, sur le tag de code, le hachage des paramètres et l'identifiant de genèse — et ceci les reconstruit tous
en quelques millisecondes, depuis les sources, sur n'importe quelle machine. Les valeurs du testnet public sont sur la
page du testnet ; une compilation qui en imprime d'autres est une compilation sur une
chaîne différente, et elle ne se connectera pas.
Attestations indépendantes#
Une personne qui reconstruit un tag prouve que le tag est reproductible. Plusieurs inconnus qui le reconstruisent et en signent le résultat prouvent bien davantage, et c'est le modèle sur lequel les projets sérieux ont convergé pour exactement cette raison. Reconstruisez un tag, puis publiez l'empreinte obtenue et le tag construit dans le fil d'annonce — y compris lorsqu'elle ne correspond pas, car c'est le cas qui mérite d'être entendu.