تقني › التشفير

دوال التجزئة: Keccak وHs وHp

كيف يحوّل Monero بايتات عشوائية إلى عدد أو إلى نقطة

باختصار

يستخدم Monero دالة التجزئة Keccak-256 (Keccak الأصلية، وليست SHA3-256 المعيارية). وتُبنى منها دالتان مشتقتان: Hs — "التجزئة إلى عدد قياسي"، وHp — "التجزئة إلى نقطة".

Keccak-256

تأخذ دالة التجزئة أي بيانات وتُخرج 32 بايتًا تبدو عشوائية. تغيير بت واحد في المدخل يغيّر المخرج كله؛ وإيجاد المدخل من المخرج، أو مدخلين لهما المخرج نفسه، أمر غير ممكن عمليًا.

يستخدم Monero (مثل Ethereum) خوارزمية Keccak كما فازت في مسابقة SHA-3 — قبل أن يغيّر NIST بايت الحشو. وبسبب هذه التفصيلة تعطي sha3_256() من المكتبات القياسية نتيجة مختلفة. إذا لم تتطابق نتائج شيفرتك مع Monero، فتحقق من هذا أولًا.

الدالةتجزئة السلسلة الفارغة
Keccak-256 (Monero)c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
SHA3-256 (NIST)a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a

في شيفرة Monero تُسمّى هذه الدالة cn_fast_hash.

Hs: التجزئة إلى عدد قياسي

كثيرًا ما نحتاج لا إلى بايتات فحسب بل إلى عدد قياسي (scalar) — عدد بترديد l (رتبة نقطة الأساس). وHs تفعل ذلك مباشرة:

Hs(data) = Keccak256(data) mod l تُقرأ بايتات التجزئة الـ32 كعدد بترتيب little-endian ثم تُختزل بترديد l (في الشيفرة: sc_reduce32)

أين تُستخدم Hs:

Hp: التجزئة إلى نقطة

أحيانًا نحتاج إلى نقطة لا يعرف أحد لوغاريتمها المتقطع. لا يمكننا ببساطة أخذ Hs(data)·G — فعندها يكون اللوغاريتم هو Hs(data) ويعرفه الجميع. تبني Hp نقطة مباشرة من التجزئة عبر تحويل خاص (في Monero نسخة من Elligator 2، الدالة ge_fromfe_frombytes_vartime)، ثم تضربها في العامل المرافق 8 لتقع النقطة في الزمرة الجزئية الصحيحة.

Hp(data) = 8 · map_to_curve( Keccak256(data) )

أين تُستخدم Hp:

  • key images: I = x·Hp(P) — الاستخدام الرئيسي؛
  • المولّد الثاني H لالتزامات Pedersen: H = Hp(G) (مع اختلافات في تفاصيل الترميز). لا أحد يعرف k بحيث H = k·G — وهذا أمر حاسم كي لا يمكن تزوير المبالغ.
فصل النطاقات

من الممارسات الجيدة أن تُسبق البيانات بسلسلة وسم ("SubAddr"، "view_tag"، "amount") قبل التجزئة، كي لا يمكن تمرير تجزئة حُسبت لغرض ما على أنها لغرض آخر. شيفرة CryptoNote القديمة فيها وسوم قليلة؛ أما الأجزاء الأحدث (view tags، Carrot، FCMP++) فتستخدمها بشكل منهجي.