تقني › من أرسل؟

Key image

البصمة التي يتركها المخرج عند إنفاقه — مرة واحدة بالضبط

باختصار

key image (صورة المفتاح) هي I = x·Hp(P)، حيث P هو المفتاح لمرة واحدة للمخرج وx مفتاحه الخاص. لمخرج معيّن تكون key image هي نفسها دائمًا، لكنها لا تكشف أي مخرج هو. تخزّن الشبكة جميع key images وترفض أي معاملة تحتوي على واحدة مكررة.

مشكلة الإنفاق المزدوج

في Bitcoin يسهل كشف الإنفاق المزدوج: كل مدخل يشير مباشرة إلى المخرج الذي ينفقه، والعقدة تتذكر أن المخرج قد أُنفق (مجموعة UTXO). أما في Monero فيشير المدخل إلى 16 مخرجًا، ولا يُعرف أيها الحقيقي. لذا يستحيل "وسم المخرج المُنفَق". نحتاج إلى طريقة لوسم الإنفاق دون كشف ما أُنفق.

الحل

I = x · Hp(P)

لماذا ينجح هذا:

  • حتمية. x وP ثابتان للمخرج، لذا فإن I فريدة. وإنفاق المخرج مرة أخرى يعني نشر I نفسها.
  • غير قابلة للربط. للتحقق من أن I تطابق P تحتاج إلى x: المراقب الخارجي يرى نقطتين "عشوائيتين" Hp(P) وI ولا يستطيع إثبات الصلة بينهما (مسألة Diffie–Hellman).
  • غير قابلة للتزوير. يُثبت التوقيع الحلقي القابل للربط أن I حُسبت من x نفسه الخاص بأحد مفاتيح الحلقة.

لماذا Hp(P) وليس G ببساطة؟ لأنه حينها I = x·G = P — فتساوي key image المفتاح العام للمخرج ويصبح الإنفاق مرئيًا فورًا. تعطي Hp نقطة لا يعرف أحد لوغاريتمها — "أساسًا ثانيًا" فريدًا لكل مخرج.

معاملة جديدةkey image I = 3f9a… قاعدة بيانات العقدة a17c… 0be2… 3f9a… ← موجودة مسبقًا! … ✗ رفض: إنفاق مزدوج لا تعرف العقدة أي مخرج أُنفق — بل فقط أن هذه البصمة شوهدت من قبل

فحص الزمرة الجزئية: خطأ 2017

يحتوي Ed25519 على نقاط أكثر بثماني مرات من الزمرة الجزئية لـ G. إضافة نقطة ذات رتبة صغيرة T (حيث 8·T = 0) إلى I تعطي نقطة مختلفة I' = I + T، وفي ظروف معينة كان التوقيع الحلقي يظل صالحًا. مخرج واحد — حتى 8 key images مختلفة — حتى 8 عمليات إنفاق. في 2017 اكتُشف هذا الخطأ في شيفرة CryptoNote الأصلية؛ وأصلحه Monero قبل استغلاله، بينما استُغل في Bytecoin.

الإصلاح: تتحقق العقدة من أن l·I = 0، أي أن I تقع في الزمرة الجزئية الصحيحة.

Key images ومحافظ العرض فقط

لتعرف المحفظة ما إذا كان مخرجك قد أُنفق، تحسب key image الخاصة به وتبحث عنها في سلسلة الكتل. وهذا يتطلب x = Hs(8aR ‖ i) + b — أي مفتاح الإنفاق. لذا لا ترى محفظة العرض فقط عمليات الإنفاق وتُظهر رصيدًا مضخّمًا. والحل البديل هو تصدير key images من المحفظة الكاملة. ويضيف Carrot مفتاحًا مخصصًا لهذا الغرض.

Key images في FCMP++

في FCMP++ تبقى key image: L = x·Hp(O). ما يتغير هو طريقة إثبات صلتها بالمخرج — فبدلًا من الحلقة، برهان عضوية في شجرة جميع المخرجات. ونتيجة مهمة: جميع key images المنشورة بالفعل في معاملات RingCT تحتفظ بمعناها — فلا يمكن إنفاق مخرج قديم مرة ثانية بعد الانتقال.