#

seedphrase

(3 articles)

Seed Phrase สร้างยังไง ?

**Disclaimer** : บทความนี้เกิดขึ้นจากการที่ผมสงสัยว่า seed phrase ที่เราจด ๆ กันไว้เนี่ย มันสร้างมาได้ยังไง ผมจึงเข้าไปอ่าน [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) ที่ว่าด้วยเรื่องการสร้าง seed phrase (mnemonic code) สำหรับนำมาสร้าง seed และได้เขียนสรุปความเข้าใจของผมเพื่อเรียบเรียงความรู้ในหัวเก็บไว้ เผื่อว่าจะเป็นประโยชน์กับคนที่เกิดความสงสัยเหมือนกันกับผม ถ้าผมเข้าใจผิดตรงไหนสามารถบอกกันได้เลยนะครับ ## ทำไมต้องมี BIP-39 ? BIP-39 เกิดขึ้นเพราะว่ามนุษย์นั้นสามารถจดหรือจำคำได้ง่ายกว่าจดหรือจำข้อมูลในรูปเลขฐานสอง (binary) หรือเลขฐานสิบหก (hexadecimal) จึงมีคนเสนอให้สร้าง mnemonic code หรือที่เราเรียกกันว่า seed phrase ขึ้นมา ซึ่งจะประกอบไปด้วย 2 ส่วนคือ การสร้าง seed phrase และการแปลง seed phrase ให้การเป็น seed ที่สามารถนำไปใช้ในการสร้าง private key และ public key ต่อได้ ## Seed Phrase สร้างยังไง ? seed phrase นั้นต้องสร้างขึ้นจากข้อมูลทางคอมพิวเตอร์ที่เค้าเรียกว่า **entropy** ที่มี**จำนวน bits หารด้วย 32 ลงตัว**และมี**จำนวน bits อยู่ระหว่าง 128 - 256 bits** ยิ่ง entropy มีจำนวน bits มากก็จะทำให้มีความปลอดภัยมากขึ้นแต่ก็จะมีจำนวนคำมากขึ้นเช่นกัน ซึ่งการสร้าง seed phrase นั้นมีขั้นตอนดังนี้ #### Step - 1 สุ่ม entropy ที่มีจำนวน bits อยู่ระหว่าง 128 - 256 bits และจำนวน bits ต้องหารด้วย 32 ลงตัว ซึ่งหลังจากนี้จะแทนจำนวน bits นี้ด้วยคำว่า ENT ตัวอย่าง entropy ที่มี ENT เท่ากับ 128 bits `00110010010101010111100101001011001101100100101001000100001100010111001101110100001110010011011101000101011010100101000101010011` #### Step - 2 คำนวณหา checksum bits ที่มีจำนวน bits เท่ากับค่า ENT หารด้วย 32 โดยการ hash entropy ด้วย SHA256 algorithm และนำผลลัพธ์มาตัดเอาแค่ส่วนหัวตามจำนวน bits ที่ต้องการ ผมนำ entropy จาก step ก่อนหน้ามาทำ `sha256_hashing(entropy)` ได้ผลลัพธ์ออกมาเป็น `01100111.........` และจะได้ (128 / 32) = 4 bits แรกคือ `0110` ซึ่งหลังจากนี้จะแทนความยาวของ checksum bits ด้วยคำว่า CS #### Step - 3 นำ checksum bits ที่ได้มาต่อท้าย entropy จะได้เป็นกลุ่มของ bits ที่มีความยาวเท่ากับ ENT + CS ผมนำ 4 bits แรกจาก step ก่อนหน้ามาต่อท้าย entropy ที่มี 128 bits ดังนี้ `"00110010010101010111100101001011001101100100101001000100001100010111001101110100001110010011011101000101011010100101000101010011" + "0110"` #### Step - 4 นำกลุ่มของ bits มาแบ่งเป็นกลุ่มย่อย กลุ่มละ 11 bits จะทำให้ได้กลุ่มทั้งหมดจำนวน (ENT + CS) / 11 กลุ่ม ซึ่งถ้า entropy มีจำนวน 128 bits ก็จะแบ่งกลุ่มได้ (128 + 4) / 11 = 12 กลุ่ม ผมแบ่งกลุ่มได้ตามนี้ `00110010010 10101011110 01010010110 01101100100 10100100010 00011000101` `11001101110 10000111001 00110111010 00101011010 10010100010 10100110110` #### Step - 5 นำกลุ่มย่อยแต่ละกลุ่มมาแปลงเป็นเลขฐานสิบซึ่งจะมีค่าตั้งแต่ 0 - 2047 และสามารถนำไปเทียบกับ wordlist ที่กำหนดไว้ใน BIP-39 ตาม index จะได้ผลลัพธ์เป็น seed phrase ที่สามารถนำไปสร้าง seed ต่อไปได้ ผม map เลขฐานสิบกับ wordlist ได้เป็น seed phrase ตามนี้ `00110010010 => 402 = crane` `10101011110 => 1374 = profit` `01010010110 => 662 = fan` `01101100100 => 868 = hold` `10100100010 => 1314 = picture` `00011000101 => 197 = board` `11001101110 => 1646 = soccer` `10000111001 => 1081 = mango` `00110111010 => 442 = dance` `00101011010 => 346 = clip` `10010100010 => 1186 = nephew` `10100110110 => 1334 = plug` ## Wordlist wordlist ที่ BIP-39 กำหนดขึ้นมานั้นมีลักษณะดังนี้ - เลือกกลุ่มคำที่สามารถพิมพ์แค่ 4 ตัวอักษรก็สามารถระบุได้ว่าเป็นคำไหน - เลี่ยงคำที่มีหน้าตาคล้าย ๆ กัน เช่นใน wordlist จะมีคำว่า build แต่ไม่มีคำว่า built เพราะอาจจะทำให้สับสนได้ - เรียงลำดับคำตามตัวอักษรเพื่อจะได้หาได้ง่าย - ตัวอักษรในคำสามารถประกอบด้วยภาษาอะไรก็ได้แต่ว่าต้องอยู่ในรูปของ UTF-8 encoding แต่ผมว่าเป็นภาษาอังกฤษน่าจะจำง่ายที่สุด ## จำนวน bits ของ entropy และจำนวน word ที่ได้ entropy **128 bits** จะมี **4 bits** checksum ได้เป็น seed phrase **12 word** entropy **160 bits** จะมี **5 bits** checksum ได้เป็น seed phrase **15 word** entropy **192 bits** จะมี **6 bits** checksum ได้เป็น seed phrase **18 word** entropy **224 bits** จะมี **7 bits** checksum ได้เป็น seed phrase **21 word** entropy **256 bits** จะมี **8 bits** checksum ได้เป็น seed phrase **24 word**

