- ผสานการเข้ารหัสแบบโฮโมมอร์ฟิก (Homomorphic Encryption) เข้ากับ CRDTs เพื่อรักษาความปลอดภัยของเอกสารที่ทำงานร่วมกันในซอฟต์แวร์แบบ local-first
- การเข้ารหัสแบบ end-to-end เพียงอย่างเดียวทำให้เซิร์ฟเวอร์ไม่สามารถรวมข้อมูลได้ จึงเกิด ข้อจำกัด ด้านการซิงก์และประสิทธิภาพของการอัปเดต
- การเข้ารหัสแบบโฮโมมอร์ฟิก เป็นเทคโนโลยีที่ทำให้สามารถ รันโปรแกรม เพื่อรวมการอัปเดต CRDT บนเซิร์ฟเวอร์ได้ โดยที่ไม่ต้องรู้เนื้อหาของข้อมูล
- แต่ด้วย ข้อจำกัดเชิงพื้นฐานของการเข้ารหัสแบบโฮโมมอร์ฟิก (ประสิทธิภาพที่ลดลง, พื้นที่และปริมาณการคำนวณที่เพิ่มขึ้น, ความจำเป็นที่โค้ดต้องทำงานตามกรณีเลวร้ายที่สุด) ทำให้การนำไปใช้จริงมี อุปสรรคสำคัญ
- มีการวิจัยแนวทางหลากหลายเพื่อให้ CRDTs อยู่ร่วมกับ การประมวลผลอย่างปลอดภัย ได้ แต่ยังคงอยู่ระหว่างการค้นหา คำตอบที่สมบูรณ์
ความท้าทายของ local-first และการทำงานร่วมกันอย่างปลอดภัย
- ในการทำงานร่วมกันระยะไกล เอกสารถูกเก็บในรูปแบบ CRDT ตามแนวทาง local-first แล้วจึงซิงก์เพื่อมอบประสบการณ์การแก้ไขร่วมกัน
- หากมีข้อกำหนดด้านความปลอดภัยที่ทำให้เนื้อหาเอกสารต้องไม่ถูกเปิดเผยต่อบุคคลที่สาม เช่น นักพัฒนาแอป มักนิยมใช้ การเข้ารหัสแบบ end-to-end
- การเข้ารหัสแบบ end-to-end มีการทำงานที่เรียบง่าย แต่เนื่องจากเซิร์ฟเวอร์ซิงก์ไม่สามารถรวมข้อมูลได้ จึงเกิด การสื่อสารข้อมูลที่ไม่มีประสิทธิภาพ เมื่อทำงานแบบอะซิงโครนัสเป็นเวลานาน
การเข้ารหัสแบบโฮโมมอร์ฟิกคืออะไร?
- การเข้ารหัสแบบโฮโมมอร์ฟิก เป็นรูปแบบการเข้ารหัสพิเศษที่ทำให้สามารถรันอัลกอริทึมได้โดยตรงบนข้อมูลที่ถูกเข้ารหัส
- เมื่อนำมาใช้ เซิร์ฟเวอร์ซิงก์จะสามารถ รวมการอัปเดต CRDT ได้โดยไม่ต้องรู้เนื้อหาของข้อมูล
- แบ่งได้เป็น partial homomorphic (รองรับเฉพาะการบวกหรือการคูณอย่างใดอย่างหนึ่ง), leveled/somewhat homomorphic (รองรับทั้งสองแบบได้บางจำนวนครั้ง), และ fully homomorphic (ไม่มีข้อจำกัด) ตามชนิดของการคำนวณที่รองรับ
- เมื่อมีการคำนวณมากขึ้น noise จะสะสมใน ciphertext จนถอดรหัสได้ยาก จึงต้องใช้เทคนิคขั้นสูงอย่าง Bootstrapping
- สามารถสร้าง วงจรบูลีน ทั่วไปได้จากการผสมเกตพื้นฐานอย่าง XOR และ AND บนระดับบิตที่เข้ารหัสแล้ว (0/1)
กรณีตัวอย่างการพัฒนา CRDT ด้วยการเข้ารหัสแบบโฮโมมอร์ฟิก
- ใช้ไลบรารี Rust TFHE-rs เพื่อสร้าง Last Write Wins Register ซึ่งเป็น CRDT แบบตัวแทนหนึ่ง ด้วยการเข้ารหัสแบบโฮโมมอร์ฟิก
- ฟิลด์และเมธอด (การเข้ารหัส/ถอดรหัส) ของ struct แบบ plaintext และ struct แบบเข้ารหัสแทบจะเหมือนกัน แต่มีความแตกต่างสำคัญในลอจิกการ merge จริง
- เนื่องจากการแตกแขนงเส้นทางการทำงาน เช่น
if/else, match อาจเป็นเบาะแสให้ถอดรหัสข้อความลับได้ ในสภาพแวดล้อมที่เข้ารหัสจึงจำเป็นต้อง ประเมินทุกแขนงและทุกลูปทันที
- การเปรียบเทียบเงื่อนไขสำคัญและการรวมข้อมูลล้วนจัดการด้วยตัวดำเนินการ FheBool ระดับบิตและเมธอด
select ทำให้ภายนอกไม่สามารถตรวจจับได้ว่าค่าเปลี่ยนไปภายใต้เงื่อนไขใด
ข้อจำกัดเชิงพื้นฐานของการเข้ารหัสแบบโฮโมมอร์ฟิก
- ความไม่สมดุลระหว่างขนาดกุญแจเข้ารหัสกับข้อมูล: ในตัวอย่าง ข้อมูล 32 ไบต์ต้องใช้ server key ขนาด 123MB (แม้บีบอัดแล้วก็ยัง 27MB) ทำให้ ใช้พื้นที่อย่างไม่มีประสิทธิภาพ อย่างรุนแรง
- ประสิทธิภาพตกลงอย่างมาก: การ merge CRDT ที่เข้ารหัสแบบโฮโมมอร์ฟิกถูกวัดได้ว่าช้ากว่าแบบไม่เข้ารหัสประมาณ 2 พันล้านเท่า หรือราว 1 วินาที
- หากลูปหรือการแตกแขนงเปลี่ยนไปตามค่าป้อนเข้า จะเกิดการเปิดเผยข้อมูลได้ จึงต้องใช้จำนวนการคำนวณและหน่วยความจำตาม กรณีเลวร้ายที่สุด เสมอ
- ตัวอย่างเช่น แม้ key-value จะมีความหนาแน่นต่ำอย่างใน last-write-wins map ก็ยังต้องรวมข้อมูลโดย เติมทุกคีย์ให้ครบตามขนาดคงที่ ส่งผลให้ความสามารถในการขยายระบบลดลงอย่างมาก
- ต้องออกแบบให้ผู้สังเกตการณ์ภายนอก ไม่สามารถอนุมานได้ จากโครงสร้าง ciphertext หรือประวัติการเปลี่ยนแปลง ว่าค่าเปลี่ยนไปหรือมีการอัปเดตส่วนใด
บทสรุปและแนวโน้ม
- CRDTs กับการเข้ารหัสแบบโฮโมมอร์ฟิก แม้ในทางทฤษฎีจะผสานกันได้อย่างเป็นธรรมชาติ แต่ในทางปฏิบัติกลับมี ข้อจำกัดร้ายแรง ด้านประสิทธิภาพเชิงเวลา/พื้นที่และโครงสร้างโปรแกรม
- ณ เวลานี้ยังไม่มีโซลูชันที่ใช้งานได้จริงอย่างสมบูรณ์ แต่ตัว CRDTs เองก็ยังเป็นเทคโนโลยีที่ค่อนข้างใหม่และยังมี การวิจัยอย่างต่อเนื่อง
- สำหรับแอปทำงานร่วมกันแบบ local-first ความเป็นไปได้ของโซลูชันนวัตกรรมที่สร้างสมดุลระหว่าง ความปลอดภัยและการใช้งานจริง ยังเปิดกว้างอยู่
1 ความคิดเห็น
ความคิดเห็นใน Hacker News
แม้จะเป็นความจริงที่วงการ Fully Homomorphic Encryption นั้นช้าและไม่มีประสิทธิภาพมาก แต่ก็อยากชี้ให้เห็นว่านี่เป็นสาขาที่ค่อนข้างใหม่ซึ่งเพิ่งปรากฏในปี 2009 และความก้าวหน้าในช่วง 15 ปีที่ผ่านมาเรียกได้ว่าน่าทึ่งมาก สคีม homomorphic encryption รุ่นแรกต้องใช้คีย์ขนาดระดับ TB/PB และการ bootstrapping (กระบวนการจำเป็นเมื่อมีการคำนวณแบบคูณมากขึ้นใน homomorphic encryption) ใช้เวลาหลายพันชั่วโมง แต่ตอนนี้คีย์เหลือเพียงราว 30MB และ bootstrapping ทำได้ภายใน 0.1 วินาที หวังว่ามันจะพัฒนาต่อไปจนถึงวันที่นำไปใช้งานจริงได้
CRDT ยุคแรกๆ (CRDT: Conflict-free Replicated Data Type) ก็ใช้งานจริงแทบไม่ได้เหมือนกัน เช่น WOOT แต่ฐานข้อมูล CRDT รุ่นใหม่ทุกวันนี้มีประสิทธิภาพด้อยกว่า LSM ทั่วไปไม่มากนัก ตัวอย่างเช่น RDX CRDT ทำงานด้วยอัลกอริทึมคล้าย merge sort ทำให้ทั้งหมดเป็น O(N) และใน implementation ส่วนใหญ่ก็ยังควบคุม metadata overhead ได้ดี ดู WOOT, librdx, go-rdx
ด้วยลักษณะสถาปัตยกรรมของ CRDT มันจึงหลีกเลี่ยงความช้าได้ยาก และแม้แต่อัลกอริทึมที่ดีที่สุดก็มีต้นทุนเชิงโครงสร้างสูง พอเอา homomorphic encryption มารวมด้วย ความยากก็สูงขึ้นมาก น่าประทับใจจริง แต่ก็สงสัยว่าใช้งานได้จริงแค่ไหน โดยอ้างคำอธิบายนี้เป็นหลักฐานว่า "เพื่อให้เซิร์ฟเวอร์คำนวณแมปใหม่ได้ มันต้อง merge ทุกคีย์ทีละตัว แล้วจึงส่งทั้งแมปไปยังแต่ละ peer—เพราะจากมุมมองของเซิร์ฟเวอร์ แมปทั้งก้อนแตกต่างกันทุกครั้ง"
CRDT ย่อมาจาก Conflict-free Replicated Data Type เป็นชนิดข้อมูลพิเศษที่ทำให้ซิงก์แบบกระจายได้โดยไม่มีความขัดแย้ง ดู ลิงก์วิกิพีเดียของ CRDT
ในบทความมีการพูดถึงว่าประสิทธิภาพยังไม่พอ ซึ่งในความเป็นจริง ถ้ารัน last write wins register แบบปกติบน M4 MacBook Pro จะใช้เวลา merge 0.52 นาโนวินาที แต่เวอร์ชันที่เข้ารหัสแบบ homomorphic ใช้เวลา 1.06 วินาที นั่นหมายความว่าความเร็วต่างกันถึง 2 พันล้านเท่า เป็นตัวเลขที่ช็อกมาก
FHE (Full Homomorphic Encryption) ช้ามากจริง แต่ก็มีความก้าวหน้าอย่างน่าทึ่งตั้งแต่ปี 2009 โดยเฉพาะความเร็วของ bootstrapping ที่เร็วขึ้นระดับหลายสิบล้านเท่า มีการสาธิต AES-128 บนพื้นฐาน homomorphic encryption แล้วโดยใช้ tfhe-rs และทำให้คิดได้ว่าความเป็นไปได้ของการนำ FHE มาใช้แบบเรียลไทม์สำหรับ AI inference/training กำลังสูงขึ้นเรื่อยๆ ดู ลิงก์ GitHub ของ tfhe-aes-128
ไม่เห็นด้วยกับข้อความที่บอกว่าเซิร์ฟเวอร์ไม่สามารถเข้าใจการเปลี่ยนแปลงของไคลเอนต์ได้อีกต่อไป จริงๆ แล้วเซิร์ฟเวอร์แค่ส่งเฉพาะการเปลี่ยนแปลงที่ผู้ใช้ยังไม่เคยเห็น จากนั้นผู้ใช้ก็ถอดรหัสและ merge เองเพื่อสร้างเอกสารเวอร์ชันล่าสุด Homomorphic encryption น่าสนใจก็จริง แต่แทบไม่เหมาะกับสถานการณ์ที่ต้องการประสิทธิภาพหรือแบนด์วิดท์อย่างสมเหตุสมผล ก่อนหน้านี้เคยเห็นงานวิจัยเกี่ยวกับ fully confidential computing บนพื้นฐาน homomorphic encryption (เข้ารหัส CPU+RAM แบบคัสตอม แล้วประมวลผลหนึ่งคำสั่งต่อหนึ่งสัญญาณนาฬิกา) มันทำงานได้จริง แต่เร็วแค่ประมาณ 1 คำสั่งของ virtual CPU ต่อวินาที ถ้ารับความเร็วและต้นทุนระดับนี้ได้ ก็ควรรันบนเครื่องตัวเองไปเลย หรือถ้ารวยมากก็ซื้อฮาร์ดแวร์มาประมวลผลในเครื่องเองจะฉลาดกว่า
งานวิจัยด้านวิทยาการคอมพิวเตอร์และคริปโตกราฟีมักมีเนื้อหาที่ห่างไกลจากการใช้งานจริงอยู่บ่อยๆ เช่น ลดความซับซ้อนของการโจมตีจาก 2^250 เหลือ 2^230 ซึ่งดูไม่สมจริงอย่างมาก แต่งานแบบนี้ก็ยังมีความหมายต่อ R&D จริงและช่วยขยายขอบเขตของสิ่งที่เป็นไปได้
ถ้าเซิร์ฟเวอร์จัดการเนื้อหาโดยตรงไม่ได้ มันก็จะ merge เอกสาร CRDT ไม่ได้ และต้องรับแล้วส่งสถานะทั้งหมดของ CRDT ทุกครั้ง ถ้าเพื่อนออนไลน์พร้อมกันก็ยังส่ง operations เพื่อ merge แบบเรียลไทม์ได้ แต่ถ้าไม่ใช่ก็จะไม่มีประสิทธิภาพมาก
สงสัยว่านักเรียนจะยังเชื่อถือได้หรือไม่ถ้าปล่อยให้พวกเขารันโค้ดตรวจให้คะแนน WASM หรือ JS ที่เข้ารหัสด้วย FHE เองบน Chromebook ผ่าน JupyterLite กับ ottergrader และก็สงสัยด้วยว่ามันเกี่ยวข้องกับ code signing และ screensaver ของ SETI@home อย่างไร
ไม่แนะนำให้ใช้ THFE-rs เพราะฝั่ง Zama ต้องการไลเซนส์เชิงพาณิชย์หากไม่ใช่การใช้งานเพื่อทำต้นแบบ ทำให้เงื่อนไขไลเซนส์ค่อนข้างลำบาก แนะนำให้ใช้ไลบรารี openFHE (C++) หรือ lattigo (golang) แทน ซึ่งทั้งคู่ใช้เชิงพาณิชย์ได้อย่างอิสระ
คิดว่า FHE โดยเนื้อแท้แล้วไม่เหมาะกับงานนี้ FHE เหมาะกับการจัดการข้อมูลที่เซิร์ฟเวอร์ศูนย์กลางเป็นเจ้าของหรือรับรู้ แต่กรณีนี้มีผู้ใช้หลายคนที่ต้องประมวลผลข้อมูลแบบกระจายร่วมกัน ดังนั้น MPC (multi-party computation: การคำนวณร่วมกันของหลายฝ่ายโดยแต่ละฝ่ายเก็บข้อมูลลับของตัวเองไว้) จึงมีประสิทธิภาพกว่ามาก
ยังไม่ค่อยเข้าใจสมมติฐานที่บทความเสนอ แม้จะเข้าใจแนวคิดของ CRDT และ homomorphic encryption แต่ก็สงสัยว่าทำไมการซิงก์ถึงต้องให้ทั้งสองฝ่ายออนไลน์พร้อมกัน ถ้าใช้วิธี 'store-and-forward' เพื่อรับส่งอัปเดตแบบอะซิงก์ ข้อมูลระหว่างทางก็ยังเข้ารหัสอยู่ได้ แล้วทำไมเซิร์ฟเวอร์ถึงต้องเก็บสถานะไว้ด้วย (และยังเป็นสถานะที่เข้ารหัส) รวมถึงทำไมต้องแก้แบบที่เสนอไว้ด้วย
รู้สึกขำดีที่เอาความช้าและความไม่มีประสิทธิภาพของ FHE มาผสมกับการสิ้นเปลืองพื้นที่จัดเก็บของ CRDT