**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**