HashWX
HashWX คือ proof of work เริ่มต้นของ Cap ในขณะที่ SHA-256 ใช้ฟังก์ชันแฮชตายตัว HashWX จะสร้างฟังก์ชันใหม่สำหรับ nonce ทุกบล็อก โดยประกอบจากการดำเนินการกับจำนวนเต็มและการแตกกิ่งที่ GPU รันได้ไม่ดี ผู้ออกแบบคือ tevador คนเดียวกับที่เขียน RandomX และเอกสารการออกแบบของเขาอธิบายหลักการทำงานไว้ Cap ใช้บิลด์ WebAssembly ฉบับอ้างอิงของเขา
HashWX เป็นค่าเริ่มต้นทั้งใน capd และในไลบรารี core
ทำไมไม่ใช้ SHA-256
สิ่งที่สำคัญสำหรับการกันบอทคือผู้โจมตีแก้ challenge ได้กี่ข้อต่อชั่วโมง ไม่ใช่ว่าข้อหนึ่งใช้เวลานานแค่ไหน GPU รันฟังก์ชันตายตัวอย่าง SHA-256 พร้อมกันได้นับพันเลน ก่อน HashWX นั้น Cap ใช้ปริศนา time-lock แบบ RSW ซึ่งทำขนานภายในปริศนาข้อเดียวไม่ได้ แต่ GPU ยังรันปริศนาที่แยกจากกันนับพันข้อพร้อมกันได้ เมื่อวัดเทียบกับ GPU ระดับผู้ใช้ทั่วไป:
| อัลกอริทึม | CPU, Ryzen 3700X, 16 เธรด | GPU, RTX 5060 Ti | GPU ได้เปรียบ |
|---|---|---|---|
| SHA-256 | 41 MH/s | 6150 MH/s | ~150x |
| RSW | 26 H/s | 4400 H/s | ~170x |
| HashWX | 2.8 MH/s | 5.8 MH/s | ~2x |
ตัวเลขชุดนี้เป็นของ tevador จากโค้ด CUDA ของเขาเองที่ยังไม่ได้เผยแพร่ Cap วัดแถว RSW ซ้ำได้ผลตรงกัน โดย M3 ทำได้ 2.11 H/s ต่อเธรด ซึ่งคิดเป็น 26 H/s สำหรับ 16 เธรดของ Ryzen
RSW ถูกเลิกใช้แล้ว ตอนนี้ capd ส่ง HashWX ให้คีย์ที่เคยตั้งเป็น RSW ไลบรารี core ยังออก challenge แบบ RSW ได้เมื่อร้องขอ แต่ไม่ควรเลือกใช้กับระบบที่ติดตั้งใหม่
ต้นทุน
เวลาฝั่งเซิร์ฟเวอร์ต่อ challenge หนึ่งข้อบนคอร์เดียวของ Apple M3 เป็นค่ามัธยฐานจากการสร้าง 200 ครั้งและการตรวจสอบ 40 ครั้ง:
| โปรโตคอล | การสร้าง | การตรวจสอบ | รวม |
|---|---|---|---|
| HashWX, 1 challenge | 14 µs | 40 µs | 54 µs |
| HashWX, 4 challenge ย่อย (ค่าเริ่มต้น) | 20 µs | 129 µs | 149 µs |
| SHA-256, 50 challenge ที่ความยาก 4 | 4 µs | 83 µs | 87 µs |
| RSW, t = 75,000 | 1522 µs | 14 µs | 1536 µs |
ความยากไม่มีผลกับตัวเลขเหล่านี้ เพราะการตรวจสอบคือการแฮชหนึ่งครั้งต่อหนึ่ง challenge ย่อย ไม่ว่าจะใช้เวลาหาคำตอบนานแค่ไหน
ฝั่งไคลเอนต์นั้น challenge เดียวมีเวลาแก้แบบสุ่ม ความยากเท่ากันอาจใช้ 30 มิลลิวินาทีสำหรับผู้เข้าชมคนหนึ่ง และ 3 วินาทีสำหรับคนถัดไป Cap จึงแบ่งความยากออกเป็นสี่ challenge ย่อยเป็นค่าเริ่มต้น เพื่อให้เวลาแก้สม่ำเสมอขึ้น วัดผ่านวิดเจ็ตใน Chrome บน M3 8 คอร์ ชุดละ 72 ครั้ง โดยปรับความยากทั้งสองแบบให้มีค่ามัธยฐานใกล้เคียงกัน:
| 1 challenge, d = 1,330,000 | 4 challenge ย่อย, d = 1,000,000 | |
|---|---|---|
| ค่ามัธยฐาน | 536 ms | 490 ms |
| p90 | 1447 ms | 778 ms |
| ช้าที่สุดใน 72 ครั้ง | 2378 ms | 1490 ms |
คอลัมน์ขวาคือค่าเริ่มต้น เมื่อวัดกับคีย์ของ capd ได้ค่ามัธยฐาน 578 มิลลิวินาที และ p90 0.9 วินาที การแบ่งไม่ได้เปลี่ยนสิ่งที่ผู้โจมตีต้องจ่าย เพราะงานที่คาดหวังยังคงเป็น d แฮชไม่ว่าจะแบ่งอย่างไร
เบราว์เซอร์
บิลด์ WebAssembly ทำงานได้ราว 60% ของความเร็วเนทีฟ วัดบน M3 เครื่องเดียวกัน:
| เบราว์เซอร์ | 1 worker | 8 workers | การถอยไปใช้โหมดตีความ |
|---|---|---|---|
| Chrome 153 | 440 KH/s | 2050 KH/s | 94 KH/s |
| Firefox 156 | 420 KH/s | 1850 KH/s | 105 KH/s |
| Safari 27.2 | 410 KH/s | 1480 KH/s | 105 KH/s |
เมื่อใช้ทุกคอร์ Safari ทำได้ราว 70% ของความเร็ว Chrome ดังนั้นให้ตั้งความยากโดยอิง Safari ที่ค่าเริ่มต้น เวลาแก้จะอยู่ราว 0.5 วินาทีบน Chrome และ 0.7 วินาทีบน Safari
ถ้าจะวัดเอง ให้ใช้บิลด์รุ่นเสถียรและเปิดแท็บไว้หน้าสุด Firefox ที่มาพร้อม Playwright รันงาน WebAssembly ทุกชนิดช้ากว่า Firefox จริงสามถึงหกเท่า และแท็บที่อยู่เบื้องหลังอาจถูกย้ายไปรันบนคอร์ประหยัดพลังงาน
โทรศัพท์มือถือ
ความยากเริ่มต้นบนโทรศัพท์จริงผ่าน BrowserStack เครื่องละ 15 ครั้ง ทุกรอบเริ่มจากหน้าที่เพิ่งโหลดใหม่:
| อุปกรณ์ | ระบบปฏิบัติการ | ทุกคอร์ | ค่ามัธยฐาน | ช้าที่สุด |
|---|---|---|---|---|
| Galaxy S24 | Android 14 | 1238 KH/s | 1.1 s | 1.8 s |
| Pixel 9 | Android 15 | 837 KH/s | 1.4 s | 2.0 s |
| Pixel 6 | Android 12 | 746 KH/s | 1.9 s | 2.4 s |
| iPhone 15 | iOS 17 | ไม่ได้วัด | 1.9 s | 4.3 s |
| iPhone 12 | iOS 17 | 620 KH/s | 2.0 s | 3.3 s |
| iPhone 13 | iOS 15 | 678 KH/s | 2.2 s | 4.1 s |
| iPhone SE 2022 | iOS 15 | 588 KH/s | 2.4 s | 4.0 s |
| Redmi Note 11 | Android 11 | 456 KH/s | 2.4 s | 4.8 s |
การแก้แต่ละครั้งรวมการรับส่งข้อมูลไป-กลับกับเซิร์ฟเวอร์ทดสอบสองครั้ง ครั้งละ 80 ถึง 190 มิลลิวินาที หน้าที่รัน HashWX มาแล้วหนึ่งนาทีแก้ได้เร็วขึ้น 24% ถึง 29% ดังนั้นการวัดที่วอร์มอัปก่อนจะได้ตัวเลขดีกว่าสิ่งที่ผู้เข้าชมเจอ
ถ้าทราฟฟิกส่วนใหญ่ของคุณมาจากมือถือ ให้ลดความยากลง เวลาแก้แปรผันตรงกับความยาก ดังนั้น 500,000 จะทำให้ส่วนที่ใช้คำนวณของตัวเลขเหล่านี้ลดลงราวครึ่งหนึ่ง
HashWX ต้องใช้ WebAssembly และบน iPhone ต้องใช้ iOS 15 ขึ้นไป สำหรับเบราว์เซอร์ที่ไม่มี WebAssembly ให้ใช้ SHA-256 ซึ่งมีทางถอยเป็น JavaScript
ข้อจำกัด
ฮาร์ดแวร์เฉพาะทางยังเอาชนะ CPU ได้อยู่ดี FPGA หรือ ASIC ที่สร้างมาเพื่อ HashWX มีต้นทุนออกแบบหลายล้าน ซึ่งไม่คุ้มกับการแก้ CAPTCHA แต่นั่นเป็นเหตุผลทางเศรษฐศาสตร์ ไม่ใช่เหตุผลทางการเข้ารหัสลับ
มันหยุดคนที่ได้รับค่าจ้างให้แก้ challenge ด้วยมือไม่ได้เช่นกัน ใช้มันคู่กับ instrumentation เพื่อให้ต้องมีเบราว์เซอร์จริงด้วย
