
Legion هو بنية مصادقة قائمة على المعرفة الصفرية (Zero-Knowledge) صُمِّمت للخصوصية.
مصادقة حقيقية بالمعرفة الصفرية مع توقيعات حلقية للأجهزة مرتبطة بالعتاد
Legion هو نظام مصادقة بالمعرفة الصفرية بدون كلمة مرور يُثبت أنك مخوَّل دون الكشف عن هويتك.
يمكنك المصادقة باستخدام بصمة إصبعك + عبارة الاسترداد المكوَّنة من 24 كلمة (مثل MetaMask). لا أسماء مستخدمين، لا كلمات مرور، ولا أسرار على جانب الخادم.
git clone https://github.com/deadends/legion.git cd legion
chmod +x scripts/install.sh && ./scripts/install.sh
scripts\install.bat
**هذا كل شيء!** افتح http://localhost في متصفحك.
### ما الذي يتم تثبيته
- ✅ Redis (تخزين الجلسات)
- ✅ Legion Server (التحقق من براهين ZK)
- ✅ الواجهة الأمامية (عميل WASM)
- ✅ Nginx (وكيل عكسي)
**الأداء**: التسجيل ~5 ثوانٍ، المصادقة ~2 دقيقة (توليد برهان k=14)
---
### الإعداد اليدوي (بدون Docker)
<details>
<summary>انقر لتوسيع التثبيت اليدوي</summary>```bash
# 1. Install Redis
# macOS: brew install redis && redis-server
# Ubuntu: sudo apt install redis && redis-server
# Windows: https://redis.io/docs/install/install-redis/install-redis-on-windows/
# 2. Run server (terminal 1)
cd legion-server
cargo run --release --features redis
# 3. Build frontend (terminal 2)
cd wasm-client
wasm-pack build --target web --release
python3 -m http.server 8000
# 4. Open http://localhost:8000
للنشر في الإنتاج، انظر DEPLOYMENT.md
جهاز الاختبار: Lenovo IdeaPad 3 - Intel Core i3 11th Gen
ملاحظة: قد يختلف الأداء اعتمادًا على مواصفات الجهاز.
التفصيل:
التفصيل:
مهم: توليد Params وkeygen تكلفة لمرة واحدة يمكن تخزينها مؤقتًا. بمجرد التخزين المؤقت، يستغرق التحقق ~108-967 مللي ثانية فقط حسب قيمة k. لا يقوم التنفيذ الحالي بتخزين Params مؤقتًا بعد.
لماذا يكون أبطأ من المعايير السابقة؟ تتحقق الدائرة غير المعتمدة على كلمة المرور الآن من شجرتي Merkle (المستخدم + الجهاز) بدلاً من شجرة واحدة، مما يوفر إخفاء هوية حقيقيًا على مستوى الجهاز (جهاز واحد من أصل 1024 جهازًا لكل مستخدم).
📖 للحصول على تدفق مصادقة مفصّل خطوة بخطوة مع تفاصيل التشفير، راجع ARCHITECTURE_FLOW.md
┌─────────────────────────────────────────────────────────────────────────┐ │ CLIENT (Browser + WASM) │ ├─────────────────────────────────────────────────────────────────────────┤ │ ┌────────────────┐ ┌─────────────────┐ ┌──────────────────────────┐ │ │ │ UI Layer │ │ WASM Prover │ │ Local Storage │ │ │ │ (Vanilla JS) │ │ (Rust→WASM) │ │ (IndexedDB) │ │ │ ├────────────────┤ ├─────────────────┤ ├──────────────────────────┤ │ │ │ • Registration │ │ • Blake3 Hash │ │ • Full Merkle Tree │ │ │ │ • Login Form │ │ • BIP-39 Derive │ │ • Device Trees │ │ │ │ • Session UI │ │ • Halo2 Prover │ │ • WebAuthn Credentials │ │ │ │ • Tree Sync │ │ • Merkle Proof │ │ • Tree Version Cache │ │ │ └────────────────┘ │ • Ring Sigs │ └──────────────────────────┘ │ │ └─────────────────┘ │ │ ┌──────────────────────────────────────────────────────────────────┐ │ │ │ Hardware Security (WebAuthn Level 2) │ │ │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ • TPM 2.0 / Secure Enclave • FIDO2 Authenticator │ │ │ │ • Device Private Key (ECDSA) • Biometric/Touch Required │ │ │ └──────────────────────────────────────────────────────────────────┘ │ └────────────────────────────────┬────────────────────────────────────────┘ │ HTTPS/TLS 1.3 │ (Encrypted Channel) ▼ ┌──────────────────────────────────────────────────────────────────────────┐ │ LEGION SERVER (Rust/Axum) │ ├──────────────────────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ API Layer (Axum) │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ POST /api/register-blind │ Blind registration │ │ │ │ GET /api/download-tree │ Download full Merkle tree │ │ │ │ POST /api/verify-anonymous-proof │ Verify ZK proof │ │ │ │ POST /api/verify-session │ Session validation │ │ │ │ POST /api/webauthn/* │ WebAuthn endpoints │ │ │ │ GET /health │ Health check │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Business Logic Layer │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ • Blind Registration │ • Tree Synchronization │ │ │ │ • ZK Proof Verifier │ • Nullifier Tracker (replay) │ │ │ │ • Session Manager │ • Linkability Tag Validator │ │ │ │ • WebAuthn Service │ • Timestamp Validator (±10min) │ │ │ │ • Device Revocation │ • Rate Limiter (5/hour) │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Cryptographic Layer │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ • Halo2 Verifier (PLONK) │ • Poseidon Hash (ZK-friendly) │ │ │ │ • Blake3 (credential) │ • BIP-39 (recovery phrase) │ │ │ │ • Merkle Tree (2^20) │ • Device Trees (2^10 per user) │ │ │ │ • Ring Signature Verify │ • WebAuthn Signature Verify │ │ │ └─────────────────────────────────────────────────────────────────┘ │ └────────────────────────┬──────────────────────┬──────────────────────────┘ │ │ ▼ ▼ ┌────────────────────────┐ ┌───────────────────────────┐ │ Redis (In-Memory) │ │ RocksDB (Persistent) │ ├────────────────────────┤ ├───────────────────────────┤ │ • Session Tokens │ │ • Merkle Tree Leaves │ │ • Linkability Tags │ │ • Device Trees │ │ • Spent Nullifiers │ │ • Nullifier History │ │ • Rate Limit Counters │ │ • WebAuthn Credentials │ │ TTL: 1 hour │ │ • Revoked Devices │ └────────────────────────┘ └───────────────────────────┘
### تدفق المصادقة (مبسّط)```
┌─────────────┐ ┌──────────────┐
│ Client │ │ Server │
│ (Browser) │ │ (Verifier) │
└──────┬──────┘ └──────┬───────┘
│ │
│ 1. Generate 24-word recovery phrase (BIP-39) │
│ → 256-bit entropy (like MetaMask) │
│ → User writes down on paper │
│ │
│ 2. Derive account_id from phrase (Blake3) │
│ account_id = Blake3("LEGION_ACCOUNT_V2" || bip39_seed) │
│ → Deterministic, no server interaction │
│ │
│ 3. Hash account_id for tree leaf (Poseidon) │
│ credential_hash = Poseidon(account_id) │
│ │
│ 4. Blind registration (TRUE zero-knowledge) ────►│
│ → Sends ONLY credential_hash (no phrase/identity) │
│ → Server adds to tree, returns tree_index │
│ ◄────│ {tree_index: 114}
│ │
│ 5. Download full Merkle tree (one-time sync) ────►│
│ → Client stores entire tree in IndexedDB │
│ → Enables TRUE zero-knowledge (no server queries) │
│ ◄────│ {tree_data: [all leaves],
│ │ merkle_root, version}
│ │
│ 6. Generate WebAuthn key (TPM/Secure Enclave) │
│ → Fingerprint prompt creates hardware-bound key │
│ → device_pubkey (ECDSA P-256, non-exportable) │
│ → Stored in TPM 2.0 / Secure Enclave │
│ │
│ 7. Register device in device tree ────►│
│ → device_commitment = Blake3(credential_id) │
│ → Server converts to valid field element if needed │
│ → Server adds to user's device tree (1 of 1024 slots) │
│ ◄────│ {device_position: 0,
│ │ device_tree_root}
│ │
│ 8. LOGIN: Touch fingerprint to authenticate │
│ → WebAuthn verifies hardware-bound key │
│ → Decrypts recovery phrase from local storage │
│ → Re-derives account_id from phrase │
│ │
│ 9. Fetch device Merkle proof ────►│
│ → Sends account_id (derived from phrase) │
│ → Server returns device tree path │
│ ◄────│ {device_path: [siblings],
│ │ device_root}
│ │
│ 10. Compute user Merkle proof CLIENT-SIDE │
│ → Uses local tree from IndexedDB │
│ → Computes path for tree_index │
│ → Server NEVER learns which user! │
│ │
│ 11. Compute nullifier (replay protection) │
│ nullifier = Poseidon(account_id || challenge) │
│ → ONE-TIME USE: Different every login │
│ → Prevents proof replay attacks │
│ │
│ 12. Compute linkability tag (session binding) │
│ linkability_tag = Blake3(device_pubkey || nullifier) │
│ ⚠️ Binds session to specific device+user │
│ │
│ 13. Generate ZK proof (Halo2 PLONK, ~2min for k=14) │
│ Proves in zero-knowledge: │
│ ✓ User exists in Merkle tree (1 of 2^20) │
│ ✓ Device exists in device tree (1 of 2^10) │
│ ✓ account_id hashes to credential_hash │
│ ✓ Nullifier computed correctly │
│ ✓ Timestamp is fresh │
│ WITHOUT revealing which user or device │
│ │
│ 14. Submit proof ────►│
│ {proof, public_inputs, linkability_tag, k=14} │
│ │ • Check device not revoked
│ │ • Verify timestamp (±10min)
│ │ • Rate limit check (5/hour)
│ │ • Check nullifier (replay?)
│ │ • Verify ZK proof (~115s)
│ │ • Mark nullifier as used
│ │
│ ◄────│ {session_token, expires_at}
│ │
│ 15. Verify session (every request) ────►│
│ {session_token, linkability_tag} │
│ │ • Lookup in Redis
│ │ • Verify linkability_tag
│ │ (prevents session theft)
│ │ • Check not spent
│ ◄────│ {valid: true}
│ │
🔍 هل تريد مزيدًا من التفاصيل؟ راجع ARCHITECTURE_FLOW.md للحصول على:
┌─────────────────────────────────────────────────────────────────────────┐ │ SESSION SECURITY MECHANISMS │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ 1. LINKABILITY TAG (Zero-Knowledge Device Binding) │ │ ═══════════════════════════════════════════════════════ │ │ │ │ linkability_tag = Blake3(device_pubkey || nullifier) │ │ │ │ • Computed client-side using hardware-bound device key │ │ • Sent with every session validation request │ │ • Server verifies: stored_tag == provided_tag │ │ │ │ ✅ PREVENTS: Session token theft/replay on different device │ │ ✅ ENSURES: Same user + same device for entire session │ │ ✅ MAINTAINS: Zero-knowledge (server doesn't learn identity) │ │ │ │ ───────────────────────────────────────────────────────────────── │ │ │ │ 2. SESSION TOKEN (Cryptographic Binding) │ │ ═══════════════════════════════════════════════════════ │ │ │ │ session_token = Poseidon(nullifier || timestamp || linkability_tag) │ │ │ │ • Generated server-side after proof verification │ │ • Stored in Redis with linkability_tag as value │ │ • Cannot be forged without knowing nullifier │ │ │ │ ✅ PREVENTS: Token forgery │ │ ✅ ENSURES: Cryptographic binding to proof │ │ │ │ ───────────────────────────────────────────────────────────────── │ │ │ │ 3. NULLIFIER (Replay Protection) │ │ ═══════════════════════════════════════════════════════ │ │ │ │ nullifier = Poseidon(credential_hash || challenge) │ │ │ │ • Unique per authentication attempt │ │ • Tracked in RocksDB (permanent) and Redis (cache) │ │ • Server rejects if nullifier seen before │ │ │ │ ✅ PREVENTS: Proof replay attacks │ │ ✅ ENSURES: One-time use per challenge │ │ │ │ ───────────────────────────────────────────────────────────────── │ │ │ │ 4. TIMESTAMP VALIDATION (Time-Bound Security) │ │ ═══════════════════════════════════════════════════════ │ │ │ │ • Proof includes timestamp (Unix epoch) │ │ • Server validates: |proof_time - server_time| < 5 minutes │ │ • Session TTL: 1 hour (sliding window) │ │ │ │ ✅ PREVENTS: Old proof replay │ │ ✅ ENSURES: Fresh authentication │ │ │ │ ───────────────────────────────────────────────────────────────── │ │ │ │ 5. CHALLENGE-RESPONSE (Freshness Guarantee) │ │ ═══════════════════════════════════════════════════════ │ │ │ │ • Server generates random 32-byte challenge │ │ • Stored in Redis with 5-minute TTL │ │ • Client must include in proof │ │ • Server verifies challenge matches and deletes │ │ │ │ ✅ PREVENTS: Pre-computed proof attacks │ │ ✅ ENSURES: Proof generated for this specific session │ │ │ └─────────────────────────────────────────────────────────────────────────┘
## 🔐 خصائص المعرفة الصفرية
### ما يعرفه الخادم
- ✅ تمت مصادقة أحد أعضاء مجموعة إخفاء الهوية
- ✅ الإثبات صالح تشفيريًا
- ✅ نفس المستخدم والجهاز عبر علامة الارتباط
- ✅ حالة حد المعدل (المحاولات المتبقية)
- ✅ حالة إبطال الجهاز
- ✅ إجمالي عدد المستخدمين المسجلين
- ✅ جذر شجرة Merkle (عام)
### ما لا يمكن للخادم معرفته
- ❌ أي مستخدم محدد (1 من 1M)
- ❌ أي جهاز محدد (1 من 1K لكل مستخدم)
- ❌ عبارة الاسترداد (BIP-39 seed)
- ❌ account_id (مشتق من العبارة)
- ❌ المفتاح الخاص للجهاز (في TPM/Secure Enclave)
- ❌ أي ورقة شجرة تخص أي مستخدم
- ❌ مسار Merkle للمستخدم (يُحسب من جانب العميل)
- ❌ موضع tree_index الخاص بالمستخدم
## 📦 النشر
انظر [DEPLOYMENT.md](https://github.com/deadends/legion/blob/HEAD/docs/DEPLOYMENT.md) للحصول على دليل نشر الإنتاج المفصّل.
### نشر سريع مع Docker```bash
# Production build
docker-compose -f deployment/docker-compose.yml up -d
# Check logs
docker-compose -f deployment/docker-compose.yml logs -f legion-server
# Check health
curl http://localhost/health
RUST_LOG=info LEGION_DATA_PATH=/var/lib/legion/data REDIS_URL=redis://127.0.0.1:6379
## 🧪 الاختبار```bash
# Run all tests
cargo test --workspace
# Run with Redis features
cargo test --workspace --features redis
# Benchmark
cargo bench
المساهمات مرحّب بها! يرجى قراءة CONTRIBUTING.md أولاً.
git checkout -b feature/amazing)git commit -m 'Add amazing feature')git push origin feature/amazing)وجدت مشكلة أمنية؟ راجع SECURITY.md للإفصاح المسؤول.
لا تفتح مشكلات عامة للثغرات الأمنية.
رخصة MIT - راجع ملف LICENSE للتفاصيل.
التغييرات الرئيسية:
البنية المعمارية:
التغييرات الرئيسية:
الإضافات:
إصلاحات أمنية:
بُني بـ ❤️ من أجل الخصوصية والأمان
| الخاصية | الضمان |
|---|
| المصادقة | بدون كلمة مرور (BIP-39 + بصمة الإصبع) |
| إخفاء هوية المستخدم | 1 من 2^20 (1,048,576) |
| إخفاء هوية الجهاز | 1 من 2^10 (1,024) لكل مستخدم |
| خطأ السلامة | 2^-128 |
| نظام الإثبات | Halo2 PLONK (إعداد شفاف) |
| اشتقاق بيانات الاعتماد | Blake3 (بذرة BIP-39) |
| ربط العتاد | WebAuthn Level 2 (TPM/Secure Enclave) |
| الأجهزة المتعددة | حد أقصى جهازان لكل حساب |
| تحديد المعدل | 5 محاولات/ساعة |
| إبطال الجهاز | قائمة سوداء فورية |
| مستوى الأمان | k | زمن الإثبات | حجم الإثبات | حالة الاستخدام |
|---|
| التطوير | 12 | ~30 ثانية | 3.2 كيلوبايت | الاختبار |
| الإنتاج | 14 | ~2 دقيقة | 3.4 كيلوبايت | موصى به |
| المقياس | القيمة | ملاحظات |
|---|
| حجم الإثبات | 3,264 بايت | 3.19 كيلوبايت مضغوط |
| المدخلات العامة | 10 | جذر شجرة المستخدم، جذر شجرة الجهاز، nullifier، إلخ. |
| توليد Params | 7.03 ثانية | إعداد لمرة واحدة لكل قيمة k |
| إنشاء الدائرة | 2.3 ميكروثانية | عبء إضافي لا يُذكر |
| توليد مفتاح التحقق | 1.29 ثانية | توليد مفاتيح لمرة واحدة |
| التحقق من الإثبات | 107.7 مللي ثانية | فحص إثبات ZK الفعلي |
| إجمالي التحقق | 8.43 ثانية | من البداية إلى النهاية (بدون تخزين مؤقت) |
| المقياس | القيمة | ملاحظات |
|---|
| حجم الإثبات | 3,392 بايت | 3.31 كيلوبايت مضغوط |
| المدخلات العامة | 10 | جذر شجرة المستخدم، جذر شجرة الجهاز، nullifier، إلخ. |
| توليد Params | 100.78 ثانية | إعداد لمرة واحدة لكل قيمة k |
| إنشاء الدائرة | 5 ميكروثانية | عبء إضافي لا يُذكر |
| توليد مفتاح التحقق | 12.89 ثانية | توليد مفاتيح لمرة واحدة |
| التحقق من الإثبات | 967.2 مللي ثانية | فحص إثبات ZK الفعلي |
| إجمالي التحقق | 114.65 ثانية | من البداية إلى النهاية (بدون تخزين مؤقت) |