Go เวอร์ชั่น 1.22 เปลี่ยนโครงสร้างภายในของไลบรารี math/rand เป็นเวอร์ชั่น 2 โดยแกนกลางสำคัญคือการเปลี่ยนอัลกอริทึมจากเดิมที่เคยเป็น linear-feedback shift register แบบง่ายๆ ทำงานได้เร็ว มาเป็นตัวสร้างเลขสุ่มแบบ PCG และ ChaCha8 หลายเดือนหลังปรับปรุงทีมงานก็ออกมาอธิบายแนวคิดเบื้องหลัง
ระบบสร้างเลขสุ่มทั้งสองแบบมีเป้าหมายคล้ายกัน คือ สถานะภายในมีขนาดใหญ่ขึ้น ทำให้กระบวนการสร้างเลขสุ่มมีคุณภาพดีขึ้น จุดที่น่าสนใจคือ ChaCha8 นั้นเป็นตัวสร้างเลขสุ่มที่ลดรูปมาจาก ChaCha20 ที่กูเกิลเสนอให้ใช้สำหรับเข้ารหัสข้อมูลเว็บในอุปกรณ์ที่พลังประมวลผลต่ำ ทุกวันนี้ ChaCha20 ยังคงมีการใช้งานเป็นวงกว้างและความปลอดภัยภัยดีพอ ทีมงาน Go นั้นอ้างอิงรายงานที่ระบุว่าการลดรอบการทำงานของ ChaCha ลงก็ยังมีความปลอดภัยเพียงพอทำให้เลือกใช้ ChaCha8 ที่ความเร็วสูงกว่า ChaCha20 หนึ่งเท่าตัว
การสร้างเลขสุ่มอย่างปลอดภัยเช่นการสร้างกุญแจลับนั้นปกติแล้วควรใช้ไลบรารี crypto/rand ซึ่งจะพยายามใช้เลขสุ่มอย่างแท้จริงโดยอาศัยแหล่งความยุ่งเหยิง (entropy) จากแหล่งต่างๆ เช่นการขยับเมาส์หรือระยะเวลาเน็ตเวิร์ค แต่กระบวนการนี้ทำงานช้ามาก ChaCha8 ของ math/rand/v2 นี้ใช้ค่าเริ่มต้น (seed) เป็นค่าสุ่มอย่างปลอดภัยขนาด 300 ไบต์ แต่หลังจากนั้นก็รันอัลกอริทึมสุ่มค่าอย่างรวดเร็ว ทำให้ความเร็วของการสุ่มโดยรวมยังคงดีอยู่โดยที่มีความปลอดภัยพอสมควร แม้นักพัฒนาจะเอาไปใช้ในส่วนที่ควรใช้ crypto/rand อย่างผิดพลาดก็ยังถูกแกะได้ยาก กระบวนการสร้างเลขสุ่มที่ปลอดภัยขึ้นยังช่วยในกรณีที่ระบบต้องออกหมายเลข UUID จำนวนมากๆ ซึ่งหากระบบออกเลขสุ่มไม่ดีพอก็อาจจะทำให้มีหมายเลข UUID ซ้ำกันได้
ทีมงาน Go ระบุว่าการที่โปรแกรมเมอร์ใช้ตัวสุ่มค่าไม่ปลอดภัย เป็นปัญหาในวงกว้าง ไม่ใช่เฉพาะในโครงการ Go เท่านั้น จึงหวังว่าในอนาคตทุกภาษาจะพยายามปรับปรุงตัวสุ่มค่าให้ปลอดภัยขึ้นด้วยเช่นกัน
ที่มา - Go.dev
Comments
UUID นี้มันแค่ 16 bytes
แต่ seed 300 bytes นี้มัน overhead เกินไปไหม
ผมเองก็ไม่เข้าใจเรื่อง random algorithm เท่าไร เวลา rand เขาเอา bit จากใน seed มาสร้าง random number หรือไง?
พวกนี้มัน seed ทีเดียวแล้วอยู่ยาวตลอด process (หรือ thread) ครับ ดังนั้นอาจจะใช้ออก UUID นับพันนับหมื่นตัวเลย
lewcpe.com, @wasonliw