أخبارالمطورينإدخالالمشروع Blockchain شرح الأحداث والمؤتمرات الصحافةالنشرات الإخبارية
اشترك في نشرتنا الإخبارية.
عنوان بريد الكتروني
نحن نحترم خصوصيتك
الرئيسيةالمدونةتطوير Blockchain
مقدمة إلى zk-SNARKs
نظرة عامة على براهين المعرفة الصفرية وكيفية دمج zk-SNARKs في Ethereum. بواسطة ConsenSys 27 مارس 2017 نُشر في 27 مارس 2017
نهدف في هذا المنشور إلى تقديم لمحة عامة عن zk-SNARKs من وجهة نظر عملية. سوف نتعامل مع الرياضيات الفعلية على أنها صندوق أسود ونحاول تطوير بعض الحدس حول كيفية استخدامها. سنقدم أيضًا تطبيقًا بسيطًا للعمل الأخير في دمج zk-SNARKs في Ethereum.
براهين المعرفة الصفرية
الهدف من براهين عدم المعرفة الصفرية هو أن تكون المحققة قادرة على إقناع نفسها بأن المُثبِت يمتلك معرفة معلمة سرية ، تُدعى شاهدًا ، ترضي بعض العلاقة ، دون الكشف عن الشاهد للمحقق أو أي شخص آخر.
يمكننا التفكير في هذا بشكل أكثر تحديدًا على أنه وجود برنامج ، يُشار إليه بـ C ، يأخذ مدخلين: C (x ، w). المدخلات x هي المدخلات العامة ، و w هي المدخلات السرية للشاهد. ناتج البرنامج منطقي ، أي إما صواب أو خطأ. يتم إعطاء الهدف بعد ذلك مدخلات عامة محددة x ، وإثبات أن المُثبِت يعرف إدخالًا سريًا مثل أن C (x ، w) == صحيح.
سنناقش على وجه التحديد براهين المعرفة الصفرية غير التفاعلية. هذا يعني أن الإثبات بحد ذاته عبارة عن كتلة بيانات يمكن التحقق منها دون أي تفاعل من المُثبِت.
برنامج مثال
لنفترض أن بوب حصل على تجزئة H ذات قيمة ما ، وأنه يرغب في الحصول على دليل على أن أليس تعرف القيم التي تجزئة إلى H. عادةً ما تثبت أليس ذلك من خلال إعطاء s إلى Bob ، وبعد ذلك سيحسب بوب التجزئة ويتحقق من ذلك يساوي H..
ومع ذلك ، لنفترض أن أليس لا تريد الكشف عن القيمة لبوب ولكنها بدلاً من ذلك تريد فقط إثبات أنها تعرف القيمة. يمكنها استخدام zk-SNARK لهذا الغرض.
يمكننا وصف سيناريو أليس باستخدام البرنامج التالي ، مكتوبًا هنا كدالة جافا سكريبت:
الوظيفة C (x، w) {return (sha256 (w) == x)؛} لغة الشفرة: JavaScript (javascript)
بمعنى آخر: يأخذ البرنامج علامة تجزئة عامة x وقيمة سرية w ويعيد صحيحًا إذا كان تجزئة SHA-256 لـ w يساوي x.
عند ترجمة مشكلة أليس باستخدام الوظيفة C (x، w) ، نرى أن Alice تحتاج إلى إنشاء دليل على أنها تمتلك أدلة على أن C (H، s) == صحيحة ، دون الحاجة إلى الكشف عن s. هذه هي المشكلة العامة التي تحلها zk-SNARKs.
تعريف zk-SNARK
يتكون zk-SNARK من ثلاث خوارزميات G و P و V محددة على النحو التالي:
يأخذ منشئ المفاتيح G معلمة سرية lambda وبرنامج C ، وينشئ مفتاحين متاحين للجمهور ، ومفتاح إثبات pk ، ومفتاح تحقق vk. هذه المفاتيح هي معلمات عامة يجب إنشاؤها مرة واحدة فقط لبرنامج معين C.
يأخذ المُثبِف P كمدخلات مفتاح إثبات pk ومدخل عام x وشاهد خاص ث. تنشئ الخوارزمية دليلًا على أن prf = P (pk ، x ، w) يعرف أن الشاهد يعرف شاهدًا وأن الشاهد يرضي البرنامج.
المدقق V يحسب V (vk ، x ، prf) الذي يعيد صحيحًا إذا كان الدليل صحيحًا ، والخطأ بخلاف ذلك. وبالتالي فإن هذه الوظيفة تعود إلى الحقيقة إذا كان المُثبِت يعرف أن الشاهد يرضي C (x، w) == صحيح.
لاحظ هنا المعلمة السرية lambda المستخدمة في المولد. تجعل هذه المعلمة أحيانًا من الصعب استخدام zk-SNARKs في تطبيقات العالم الحقيقي. والسبب في ذلك هو أن أي شخص يعرف هذه المعلمة يمكنه إنشاء أدلة مزيفة. على وجه التحديد ، بالنظر إلى أي برنامج C والمدخلات العامة x ، يمكن لأي شخص يعرف lambda إنشاء دليل fake_prf مثل أن V (vk، x، fake_prf) يقيّم إلى صحيح دون معرفة السر..
وبالتالي ، فإن تشغيل المولد في الواقع يتطلب عملية آمنة للغاية للتأكد من عدم معرفة أي شخص بالمعلمة وحفظها في أي مكان. كان هذا سبب مراسم معقدة للغاية أجرى فريق Zcash من أجل إنشاء مفتاح إثبات ومفتاح التحقق ، مع التأكد من إتلاف معلمة “النفايات السامة” لامدا أثناء العملية.
برنامج zk-SNARK للحصول على مثالنا
كيف يمكن لأليس وبوب استخدام zk-SNARK عمليًا حتى تثبت أليس أنها تعرف القيمة السرية في المثال أعلاه?
بادئ ذي بدء ، كما تمت مناقشته أعلاه ، سنستخدم برنامجًا محددًا بالوظيفة التالية:
الوظيفة C (x، w) {return (sha256 (w) == x) ؛ } لغة الكود: JavaScript (javascript)
تتمثل الخطوة الأولى في أن يقوم Bob بتشغيل المولد G لإنشاء مفتاح إثبات pk ومفتاح التحقق vk. أولاً ، قم بإنشاء لامدا عشوائيًا واستخدمها كمدخلات:
(pk ، vk) = G (C ، لامدا)
تعامل مع المعلمة lambda بعناية ، لأنه إذا تعلمت Alice قيمة lambda ، فستتمكن من إنشاء أدلة مزيفة. سيشارك بوب pk و vk مع أليس.
ستلعب أليس الآن دور المُثبِّت. تحتاج إلى إثبات أنها تعرف القيم التي يتم تجزئتها إلى التجزئة المعروفة H. وهي تدير خوارزمية الإثبات P باستخدام المدخلات pk و H و s لإنشاء إثبات prf:
prf = P (pk ، H ، s)
بعد ذلك ، تقدم Alice الدليل prf إلى Bob الذي يدير وظيفة التحقق V (vk ، H ، prf) والتي ستعود صحيحًا في هذه الحالة نظرًا لأن Alice كانت تعرف السر بشكل صحيح. يمكن لبوب أن يكون واثقًا من أن أليس كانت على علم بالسر ، لكن أليس لم تكن بحاجة إلى الكشف عن السر لبوب.
مفاتيح إثبات وتحقق قابلة لإعادة الاستخدام
في المثال أعلاه ، لا يمكن استخدام zk-SNARK إذا أراد بوب أن يثبت لأليس أنه يعرف سرًا ، لأن أليس لا تعرف أن بوب لم يحفظ معلمة lambda. يمكن أن يكون بوب قادرًا بشكل معقول على تزوير البراهين.
إذا كان أحد البرامج مفيدًا للعديد من الأشخاص (مثل مثال Zcash) ، فيمكن لمجموعة مستقلة موثوق بها منفصلة عن Alice and Bob تشغيل المولد وإنشاء مفتاح إثبات pk ومفتاح التحقق vk بطريقة لا يعرفها أحد عن lambda.
يمكن لأي شخص يثق في أن المجموعة لم تغش أن يستخدم هذه المفاتيح للتفاعلات المستقبلية.
zk-SNARKs في Ethereum
بدأ المطورون بالفعل في دمج zk-SNARKs في Ethereum. ماذا يعني هذا تبدو؟ بشكل ملموس ، يمكنك إضافة اللبنات الأساسية لخوارزمية التحقق إلى Ethereum في شكل عقود مجمعة مسبقًا. وإليك الطريقة: قم بتشغيل المولد خارج السلسلة لإنتاج مفتاح الإثبات ومفتاح التحقق. يمكن لأي مُثبَت بعد ذلك استخدام مفتاح الإثبات لإنشاء برهان ، وأيضًا خارج السلسلة. يمكنك بعد ذلك تشغيل خوارزمية التحقق العامة داخل عقد ذكي ، باستخدام الإثبات ومفتاح التحقق والمدخلات العامة كمعلمات إدخال. يمكنك بعد ذلك استخدام نتيجة خوارزمية التحقق لتشغيل نشاط آخر على السلسلة.
مثال: المعاملات السرية
فيما يلي مثال بسيط لكيفية مساعدة zk-SNARKs في الخصوصية على Ethereum. افترض أن لدينا عقد رمزي بسيط. عادةً ما يحتوي عقد الرمز المميز في جوهره على تعيين من العناوين إلى الأرصدة:
تعيين (العنوان => uint256) الأرصدة ؛ لغة الشفرة: JavaScript (javascript)
سنحتفظ بنفس الجوهر الأساسي ، باستثناء استبدال التوازن بقطعة التوازن:
تعيين (العنوان => bytes32) BalanceHashes ؛ لغة الكود: JavaScript (javascript)
لن نخفي المرسل أو المستلم للمعاملات. لكننا سنخفي الأرصدة والمبالغ المرسلة. يشار إلى هذه الخاصية أحيانًا باسم المعاملات السرية.
سنستخدم رمزين zk-SNARKs لإرسال الرموز المميزة من حساب إلى آخر. يتم إنشاء دليل واحد بواسطة المرسل وآخر بواسطة المتلقي.
عادة في عقد الرمز المميز لكي تكون المعاملة ذات القيمة الحجمية صالحة ، نحتاج إلى التحقق مما يلي:
أرصدة [من العنوان] >= القيمة
تحتاج zk-SNARKs الخاصة بنا إلى إثبات أن هذا صحيح ، بالإضافة إلى أن التجزئة المحدثة تتطابق مع الأرصدة المحدثة.
الفكرة الرئيسية هي أن المرسل سيستخدم رصيد البداية وقيمة المعاملة كمدخلات خاصة. كمدخلات عامة ، يستخدمون تجزئات توازن البداية والتوازن الختامي والقيمة. وبالمثل ، سيستخدم المتلقي رصيد البداية والقيمة كمدخلات سرية. كمدخلات عامة ، يستخدمون تجزئات توازن البداية والتوازن الختامي والقيمة.
يوجد أدناه البرنامج الذي سنستخدمه للمرسل zk-SNARK ، حيث يمثل x المدخلات العامة كما كان من قبل ، ويمثل w المدخلات الخاصة.
function senderFunction (x، w) {return (w.senderBalanceBefore > ث القيمة && sha256 (w.value) == x.hashValue && sha256 (w.senderBalanceBefore) == x.hashSenderBalanceBefore && sha256 (w.senderBalanceBefore – w.value) == x.hashSenderBalanceAfter)} لغة الشفرة: جافا سكريبت (جافا سكريبت)
البرنامج المستخدم من قبل المتلقي أدناه:
وظيفة ReceiverFunction (x، w) {return (sha256 (w.value) == x.hashValue && sha256 (w.receiverBalanceBefore) == x.hashReceiverBalanceBefore && sha256 (w.receiverBalanceBefore + w.value) == x.hashReceiverBalanceAfter)} لغة الترميز: جافا سكريبت (جافا سكريبت)
تتحقق البرامج من أن رصيد الإرسال أكبر من القيمة المرسلة ، بالإضافة إلى التحقق من تطابق جميع التجزئة. يمكن لمجموعة موثوق بها من الأشخاص إنشاء مفاتيح الإثبات والتحقق لـ zk-SNARKs الخاصة بنا. دعونا نسميها confTxSenderPk و confTxSenderVk و confTxReceiverPk و confTxReceiverVk.
سيبدو استخدام zk-SNARKs في عقد رمزي مشابهًا لما يلي:
نقل الوظيفة (العنوان _to، bytes32 hashValue، bytes32 hashSenderBalanceAfter، bytes32 hashReceiverBalanceAfter، bytes zkProofSender، bytes zkProofReceiver) {bytes32 hashSenderBalanceBefore = BalanceHashes [msg.sender] ؛ bytes32 hashReceiverBalanceBefore = BalanceHashes [_to]؛ bool senderProofIsCorrect = zksnarkverify (confTxSenderVk، [hashSenderBalanceBefore، hashSenderBalanceAfter، hashValue]، zkProofSender)؛ bool receiverProofIsCorrect = zksnarkverify (confTxReceiverVk، [hashReceiverBalanceBefore، hashReceiverBalanceAfter، hashValue]، zkProofReceiver) ؛ إذا كان (senderProofIsCorrect && ReceiverProofIsCorrect) {BalanceHashes [msg.sender] = hashSenderBalanceAfter؛ BalanceHashes [_to] = hashReceiverBalanceAfter ، }} لغة الشفرة: JavaScript (javascript)
وبالتالي ، فإن التحديثات الوحيدة على blockchain هي تجزئة الأرصدة وليس الأرصدة نفسها. ومع ذلك ، يمكننا معرفة أنه تم تحديث جميع الأرصدة بشكل صحيح لأنه يمكننا التحقق بأنفسنا من التحقق من الدليل.
تفاصيل
يهدف مخطط المعاملات السرية أعلاه بشكل أساسي إلى إعطاء مثال عملي لكيفية استخدام zk-SNARKs على Ethereum. لإنشاء نظام معاملات سرية قوي ، سنحتاج إلى معالجة عدد من المشكلات:
- سيحتاج المستخدمون إلى تتبع أرصدتهم من جانب العميل ، وإذا فقدت الرصيد ، فلا يمكن استرداد هذه الرموز المميزة. ربما يمكن تخزين الأرصدة مشفرة على السلسلة باستخدام مفتاح مشتق من مفتاح التوقيع.
- تحتاج الأرصدة إلى استخدام 32 بايت من البيانات وترميز الانتروبيا لمنع القدرة على عكس التجزئة لمعرفة الأرصدة.
- تحتاج إلى التعامل مع حالة الحافة للإرسال إلى عنوان غير مستخدم.
- يحتاج المرسل إلى التفاعل مع المتلقي من أجل الإرسال. من المحتمل أن يكون لدى المرء نظام يستخدم فيه المرسل إثباته لبدء المعاملة. يمكن للمستقبل بعد ذلك أن يرى على blockchain أن لديه “معاملة واردة معلقة” ويمكنه إنهاءها.
اشترك في النشرة الإخبارية لدينا للحصول على أحدث أخبار Ethereum وحلول المؤسسات وموارد المطورين والمزيد.ندوة عبر الإنترنت
كيفية بناء منتج Blockchain ناجح
ندوة عبر الإنترنت
كيفية إعداد وتشغيل عقدة إيثريوم
ندوة عبر الإنترنت
كيفية بناء Ethereum API الخاصة بك
ندوة عبر الإنترنت
كيفية إنشاء رمز اجتماعي
ندوة عبر الإنترنت
استخدام أدوات الأمن في تطوير العقود الذكية
ندوة عبر الإنترنت