Disclaimer : บทความนี้เกิดขึ้นจากการที่ผมสงสัยว่า seed phrase ที่เราจด ๆ กันไว้เนี่ย มันสร้างมาได้ยังไง ผมจึงเข้าไปอ่าน BIP-39 ที่ว่าด้วยเรื่องการสร้าง 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 นั้นต้องสร้างขึ้นจากข้อมูลทางคอมพิวเตอร์ที่เค้าเรียกว่า 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