Bitcoin’in kaynak kodları https://github.com/bitcoin/bitcoin adresindedir. Bu repository altında src dizininde chainparams.cpp adında bir dosya vardır.

Öncelikle belirtelim Bitcoin C++ ile yazılmıştır. chainparams.cpp altında Genesis Block’u oluşturan iki adet statik fonksiyon tanımlanmıştır. Bunların kodları aşağıdadır:
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
CMutableTransaction txNew;
txNew.nVersion = 1;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = genesisReward;
txNew.vout[0].scriptPubKey = genesisOutputScript;
CBlock genesis;
genesis.nTime = nTime;
genesis.nBits = nBits;
genesis.nNonce = nNonce;
genesis.nVersion = nVersion;
genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
genesis.hashPrevBlock.SetNull();
genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
return genesis;
}
/**
* Build the genesis block. Note that the output of its generation
* transaction cannot be spent since it did not originally exist in the
* database.
*
* CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
* CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
* CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
* CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
* vMerkleTree: 4a5e1e
*/
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
Daha önceki yıllarda incelediğimde Unique Genesis Block’u oluşturan bir kod vardı, Unique Genesis Block’u oluşturmak için 6 elemanlı bir rastgele sayısı dizisi private hash olarak üretilip kullanılıyordu. Deploy edilmiş Bitcoin hala böyle olması gerekiyor, çünkü Blockchain’in değiştirilmemesi lazım. Ancak şimdi incelediğimde Genesis Block üretiminin değiştirildiğini ve PubKey’in CScript ile üretildiğini görüyorum. Bu kaynak kod geliştiricilere özel sunulmuş olabilir halen production’daki Bitcoin 6 elemanlı rastgele sayı dizisini Genesis block’un private key’i olarak kullanıyor olabilir. Bunu bilmiyoruz. Ancak eğer öyleyse productionda bir güvenlik zayıflığı var demektir.
Şu anki sürümde CScript’te Hexadecimal bir sayı gönderiliyor ve araştırma yaptığımızda bu CScript’ten PubKey’in extract edilmesinin mümkün olduğunu anlaşılıyor. CScript’ten PubKey’i extract etmek için şu adrese bakabilirsiniz. https://www.programcreek.com/cpp/?CodeExample=extract+pub+key
Ayrıca bu adreste coinbase’deki PubKey ortaya çıkartılmış durumda: https://ma.ttias.be/retrieving-the-genesis-block-in-bitcoin-with-bitcoin-cli/ Yani bitcoin merkezinin Coinbase olduğunu anlıyoruz.
Evet yukarıdaki fonksiyonlar haricinde Main fonksiyonu içerisinde aşağıdaki kodları görmek mümkün:
genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
Bu kodlardaki assert’lerden sanki Genesis Block’un ve Merkle Root’un Bitcoine özel sabit bir hashi olduğunu anlamak mümkün.
Bu durumda 0. block yani Genesis Block’u ile ilgili bilinmeyen bir şey yok gibi duruyor, bu durumda 1. block’a bakmamız lazım. 1. block’ta da muhtemelen cüzdandan alınan private key’i gizli parametre olarak kullanılıyor, bu durumda güvenlik maksimize edilmiş görünüyor.
Sonuç:
Bitcoin’in önceki sürümlerinde bir güvenlik zayıflığı vardı. Çünkü 6 elemanlı rastgele sayısı dizisi Genesis Block’un private key’i olarak kullanılıyordu. Şimdi ise Genesis block açıkça statik ve sabit bir hashe kavuşmuş. Cüzdanların private key’leri ile bir güvenlik sağlanmış. Bu durumda Satoshi Nakamoto’nun gizli bir cüzdanı olduğu sonucuna varabiliriz. Bu durumda Satoshi Nakamoto (minimum) ilk iki block’la ilgili tüm bilgilere sahip özel biri oluyor. Ve bitcoin ekibi, kurucuları ilk blocklardaki tüm detayları biliyorlar. Private key’leri de biliyorlar. Peki bu ona ve onlara ne avantaj sağlar?
Buradan yola çıkarak diğer block’lardaki private key’leri tespit edebilirler mi? Bunun için SHA256 hash algoritmasını decrypt etmeyi çözmeleri lazım. Olası bir teorimi paylaşmak istiyorum.
- cüzdan private key’ini SHA256 ile şifreleyelim.
- PreviousHash+Block+SHA256(PrivateKey) tekrar SHA256 ile şifreleyip Public Key hashini üretelim
Diğer kodları incelemediğim için teorik olarak Bitcoin’in güvenli olduğunu, SHA256 hashi kırılmadığı sürece bir sıkıntı olmadığını söyleyebilirim. Ancak aşağıdaki makalede 1500 qubitlik bir kuantum bilgisayar ile SHA256 güvenlik algoritmasının kırılabileceği tahmin edilmiş.
https://www.forbes.com/sites/billybambrough/2019/10/02/could-google-be-about-to-break-bitcoin/
Ve uzun zamandır 2000 qubitten fazla quantum bilgisayarlar çıkmış durumda. SHA256’nın kırılmak üzere olduğunu anlaşıldığı için SHA3 çıkartıldı.
Ve NIST kuantum bilgisayarlara dirençli güvenlik algoritmaları üzerinde bir taraftan çalışıyor: https://csrc.nist.gov/Projects/post-quantum-cryptography
SHA256 kırılmak üzere olduğundan post-kuantum güvenlik algoritmalarına geçmeye öncelik vermeliyiz.
Mutlu kodlamalar 🙂