จาก Seed Phrase สู่ Binary Seed

## การสร้าง Seed จาก Seed Phrase ในการสร้าง Binary Seed นั้นจะใช้ function ชื่อว่า [PBKDF2](https://cryptobook.nakov.com/mac-and-key-derivation/pbkdf2) ซึ่งหน้าตาจะเป็นแบบนี้ ` pbkdf2(password, salt, iterations-count, hash-function, derived-key-len) ` แต่ละ parameters จะแทนค่าตามนี้ - `password` คือ mnemonic sentence หรือ seed phrase (encoded in UTF-8) ยกตัวอย่างเช่น `craneprofitfanholdpictureboardsoccermangodanceclipnephewplug` - `salt` คือ คำว่า "mnemonic" + passphrase (encoded in UTF-8) หรือ ถ้าไม่มี passphrase ก็จะเป็นแค่คำว่า "mnemonic" คำเดียว ยกตัวอย่างเช่น กรณีมี passphrase ก็คือ `mnemonichelloworld` หรือ กรณีไม่มี passphrase ก็คือ `mnemonic` - `iterations-count` คือ 2048 - `hash-function` คือ HMAC-SHA512 - `derived-key-len` คือ 512 bits หรือ 64 bytes ค่า binary ที่ได้ออกมาจาก function จะมีความยาวตาม `derived-key-len` ก็คือ 512 bits ซึ่งสามารถนำค่านี้ไปสร้าง deterministic wallets ตาม [BIP-32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) ได้