
دراسة تعليمية لإنتروبيا مفاتيح بيتكوين: تعداد محافظ RNG الضعيفة (فئة Milk Sad / CVE-2023-39910) مقابل عدم جدوى كسر مفتاح جيد بالقوة العمياء.
| التجربة | فضاء البحث | هل هو مجدٍ؟ | ما الذي تعلّمه |
|---|
weak_entropy — تعداد فضاء محافظ بعشوائية ضعيفة | 2³² (مولّد RNG سيئ) | نعم، في غضون أيام | المحفظة بقوة العشوائية التي تقف خلفها فقط. |
blind_search — هجوم القوة العمياء على فضاء مفاتيح جيد | 2¹⁶⁰ (مولّد RNG جيد) | لا، أبدًا | مع عشوائية حقيقية، يصبح فضاء المفاتيح غير قابل للبحث فيزيائيًا. |
المغزى كله هو التباين: تُسرَق المفاتيح بمهاجمة العشوائية السيئة، لا بمحاولة التفوق حسابيًا على العشوائية الجيدة. كلا التجربتين تنتجان نفس النوع من عناوين الشبكة الرئيسية الحقيقية، لذا فإن المتغير الوحيد هو العشوائية.
هذا المستودع مخصّص للتوعية الدفاعية والأبحاث الأمنية: لفهم لماذا كانت أخطاء المحافظ ذات العشوائية الضعيفة (Milk Sad / CVE-2023-39910، وخطأ إضافة Trust Wallet عام 2018، وما يشابهها) كارثية، ولماذا لا يمكن هجوم القوة العمياء على مفتاح مولّد بشكل صحيح.
weak_entropy يعدّد فضاءً اصطناعيًا مكتفيًا بذاته. دالّة weak_entropy() هي نموذج مقصود لفئة الثغرة — مولّد PRNG ببتات 32 يغذّي BIP39 — وليس نسخة مطابقة بايتًا-ببايت لمولّد RNG خاص بأي محفظة حقيقية. العناوين التي ينتجها لا تطابق محفظة أي شخص حقيقية.blind_search هو بحث قراءة-فقط عن الأرصدة ضد عقدتك الخاصة. لا يشتق أي مفاتيح ولا يمكنه إنفاق أي شيء؛ وضعه الأساسي يقيس عبثية البحث الأعمى.استخدمه على محافظ تملكها، أو على testnet، أو كبيئة اختبار معزولة. لا توجّهه نحو أموال الآخرين.
لـالأغراض التعليمية والأبحاث الأمنية المصرّح بها فقط. استخدمه حصريًا على مفاتيح ومحافظ وأنظمة تملكها أو لديك إذن كتابي صريح لاختبارها. الوصول غير المصرّح إلى محافظ أو أنظمة الآخرين، وسرقة الأصول الرقمية، أمور غير قانونية بموجب قوانين مثل CFAA الأميركية (18 U.S.C. § 1030)، وقانون إساءة استخدام الحواسيب البريطاني لعام 1990، وتوجيه الاتحاد الأوروبي 2013/40/EU — بغض النظر عن الوسائل التقنية. مُقدَّم "كما هو"، دون أي ضمان؛ المؤلفون لا يتحملون أي مسؤولية عن إساءة الاستخدام. هذه ليست استشارة قانونية. الشروط الكاملة وإرشادات الإفصاح المسؤول: DISCLAIMER.md.
أمان المحفظة محدود بـالعشوائية التي دخلت في بذرة الإنشاء، وليس بقوة SHA-256 / PBKDF2 / secp256k1 في المراحل اللاحقة.
يحوّل BIP39 العشوائية إلى عبارة استعادة، ويمددها PBKDF2 إلى بذرة، ويشتق BIP32 شجرة مفاتيح. كل ذلك قوي. لكن لا شيء من ذلك يضيف عشوائية — إذا كانت البذرة مستخرجة من مجموعة صغيرة، فإن كل عنوان يمكن أن تنتجه المحفظة قابل للتعداد، ولا كمية تجزئة تخفي ذلك.
bitcoin-security/
├── bitcoin_security/ # the package
│ ├── derivation.py # shared core: BIP39 + BIP32 + P2PKH/WIF
│ ├── data/english.txt # BIP39 English wordlist (2048 words)
│ ├── weak_entropy/ # Experiment 1 — enumerable weak space
│ │ ├── enumerate.py # recovery demo + full-space dump
│ │ └── README.md
│ └── blind_search/ # Experiment 2 — futile brute-force search
│ ├── scan.py # UTXO-set balance scanner + odds
│ └── README.md
├── tests/ # offline test suites (no node/network)
│ ├── test_blind_search_addresses.py
│ └── test_blind_search_pipeline.py
├── docs/FINDINGS.md # benchmarks + exact full-space size derivation
├── pyproject.toml
├── requirements.txt
└── LICENSE
تعكس الشجرة الفكرة: نواة derivation واحدة مشتركة، وتجربتان تستخدمانها للوصول إلى استنتاجين متعاكسين حول نفس فضاء العناوين.
pip install -r requirements.txt # runtime deps
# optional — installs the package + `bsec-enumerate` / `bsec-scan` commands:
pip install -e .
مكتبة coincurve (libsecp256k1 الأصلية) تجعل الاشتقاق أسرع بنحو ~5× لكنها اختيارية — إذ يقع derivation.py في وضع التراجع إلى ecdsa النقي بلغة Python مع مخرجات مطابقة تمامًا. لا شيء هنا يلمس الشبكة باستثناء علامة --check-balance الاختيارية وblind_search (والذي يحتاج عقدة Bitcoin محلية).
كل شيء يعمل كوحدة من جذر المستودع؛ لا حاجة للتثبيت:
python3 -m bitcoin_security.weak_entropy --help
python3 -m bitcoin_security.blind_search --help
weak_entropy: العشوائية الضعيفة قابلة للتعدادالبايتات الستة عشر "العشوائية" لـ BIP39 في المحفظة تأتي في الواقع من بذرة 32-بت. الاشتقاق الكامل حقيقي ومتحقق منه وفق متجهات المواصفات.
seed32 ──MT19937──▶ 16-byte entropy ──BIP39──▶ mnemonic ──PBKDF2(2048)──▶ 64-byte seed
│
address ◀──hash160──── pubkey ◀──BIP32 m/44'/0'/0'/0/0
# Recovery: derive a victim wallet from a weak seed, then recover its full
# mnemonic + private key knowing only the public address.
python3 -m bitcoin_security.weak_entropy
# Expand one seed into every form.
python3 -m bitcoin_security.weak_entropy --show 3571
# Materialize the whole 2**32 space to sharded, resumable files.
python3 -m bitcoin_security.weak_entropy --dump-all --out-dir space_dump --max-file-mb 1000
الصفوف ضئيلة (address <TAB> seed32) لأن كل صيغة أخرى هي دالة حتمية لـ seed32، يُعاد توليدها عند الطلب باستخدام --show. التفريغ قابل للاستئناف على مستوى الأجزاء (مُتحقَّق منه لإعادة إنتاج تغطية متواصلة، بلا فجوات، وبلا تكرار). مرجع كامل للعلامات في weak_entropy/README.md.
تحذير متعلق بالحجم. التفريغ الكامل 2³² يبلغ ~196 غيغابايت (في الوضع الأدنى) أو ~1.05 تيرابايت (
--full) ويستغرق أيامًا حتى مع الخلفية الأصلية — انظرdocs/FINDINGS.md. لن تحتاج تقريبًا أبدًا إلى الكل؛ ففرّغ شريحة محدودة للفحص.
blind_search: لا يمكنك كسر مفتاح جيد بالقوة العمياءماسح أرصدة حقيقي وعامل على مجموعة UTXO الخاصة بعقدة محلية (مع دعم pruning) عبر scantxoutset. الغرض منه هو النتيجة الصفرية: ابحث في فضاء العناوين بشكل أعمى، وقِس أنك لا تجد شيئًا، واطبع الحسابات التي تُظهر أنك لن تجد شيئًا دائمًا.
python3 -m bitcoin_security.blind_search --odds-only # just the math, no node
python3 -m bitcoin_security.blind_search --random 200000 --odds # search 200k random addrs, then the math
python3 -m bitcoin_security.blind_search --control # verify the pipeline finds known-funded addrs
النتيجة: الفضاء هو 2¹⁶⁰ ≈ 1.46×10⁴⁸؛ نحو ~55 مليون عنوان تحمل رصيدًا؛ إذًا احتمال أن يكون عنوان عشوائي ممولًا هو ~3.8×10⁻⁴¹. حتى بمعدل مليار عنوان في الثانية، ستنتظر نحو ~8×10²³ عامًا — أي حوالي ~61 تريليون ضعف عمر الكون. ليست مشكلة عتاد: بحد لانداور، مجرد العد إلى 2¹⁶⁰ يتجاوز إجمالي الطاقة المتبقية للشمس. إعداد العقدة في blind_search/README.md.
كلا التجربتين تنتجان نفس النوع من العناوين. الاختلاف الوحيد هو حجم المجموعة التي سُحبت منها البذرة:
تلك الفجوة — 128 بتًا — هي اللعبة كلها. كل عملية سرقة حقيقية في هذه الفئة عاشت داخل تلك الفجوة.
python3 tests/test_blind_search_addresses.py # BIP-173/350/380 address vectors
python3 tests/test_blind_search_pipeline.py # scan pipeline, RPC stubbed
python3 -m bitcoin_security.derivation # derivation self-test (spec vectors)
التفاصيل الكاملة والمنهجيات ومواصفات الجهاز في docs/FINDINGS.md.
ecdsa النقي بلغة Python بمكتبة coincurve (libsecp256k1) قلّص زمن اشتقاق كل محفظة من 3.02 مللي ثانية إلى 0.591 مللي ثانية (~5.1×) على Apple M3 Max؛ أما الحد الأدنى المتبقي فهو PBKDF2-HMAC-SHA512 ×2048 عند 0.463 مللي ثانية/محفظة.--full، من صيغة مغلقة دقيقة لأرقام seed32 بالإضافة إلى متوسط مُقاس لطول العنوان.MIT — انظر LICENSE. شروط الاستخدام وإرشادات الإفصاح المسؤول: DISCLAIMER.md. الإبلاغ: SECURITY.md.