डाउनलोड का सत्यापन
एक पुनरुत्पाद्य बिल्ड यह दावा करता है कि यह इस स्रोत से आया है, और कोई भी जाँच सकता है — और गुमनाम रूप से प्रकाशित परियोजना कोड-साइनिंग प्रमाणपत्र की जगह यही आश्वासन दे सकती है। इसे भुनाने का तरीक़ा यह है।
तीन जाँचें, और वे अलग-अलग प्रश्नों का उत्तर देती हैं। इन्हें इसी क्रम में चलाएँ; हर एक का मोल अपने से पहले वाली के बिना कम है।
| जाँच | यह क्या सिद्ध करती है | यह क्या सिद्ध नहीं करती |
|---|---|---|
| चेकसम | फ़ाइल रास्ते में बदली नहीं गई। | इस बारे में कुछ नहीं कि उसे किसने बनाया, या उसमें क्या है। |
| हस्ताक्षर | चेकसम सूची परियोजना कुंजी रखने वाले से आई। | कि वह कुंजी किसी ऐसे व्यक्ति की है जिस पर भरोसा करने का आपके पास कारण हो। |
| पुनर्निर्माण | बाइनरी में यही स्रोत है और कुछ नहीं। | कि स्रोत ईमानदार है — उसे पढ़ें, या समीक्षाएँ पढ़ें। |
चेकसम#
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 वैकल्पिक नहीं है, और कोई ढील भी नहींरिलीज़ अब केवल -randomx आर्काइव भेजती हैं, इसलिए
SHA256SUMS.randomx वही सूची है जो आपके डाउनलोड को शामिल करती है;
SHA256SUMS.deb और SHA256SUMS.desktop Debian पैकेजों और डेस्कटॉप
वॉलेट को शामिल करती हैं। हर एक कई फ़ाइलों को शामिल करती है और आपने एक डाउनलोड की। इस फ़्लैग के बिना, जो पाँच आपके पास नहीं हैं उन्हें
FAILED open or read बताया जाता है और कमांड एक बिलकुल सही डाउनलोड पर नॉन-ज़ीरो के साथ बाहर निकलती है, ठीक उसी
पृष्ठ पर जो आपसे कहता है कि बेमेल का मतलब है छेड़छाड़ की गई बाइनरी। जिस जाँच का सामान्य परिणाम
विफलता हो, लोग उस जाँच को अनदेखा करना सीख जाते हैं।
हस्ताक्षर#
रिलीज़ फ़िलहाल zycord-release-key.asc भेजती हैं — यानी सार्वजनिक कुंजी — पर
अपडेटर के मैनिफ़ेस्ट के अलावा उससे हस्ताक्षरित कुछ नहीं: किसी चेकसम फ़ाइल के साथ कोई अलग
हस्ताक्षर नहीं है, और कोई क्लियरसाइन भी नहीं है। इसलिए नीचे दी गई gpg --verify आज एक
ग़ायब फ़ाइल के साथ विफल होती है, और यह आपकी ग़लती नहीं बल्कि रिलीज़ की कमी है। जब तक वह कमी नहीं भरती, तब तक
भरोसे का तर्क असल में जो जाँच ढोती है वह है यह
पुनर्निर्माण: उसे किसी हस्ताक्षर की ज़रूरत ही नहीं, क्योंकि बाइट्स आप ख़ुद बनाते हैं और मिलान करते हैं।
जब कोई चेकसम हस्ताक्षर प्रकाशित होगा, वह परियोजना कुंजी से बना होगा। पूरा फ़िंगरप्रिंट यह है:
E724 39CE DD85 11F9 D607 550B 87FD 60D5 EB4A 0B29
वह श्वेतपत्र के शीर्ष में, संग्रहित निक्षेप में, और genesis घोषणा में प्रकाशित है। यह कभी चुपचाप नहीं बदलती: जो कुंजी पुरानी कुंजी से हस्ताक्षरित कथन के बिना बदल जाए वह किसी समझौते से अभेद्य है, और उसे वैसा ही माना जाना चाहिए।
कुंजी जहाँ से सुविधाजनक हो वहाँ से लें और फिर जो मिला उसे ऊपर की पंक्ति से मिलाएँ। जिस कुंजी फ़ाइल का फ़िंगरप्रिंट वही हो वह परियोजना कुंजी है, चाहे कोई भी होस्ट उसे आपको दे, और जिसका फ़िंगरप्रिंट कुछ और हो वह बेकार है, चाहे होस्ट कितना ही भरोसेमंद क्यों न दिखा हो।
तीन जगहें उसे रखती हैं। उनमें से कोई भी चलेगी:
# 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
फिर, उस पर निर्भर होने से पहले, पुष्टि करें कि आपके keyring में क्या आया:
gpg --fingerprint E72439CEDD8511F9D607550B87FD60D5EB4A0B29
keys.openpgp.org का उपयोग न करेंकई GnuPG बिल्ड में यह डिफ़ॉल्ट keyserver है, और यह एक छँटी हुई प्रति परोसता है: सिर्फ़ नंगा
public-key पैकेट, बिना किसी user ID और बिना स्व-हस्ताक्षर के। GnuPG उस प्रति को मना कर देता है —
gpg: key 87FD60D5EB4A0B29: new key but contains no user ID - skipped — और
कुंजी keyring में कभी नहीं आती, इसलिए नीचे का सत्यापन ऐसे विफल होता है जो ख़राब हस्ताक्षर जैसा दिखता है पर
असल में एक ग़ायब कुंजी है। वह सर्वर नीति के तहत user ID तब तक छाँट देता है जब तक उसके ज़रिए कोई पता
पुष्ट न हो जाए, और यह ऐसी चीज़ नहीं जो कोई छद्मनामी परियोजना कर सके।
gpg --verify SHA256SUMS.randomx.asc SHA256SUMS.randomx
आज यह No such file or directory बताता है,
क्योंकि किसी रिलीज़ ने अभी तक वह फ़ाइल प्रकाशित नहीं की है। इस अनुभाग के शीर्ष पर दी गई टिप्पणी देखें।
gpg यह भी जोड़ेगा कि कुंजी किसी विश्वसनीय हस्ताक्षर से प्रमाणित नहीं है। यह
अपेक्षित है और कोई विफलता नहीं है। इसका मतलब है कि आपने अपने keyring को नहीं बताया कि आप
व्यक्तिगत रूप से इस कुंजी की ज़मानत लेते हैं, और फ़िंगरप्रिंट ठीक इसी बात को निपटाने के लिए है। मायने यह
रखता है कि हस्ताक्षर सत्यापित हो, और जिस कुंजी के विरुद्ध वह सत्यापित हुआ वही ऊपर छपा फ़िंगरप्रिंट हो।
श्वेतपत्र पर भी हस्ताक्षर है#
इस साइट से परोसे गए PDF के साथ उसी कुंजी से बना एक अलग हस्ताक्षर रखा है:
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
पुनर्निर्माण — वह जाँच जो वास्तव में प्रमाणपत्र की जगह लेती है#
एक हैश आपको बताता है कि फ़ाइल रास्ते में बदली नहीं गई। वह इस बारे में कुछ नहीं कहता कि प्रकाशक ने उसमें क्या डाला। यह कहता है:
git clone https://gitlab.com/zycord-group/zycord-node.git
cd zycord-node
git checkout v<version>
make build
sha256sum bin/zcd bin/zycordd
रिलीज़ के SHA256SUMS.binaries से मिलान करें। उन्हें बिलकुल मेल खाना
चाहिए। अगर वे मेल खाते हैं, तो आपकी डाउनलोड की हुई बाइनरी में यही स्रोत है और कुछ नहीं
— ऐसा दावा किसी प्रमाणपत्र ने कभी किसी चीज़ के बारे में नहीं किया।
Go toolchain उसी का हिस्सा है जिसे आप पुनरुत्पादित कर रहे हैं#
वह है go1.26.2। एक ही स्रोत को दो अलग Go रिलीज़ से कंपाइल करने पर दो अलग
बाइनरी बनती हैं; यह कोई बारीकी नहीं, यह मापने योग्य है — इसी रिपॉज़िटरी के रिलीज़
वर्कफ़्लो ने एक बार एक ही कमिट और एक ही फ़्लैग सेट के लिए तीन अलग SHA-256 मान दर्ज किए थे, प्रति
Go संस्करण एक। इसलिए make build GOTOOLCHAIN=go1.26.2 को पिन करता है और अगर
वह toolchain इस्तेमाल न कर सके तो व्याख्या के साथ रुक जाता है, बजाय इसके कि ऐसा बेमेल पैदा करे जो उसी
छेड़छाड़ जैसा दिखे जिसे पकड़ने के लिए यह पूरा पृष्ठ मौजूद है।
दो नतीजे जो रखने लायक हैं:
- आपको ऊपर लिखे संस्करण पर भरोसा नहीं करना पड़ता। जारी की गई बाइनरी ख़ुद उसे
बताती है:
go version -m zcdउस toolchain को छापता है जिसने उसे बनाया, मॉड्यूल और बिल्ड फ़्लैग के साथ। अगर वह पंक्ति औरMakefileका पिन कभी असहमत हों, तो बाइनरी उस तरह नहीं बनी जैसा यह पृष्ठ कहता है। - कोई पुराना टैग चेकआउट करने पर उसका स्रोत उसके पिन के साथ आता है, इसलिए परियोजना के नए Go पर जाने के बाद भी पुरानी रिलीज़ का पुनर्निर्माण काम करता रहता है।
यहाँ लाइन एंडिंग स्रोत का हिस्सा हैं#
wallet/webui वॉलेट फ़्रंटएंड को //go:embed से जड़ता है, इसलिए उन
फ़ाइलों के लाइन एंडिंग बाइनरी में बाइट हैं: CRLF में बदला गया चेकआउट उसी कमिट से अलग
zcd बनाता है — एक ऐसा बेमेल जिसका कारण निर्दोष है और रूप डरावना।
* text=auto eol=lf रखने वाली .gitattributes हर प्लेटफ़ॉर्म और हर git
कॉन्फ़िगरेशन पर वर्किंग ट्री में LF देती है, इसलिए एक ताज़ा क्लोन हर जगह
वही उत्तर देता है।
दो स्थितियाँ जो इसमें शामिल नहीं: उस फ़ाइल से पुराने टैग का पुनर्निर्माण (चेकआउट से पहले
core.autocrlf=input सेट करें), और core.autocrlf=true के साथ बना पहले से
मौजूद क्लोन, जो pull करने पर ठीक नहीं होता।
-randomx आर्काइव रचना से ही पुनरुत्पाद्य नहीं हैंRandomX C++ में है, इसलिए cgo बिल्ड आउटपुट में सिस्टम का C toolchain ले आता है और कोई उसे
बाइट-दर-बाइट दोबारा नहीं बना सकता। उन आर्काइव का चेकसम SHA256SUMS.randomx में है और
वे जानबूझकर SHA256SUMS.binaries से अनुपस्थित हैं, जो बताता है कि आपके
स्रोत से बनाए बिल्ड का हैश क्या होना चाहिए। यही वह इकलौती जगह है जहाँ
नेटवर्क से जुड़ने वाली श्रेणी और अनुप्रमाणित श्रेणी आपस में नहीं मिलतीं — दो-श्रेणी वाली तालिका
इंस्टॉलेशन के तहत देखें।
इसे बताना ही मक़सद है: यह आपका निर्णय हो, आपके लिए मान ली गई कोई बात नहीं।
कार्यान्वयन को प्रोटोकॉल के विरुद्ध जाँचें#
किसी बाइनरी की उत्पत्ति जाँचने से अलग, आप यह भी जाँच सकते हैं कि वह प्रोटोकॉल को लागू करती है या नहीं। golden vectors ही प्रोटोकॉल हैं; जो स्वतंत्र कार्यान्वयन उन्हें पास कर ले वह एक पीयर है, 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 ही सबसे ज़्यादा मायने रखने वाली कमांड है: कोई लॉन्च घोषणा हफ़्तों पहले
कोड टैग, पैरामीटर हैश और genesis id के प्रति प्रतिबद्ध होती है — और यह उन सबको किसी भी
मशीन पर, स्रोत से, मिलीसेकंडों में दोबारा बना देती है। सार्वजनिक testnet के मान
testnet पृष्ठ पर हैं; जो बिल्ड इनसे अलग मान छापे वह किसी और चेन का
बिल्ड है, और वह जुड़ेगा नहीं।
स्वतंत्र अनुप्रमाणन#
एक व्यक्ति द्वारा किसी टैग का पुनर्निर्माण यह सिद्ध करता है कि वह टैग पुनरुत्पाद्य है। कई अजनबियों द्वारा उसका पुनर्निर्माण करके परिणाम पर हस्ताक्षर करना इससे कहीं ज़्यादा सिद्ध करता है, और गंभीर परियोजनाएँ ठीक इसी कारण इस तरीक़े पर पहुँची हैं। एक टैग दोबारा बनाएँ, फिर जो digest मिला और जो टैग आपने बनाया, उसे घोषणा थ्रेड में पोस्ट करें — तब भी जब वह मेल न खाए, क्योंकि वही सुनने लायक़ मामला है।